You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by an...@apache.org on 2016/11/14 23:50:48 UTC

[01/56] [abbrv] libcloud git commit: Removed sdist

Repository: libcloud
Updated Branches:
  refs/heads/trunk df93d65f6 -> 32558b522


http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/test/test_utils.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/test/test_utils.py b/apache-libcloud-1.0.0rc2/libcloud/test/test_utils.py
deleted file mode 100644
index 4c1b6c0..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/test/test_utils.py
+++ /dev/null
@@ -1,385 +0,0 @@
-# -*- coding: utf-8 -*-
-# Licensed to the Apache Software Foundation (ASF) under one or more�
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 sys
-import socket
-import codecs
-import unittest
-import warnings
-import os.path
-
-from itertools import chain
-
-# In Python > 2.7 DeprecationWarnings are disabled by default
-warnings.simplefilter('default')
-
-import libcloud.utils.files
-
-from libcloud.utils.misc import get_driver, set_driver
-
-from libcloud.utils.py3 import PY3
-from libcloud.utils.py3 import StringIO
-from libcloud.utils.py3 import b
-from libcloud.utils.py3 import bchr
-from libcloud.utils.py3 import hexadigits
-from libcloud.utils.py3 import urlquote
-from libcloud.compute.types import Provider
-from libcloud.compute.providers import DRIVERS
-from libcloud.utils.misc import get_secure_random_string
-from libcloud.utils.networking import is_public_subnet
-from libcloud.utils.networking import is_private_subnet
-from libcloud.utils.networking import is_valid_ip_address
-from libcloud.utils.networking import join_ipv4_segments
-from libcloud.utils.networking import increment_ipv4_segments
-from libcloud.storage.drivers.dummy import DummyIterator
-
-
-WARNINGS_BUFFER = []
-
-if PY3:
-    from io import FileIO as file
-
-
-def show_warning(msg, cat, fname, lno, line=None):
-    WARNINGS_BUFFER.append((msg, cat, fname, lno))
-
-original_func = warnings.showwarning
-
-
-class TestUtils(unittest.TestCase):
-    def setUp(self):
-        global WARNINGS_BUFFER
-        WARNINGS_BUFFER = []
-
-    def tearDown(self):
-        global WARNINGS_BUFFER
-        WARNINGS_BUFFER = []
-        warnings.showwarning = original_func
-
-    def test_guess_file_mime_type(self):
-        file_path = os.path.abspath(__file__)
-        mimetype, encoding = libcloud.utils.files.guess_file_mime_type(
-            file_path=file_path)
-
-        self.assertTrue(mimetype.find('python') != -1)
-
-    def test_get_driver(self):
-        driver = get_driver(drivers=DRIVERS, provider=Provider.DUMMY)
-        self.assertTrue(driver is not None)
-
-        try:
-            driver = get_driver(drivers=DRIVERS, provider='fooba')
-        except AttributeError:
-            pass
-        else:
-            self.fail('Invalid provider, but an exception was not thrown')
-
-    def test_set_driver(self):
-        # Set an existing driver
-        try:
-            driver = set_driver(DRIVERS, Provider.DUMMY,
-                                'libcloud.storage.drivers.dummy',
-                                'DummyStorageDriver')
-        except AttributeError:
-            pass
-
-        # Register a new driver
-        driver = set_driver(DRIVERS, 'testingset',
-                            'libcloud.storage.drivers.dummy',
-                            'DummyStorageDriver')
-
-        self.assertTrue(driver is not None)
-
-        # Register it again
-        try:
-            set_driver(DRIVERS, 'testingset',
-                       'libcloud.storage.drivers.dummy',
-                       'DummyStorageDriver')
-        except AttributeError:
-            pass
-
-        # Register an invalid module
-        try:
-            set_driver(DRIVERS, 'testingnew',
-                       'libcloud.storage.drivers.dummy1',
-                       'DummyStorageDriver')
-        except ImportError:
-            pass
-
-        # Register an invalid class
-        try:
-            set_driver(DRIVERS, 'testingnew',
-                       'libcloud.storage.drivers.dummy',
-                       'DummyStorageDriver1')
-        except AttributeError:
-            pass
-
-    def test_deprecated_warning(self):
-        warnings.showwarning = show_warning
-
-        libcloud.utils.SHOW_DEPRECATION_WARNING = False
-        self.assertEqual(len(WARNINGS_BUFFER), 0)
-        libcloud.utils.deprecated_warning('test_module')
-        self.assertEqual(len(WARNINGS_BUFFER), 0)
-
-        libcloud.utils.SHOW_DEPRECATION_WARNING = True
-        self.assertEqual(len(WARNINGS_BUFFER), 0)
-        libcloud.utils.deprecated_warning('test_module')
-        self.assertEqual(len(WARNINGS_BUFFER), 1)
-
-    def test_in_development_warning(self):
-        warnings.showwarning = show_warning
-
-        libcloud.utils.SHOW_IN_DEVELOPMENT_WARNING = False
-        self.assertEqual(len(WARNINGS_BUFFER), 0)
-        libcloud.utils.in_development_warning('test_module')
-        self.assertEqual(len(WARNINGS_BUFFER), 0)
-
-        libcloud.utils.SHOW_IN_DEVELOPMENT_WARNING = True
-        self.assertEqual(len(WARNINGS_BUFFER), 0)
-        libcloud.utils.in_development_warning('test_module')
-        self.assertEqual(len(WARNINGS_BUFFER), 1)
-
-    def test_read_in_chunks_iterator_no_data(self):
-        iterator = DummyIterator()
-        generator1 = libcloud.utils.files.read_in_chunks(iterator=iterator,
-                                                         yield_empty=False)
-        generator2 = libcloud.utils.files.read_in_chunks(iterator=iterator,
-                                                         yield_empty=True)
-
-        # yield_empty=False
-        count = 0
-        for data in generator1:
-            count += 1
-            self.assertEqual(data, b(''))
-
-        self.assertEqual(count, 0)
-
-        # yield_empty=True
-        count = 0
-        for data in generator2:
-            count += 1
-            self.assertEqual(data, b(''))
-
-        self.assertEqual(count, 1)
-
-    def test_read_in_chunks_iterator(self):
-        def iterator():
-            for x in range(0, 1000):
-                yield 'aa'
-
-        for result in libcloud.utils.files.read_in_chunks(iterator(),
-                                                          chunk_size=10,
-                                                          fill_size=False):
-            self.assertEqual(result, b('aa'))
-
-        for result in libcloud.utils.files.read_in_chunks(iterator(), chunk_size=10,
-                                                          fill_size=True):
-            self.assertEqual(result, b('aaaaaaaaaa'))
-
-    def test_read_in_chunks_filelike(self):
-            class FakeFile(file):
-                def __init__(self):
-                    self.remaining = 500
-
-                def read(self, size):
-                    self.remaining -= 1
-                    if self.remaining == 0:
-                        return ''
-                    return 'b' * (size + 1)
-
-            for index, result in enumerate(libcloud.utils.files.read_in_chunks(
-                                           FakeFile(), chunk_size=10,
-                                           fill_size=False)):
-                self.assertEqual(result, b('b' * 11))
-
-            self.assertEqual(index, 498)
-
-            for index, result in enumerate(libcloud.utils.files.read_in_chunks(
-                                           FakeFile(), chunk_size=10,
-                                           fill_size=True)):
-                if index != 548:
-                    self.assertEqual(result, b('b' * 10))
-                else:
-                    self.assertEqual(result, b('b' * 9))
-
-            self.assertEqual(index, 548)
-
-    def test_exhaust_iterator(self):
-        def iterator_func():
-            for x in range(0, 1000):
-                yield 'aa'
-
-        data = b('aa' * 1000)
-        iterator = libcloud.utils.files.read_in_chunks(iterator=iterator_func())
-        result = libcloud.utils.files.exhaust_iterator(iterator=iterator)
-        self.assertEqual(result, data)
-
-        result = libcloud.utils.files.exhaust_iterator(iterator=iterator_func())
-        self.assertEqual(result, data)
-
-        data = '12345678990'
-        iterator = StringIO(data)
-        result = libcloud.utils.files.exhaust_iterator(iterator=iterator)
-        self.assertEqual(result, b(data))
-
-    def test_exhaust_iterator_empty_iterator(self):
-        data = ''
-        iterator = StringIO(data)
-        result = libcloud.utils.files.exhaust_iterator(iterator=iterator)
-        self.assertEqual(result, b(data))
-
-    def test_unicode_urlquote(self):
-        # Regression tests for LIBCLOUD-429
-        if PY3:
-            # Note: this is a unicode literal
-            val = '\xe9'
-        else:
-            val = codecs.unicode_escape_decode('\xe9')[0]
-
-        uri = urlquote(val)
-        self.assertEqual(b(uri), b('%C3%A9'))
-
-        # Unicode without unicode characters
-        uri = urlquote('~abc')
-        self.assertEqual(b(uri), b('%7Eabc'))
-
-        # Already-encoded bytestring without unicode characters
-        uri = urlquote(b('~abc'))
-        self.assertEqual(b(uri), b('%7Eabc'))
-
-    def test_get_secure_random_string(self):
-        for i in range(1, 500):
-            value = get_secure_random_string(size=i)
-            self.assertEqual(len(value), i)
-
-    def test_hexadigits(self):
-        self.assertEqual(hexadigits(b('')), [])
-        self.assertEqual(hexadigits(b('a')), ['61'])
-        self.assertEqual(hexadigits(b('AZaz09-')),
-                         ['41', '5a', '61', '7a', '30', '39', '2d'])
-
-    def test_bchr(self):
-        if PY3:
-            self.assertEqual(bchr(0), b'\x00')
-            self.assertEqual(bchr(97), b'a')
-        else:
-            self.assertEqual(bchr(0), '\x00')
-            self.assertEqual(bchr(97), 'a')
-
-
-class NetworkingUtilsTestCase(unittest.TestCase):
-    def test_is_public_and_is_private_subnet(self):
-        public_ips = [
-            '213.151.0.8',
-            '86.87.86.1',
-            '8.8.8.8',
-            '8.8.4.4'
-        ]
-
-        private_ips = [
-            '192.168.1.100',
-            '10.0.0.1',
-            '172.16.0.0'
-        ]
-
-        for address in public_ips:
-            is_public = is_public_subnet(ip=address)
-            is_private = is_private_subnet(ip=address)
-
-            self.assertTrue(is_public)
-            self.assertFalse(is_private)
-
-        for address in private_ips:
-            is_public = is_public_subnet(ip=address)
-            is_private = is_private_subnet(ip=address)
-
-            self.assertFalse(is_public)
-            self.assertTrue(is_private)
-
-    def test_is_valid_ip_address(self):
-        valid_ipv4_addresses = [
-            '192.168.1.100',
-            '10.0.0.1',
-            '213.151.0.8',
-            '77.77.77.77'
-        ]
-
-        invalid_ipv4_addresses = [
-            '10.1',
-            '256.256.256.256',
-            '0.567.567.567',
-            '192.168.0.257'
-        ]
-
-        valid_ipv6_addresses = [
-            'fe80::200:5aee:feaa:20a2',
-            '2607:f0d0:1002:51::4',
-            '2607:f0d0:1002:0051:0000:0000:0000:0004',
-            '::1'
-        ]
-
-        invalid_ipv6_addresses = [
-            '2607:f0d',
-            '2607:f0d0:0004',
-        ]
-
-        for address in valid_ipv4_addresses:
-            status = is_valid_ip_address(address=address,
-                                         family=socket.AF_INET)
-            self.assertTrue(status)
-
-        for address in valid_ipv6_addresses:
-            status = is_valid_ip_address(address=address,
-                                         family=socket.AF_INET6)
-            self.assertTrue(status)
-
-        for address in chain(invalid_ipv4_addresses, invalid_ipv6_addresses):
-            status = is_valid_ip_address(address=address,
-                                         family=socket.AF_INET)
-            self.assertFalse(status)
-
-        for address in chain(invalid_ipv4_addresses, invalid_ipv6_addresses):
-            status = is_valid_ip_address(address=address,
-                                         family=socket.AF_INET6)
-            self.assertFalse(status)
-
-    def test_join_ipv4_segments(self):
-        values = [
-            (('127', '0', '0', '1'), '127.0.0.1'),
-            (('255', '255', '255', '0'), '255.255.255.0'),
-        ]
-
-        for segments, joined_ip in values:
-            result = join_ipv4_segments(segments=segments)
-            self.assertEqual(result, joined_ip)
-
-    def test_increment_ipv4_segments(self):
-        values = [
-            (('127', '0', '0', '1'), '127.0.0.2'),
-            (('255', '255', '255', '0'), '255.255.255.1'),
-            (('254', '255', '255', '255'), '255.0.0.0'),
-            (('100', '1', '0', '255'), '100.1.1.0'),
-        ]
-
-        for segments, incremented_ip in values:
-            result = increment_ipv4_segments(segments=segments)
-            result = join_ipv4_segments(segments=result)
-            self.assertEqual(result, incremented_ip)
-
-
-if __name__ == '__main__':
-    sys.exit(unittest.main())

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/requirements-tests.txt
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/requirements-tests.txt b/apache-libcloud-1.0.0rc2/requirements-tests.txt
deleted file mode 100644
index 791dfb5..0000000
--- a/apache-libcloud-1.0.0rc2/requirements-tests.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-pep8>=1.7.0,<1.8
-flake8>=2.5.1,<2.6
-mock>=1.0.1,<1.1

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/setup.cfg
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/setup.cfg b/apache-libcloud-1.0.0rc2/setup.cfg
deleted file mode 100644
index bcb0348..0000000
--- a/apache-libcloud-1.0.0rc2/setup.cfg
+++ /dev/null
@@ -1,5 +0,0 @@
-[wheel]
-universal = 1
-
-[nosetests]
-exclude=TestCaseMixin

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/setup.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/setup.py b/apache-libcloud-1.0.0rc2/setup.py
deleted file mode 100644
index e8cc1bf..0000000
--- a/apache-libcloud-1.0.0rc2/setup.py
+++ /dev/null
@@ -1,306 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 os
-import sys
-import doctest
-
-from setuptools import setup
-from distutils.core import Command
-from unittest import TextTestRunner, TestLoader
-from glob import glob
-from os.path import splitext, basename, join as pjoin
-
-try:
-    import epydoc  # NOQA
-    has_epydoc = True
-except ImportError:
-    has_epydoc = False
-
-import libcloud.utils
-from libcloud.utils.dist import get_packages, get_data_files
-
-libcloud.utils.SHOW_DEPRECATION_WARNING = False
-
-# Different versions of python have different requirements.  We can't use
-# libcloud.utils.py3 here because it relies on backports dependency being
-# installed / available
-PY2 = sys.version_info[0] == 2
-PY3 = sys.version_info[0] == 3
-PY2_pre_25 = PY2 and sys.version_info < (2, 5)
-PY2_pre_26 = PY2 and sys.version_info < (2, 6)
-PY2_pre_27 = PY2 and sys.version_info < (2, 7)
-PY2_pre_279 = PY2 and sys.version_info < (2, 7, 9)
-PY3_pre_32 = PY3 and sys.version_info < (3, 2)
-
-HTML_VIEWSOURCE_BASE = 'https://svn.apache.org/viewvc/libcloud/trunk'
-PROJECT_BASE_DIR = 'http://libcloud.apache.org'
-TEST_PATHS = ['libcloud/test', 'libcloud/test/common', 'libcloud/test/compute',
-              'libcloud/test/storage', 'libcloud/test/loadbalancer',
-              'libcloud/test/dns', 'libcloud/test/container',
-              'libcloud/test/backup']
-DOC_TEST_MODULES = ['libcloud.compute.drivers.dummy',
-                    'libcloud.storage.drivers.dummy',
-                    'libcloud.dns.drivers.dummy',
-                    'libcloud.container.drivers.dummy',
-                    'libcloud.backup.drivers.dummy']
-
-SUPPORTED_VERSIONS = ['2.5', '2.6', '2.7', 'PyPy', '3.x']
-
-TEST_REQUIREMENTS = [
-    'mock'
-]
-
-if PY2_pre_279 or PY3_pre_32:
-    TEST_REQUIREMENTS.append('backports.ssl_match_hostname')
-
-if PY2_pre_27:
-    unittest2_required = True
-else:
-    unittest2_required = False
-
-if PY2_pre_25:
-    version = '.'.join([str(x) for x in sys.version_info[:3]])
-    print('Version ' + version + ' is not supported. Supported versions are ' +
-          ', '.join(SUPPORTED_VERSIONS))
-    sys.exit(1)
-
-
-def read_version_string():
-    version = None
-    sys.path.insert(0, pjoin(os.getcwd()))
-    from libcloud import __version__
-    version = __version__
-    sys.path.pop(0)
-    return version
-
-
-def forbid_publish():
-    argv = sys.argv
-    if 'upload'in argv:
-        print('You shouldn\'t use upload command to upload a release to PyPi. '
-              'You need to manually upload files generated using release.sh '
-              'script.\n'
-              'For more information, see "Making a release section" in the '
-              'documentation')
-        sys.exit(1)
-
-
-class TestCommand(Command):
-    description = "run test suite"
-    user_options = []
-    unittest_TestLoader = TestLoader
-    unittest_TextTestRunner = TextTestRunner
-
-    def initialize_options(self):
-        THIS_DIR = os.path.abspath(os.path.split(__file__)[0])
-        sys.path.insert(0, THIS_DIR)
-        for test_path in TEST_PATHS:
-            sys.path.insert(0, pjoin(THIS_DIR, test_path))
-        self._dir = os.getcwd()
-
-    def finalize_options(self):
-        pass
-
-    def run(self):
-        for module_name in TEST_REQUIREMENTS:
-            try:
-                __import__(module_name)
-            except ImportError:
-                print('Missing "%s" library. %s is library is needed '
-                      'to run the tests. You can install it using pip: '
-                      'pip install %s' % (module_name, module_name,
-                                          module_name))
-                sys.exit(1)
-
-        if unittest2_required:
-            try:
-                from unittest2 import TextTestRunner, TestLoader
-                self.unittest_TestLoader = TestLoader
-                self.unittest_TextTestRunner = TextTestRunner
-            except ImportError:
-                print('Python version: %s' % (sys.version))
-                print('Missing "unittest2" library. unittest2 is library is '
-                      'needed to run the tests. You can install it using pip: '
-                      'pip install unittest2')
-                sys.exit(1)
-
-        status = self._run_tests()
-        sys.exit(status)
-
-    def _run_tests(self):
-        secrets_current = pjoin(self._dir, 'libcloud/test', 'secrets.py')
-        secrets_dist = pjoin(self._dir, 'libcloud/test', 'secrets.py-dist')
-
-        if not os.path.isfile(secrets_current):
-            print("Missing " + secrets_current)
-            print("Maybe you forgot to copy it from -dist:")
-            print("cp libcloud/test/secrets.py-dist libcloud/test/secrets.py")
-            sys.exit(1)
-
-        mtime_current = os.path.getmtime(secrets_current)
-        mtime_dist = os.path.getmtime(secrets_dist)
-
-        if mtime_dist > mtime_current:
-            print("It looks like test/secrets.py file is out of date.")
-            print("Please copy the new secrets.py-dist file over otherwise" +
-                  " tests might fail")
-
-        if PY2_pre_26:
-            missing = []
-            # test for dependencies
-            try:
-                import simplejson
-                simplejson              # silence pyflakes
-            except ImportError:
-                missing.append("simplejson")
-
-            try:
-                import ssl
-                ssl                     # silence pyflakes
-            except ImportError:
-                missing.append("ssl")
-
-            if missing:
-                print("Missing dependencies: " + ", ".join(missing))
-                sys.exit(1)
-
-        testfiles = []
-        for test_path in TEST_PATHS:
-            for t in glob(pjoin(self._dir, test_path, 'test_*.py')):
-                testfiles.append('.'.join(
-                    [test_path.replace('/', '.'), splitext(basename(t))[0]]))
-
-        # Test loader simply throws "'module' object has no attribute" error
-        # if there is an issue with the test module so we manually try to
-        # import each module so we get a better and more friendly error message
-        for test_file in testfiles:
-            try:
-                __import__(test_file)
-            except Exception:
-                e = sys.exc_info()[1]
-                print('Failed to import test module "%s": %s' % (test_file,
-                                                                 str(e)))
-                raise e
-
-        tests = self.unittest_TestLoader().loadTestsFromNames(testfiles)
-
-        for test_module in DOC_TEST_MODULES:
-            tests.addTests(doctest.DocTestSuite(test_module))
-
-        t = self.unittest_TextTestRunner(verbosity=2)
-        res = t.run(tests)
-        return not res.wasSuccessful()
-
-
-class ApiDocsCommand(Command):
-    description = "generate API documentation"
-    user_options = []
-
-    def initialize_options(self):
-        pass
-
-    def finalize_options(self):
-        pass
-
-    def run(self):
-        if not has_epydoc:
-            raise RuntimeError('Missing "epydoc" package!')
-
-        os.system(
-            'pydoctor'
-            ' --add-package=libcloud'
-            ' --project-name=libcloud'
-            ' --make-html'
-            ' --html-viewsource-base="%s"'
-            ' --project-base-dir=`pwd`'
-            ' --project-url="%s"'
-            % (HTML_VIEWSOURCE_BASE, PROJECT_BASE_DIR))
-
-
-class CoverageCommand(Command):
-    description = "run test suite and generate coverage report"
-    user_options = []
-
-    def initialize_options(self):
-        pass
-
-    def finalize_options(self):
-        pass
-
-    def run(self):
-        import coverage
-        cov = coverage.coverage(config_file='.coveragerc')
-        cov.start()
-
-        tc = TestCommand(self.distribution)
-        tc._run_tests()
-
-        cov.stop()
-        cov.save()
-        cov.html_report()
-
-forbid_publish()
-
-install_requires = []
-if PY2_pre_26:
-    install_requires.extend(['ssl', 'simplejson'])
-
-if PY2_pre_279 or PY3_pre_32:
-    install_requires.append('backports.ssl_match_hostname')
-
-setup(
-    name='apache-libcloud',
-    version=read_version_string(),
-    description='A standard Python library that abstracts away differences' +
-                ' among multiple cloud provider APIs. For more information' +
-                ' and documentation, please see http://libcloud.apache.org',
-    author='Apache Software Foundation',
-    author_email='dev@libcloud.apache.org',
-    install_requires=install_requires,
-    packages=get_packages('libcloud'),
-    package_dir={
-        'libcloud': 'libcloud',
-    },
-    package_data={'libcloud': get_data_files('libcloud', parent='libcloud')},
-    license='Apache License (2.0)',
-    url='http://libcloud.apache.org/',
-    cmdclass={
-        'test': TestCommand,
-        'apidocs': ApiDocsCommand,
-        'coverage': CoverageCommand
-    },
-    zip_safe=False,
-    classifiers=[
-        'Development Status :: 4 - Beta',
-        'Environment :: Console',
-        'Intended Audience :: Developers',
-        'Intended Audience :: System Administrators',
-        'License :: OSI Approved :: Apache Software License',
-        'Operating System :: OS Independent',
-        'Programming Language :: Python',
-        'Topic :: Software Development :: Libraries :: Python Modules',
-        'Programming Language :: Python :: 2.5',
-        'Programming Language :: Python :: 2.6',
-        'Programming Language :: Python :: 2.7',
-        'Programming Language :: Python :: 3',
-        'Programming Language :: Python :: 3.0',
-        'Programming Language :: Python :: 3.1',
-        'Programming Language :: Python :: 3.2',
-        'Programming Language :: Python :: 3.3',
-        'Programming Language :: Python :: 3.4',
-        'Programming Language :: Python :: 3.5',
-        'Programming Language :: Python :: Implementation :: CPython',
-        'Programming Language :: Python :: Implementation :: PyPy']
-    )

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/tox.ini
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/tox.ini b/apache-libcloud-1.0.0rc2/tox.ini
deleted file mode 100644
index c08c4c2..0000000
--- a/apache-libcloud-1.0.0rc2/tox.ini
+++ /dev/null
@@ -1,62 +0,0 @@
-[tox]
-envlist = py{2.5,2.6,2.7,pypy,pypy3,3.2,3.3,3.4,3.5},lint
-
-[testenv]
-deps =
-    -r{toxinidir}/requirements-tests.txt
-    lockfile
-    py{2.5,2.6,2.7}: paramiko
-    py{2.5,2.6}: unittest2
-commands = cp libcloud/test/secrets.py-dist libcloud/test/secrets.py
-           python setup.py test
-basepython =
-    py2.5: python2.5
-    py2.6: python2.6
-    {py2.7,lint,pylint,docs}: python2.7
-    pypypy: pypy
-    pypypy3: pypy3
-    py3.2: python3.2
-    py3.3: python3.3
-    py3.4: python3.4
-    py3.5: python3.5
-whitelist_externals = cp
-
-[testenv:docs]
-deps = sphinx
-       pysphere
-       backports.ssl_match_hostname
-changedir = docs
-commands = python ../contrib/generate_provider_feature_matrix_table.py
-           sphinx-apidoc -d 4 ../libcloud/ -o apidocs/
-           sphinx-build -W -b html -d {envtmpdir}/doctrees . _build/html
-
-[testenv:docs-travis]
-# Note: We don't build API docs on Travis since it causes build failures because
-# those API docs files are not included anywhere.
-deps = sphinx
-       pysphere
-       backports.ssl_match_hostname
-changedir = docs
-commands = python ../contrib/generate_provider_feature_matrix_table.py
-           sphinx-build -W -b html -d {envtmpdir}/doctrees . _build/html
-
-[testenv:scrape-ec2-prices]
-deps = requests
-       demjson
-commands = python contrib/scrape-ec2-prices.py
-
-[testenv:pylint]
-deps = pylint
-       backports.ssl_match_hostname
-commands = pylint --rcfile=.pylintrc -E libcloud/
-
-[testenv:lint]
-deps = -r{toxinidir}/requirements-tests.txt
-       backports.ssl_match_hostname
-
-commands = flake8 --ignore=E402 --exclude="test" libcloud/
-           flake8 --ignore=E402 --max-line-length=160 libcloud/test/
-           flake8 --ignore=E402 demos/
-           flake8 --ignore=E402,E902 docs/examples/
-           flake8 --ignore=E402,E902 --max-line-length=160 contrib/
-           python -mjson.tool libcloud/data/pricing.json


[44/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/CHANGES.rst
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/CHANGES.rst b/apache-libcloud-1.0.0rc2/CHANGES.rst
deleted file mode 100644
index cdb2014..0000000
--- a/apache-libcloud-1.0.0rc2/CHANGES.rst
+++ /dev/null
@@ -1,4205 +0,0 @@
-\ufeffChangelog
-=========
-
-Changes with latest version of Apache Libcloud
-----------------------------------------------
-
-General
-~~~~~~~
-
-Compute
-~~~~~~~
-
-- Fix a race condition on GCE driver `list_nodes()`- Invoking GCE\u2019s
-  `list_nodes()` while some VMs are being shutdown can result in the following
-  `libcloud.common.google.ResourceNotFoundError` exception to be raised.
-  (GITHUB-727)
-  [L�na�c Huard]
-
-- Allow user to filter nodes by location by adding optional `location`
-  argument to the `list_nodes()` method in the CloudStack driver.
-  (GITHUB-737)
-  [Lionel Schaub]
-
-- Fix OpenStack IP type resolution - make sure IP addresses are correctly
-  categorized and assigned on `private_ips` and `public_ips` Node attribute.
-  (GITHUB-738)
-  [Lionel Schaub]
-
-- Add new `Perth, Australia` and `Manila, Philippines` region to the CloudSigma
-  v2 driver.
-  [Tomaz Muraus]
-
-DNS
-~~~
-
-- Added BuddyNS driver
-  (GITHUB-742)
-  [Oltjano Terpollari]
-
-
-Changes with Apache Libcloud in 1.0.0-rc2
------------------------------------------
-
-General
-~~~~~~~
-
-- Fix a bug with consuming stdout and stderr in the paramiko SSH client which
-  would manifest itself under very rare condition when a consumed chunk only
-  contained a single byte or part of a multi byte UTF-8 character.
-  [Lakshmi Kannan, Tomaz Muraus]
-
-- Increase default chunk size from ``1024`` to ``4096`` bytes in the paramiko
-  SSH client. This results in smaller number of receive calls on the average.
-  [Tomaz Muraus]
-
-- Fix to Dimension Data API address for Middle-East and Africa
-  (GITHUB-700)
-  [Anthony Shaw]
-
-- Addition of Dimension Data Australia federal government region to dimension data
-  drivers.
-  (GITHUB-700)
-  [Anthony Shaw]
-
-- Throw a more user-friendly exception on "No address associated with hostname".
-  (GITHUB-711, GITHUB-714, LIBCLOUD-803)
-  [Tomaz Muraus, Scott Crunkleton]
-
-* Remove deprecated provider constants with the region in the name and related
-  driver classes (e.g. ``EC2_US_EAST``, etc.).
-
-  Those drivers have moved to single provider constant + ``region`` constructor
-  argument model.
-  [Tomaz Muraus]
-
-* Introduce new `list_regions`` class method on the base driver class. This
-  method is to be used with provider drivers which support multiple regions and
-  ``region`` constructor argument. It allows users to enumerate available /
-  supported regions.
-  [Tomaz Muraus]
-
-Compute
-~~~~~~~
-
-- [dimension data] added support for VMWare tools VM information inside list_nodes responses
-  (GITHUB-734)
-  [Jeff Dunham]
-
-- [ec2] added ex_encrypted and ex_kms_key_id optional parameters to the create volume method
-  (GITHUB-729)
-  [Viktor Ognev]
-
-- [dimension data] added support for managing host anti-affinity rules, added paging support to
-  all supported calls and added support for requesting priority ordering when creating ACL rules
-  (GITHUB-726)
-  [Jeff Dunham]
-
-- [openstack] when creating floating IPs, added pool_id as an optional argument
-  (GITHUB-725)
-  [marko-p]
-
-- [google compute] Added setMachineType method to allow for changing sizes of instances
-  (GITHUB-721)
-  [Eric Johnson]
-
-- [google compute] allow bypassing image search in standard project list
-  (GITHUB-713)
-  [Max Illfelder]
-
-- Add support for requesting a MKS token for accessing the remote console in VMware
-  vCloud driver
-  (GITHUB-706)
-  [Juan Font Alonso]
-
-- Add support in VMware vCloud driver for v5.5 API, with snapshot support
-  (GITHUB-658)
-  [Juan Font Alonso]
-
-- Added support for adding a family to an image on Google Compute Driver
-  (GITHUB-704)
-  [Max Illfelder]
-
-- Deprecated IBM SCE, HP Helion, OpSource, Ninefold and CloudFrames drivers, removed
-  driver code and tests.
-  (GITHUB-701, LIBCLOUD-801)
-  [Anthony Shaw]
-
-- Introduced error messages (`libcloud.compute.deprecated`) for deprecated drivers
-  (GITHUB-701, LIBCLOUD-801)
-  [Anthony Shaw]
-
-- New Compute drivers- BSNL, Indosat, Med-1, NTT-America, Internet Solutions
-  (GITHUB-700)
-  [Anthony Shaw]
-
-- Fix to set default signature version for AWS Seoul region to v4, removed
-  non-supported size (hs1.xlarge)
-  (GITHUB-684)
-  [Geunwoo Shin]
-
-- Support filtering by location in list_nodes for dimension data compute driver
-  fix lack of paging support
-  (GITHUB-691)
-  [Jeff Dunham]
-
-- Support for filtering by IPv4, IPv6, network, network domain, VLAN in Dimension
-  data driver.
-  (GITHUB-694)
-  [Jeff Dunham]
-
-- Added `Node.created_at` which, on supported drivers, contains the datetime the
-  node was first started.
-  (GITHUB-698)
-  [Allard Hoeve] [Rick van de Loo]
-
-- New driver for Aliyun Elastic Compute Service.
-  (LIBCLOUD-802, GITHUB-712)
-  [Sam Song]
-
-Storage
-~~~~~~~
-
-- Added Outscale storage driver
-  (GITHUB-730)
-  [Javier M. Mellid]
-
-- Improvements to Google Auth for Storage and Compute and MIME bug fix
-  (LIBCLOUD-800, GITHUB-689)
-  [Scott Crunkleton]
-
-- Implement ``get_container``, ``get_object`` and ``upload_object_via_stream``
-  methods in the Backblaze B2 storage driver.
-
-  Note: Backblaze API doesn't upload streaming uploads so when using
-  ``upload_object_via_stream`` whole file is read and buffered in memory.
-  (GITHUB-696)
-  [Jay jshridha]
-
-- New driver for Aliyun OSS Storage Service.
-  (LIBCLOUD-802, GITHUB-712)
-  [Sam Song]
-
-Loadbalancer
-~~~~~~~~~~~~
-
-- New driver for Aliyun SLB Loadbalancer Service.
-  (LIBCLOUD-802, GITHUB-712)
-  [Sam Song]
-
-DNS
-~~~~
-
-- Added NearlyFreeSpeech.net (NSFN) driver
-  [Ken Drayer]
-  (GITHUB-733)
-
-- Added Lua DNS driver
-  [Oltjano Terpollari]
-  (GITHUB-732)
-
-- Added NSOne driver
-  [Oltjano Terpollari]
-  (GITHUB-710)
-
-- Fix a bug in the GoDaddy driver - make sure ``host`` attribute on the
-  connection class is correctly set to the hostname.
-  [Tomaz Muraus]
-
-- Fix handling of ``MX`` records in the Gandi driver.
-  (GITHUB-718)
-  [Ryan Lee]
-
-Backup
-~~~~~~
-
-- Dimension Data - added additional testing, fixed bug on client response naming,
-  added support for adding backup clients to a backup enabled node.
-  (GITHUB-692, GITHUB-693, GITHUB-695)
-  [Jeff Dunham]
-
-Changes with Apache Libcloud 1.0.0-pre1
----------------------------------------
-
-General
-~~~~~~~
-
-- Introduction of container based drivers for Docker, Rkt and Container-as-a-service
-  providers
-  (LIBCLOUD-781, GITHUB-666)
-  [Anthony Shaw]
-
-- Introduce a new ``libcloud.backup`` API for Backup as a Service projects and
-  products.
-  (GITHUB-621)
-  [Anthony Shaw]
-
-- Also retry failed HTTP(s) requests upon transient "read operation timed out"
-  SSL error.
-  (GITHUB-556, LIBCLOUD-728)
-  [Scott Kruger]
-
-- Throw a more user-friendly exception if a client fails to establish SSL / TLS
-  connection with a server because of an unsupported SSL / TLS version.
-  (GITHUB-682)
-  [Tomaz Muraus]
-
-Compute
-~~~~~~~
-
-- Add ap-northeast-2 region to EC2 driver (South Korea)
-  (GITHUB-681)
-  [Anthony Shaw]
-
-- Added Added volume type to EC2 volume extra to EC2 driver.
-  (GITHUB-680)
-  [Gennadiy Stas]
-
-- Add LazyObject class that provides lazy-loading, see `GCELicense` for usage
-  (LIBCLOUD-786, GITHUB-665)
-  [Scott Crunkleton]
-
-- Added t2.nano instance type to EC2 Compute driver
-  (GITHUB-663)
-  [Anthony Shaw]
-
-- Support for passing the image ID as a string instead of an instance of image when
-  creating nodes in Dimension Data driver.
-  (GITHUB-664)
-  [Anthony Shaw]
-
-DNS
-~~~
-
-- Add support for 'health checks' in Aurora DNS driver
-  (GITHUB-672)
-  [Wido den Hollander]
-
-- Make sure ``ttl`` attribute is correctly parsed and added to the ``Record``
-  ``extra`` dictionary.
-  (GITHUB-675)
-  [Wido den Hollander]
-
-- Improve unit tests of Aurora DNS driver
-  (GITHUB-679)
-  [Wido den Hollander]
-
-Changes with Apache Libcloud 0.20.1
------------------------------------
-
-Compute
-~~~~~~~
-
-- [google] Allow for old and new style service account client email address
-  (LIBCLOUD-785)
-  [Hoang Phan]
-
-Changes with Apache Libcloud 0.20.0
------------------------------------
-
-General
-~~~~~~~
-
-- Added .editorconfig file for easier editing
-  (GITHUB-625)
-  [Misha Brukman]
-
-- Fix a bug with Libcloud accidentally setting paramiko root logger level to
-  DEBUG (this should only happen if ``LIBCLOUD_DEBUG`` environment variable is
-  provided).
-
-  Reported by John Bresnahan.
-  (LIBCLOUD-765)
-  [Tomaz Muraus, John Bresnahan]
-
-- Simply travis and tox config (.travis.yml, tox.ini).
-  (GITHUB-608)
-  [Anthony Monthe]
-
-- Fixed Python2.6 unit testing (and Google Cloud Storage tests)
-  (GITHUB-648)
-  [Scott Crunkleton]
-
-Compute
-~~~~~~~
-
-- [google] Allow for old and new style service account client email address
-  (LIBCLOUD-785)
-  [Hoang Phan]
-
-- Minor security improvement for storing cached GCE credentials
-  (LIBCLOUD-718)
-  [Siim P�der]
-
-- Removed DreamHosts Compute Driver, DreamHosts users will now use the OpenStack Node driver since DreamHosts are OpenStack
-  API compliant
-  (GITHUB-655)
-  [Stephano Maffulli]
-
-- Added additional kwargs to the create_node method for Dimension Data driver, allowing the user to specify the RAM and
-  CPU upfront. Added a ex_reconfigure_node method and ex_list_customer_images as well as updating the API to 2.1.
-  (LIBCLOUD-783, GITHUB-656)
-  [Anthony Shaw]
-
-- The EC2 Instance Type updated with correct disk sizes (especially the disk size for the m3 instances),
-  conversion errors between GiB an M[i]B, disk count were the cause.
-  Added instance types - g2.8xlarge and t2.large.
-  (GITHUB-646)
-  [Philipp Hahn]
-
-- Add update node, update VMware tools, add storage, change storage size or speed, remove storage to Dimension Data Driver.
-  (LIBCLOUD-775, GITHUB-644)
-  [Anthony Shaw]
-
-- Include 'service_name' support in _parse_service_catalog_auth_v3 for Openstack Drivers
-  (GITHUB-647)
-  [Steve Gregory]
-
-- Outscale inc & sas driver update
-  (GITHUB-645)
-  [@LordShion]
-
-- Add new `eu-west-2` & `us-east-2` regions to the OUTSCALE_INC & OUTSCALE_SAS drivers.
-  [Filipe Silva /lordshion]
-
-- [google compute] add pricing data update script
-  (GITHUB-464)
-  [Misha Brukman]
-
-- Fix a bug in the ``list_volumes`` method in the CloudStack driver so it
-  returns an empty list if no volumes are found.
-  (GITHUB-617)
-  [Wido den Hollander]
-
-- Return proper volume state for CloudStack volumes.
-  (GITHUB-615, LIBCLOUD-764)
-  [Wido den Hollander]
-
-- Add support for multiple regions in Aurora compute driver
-  (GITHUB-623)
-  [Wido den Hollander]
-
-- Fix value of ``node.extra['ip_addresses']`` node attribute in the CloudStack
-  driver.
-  (LIBCLOUD-767, GITHUB-627)
-  [Atsushi Sasaki]
-
-- Make sure that ``node.public_ips`` attribute in the CloudStack driver doesn't
-  contain duplicated values..
-  (LIBCLOUD-766, GITHUB-626)
-  [Atsushi Sasaki]
-
-- Allow user to wait for a resource to reach a desired state in the
-  Dimension Data driver by using new ``ex_wait_for_state`` method.
-  (LIBCLOUD-707, GITHUB-631)
-  [Anthony Shaw]
-
-- Added M4 pricing and instance information to EC2 driver
-  (GITHUB-634)
-  [Benjamin Zaitlen]
-
-- Added C4 instance information to EC2 driver
-  (GITHUB-638)
-  [amitofs]
-
-- Allow location of the datacenter to be supplied in ProfitBricks driver
-  (LIBCLOUD-771, GITHUB-635)
-  [Joel Reymont]
-
-- Reduce redundant API calls in CloudStack driver
-  (LIBCLOUD-590, GITHUB-641)
-  [Atsushi Sasaki]
-
-- Add an additional argument to libcloud.compute.drivers.GCENodeDriver.create_node
-  to allow for creation of preemptible GCE instances
-  (GITHUB-643)
-  [@blawney]
-
-- GoogleStorageDriver can now use either our S3 authentication or other Google Cloud Platform OAuth2 authentication methods.
-  (GITHUB-633)
-  [Scott Crunkleton]
-
-- All NodeState, StorageVolumeState, VolumeSnapshotState and Provider attributes
-  are now strings instead of integers.
-  (GITHUB-624)
-  [Allard Hoeve]
-
-Storage
-~~~~~~~
-
-Loadbalancer
-~~~~~~~~~~~~
-
-DNS
-~~~
-
-- RackSpace driver - New DNS driver methods:
-   - ex_iterate_ptr_records
-   - ex_get_ptr_record
-   - ex_create_ptr_record
-   - ex_update_ptr_record
-   - ex_delete_ptr_record
-
-  This should cover all of the functionality offered by the Rackspace DNS API
-  in regards to RDNS.
-  (LIBCLOUD-780, GITHUB-652)
-  [Greg Hill]
-
-- Update ``create_record`` in the WorldWideDNS driver so it automatically
-  selects a slot if one is not provided by the user via ``extra['entry']``
-  argument.
-  (GITHUB-621)
-  [Alejandro Pereira]
-
-- Introduce GoDaddy DNS Driver with examples and documentation.
-  (LIBCLOUD-772, GITHUB-640, LIBCLOUD-778)
-  [Anthony Shaw]
-
-- Add new driver for CloudFlare DNS (https://www.cloudflare.com/dns/).
-  (GITHUB-637)
-  [Tomaz Muraus]
-
-Changes with Apache Libcloud 0.19.0
------------------------------------
-
-General
-~~~~~~~
-
-- Update Rackspace AUTH_URL
-  (LIBCLOUD-738)
-  [Brian Curtin]
-
-- Fix ``LIBCLOUD_DEBUG`` mode so it works on Python 3.x.
-  [Tomaz Muraus]
-
-- Fix Libcloud code so it doesn't throw an exception if simplejson < 2.1.0 is
-  installed.
-  (LIBCLOUD-714, GITHUB-577)
-  [Erik Johnson]
-
-- Fix endpoint URL for DimensionData Asia Pacific region.
-  (GITHUB-585)
-  [Anthony Shaw]
-
-- Document potential time drift issue which could cause authentication in the
-  GCE drivers to fail.
-  (GITHUB-571)
-  [Michal Tekel]
-
-- Update documentation for EC2 - make sure they reflect region changes from
-  0.14 release.
-  (GITHUB-606)
-  [James Guthrie]
-
-Compute
-~~~~~~~
-
-- Fixed malformed XML requests with Dimension Data driver.
-  (LIBCLOUD-760, GITHUB-610)
-  [Anthony Shaw]
-
-- Update list of scopes for Google Compute Engine driver.
-  (GITHUB-607)
-  [Otto Bretz]
-
-- Allow user to filter VPC by project in the CloudStack driver by passing
-  ``project`` argument to the ``ex_list_vps`` method.
-  (GITHUB-516)
-  [Syed Mushtaq Ahmed]
-
-- Add volume management methods and other various improvements and fixes in the
-  RunAbove driver.
-  (GITHUB-561)
-  [Anthony Monthe]
-
-- Add support and update Dimension Data driver to use API v2.0 by default.
-  (LIBCLOUD-736, GITHUB-564)
-  [Anthony Shaw]
-
-- Add new ``ex_virtual_network_name`` and ``ex_network_config`` argument to the
-  `create_node`` method in the Azure driver. With those arguments user can now
-  specify which virtual network to use.
-  (GITHUB-569)
-  [Jesaja Everling]
-
-- Fix ``create_node`` method in the GCE driver calling inexistent method
-  (ex_get_disk instead of ex_get_volume).
-  (GITHUB-574)
-  [Alex Poms]
-
-- Allow user to pass ``proxy_url`` keyword argument to the VCloud driver
-  constructor.
-  (GITHUB-578)
-  [Daniel Pool]
-
-- Various fixes and improvements in the DimensionData driver (support for
-  creating servers in MCP 1 and 2 data center, performance improvements in the
-  location fetching, etc.).
-  (GITHUB-587, GITHUB-593, LIBCLOUD-750, LIBCLOUD-753)
-  [Anthony Shaw]
-
-- Added ``ex_assign_public_ip`` argument to ``create_node`` in the EC2 driver.
-  (GITHUB-590)
-  [Kyle Long]
-
-- Added ``ex_terminate_on_shutdown`` argument to ``create_node`` in the EC2
-  driver.
-  (GITHUB-595)
-  [Kyle Long]
-
-- Various fixes and improvements in the ``ex_authorize_security_group_ingress``
-  in the CloudStack driver.
-  (LIBCLOUD-749, GITHUB-580)
-  [Lionel Schaub]
-
-- Add pricing information for Softlayer.
-  (LIBCLOUD-759, GITHUB-603)
-  [David Wilson]
-
-- Standardize VolumeSnapshot states into the ``state`` attribute.
-  (LIBCLOUD-758, GITHUB-602)
-  [Allard Hoeve]
-
-Storage
-~~~~~~~
-
-- Add support for ``sa-east-1`` region to the Amazon S3 driver.
-  (GITHUB-562)
-  [Iuri de Silvio]
-
-- Fix handling of binary data in Local storage driver on Python 3. Now the file
-  which is to be written or read from is opened in the binary mode (``b`` flag).
-  (LIBCLOUD-725, GITHUB-568)
-  [Torf]
-
-Loadbalancer
-~~~~~~~~~~~~
-
-- Add a new driver for DimensionData load-balancing service
-  (http://cloud.dimensiondata.com/).
-  (LIBCLOUD-737, GITHUB-567)
-  [Anthony Shaw]
-
-DNS
-~~~
-
-- Update Google Cloud DNS API from 'v1beta1' to 'v1'
-  (GITHUB-583)
-  [Misha Brukman]
-
-- Add new driver for AuroraDNS service.
-  (GITHUB-562, LIBCLOUD-735)
-  [Wido den Hollander]
-
-- Fix "_to_record" in the Route53 driver - make sure it doesn't throw if the
-  record TTL is not available.
-  [Tomaz Muraus]
-
-- Add new driver for WorldWideDNS service
-  (http://www.worldwidedns.net/home.asp).
-  (GITHUB-566, LIBCLOUD-732)
-  [Alejandro Pereira]
-
-- Add new driver for DNSimple service (https://dnsimple.com/).
-  (GITHUB-575, GITHUB-604, LIBCLOUD-739)
-  [Alejandro Pereira, Patrick Humpal]
-
-- Add new driver for PointDNS service (https://pointhq.com).
-  (GITHUB-576, GITHUB-591, LIBCLOUD-740)
-  [Alejandro Pereira]
-
-- Add new driver for Vultr DNS service (https://www.vultr.com).
-  (GITHUB-579, GITHUB-596, LIBCLOUD-745)
-  [Alejandro Pereira, Janez Troha]
-
-- Add new driver for Liquidweb DNS service (http://www.liquidweb.com/).
-  (GITHUB-581, LIBCLOUD-746)
-  [Oltjano Terpollari, Alejandro Pereira]
-
-- Add new driver for Zonomi DNS hosting service (http://zonomi.com/).
-  (GITHUB-582, LIBCLOUD-747)
-  [Oltjano Terpollari, Alejandro Pereira]
-
-- Add new driver for Durable DNS service (https://durabledns.com/).
-  (GITHUB-588, LIBCLOUD-748)
-  [Oltjano Terpollari, Alejandro Pereira]
-
-Changes with Apache Libcloud 0.18.0
------------------------------------
-
-General
-~~~~~~~
-
-- Use native ``ssl.match_hostname`` functionality when running on Python >=
-  3.2 and only require ``backports.ssl_match_hostname`` dependency on Python
-  versions < 3.2.
-  [Tomaz Muraus]
-
-- Add support for AWS Signature version 4.
-
-  Note: Currently only GET HTTP method is supported.
-  (GITHUB-444)
-  [Gertjan Oude Lohuis]
-
-- Fix a bug in the debug mode logging (LIBCLOUD_DEBUG). Logging to the debug
-  file would throw an exception if the text contained non-ascii characters.
-  [Tomaz Muraus]
-
-- Fix a bug with connection code throwing an exception if a port was a unicode
-  type and not a str or int.
-  (GITHUB-533, LIBCLOUD-716)
-  [Avi Weit]
-
-- Update ``is_valid_ip_address`` function so it also works on Windows.
-  (GITHUB-343, GITHUB-498, LIBCLOUD-601, LIBCLOUD-686)
-  [Nicolas Fraison, Samuel Marks]
-
-- Add support for retrying failed HTTP requests.
-
-  Retrying is off by default and can be enabled by setting
-  ``LIBCLOUD_RETRY_FAILED_HTTP_REQUESTS`` environment variable.
-  (GITHUB-515, LIBCLOUD-360, LIBCLOUD-709)
-
-- Fix a bug in consuming stdout and stderr strams in Paramiko SSH client.
-  In some cases (like connecting to localhost via SSH), exit_status_ready
-  gets set immediately even before the while loop to consume the streams
-  kicks in. In those cases, we will not have consumed the streams at all.
-  (GITHUB-558)
-  [Lakshmi Kannan]
-
-Compute
-~~~~~~~
-
-- Google Compute now supports paginated lists including filtering.
-  (GITHUB-491)
-  [Lee Verberne]
-
-- OpenStackNodeSize objects now support optional, additional fields that are
-  supported in OpenStack 2.1: `ephemeral_disk`, `swap`, `extra`.
-  (GITHUB-488, LIBCLOUD-682)
-  [Greg Hill]
-
-- StorageVolume objects now have an attribute `state` that holds a
-  state variable that is standardized state across drivers. Drivers that
-  currently support the `state` attribute are OpenStack and EC2.
-  StorageVolume objects returned by drivers that do not support the
-  attribute will have a `state` of `None`. When a provider returns a state
-  that is unknown to the driver, the state will be `UNKNOWN`. Please report
-  such states. A couple of drivers already put state fields in the `extra`
-  fields of StorageVolumes. These fields were kept for
-  backwards-compatibility and for reference.
-  (GITHUB-476)
-  [Allard Hoeve]
-
-- StorageVolume objects on EC2 and OpenStack now have a key called snapshot_id
-  in their extra dicts containing the snapshot ID the volume was based on.
-  (GITHUB-479)
-  [Allard Hoeve]
-
-- OpenStack driver: deprecated ex_create_snapshot and ex_delete_snapshot in
-  favor of create_volume_snapshot and destroy_volume_snapshot. Updated base
-  driver method create_storage_volume argument name to be optional.
-  (GITHUB-478)
-  [Allard Hoeve]
-
-- Add support for creating volumes based on snapshots to EC2 and OS drivers.
-  Also modify signature of base NodeDriver.create_volume to reflect the fact
-  that all drivers expect a StorageSnapshot object as the snapshot argument.
-  (GITHUB-467, LIBCLOUD-672)
-  [Allard Hoeve]
-
-- VolumeSnapshots now have a `created` attribute that is a `datetime`
-  field showing the creation datetime of the snapshot. The field in
-  VolumeSnapshot.extra containing the original string is maintained, so
-  this is a backwards-compatible change.
-  (GITHUB-473)
-  [Allard Hoeve]
-
-- Improve GCE create_node, make sure ex_get_disktype function
-  (GITHUB-448)
-  [Markos Gogoulos]
-
-- GCE driver fix to handle unknown image projects
-  (GITHUB-447)
-  [Markos Gogoulos]
-
-- Allow user to pass ``ex_blockdevicemappings`` argument to the create_node
-  method in the OpenStack driver.
-  (GITHUB-398, LIBCLOUD-637)
-  [Allard Hoeve]
-
-- Fix ``list_volume_snapshots`` method in the EC2 driver so it comforms to the
-  base API.
-  (LIBCLOUD-664, GITHUB-451)
-  [Allard Hoeve]
-
-- Add ``volumes_attached`` attibute to ``node.extra`` in the OpenStack driver.
-  (LIBCLOUD-668, GITHUB-462)
-  [Allard Hoeve]
-
-- Add the following new methods to the Linode driver: ``ex_list_volumes``,
-  ``ex_create_volume``, ``ex_destroy_volume``.
-  (LIBCLOUD-649, GITHUB-430)
-  [Wojciech Wirkijowski]
-
-- Add ``list_volume_snapshots`` method to the OpenStack driver.
-  (LIBCLOUD-663, GITHUB-450)
-  [Allard Hoeve]
-
-- Add Site to Site VPN functionality to CloudStack driver.
-  (GITHUB-465)
-  [Avi Nanhkoesingh]
-
-- Add affinity group support to CloudStack driver
-  (LIBCLOUD-671, GITHUB-468)
-  [Mateusz Korszun]
-
-- Add a support for a new AWS Frankfurt, Germany region (``eu-central-1``) to
-  the EC2 driver using AWS Signature v4.
-  (GITHUB-444)
-  [Gertjan Oude Lohuis, Tomaz Muraus]
-
-- Allow Filtering in EC2 list_images() driver
-  (GITHUB-456, LIBCLOUD-667)
-  [Katriel Traum]
-
-- Add ex_list_ip_forwarding_rules() to CloudStack driver
-  (GITHUB-483)
-  [Atsushi Sasaki]
-
-- Add AURORA compute driver
-  (LIBCLOUD-641, GITHUB-477)
-  [Wido den Hollander]
-
-- Update ``ex_describe_tags`` method in the EC2 driver and allow user to list
-  tags for any supported resource. Previously you could only list tags for a
-  node or a storage volume.
-  (LIBCLOUD-676, GITHUB-482)
-  [John Kinsella]
-
-- Various improvements in the HostVirual driver (code refactoring, support for
-  managing "packages").
-  (LIBCLOUD-670, GITHUB-472)
-  [Dinesh Bhoopathy]
-
-- Add support for DigitalOcean API v2.0 while maintaining support for the old
-  API v2.0.
-
-  Note: API v2.0 is now used by default. To use the old API v1.0, pass
-  ``api_version='1.0'`` argument to the driver constructor.
-  (GITHUB-442)
-  [Andrew Starr-Bochicchio]
-
-- Add new ``d4.`` instance types to the EC2 driver. Also update EC2 pricing data.
-  (GITHUB-490)
-  [Tomaz Muraus]
-
-- Add new driver for Microsft Azure Virtual Machines service.
-  (LIBCLOUD-556, GITHUB-305, GITHUB-499, GITHUB-538)
-  [Michael Bennett, davidcrossland, Richard Conway, Matt Baldwin, Tomaz Muraus]
-
-- Fix VPC lookup method in CloudStack driver
-  (GITHUB-506)
-  [Avi Nanhkoesingh]
-
-- Add new driver for the Dimension Data provider based on the OpSource driver.
-  (LIBCLOUD-698, GITHUB-507, LIBCLOUD-700, GITHUB-513)
-  [Anthony Shaw]
-
-- Add "virtualmachine_id" attribute to the ``CloudStackAddress`` class in the
-  CloudStack driver.
-  (LIBCLOUD-679, GITHUB-485)
-  [Atsushi Sasaki]
-
-- Allow user to pass filters via arguments to the
-  ``ex_list_port_forwarding_rules`` in the CloudStack driver.
-  (LIBCLOUD-678, GITHUB-484)
-  [Atsushi Sasaki]
-
-- Fix an issue with ``list_nodes`` in the CloudSigma driver throwing an
-  exception if a node in the list had a static IP.
-  (LIBCLOUD-707, GITHUB-514)
-  [Chris O'Brien]
-
-- Don't throw an exception if a limit for a particular CloudStack resource is
-  "Unlimited" and not a number.
-  (GITHUB-512)
-  [Syed Mushtaq Ahmed]
-
-- Allow user to pass ``ex_config_drive`` argument to the ``create_node`` method
-  in the OpenStack driver.
-  (LIBCLOUD-356, GITHUB-330)
-  [Ryan Parrish]
-
-- Add new driver for Cloudwatt (https://www.cloudwatt.com/en/) provider.
-  (GITHUB-338)
-  [Anthony Monthe]
-
-- Add new driver for Packet (https://www.packet.net/) provider.
-  (LIBCLOUD-703, GITHUB-527)
-  [Aaron Welch]
-
-- Update Azure VM pricing information and add information for new D instance
-  types.
-  (GITHUB-528)
-  [Michael Bennett]
-
-- Add ``ex_get_node`` and ``ex_get_volume`` methods to CloudStack driver.
-  (GITHUB-532)
-  [Anthony Monthe]
-
-- Update CloudSigma driver so the "unavailable" and "paused" node state is
-  correctly mapped to "error" and "paused" respectively.
-  (GITHUB-517)
-  [Chris O'Brien]
-
-- Add SSH key pair management methods to the Gandi driver.
-  (GITHUB-534)
-  [Anthony Monthe]
-
-- Add ``ex_get_node`` and ``ex_get_volume`` methods to Gandi driver.
-  (GITHUB-534)
-  [Anthony Monthe]
-
-- Add ``fault`` attribute to the ``extra`` dictionary of the ``Node`` instance
-  returned by the OpenStack driver.
-  (LIBCLOUD-730, GITHUB-557)
-  [Nick Fox]
-
-- Add new driver for Onapp IaaS platform.
-  (LIBCLOUD-691, GITHUB-502)
-  [Matthias Wiesner]
-
-- Allow user to inject custom data / script into the Azure node by passing
-  ``ex_custom_data`` argument to the ``create_node`` method.
-  (LIBCLOUD-726, GITHUB-554)
-  [David Wilson]
-
-- Add ``ex_create_cloud_service`` and ``ex_destroy_cloud_service`` method to the
-  Azure driver.
-  (LIBCLOUD-724, GITHUB-551)
-  [David Wilson]
-
-- Add support for passing user data when creating a DigitalOcean node
-  (``ex_user_data`` argument).
-  (LIBCLOUD-731, GITHUB-559)
-  [David Wilson]
-
-- Allow user to specify which arguments are passed to ``list_nodes`` method
-  which is called inside ``wait_until_running`` by passing
-  ``ex_list_nodes_kwargs`` argument to the ``wait_until_running`` method.
-  (``ex_user_data`` argument).
-  (LIBCLOUD-723, GITHUB-548)
-  [David Wilson]
-
-- Allow user to pass ``ex_volume_type`` argument to the ``create_volume`` method
-  in the OpennStack driver.
-  (GITHUB-553)
-  [Rico Echwald-Tijsen]
-
-- Add new driver for RunAbove (https://www.runabove.com) provider.
-  (GITHUB-550)
-  [Anthony Monthe]
-
-- Fix a bug with exception being throw inside the CloudStack driver when the
-  provider returned no error message in the body.
-  (GITHUB-555)
-  [Konstantin Skaburskas]
-
-- Various improvements in the DigitalOcean driver:
-   - Increase page size to API maximum.
-   - Add ``ex_create_attr`` kwarg to ``create_node`` method.
-   - Update all the ``list_*`` methods to use paginated requests
-   - Allow user to specify page size by passing ``ex_per_page`` argument to the
-     constructor.
-
-  (LIBCLOUD-717, GITHUB-537)
-  [Javier Castillo II]
-
-Storage
-~~~~~~~
-
-- Fix a bug with authentication in the OpenStack Swift driver.
-  (GITHUB-492, LIBCLOUD-635)
-  [Tom Fifield]
-
-- Add AuroraObjects Storage Driver.
-  (GITHUB-540, LIBCLOUD-719)
-  [Wido den Hollander]
-
-Loadbalancer
-~~~~~~~~~~~~
-
-- Add a new driver for Softlayer load-balancing service
-  (https://www.softlayer.com/load-balancing).
-  (GITHUB-500, LIBCLOUD-688)
-  [Avi Weit]
-
-DNS
-~~~
-
-- Fix a bug when a ZoneDoesntExist exception was thrown when listing records
-  for a zone which has no records in the HostVirtual driver.
-  (GITHUB-460)
-  [Van\u010d Levstik]
-
-- Correctly handle MX records priority in the Route53 driver.
-  (GITHUB-469)
-  [Van\u010d Levstik]
-
-- Allow user to create an A record which points directly to the domain zone
-  name in the Route53 driver.
-  (GITHUB-469)
-  [Van\u010d Levstik]
-
-- Fix delete_zone method in the HostVirtual driver.
-  (GITHUB-461)
-  [Van\u010d Levstik]
-
-- Fix parsing of the record name in the HostVirtual driver.
-  (GITHUB-461)
-  [Van\u010d Levstik]
-
-- Add new driver for DigitalOcean DNS service.
-  (GITHUB-505)
-  [Javier Castillo II]
-
-Changes with Apache Libcloud 0.17.0
------------------------------------
-
-General
-~~~~~~~
-
-- Use ``match_hostname`` function from ``backports.ssl_match_hostname``
-  package to verify the SSL certificate hostname instead of relying on
-  our own logic.
-  (GITHUB-374)
-  [Alex Gaynor]
-
-Compute
-~~~~~~~
-
-- Add new `eu-west-2` & `us-east-2` regions to the OUTSCALE_INC & OUTSCALE_SAS drivers.
-  [Filipe Silva /lordshion]
-
-- GCE driver updated to include ex_stop_node() and ex_start_node() methods.
-  (GITHUB-442)
-  [Eric Johnson]
-
-- GCE driver now raises ResourceNotFoundError when the specified image is
-  not found in any image project. Previously, this would return None but now
-  raises the not-found exception instead. This fixes a bug where returning
-  None caused ex_delete_image to raise an AttributeError.
-  (GITHUB-441)
-  [Eric Johnson]
-
-- GCE driver update to support JSON format Service Account files and a PY3
-  fix from Siim P�der for LIBCLOUD-627.
-  (LIBCLOUD-627, LIBCLOUD-657, GITHUB-438)
-  [Eric Johnson]
-
-- GCE driver fixed for missing param on ex_add_access_config.
-  (GITHUB-435)
-  [Peter Mooshammer]
-
-- GCE driver support for HTTP load-balancer resources.
-  (LIBCLOUD-605, GITHUB-429)
-  [Lee Verberne]
-
-- GCE driver updated to make better use of GCEDiskTypes.
-  (GITHUB-428)
-  [Eric Johnson]
-
-- GCE driver list_images() now returns all non-deprecated images by default.
-  (LIBCLOUD-602, GITHUB-423)
-  [Eric Johnson]
-
-- Improve GCE API coverage for create_node().
-  (GITHUB-419)
-  [Eric Johnson]
-
-- GCE Licenses added to the GCE driver.
-  (GITHUB-420)
-  [Eric Johnson]
-
-- GCE Projects support common instance metadata and usage export buckets.
-  (GITHUB-409)
-  [Eric Johnson]
-
-- Improvements to TargetPool resource in GCE driver.
-  (GITHUB-414)
-  [Eric Johnson]
-
-- Adding TargetInstances resource to GCE driver.
-  (GITHUB-393)
-  [Eric Johnson]
-
-- Adding DiskTypes resource to GCE driver.
-  (GITHUB-391)
-  [Eric Johnson]
-
-- Fix boot disk auto_delete in GCE driver.
-  (GITHUB-412)
-  [Igor Bogomazov]
-
-- Add Routes to GCE driver.
-  (GITHUB-410)
-  [Eric Johnson]
-
-- Add missing ``ubuntu-os-cloud`` images to the GCE driver.
-  (LIBCLOUD-632, GITHUB-385)
-  [Borja Martin]
-
-- Add new `us-east-2` and `us-east-3` region to the Joyent driver.
-  (GITHUB-386)
-  [Anthony Monthe]
-
-- Add missing t2. instance types to the us-west-1 region in the EC2 driver.
-  (GITHUB-388)
-  [Matt Lehman]
-
-- Add option to expunge VM on destroy in CloudStack driver.
-  (GITHUB-382)
-  [Roeland Kuipers]
-
-- Add extra attribute in list_images for CloudStack driver.
-  (GITHUB-389)
-  [Loic Lambiel]
-
-- Add ``ex_security_group_ids`` argument to the create_node method in the
-  EC2 driver. This way users can launch VPC nodes with security groups.
-  (GITHUB-373)
-  [Itxaka Serrano]
-
-- Add description argument to GCE Network.
-  (GITHUB-397)
-  [Eric Johnson]
-
-- GCE: Improve MachineType (size) coverage of GCE API.
-  (GITHUB-396)
-  [Eric Johnson]
-
-- GCE: Improved Images coverage.
-  (GITHUB-395)
-  [Eric Johnson]
-
-- GCE: Support for global IP addresses.
-  (GITHUB-390, GITHUB-394)
-  [Eric Johnson]
-
-- GCE: Add missing snapshot attributes.
-  (GITHUB-401)
-  [Eric Johnson]
-
-- AWS: Set proper disk size in c3.X instance types.
-  (GITHUB-405)
-  [Itxaka Serrano]
-
-- Fix a bug with handling of the ``ex_keyname`` argument in the Softlayer
-  driver.
-  (GITHUB-416, LIBCLOUD-647)
-  [Dustin Oberloh]
-
-- Update CloudSigma region list (remove Las Vegas, NV region and add new San
-  Jose, CA and Miami, FL region).
-  (GITHUB-417)
-  [Viktor Petersson]
-
-- Add ``ex_get_node`` method to the Joyent driver.
-  (GITHUB-421)
-  [Anthony Monthe]
-
-- Add support for placement group management to the EC2 driver.
-  (GITHUB-418)
-  [Mikhail Ovsyannikov]
-
-- Add new tok02 region to the Softlayer driver.
-  (GITHUB-436, LIBCLOUD-656)
-  [Dustin Oberloh]
-
-- Add new Honolulu, HI endpoint to the CloudSigma driver.
-  (GITHUB-439)
-  [Stephen D. Spencer]
-
-- Fix a bug with config_drive attribute in the OpenStack driver. New versions
-  of OpenStack now return a boolean and not a string.
-  (GITHUB-433)
-  [quilombo]
-
-- Add support for Abiquo API v3.x, remove support for now obsolete API v2.x.
-  (GITHUB-433, LIBCLOUD-652)
-  [David Freedman]
-
-- Allow rootdisksize parameter in create_node CloudStack driver
-  (GITHUB-440, LIBCLOUD-658)
-  [Loic Lambiel]
-
-Storage
-~~~~~~~
-
-- Allow user to pass ``headers`` argument to the ``upload_object`` and
-  ``upload_object_via_stream`` method.
-
-  This way user can specify CORS headers with the drivers which support that.
-  (GITHUB-403, GITHUB-404)
-  [Peter Schmidt]
-
-- Fix upload_object_via_stream so it works correctly under Python 3.x if user
-  manually passes an iterator to the method.
-
-  Also improve how reading a file in chunks works with drivers which support
-  chunked encoding - always try to fill a chunk with CHUNK_SIZE bytes instead
-  of directly streaming the chunk which iterator returns.
-
-  Previously, if iterator returned 1 byte in one iteration, we would directly
-  send this as a single chunk to the API.
-  (GITHUB-408, LIBCLOUD-639)
-  [Peter Schmidt]
-
-Loadbalancer
-~~~~~~~~~~~~
-
-- Updates to CloudStack driver.
-  (GITHUB-434)
-  [Jeroen de Korte]
-
-DNS
-~~~
-
-- New driver for Softlayer DNS service.
-  (GITHUB-413, LIBCLOUD-640)
-  [Van\u010d Levstik]
-
-- Fix a bug with ``ex_create_multi_value_record`` method in the Route53 driver
-  only returning a single record.
-  (GITHUB-431, LIBCLOUD-650)
-  [Itxaka Serrano]
-
-Changes with Apache Libcloud 0.16.0
------------------------------------
-
-General
-~~~~~~~
-
-- Add new ``OpenStackIdentity_3_0_Connection`` class for working with
-  OpenStack Identity (Keystone) service API v3.
-  [Tomaz Muraus]
-
-- Add support for prettifying JSON or XML response body which is printed to a
-  file like object when using ``LIBCLOUD_DEBUG`` environment variable.
-  This option can be enabled by setting
-  ``LIBCLOUD_DEBUG_PRETTY_PRINT_RESPONSE`` environment variable.
-  [Tomaz Muraus]
-
-- Add support for using an HTTP proxy for outgoing HTTP and HTTPS requests.
-  [Tomaz Muraus, Philip Kershaw]
-
-Compute
-~~~~~~~
-
-- Fix an issue with ``LIBCLOUD_DEBUG`` not working correctly with the
-  Linode driver.
-  [Tomaz Muraus, Juan Carlos Moreno]
-  (LIBCLOUD-598, GITHUB-342)
-
-- Add new driver for VMware vSphere (http://www.vmware.com/products/vsphere/)
-  based clouds.
-  [Tomaz Muraus]
-
-- Add two new default node states - ``NodeState.SUSPENDED`` and
-  ``NodeState.ERROR``.
-  [Tomaz Muraus]
-
-- Fix to join networks properly in ``deploy_node`` in the CloudStack
-  driver.
-  (LIBCLOUD-593, GITUHB-336)
-  [Atsushi Sasaki]
-
-- Create ``CloudStackFirewallRule`` class and corresponding methods.
-  (LIBCLOUD-594, GITHUB-337)
-  [Atsushi Sasaki]
-
-- Add support for SSD disks to Google Compute driver.
-  (GITHUB-339)
-  [Eric Johnson]
-
-- Add utility ``get_regions`` and ``get_service_names`` methods to the
-  ``OpenStackServiceCatalog`` class.
-  [Andrew Mann, Tomaz Muraus]
-
-- Fix a bug in ``ex_get_console_output`` in the EC2 driver which would cause
-  an exception to be thrown if there was no console output for a particular
-  node.
-
-  Reported by Chris DeRamus.
-  [Tomaz Muraus]
-
-- Add ip_address parameter in CloudStack driver ``create_node`` method.
-  (GITHUB-346)
-  [Roeland Kuipers]
-
-- Fix ``ParamikoSSHClient.run`` and ``deploy_node`` method to work correctly
-  under Python 3.
-  (GITHUB-347)
-  [Eddy Reyes]
-
-- Update OpenStack driver to map more node states to states recognized by
-  Libcloud.
-  [Chris DeRamus]
-
-- Fix a bug with ``ex_metadata`` argument handling in the Google Compute Engine
-  driver ``create_node`` method.
-  (LIBCLOUD-544, GITHUB-349, GITHUB-353)
-  [Raphael Theberge]
-
-- Add SSH key pair management methods to the Softlayer driver.
-  (GITHUB-321, GITHUB-354)
-  [Itxaka Serrano]
-
-- Correctly categorize node IP addresses into public and private when dealing
-  with OpenStack floating IPs.
-  [Andrew Mann]
-
-- Add new t2 instance types to the EC2 driver.
-  [Tomaz Muraus]
-
-- Add support for Amazon GovCloud to the EC2 driver (us-gov-west-1 region).
-  [Chris DeRamus]
-
-- Allow user to pass "gp2" for "ex_volume_type" argument to the create_volume
-  method in the EC2 driver.
-
-  Reported by Xavier Barbosa.
-  [Tomaz Muraus, Xavier Barbosa]
-
-- Add new driver for ProfitBricks provider.
-  (LIBCLOUD-589, GITHUB-352)
-  [Matt Baldwin]
-
-- Various improvements and bugs fixes in the GCE driver. For a list, see
-  https://github.com/apache/libcloud/pull/360/commits
-  (GITHUB-360)
-  [Evgeny Egorochkin]
-
-- Allow user to specify virtualization type when registering an EC2 image by
-  passing ``virtualization_type`` argument to the ``ex_register_image`` method.
-  (GITHUB-361)
-  [Andy Grimm]
-
-- Add ``ex_create_image`` method to the GCE driver.
-  (GITHUB-358, LIBCLOUD-611)
-  [Katriel Traum]
-
-- Add some methods to CloudStack driver:
-  create_volume_snapshot, list_snapshots, destroy_volume_snapshot
-  create_snapshot_template, ex_list_os_types)
-  (GITHUB-363, LIBCLOUD-616)
-  [Oleg Suharev]
-
-- Added VPC support and Egress Firewall rule support fo CloudStack
-  (GITHUB-363)
-  [Jeroen de Korte]
-
-- Add additional attributes to the ``extra`` dictionary of OpenStack
-  StorageVolume object.
-  (GITHUB-366)
-  [Gertjan Oude Lohuis]
-
-- Fix ``create_volume`` method in the OpenStack driver to return a created
-  volume object (instance of StorageVolume) on success, instead of a boolean
-  indicating operation success.
-  (GITHUB-365)
-  [Gertjan Oude Lohuis]
-
-- Add optional project parameters for ex_list_networks() to CloudStack driver
-  (GITHUB-367, LIBCLOUD-615)
-  [Rene Moser]
-
-- CLOUDSTACK: option to start VM in a STOPPED state
-  (GITHUB-368)
-  [Roeland Kuipers]
-
-- Support "config_drive" in the OpenStack driver. Allow users to pass
-  ``ex_config_drive`` argument to the ``create_node`` and ``ex_rebuild_node``
-  method.
-  (GITHUB-370)
-  [Nirmal Ranganathan]
-
-- Add support for service scopes to the ``create_node`` method in the GCE
-  driver.
-  (LIBCLOUD-578, GITHUB-373)
-  [Eric Johnson]
-
-- Update GCE driver to allow for authentication with internal metadata service.
-  (LIBCLOUD-625, LIBCLOUD-276, GITHUB-276)
-  [Eric Johnson]
-
-- Fix a bug in Elasticstack node creation method where it would raise
-  exceptions because of missing data in a response, and also fix pulling the
-  IP from the proper data item.
-  (GITHUB-325)
-  [Michael Bennett]
-
-- Fix a bug which prevented user to connect and instantiate multiple EC2 driver
-  instances for different regions at the same time.
-  (GITHUB-325)
-  [Michael Bennett]
-
-- Add methods in CloudStack driver to manage mutiple nics per vm.
-  (GITHUB-369)
-  [Roeland Kuipers]
-
-- Implements VPC network ACLs for CloudStack driver.
-  (GITHUB-371)
-  [Jeroen de Korte]
-
-Storage
-~~~~~~~
-
-- Fix a bug with CDN requests in the CloudFiles driver.
-  [Tomaz Muraus]
-
-- Fix a bug with not being able to specify meta_data / tags when uploading an
-  object using Google Storage driver.
-  (LIBCLOUD-612, GITHUB-356)
-  [Stefan Friesel]
-
-Loadbalancer
-~~~~~~~~~~~~
-
-- Allow user to specify session affinity algorithm in the GCE driver by passing
-  ``ex_session_affinity`` argument to the ``create_balancer`` method.
-  (LIBCLOUD-595, GITHUB-341)
-  [Lee Verberne, Eric Johnson]
-
-DNS
-~~~
-
-- Various fixes in the Google DNS driver.
-  (GITHUB-378)
-  [Franck Cuny]
-
-Changes with Apache Libcloud 0.15.1
------------------------------------
-
-Compute
-~~~~~~~
-
-- Allow user to limit a list of subnets which are returned by passing
-  ``subnet_ids`` and ``filters`` argument to the ``ex_list_subnets``
-  method in the EC2 driver.
-  (LIBCLOUD-571, GITHUB-306)
-  [Lior Goikhburg]
-
-- Allow user to limit a list of internet gateways which are returned by
-  passing ``gateway_ids`` and ``filters`` argument to the
-  ``ex_list_internet_gateways`` method in the EC2 driver.
-  (LIBCLOUD-572, GITHUB-307)
-  [Lior Goikhburg]
-
-- Allow user to filter which nodes are returned by passing ``ex_filters``
-  argument to the ``list_nodes`` method in the EC2 driver.
-  (LIBCLOUD-580, GITHUB-320)
-  [Lior Goikhburg]
-
-- Add network_association_id to ex_list_public_ips and CloudstackAddress object
-  (GITHUB-327)
-  [Roeland Kuipers]
-
-- Allow user to specify admin password by passing ``ex_admin_pass`` argument
-  to the ``create_node`` method in the Openstack driver.
-  (GITHUB-315)
-  [Marcus Devich]
-
-- Fix a possible race condition in deploy_node which would occur if node
-  is online and can be accessed via SSH, but the SSH key we want to use hasn't
-  been installed yet.
-
-  Previously, we would immediately throw if we can connect, but the SSH key
-  hasn't been installed yet.
-  (GITHUB-331)
-  [David Gay]
-
-- Propagate an exception in ``deploy_node`` method if user specified an invalid
-  path to the private key file. Previously this exception was silently swallowed
-  and ignored.
-  [Tomaz Muraus]
-
-DNS
-~~~
-
-- Include a better message in the exception which is thrown when a request
-  in the Rackspace driver ends up in an ``ERROR`` state.
-  [Tomaz Muraus]
-
-Changes with Apache Libcloud 0.15.0
------------------------------------
-
-General
-~~~~~~~
-
-- Use lxml library (if available) for parsing XML. This should substantially
-  reduce parsing time and memory usage for large XML responses (e.g. retrieving
-  all the available images in the EC2 driver).
-  [Andrew Mann]
-
-- Use --head flag instead of -X HEAD when logging curl lines for HEAD requests
-  in debug mode.
-
-  Reported by Brian Metzler.
-  (LIBCLOUD-552)
-  [Tomaz Muraus]
-
-- Fix Python 3 compatibility bugs in the following functions:
-
-  * import_key_pair_from_string in the EC2 driver
-  * publickey._to_md5_fingerprint
-  * publickey.get_pubkey_ssh2_fingerprint
-
-  (GITHUB-301)
-  [Csaba Hoch]
-
-- Update CA_CERTS_PATH to also look for CA cert bundle which comes with
-  openssl Homebrew formula on OS x (/usr/local/etc/openssl/cert.pem).
-  (GITHUB-309)
-  [Pedro Romano]
-
-- Update Google drivers to allow simultaneous authornization for all the
-  supported Google Services.
-  (GITHUB-302)
-  [Eric Johnson]
-
-Compute
-~~~~~~~
-
-- Fix create_key_pair method which was not returning private key.
-  (LIBCLOUD-566)
-  [Sebastien Goasguen]
-
-- Map "Stopped" node state in the CloudStack driver to NodeState.STOPPED
-  instead of NodeState.TERMINATED, "Stopping" to NodeState.PENDING instead of
-  NodeState.TERMINATED and "Expunging" to NodeState.PENDING instead of
-  NodeState.TERMINATED.
-  (GITHUB-246)
-  [Chris DeRamus, Tomaz Muraus]
-
-- Add ex_create_tags and ex_delete_tags method to the CloudStack driver.
-  (LIBCLOUD-514, GITHUB-248)
-  [Chris DeRamus]
-
-- Add new G2 instances to the EC2 driver.
-  [Tomaz Muraus]
-
-- Add support for multiple API versions to the Eucalyptus driver and allows
-  user to pass "api_version" argument to the driver constructor.
-  (LIBCLOUD-516, GITHUB-249)
-  [Chris DeRamus]
-
-- Map "Powered Off" state in the vCloud driver from "TERMINATED" to "STOPPED".
-  (GITHUB-251)
-  [Ash Berlin]
-
-- Add ex_rename_node method to the DigitalOcean driver.
-  (GITHUB-252)
-  [Rahul Ranjan]
-
-- Improve error parsing in the DigitalOcean driver.
-
-  Reported by Deni Bertovic.
-  [Tomaz Muraus]
-
-- Add extension methods for the VPC internet gateway management to the EC2
-  driver.
-  (LIBCLOUD-525, GITHUB-255)
-  [Chris DeRamus]
-
-- Add CloudStackProject class to the CloudStack driver and add option to select
-  project and disk offering on node creation.
-  (LIBCLOUD-526, GITHUB-257)
-  [Jim Divine]
-
-- Fix IP address handling in the OpenStack driver.
-  (LIBCLOUD-503, GITHUB-235)
-  [Markos Gogoulos]
-
-- Ad new ex_delete_image and ex_deprecate_image method to the GCE driver.
-  (GITHUB-260)
-  [Franck Cuny]
-
-- Ad new ex_copy_image method to the GCE driver.
-  (GITHUB-258)
-  [Franck Cuny]
-
-- Ad new ex_set_volume_auto_delete method to the GCE driver.
-  (GITHUB-264)
-  [Franck Cuny]
-
-- Add ex_revoke_security_group_ingress method to the CloudStack driver.
-  [Chris DeRamus, Tomaz Muraus]
-
-- Allow user to pass ex_ebs_optimized argument to the create_node method
-  in the EC2 driver.
-  (GITHUB-272)
-  [zerthimon]
-
-- Add "deprecated" attribute to the Node object in the Google Compute Engine
-  driver.
-  (GITHUB-276)
-  [Chris / bassdread]
-
-- Update Softlayer driver to use "fullyQualifiedDomainName" instead of
-  "hostname" attribute for the node name.
-  (GITHUB-280)
-  [RoelVanNyen]
-
-- Allow user to specify target tags using target_tags attribute when creating
-  a firewall rule in the GCE driver.
-  (GITHUB-278)
-  [zerthimon]
-
-- Add new standard API for image management and initial implementation for the
-  EC2 and Rackspace driver.
-  (GITHUB-277)
-  [Matt Lehman]
-
-- Allow user to specify "displayname" attribute when creating a CloudStack node
-  by passing "ex_displayname" argument to the method.
-
-  Also allow "name" argument to be empty (None). This way CloudStack
-  automatically uses Node's UUID for the name.
-  (GITHUB-289)
-  [Jeff Moody]
-
-- Deprecate "key" argument in the SSHClient class in favor of new "key_files"
-  argument.
-
-  Also add a new "key_material" argument. This argument can contain raw string
-  version of a private key.
-
-  Note 1: "key_files" and "key_material" arguments are mutually exclusive.
-  Note 2: "key_material" argument is not supported in the ShellOutSSHClient.
-
-- Use node id attribute instead of the name for the "lconfig" label in the
-  Linode driver. This way the label is never longer than 48 characters.
-  (GITHUB-287)
-  [earthgecko]
-
-- Add a new driver for Outscale SAS and Outscale INC cloud
-  (http://www.outscale.com).
-  (GITHUB-285, GITHUB-293, LIBCLOUD-536, LIBCLOUD-553)
-  [Benoit Canet]
-
-- Add new driver for HP Public Cloud (Helion) available via Provider.HPCLOUD
-  constant.
-  [Tomaz Muraus]
-
-- Allow user to specify availability zone when creating an OpenStack node by
-  passing "ex_availability_zone" argument to the create_node method.
-  Note: This will only work if the OpenStack installation is running
-  availability zones extension.
-  (GITHUB-295, LIBCLOUD-555)
-  [syndicut]
-
-- Allow user to pass filters to ex_list_networks method in the EC2 driver.
-  (GITHUB-294)
-  [zerthimon]
-
-- Allow user to retrieve container images using ex_get_image method in the
-  Google Compute Engine driver.
-  (GITHUB-299, LIBCLOUD-562)
-  [Magnus Andersson]
-
-- Add new driver for Kili public cloud (http://kili.io/)
-  [Tomaz Muraus]
-
-- Add "timeout" argument to the ParamikoSSHClient.run method. If this argument
-  is specified and the command passed to run method doesn't finish in the
-  defined timeout, `SSHCommandTimeoutError` is throw and the connection to the
-  remote server is closed.
-
-  Note #1: If timed out happens, this functionality doesn't guarantee that the
-  underlying command will be stopped / killed. The way it works it simply
-  closes a connect to the remote server.
-  [Tomaz Muraus]
-
-  Note #2: "timeout" argument is only available in the Paramiko SSH client.
-
-- Make "cidrs_ips" argument in the ex_authorize_security_group_egress method in
-  the EC2 driver mandatory.
-  (GITHUB-301)
-  [Csaba Hoch]
-
-- Add extension methods for managing floating IPs (ex_get_floating_ip,
-  ex_create_floating_ip, ex_delete_floating_ip) to the Openstack 1.1 driver.
-  (GITHUB-301)
-  [Csaba Hoch]
-
-- Fix bug in RimuHosting driver which caused driver not to work when the
-  provider returned compressed (gzip'ed) response.
-  (LIBCLOUD-569, GITHUB-303)
-  [amastracci]
-
-- Fix issue with overwriting the server memory values in the RimuHosting
-  driver.
-  (GUTHUB-308)
-  [Dustin Oberloh]
-
-- Add ex_all_tenants argument to the list_nodes method in the OpenStack driver.
-  (GITHUB-312)
-  [LIBCLOUD-575, Zak Estrada]
-
-- Add support for network management for advanced zones
-  (ex_list_network_offerings, ex_create_network, ex_delete_network) in the
-  CloudStack driver.
-  (GITHUB-316)
-  [Roeland Kuipers]
-
-- Add extension methods for routes and route table management to the EC2
-  driver (ex_list_route_tables, ex_create_route_table, ex_delete_route_table,
-  ex_associate_route_table, ex_dissociate_route_table,
-  ex_replace_route_table_association, ex_create_route, ex_delete_route,
-  ex_replace_route)
-  (LIBCLOUD-574, GITHUB-313)
-  [Lior Goikhburg]
-
-- Fix ex_list_snapshots for HP Helion OpenStack based driver.
-  [Tomaz Muraus]
-
-- Allow user to specify volume type and number of IOPS when creating a new
-  volume in the EC2 driver by passing ``ex_volume_type`` and ``ex_iops``
-  argument to the ``create_volume`` method.
-  [Tomaz Muraus]
-
-- Fix ex_unpause_node method in the OpenStack driver.
-  (GITHUB-317)
-  [Pablo Ordu�a]
-
-- Allow user to launch EC2 node in a specific VPC subnet by passing
-  ``ex_subnet`` argument to the create_node method.
-  (GITHUB-318)
-  [Lior Goikhburg]
-
-Storage
-~~~~~~~
-
-- Fix container name encoding in the iterate_container_objects and
-  get_container_cdn_url method in the CloudFiles driver. Previously, those
-  methods would throw an exception if user passed in a container name which
-  contained a whitespace.
-
-  Reported by Brian Metzler.
-  (LIBCLOUD-552)
-  [Tomaz MUraus]
-
-- Fix a bug in the OpenStack Swift driver which prevented the driver to work
-  with installations where region names in the service catalog weren't upper
-  case.
-  (LIBCLOUD-576, GITHUB-311)
-  [Zak Estrada]
-
-Load Balancer
-~~~~~~~~~~~~~
-
-- Add extension methods for policy managagement to the ELB driver.
-  (LIBCLOUD-522, GITHUB-253)
-  [Rahul Ranjan]
-
-DNS
-~~~
-
-- Fix update_record method in the Route56 driver so it works correctly for
-  records with multiple values.
-  [Tomaz Muraus]
-
-- Add ex_create_multi_value_record method to the Route53 driver which allows
-  user to create a record with multiple values with a single call.
-  [Tomaz Muraus]
-
-- Add new driver for Google DNS.
-  (GITHUB-269)
-  [Franck Cuny]
-
-Changes with Apache Libcloud 0.14.1
------------------------------------
-
-Compute
-~~~~~~~
-
-- Add new m3.medium and m3.large instance information to the EC2 driver.
-  [Tomaz Muraus]
-
-- Add a new driver for CloudSigma API v2.0.
-  [Tomaz Muraus]
-
-- Add "volume_id" attribute to the Node "extra" dictionary in the EC2 driver.
-  Also fix the value of the "device" extra attribute in the StorageVolume
-  object. (LIBCLOUD-501)
-  [Oleg Suharev]
-
-- Add the following extension methods to the OpenStack driver: ex_pause_node,
-  ex_unpause_node, ex_suspend_node, ex_resume_node.
-  (LIBCLOUD-505, GITHUB-238)
-  [Chris DeRamus]
-
-- Add ex_limits method to the CloudStack driver.
-  (LIBCLOUD-507, GITHUB-240)
-  [Chris DeRamus]
-
-- Add "extra" dictionary to the CloudStackNode object and include more
-  attributes in the "extra" dictionary of the network and volume object.
-  (LIBCLOUD-506, GITHUB-239)
-  [Chris DeRamus]
-
-- Add ex_register_image method to the EC2 driver.
-  (LIBCLOUD-508, GITHUB-241)
-  [Chris DeRamus]
-
-- Add methods for managing volume snapshots to the OpenStack driver.
-  (LIBCLOUD-512, GITHUB-245)
-  [Chris DeRamus]
-
-Load Balancer
-~~~~~~~~~~~~~
-
-- Fix a bug in the ex_targetpool_add_node and ex_targetpool_remove_node method
-  in the GCE driver.
-  [Rick Wright]
-
-Storage
-~~~~~~~
-
-- Allow user to use an internal endpoint in the CloudFiles driver by passing
-  "use_internal_url" argument to the driver constructor.
-  (GITHUB-229, GITHUB-231)
-  [John Obelenus]
-
-DNS
-~~~
-
-- Add PTR to the supported record types in the Rackspace driver.
-  [Tomaz Muraus]
-
-- Fix Zerigo driver to set Record.name attribute for records which refer
-  to the bare domain to "None" instead of an empty string.
-  [Tomaz Muraus]
-
-- For consistency with other drivers, update Rackspace driver to set
-  Record.name attribute for the records which refer to the bare domain
-  to "None" instead of setting them to FQDN.
-  [Tomaz Muraus]
-
-- Update Rackspace driver to support paginating through zones and records.
-  (GITHUB-230)
-  [Roy Wellington]
-
-- Update Route53 driver so it supports handling records with multiple values
-  (e.g. MX).
-  (LIBCLOUD-504, GITHUB-237)
-  [Chris DeRamus]
-
-- Update Route53 driver to better handle SRV records.
-  [Tomaz Muraus]
-
-- Update Route53 driver, make sure "ttl" attribute in the Record extra
-  dictionary is always an int.
-  [Tomaz Muraus]
-
-Changes with Apache Libcloud 0.14.0
------------------------------------
-
-General
-~~~~~~~
-
-- Update API endpoints which are used in the HostVirtual drivers.
-  (LIBCLOUD-489)
-  [Dinesh Bhoopathy]
-
-- Add support for Amazon security token to the Amazon drivers.
-  (LIBCLOUD-498, GITHUB-223)
-  [Noah Kantrowitz]
-
-Compute
-~~~~~~~
-
-- Remove Slicehost driver.
-
-  SliceHost API has been shut down in 2012 so it makes no sense to keep
-  this driver.
-  [Tomaz Muraus]
-
-- Modify drivers for public cloud providers which use HTTP Basic
-  authentication to not allow insecure connections (secure constructor
-  kwarg being set to False) by default.
-
-  This way credentials can't accidentally be sent in plain text over the
-  write.
-
-  Affected drivers: Bluebox, Joyent, NephoScale, OpSource, VPSNet
-  [Tomaz Muraus]
-
-- Remove "public_ip" and "private_ip" property which has been deprecated in
-  0.7.0 from the Node object.
-  [Tomaz Muraus]
-
-- Move "is_private_ip" and "is_valid_ip_address" function from
-  libcloud.compute.base into libcloud.utils.networking module.
-  [Tomaz Muraus]
-
-- Allow user to pass "url" argument to the CloudStack driver constructor.
-  This argument can be provided instead of "host" and "path" arguments and
-  can contain a full URL to the API endpoint. (LIBCLOUD-430)
-  [Tomaz Muraus]
-
-- Allow user to pass None as a "location" argument to the create_node
-  method. (LIBCLOUD-431)
-  [Tomaz Muraus]
-
-- Refactor CloudStack Connection class so it looks more like other
-  connection classes and user can specify which attributes to send as part
-  of query parameters in the GET request and which inside the body of a POST
-  request.
-  [Tomaz Muraus, Philipp Strube]
-
-- Add a new driver for Exoscale (https://www.exoscale.ch/) provider.
-  [Tomaz Muraus]
-
-- Fix a bug in Abiquo driver which caused the driver to fail if the endpoint
-  URL didn't start with "/api". (LIBCLOUD-447)
-
-  Reported by Igor Ajdisek.
-  [Tomaz Muraus]
-
-- Modify CloudStack driver to correctly throw InvalidCredsError exception if
-  invalid credentials are provided.
-  [Tomaz Muraus]
-
-- Don't throw an exception if a node object is missing an "image" attribute
-  in the list nodes / get node response.
-
-  This could happen if node is in an error state. (LIBCLOUD-455)
-  [Dustin Spicuzza, Tomaz Muraus]
-
-- Update CloudStack driver to better handle errors and throw ProviderError
-  instead of a generic Exception.
-  [Tomaz Muraus]
-
-- Modify ex_list_networks methods in CloudStack driver to not thrown if there
-  are no networks available.
-  [Tomaz Muraus]
-
-- Bump API version used in the EC2 driver from 2010-08-21 to 2013-10-15.
-  (LIBCLOUD-454)
-  [Tomaz Muraus]
-
-- Add ex_get_limits method for retrieving account resource limits to the
-  EC2 driver.
-  [Tomaz Muraus]
-
-- Update us-west-1 region in the EC2 driver to include c3 instance types.
-  Also include pricing information.
-  [Tomaz Muraus]
-
-- For consistency, rename "ex_add_ip_forwarding_rule" method to
-  "ex_create_ip_forwarding_rule".
-  (GITHUB-196)
-  [Oleg Suharev]
-
-- Add support for new "i2" instance types to Amazon EC2 driver. Also
-  update pricing file. (LIBCLOUD-465)
-  [Chris DeRamus]
-
-- Allow user to specify VPC id when creating a security group in the EC2
-  driver by passing "vpc_id" argument to ex_create_security_group method.
-  (LIBCLOUD-463, GITHUB-201)
-  [Chris DeRamus]
-
-- Add extension methods for managing security group rules
-  (ex_authorize_security_group_ingress, ex_authorize_security_group_egress,
-  ex_revoke_security_group_ingress, ex_revoke_security_group_egress) to the
-  EC2 driver. (LIBCLOUD-466, GITHUB-202)
-  [Chris DeRamus]
-
-- Add extension methods for deleting security groups
-  (ex_delete_security_group, ex_delete_security_group_by_id,
-  ex_delete_security_group_by_name) to the EC2 driver.
-  (LIBCLOUD-464, GITHUB-199)
-  [Chris DeRamus]
-
-- Add extension method for listing reserved instances
-  (ex_list_reserved_nodes) to the EC2 driver. (LIBCLOUD-469, GITHUB-205)
-  [Chris DeRamus]
-
-- Add extension methods for VPC management (ex_list_networks,
-  ex_create_network, ex_delete_network) to the EC2 driver.
-  (LIBCLOUD-467, GITHUB-203)
-  [Chris DeRamus]
-
-- Add extension methods for VPC subnet management (ex_list_subnets,
-  ex_create_subnet, ex_delete_subnet) to the EC2 driver.
-  (LIBCLOUD-468, GITHUB-207)
-  [Chris DeRamus]
-
-- Add ex_get_console_output extension method to the EC2 driver.
-  (LIBCLOUD-471, GITHUB-209)
-  [Chris DeRamus]
-
-- Include additional provider-specific attributes in the 'extra' dictionary
-  of the StorageVolume class in the EC2 driver. (LIBCLOUD-473, GITHUB-210)
-  [Chris DeRamus]
-
-- Change attribute name in the 'extra' dictionary of EC2 and CloudStack
-  Node object from "keyname" to "key_name". (LIBCLOUD-475)
-  [Oleg Suharev]
-
-- Fix a deployment issue which would some times cause a process to hang if
-  the executed deployment script printed a lot of output to stdout or stderr.
-  [Tomaz Muraus]
-
-- Add additional attributes to the "extra" dictionary of the VolumeSnapshot
-  object in the EC2 driver.
-
-  Also modify create_volume_snapshot method to correctly handle "name"
-  argument. Previous, "name" argument was used as a snapshot description,
-  now it's used as a Tag with a key "Name". (LIBCLOUD-480, GITHUB-214)
-  [Chris DeRamus]
-
-- Store additional attributes (iops, tags, block_device_mapping) in the
-  "extra" dictionary of the NodeImage object in the EC2 driver.
-
-  Also fix ex_image_ids filtering in the list_images method.
-  (LIBCLOUD-481, GITHUB-215)
-  [Chris DeRamus]
-
-- Add extension methods for network interface management
-  (ex_list_network_interfaces, ex_create_network_interface,
-  ex_attach_network_interface_to_node, ex_detach_network_interface,
-  ex_delete_network_interface) to the EC2 driver. (LIBCLOUD-474)
-  [Chris DeRamus]
-
-- Update Google Compute Engine driver to use and work with API v1.
-  (LIBCLOUD-450)
-  [Rick Wright]
-
-- Modify ParamikoSSHClient so that "password" and "key" arguments are not
-  mutually exclusive and both can be provided. (LIBCLOUD-461, GITHUB-194)
-  [Markos Gogoulos]
-
-- Add extension methods for the Elastic IP management to the EC2 driver.
-  Also modify "ex_allocate_address" and "ex_release_address" method to
-  take "domain" argument so it also works with VPC.
-  (LIBCLOUD-470, GITHUB-208, GITHUB-220)
-  [Chris DeRamus]
-
-- Add additional provider specific attributes to the "extra" dictionary of
-  the Node object in the EC2 driver. (LIBCLOUD-493, GITHUB-221)
-  [Chris DeRamus]
-
-- Add ex_copy_image and ex_create_image_from_node method to the EC2 driver.
-  (LIBCLOUD-494, GITHUB-222)
-  [Chris DeRamus]
-
-Storage
-~~~~~~~
-
-- Allow user to specify 'Content-Disposition' header in the CloudFiles
-  driver by passing 'content_disposition' key in the extra dictionary of
-  the upload object methods. (LIBCLOUD-430)
-  [Michael Farrell]
-
-- Fix CloudFiles driver so it references a correct service catalog entry for
-  the CDN endpoint.
-
-  This was broken in the 0.14.0-beta3 release when we migrated all the
-  Rackspace drivers to use auth 2.0 by default. (GITHUB-186)
-  [John Obelenus]
-
-- Update storage drivers to default to "application/octet-stream"
-  Content-Type if none is provided and none can be guessed.
-  (LIBCLOUD-433)
-  [Michael Farrell]
-
-- Fix a bug so you can now upload 0 bytes sized objects using multipart
-  upload in the S3 driver. (LIBCLOUD-490)
-
-  Reported by Noah Kantrowitz.
-  [Tomaz Muraus]
-
-- Update OpenStack Swift driver constructor so it accepts "region",
-  "ex_force_service_type" and "ex_force_service_name" argument.
-  [Tomaz Muraus]
-
-- Deprecate "CLOUDFILES_SWIFT" provider constant in favor of new
-  "OPENSTACK_SWIFT" one.
-  [Tomaz Muraus]
-
-- Add support for setting an ACL when uploading and object.
-  (LIBCLOUD-497, GITHUB-223)
-  [Noah Kantrowitz]
-
-- Modify get_container method to use a more efficient "HEAD"
-  approach instead of calling list_containers + doing late
-  filterting.
-  (LIBCLOUD-498, GITHUB-223)
-  [Noah Kantrowitz]
-
-DNS
-~~~
-
-- Implement iterate_* methods in the Route53 driver and makes it work
-  correctly if there are more results which can fit on a single page.
-  Previously, only first 100 results were returned. (LIBCLOUD-434)
-  [Chris Clarke]
-
-- Update HostVirtual driver constructor to only take "key" and other valid
-  arguments. Previously it also took "secret" argument which it silently
-  ignored. (LIBCLOUD-483)
-
-  Reported by  Andrew Udvare.
-  [Tomaz Muraus]
-
-- Fix list_records method in the HostVirtual driver.
-  (LIBCLOUD-484, GITHUB-218)
-
-  Reported by Andrew Udvare.
-  [Dinesh Bhoopathy]
-
-Changes with Apache Libcloud 0.14.0-beta3
------------------------------------------
-
-General
-~~~~~~~
-
-- If the file exists, read pricing data from ~/.libcloud/pricing.json
-  by default. If the file doesn't exist, fall back to the old behavior
-  and use pricing data which is bundled with the release.
-  [Tomaz Muraus]
-
-- Add libcloud.pricing.download_pricing_file function for downloading and
-  updating the pricing file.
-  [Tomaz Muraus]
-
-- Fix libcloud.utils.py3.urlquote so it works with unicode strings under
-  Python 2. (LIBCLOUD-429)
-  [Michael Farrell]
-
-Compute
-~~~~~~~
-
-- Refactor Rackspace driver classes and make them easier to use. Now there
-  are two Rackspace provider constants - Provider.RACKSPACE which
-  represents new next-gen OpenStack servers and
-  Provider.RACKSPACE_FIRST_GEN which represents old first-gen cloud
-  servers.
-
-  Note: This change is backward incompatible. For more information on those
-  changes and how to update your code, please visit "Upgrade Notes"
-  documentation page - http://s.apache.org/lc0140un
-  [Tomaz Muraus]
-
-- Deprecate the following EC2 provider constants: EC2_US_EAST,
-  EC2_EU, EC2_EU_WEST, EC2_AP_SOUTHEAST, EC2_AP_NORTHEAST,
-  EC2_US_WEST_OREGON, EC2_SA_EAST, EC2_SA_EAST and replace it with a new
-  EC2 constant.
-  Driver referenced by this new constant now takes a "region" argument which
-  dictates to which region to connect.
-
-  Note: Deprecated constants will continue to work until the next major
-  release. For more information on those changes and how to update your
-  code, please visit "Upgrade Notes" documentation page -
-  http://s.apache.org/lc0140un
-  [Tomaz Muraus]
-
-- Add support for volume related functions to OpenNebula driver.
-  (LIBCLOUD-354)
-  [Emanuele Rocca]
-
-- Add methods for managing storage volumes to the OpenStack driver.
-  (LIBCLOUD-353)
-  [Bernard Kerckenaere]
-
-- Add new driver for Google Compute Engine (LIBCLOUD-266, LIBCLOUD-386)
-  [Rick Wright]
-
-- Fix create_node "features" metadata and update affected drivers.
-  (LIBCLOUD-367)
-  [John Carr]
-
-- Update EC2 driver to accept the auth kwarg (it will accept NodeAuthSSH
-  objects and automatically import a public key that is not already
-  uploaded to the EC2 keyring). (Follow on from LIBCLOUD-367).
-  [John Carr]
-
-- Unify extension argument names for assigning a node to security groups
-  in EC2 and OpenStack driver.
-  Argument in the EC2 driver has been renamed from ex_securitygroup to
-  ex_security_groups. For backward compatibility reasons, old argument
-  will continue to work until the next major release. (LIBCLOUD-375)
-  [Tomaz Muraus]
-
-- Add ex_import_keypair_from_string and ex_import_keypair method to the
-  CloudStack driver. (LIBCLOUD-380)
-  [Sebastien Goasguen]
-
-- Add support for managing floating IP addresses to the OpenStack driver.
-  (LIBCLOUD-382)
-  [Ivan Kusalic]
-
-- Add extension methods for handling port forwarding to the CloudStack
-  driver, rename CloudStackForwardingRule class to
-  CloudStackIPForwardingRule. (LIBCLOUD-348, LIBCLOUD-381)
-  [sebastien goasguen]
-
-- Hook up deploy_node functionality in the CloudStack driver and unify
-  extension arguments for handling security groups. (LIBCLOUD-388)
-  [sebastien goasguen]
-
-- Allow user to pass "args" argument to the ScriptDeployment and
-  ScriptFileDeployment class. This argument tells which command line
-  arguments get passed to the ScriptDeployment script. (LIBCLOUD-394)
-
-  Note: This change is backward incompatible. For more information on how
-  this affects your code and how to update it, visit "Upgrade Notes"
-  documentation page - http://s.apache.org/lc0140un
-  [Tomaz Muraus]
-
-- Allow user to specify IAM profile to use when creating an EC2 node.
-  (LIBCLOUD-403)
-  [Xavier Barbosa]
-
-- Add support for keypair management to the OpenStack driver.
-  (LIBCLOUD-392)
-  [L. Schaub]
-
-- Allow user to specify disk partitioning mode using ex_disk_config argument
-  in the OpenStack based drivers. (LIBCLOUD-402)
-  [Brian Curtin]
-
-- Add new driver for NephoScale provider (http://nephoscale.com/).
-  (LIBCLOUD-404)
-  [Markos Gogoulos]
-
-- Update network related extension methods so they work correctly with
-  both, OpenStack and Rackspace driver. (LIBCLOUD-368)
-  [Tomaz Muraus]
-
-- Add tests for networking functionality in the OpenStack and Rackspace
-  driver.
-  [Tomaz Muraus]
-
-- Allow user to pass all supported extension arguments to ex_rebuild_server
-  method in the OpenStack driver. (LIBCLOUD-408)
-  [Dave King]
-
-- Add pricing information for Rackspace Cloud Sydney region.
-  [Tomaz Muraus]
-
-- Update EC2 instance type map and pricing data. High Storage instances are
-  now also available in Sydney and Singapore region.
-  [Tomaz Muraus]
-
-- Add new methods for managing storage volumes and snapshots to the EC2
-  driver (list_volumes, list_snapshots, destroy_volume_snapshot,
-  create_volume_snapshot) (LIBCLOUD-409)
-  [Oleg Suharev]
-
-- Add the following new extension methods to EC2 driver: ex_destroy_image,
-  ex_modify_instance_attributes, ex_delete_keypair. (LIBCLOUD-409)
-  [Oleg Suharev]
-
-- Allow user to specify a port range when creating a port forwarding rule.
-  (LIBCLOUD-409)
-  [Oleg Suharev]
-
-- Align Joyent driver with other drivers and deprecate "location" argument
-  in the driver constructor in favor of "region" argument.
-
-  Note: Deprecated argument will continue to work until the next major
-  release.
-  [Tomaz Muraus]
-
-- Deprecate the following ElasticHosts provider constants: ELASTICHOSTS_UK1,
-  ELASTICHOSTS_UK2, ELASTICHOSTS_US1, ELASTICHOSTS_US2, ELASTICHOSTS_US3,
-  ELASTICHOSTS_CA1, ELASTICHOSTS_AU1, ELASTICHOSTS_CN1 and replace it with a
-  new ELASTICHOSTS constant.
-  Driver referenced by this new constant now takes a "region" argument which
-  dictates to which region to connect.
-
-  Note: Deprecated constants will continue to work until the next major
-  release. For more information on those changes and how to update your
-  code, please visit "Upgrade Notes" documentation page -
-  http://s.apache.org/lc0140un (LIBCLOUD-383)
-  [Michael Bennett, Tomaz Muraus]
-
-- Add log statements to our ParamikoSSHClient wrapper. This should make
-  debugging deployment issues easier. (LIBCLOUD-414)
-  [Tomaz Muraus]
-
-- Add new "NodeState.STOPPED" node state. Update HostVirual and EC2 driver to
-  also recognize this new state. (LIBCLOUD-296)
-  [Jayy Vis]
-
-- Add new Hong Kong endpoint to Rackspace driver.
-  [Brian Curtin]
-
-- Fix ex_delete_keypair method in the EC2 driver. (LIBCLOUD-415)
-  [Oleg Suharev]
-
-- Add the following new extension methods for elastic IP management to the
-  EC2 driver: ex_allocate_address, ex_disassociate_address,
-  ex_release_address. (LIBCLOUD-417)
-  [Patrick Armstrong]
-
-- For consistency and accuracy, rename "ex_associate_addresses" method in the
-  EC2 driver to "ex_associate_address_with_node".
-
-  Note: Old method will continue to work until the next major release.
-  [Tomaz Muraus]
-
-- Add new driver for CloudFrames (http://www.cloudfounders.com/CloudFrames)
-  provider. (LIBCLOUD-358)
-  [Bernard Kerckenaere]
-
-- Update default kernel versions which are used when creating a Linode
-  server.
-
-  Old default kernel versions:
-
-  - x86 - 2.6.18.8-x86_64-linode1
-  - x86_64 - 2.6.39.1-linode34
-
-  New default kernel versions:
-
-  - x86 - 3.9.3-x86-linode52
-  - x86_64 - 3.9.3-x86_64-linode33
-
-  (LIBCLOUD-424)
-  [Tomaz Muraus, Jon Chen]
-
-- Disable cache busting functionality in the OpenStack and Rackspace next-gen
-  driver and enable it only for Rackspace first-gen driver.
-  [Tomaz Muraus]
-
-- Update Google Compute Engine driver to v1beta16.
-  [Rick Wright]
-
-- Modify auth_url variable in the OpenStack drivers so it works more like
-  users would expect it to.
-
-  Previously path specified in the auth_url was ignored and only protocol,
-  hostname and port were used. Now user can provide a full url for the
-  auth_url variable and the path provided in the url is also used.
-  [DaeMyung Kang, Tomaz Muraus]
-
-- Allow user to associate arbitrary key/value pairs with a node by passing
-  "ex_metadata" argument (dictionary) to create_node method in the EC2
-  driver.
-  Those values are associated with a node using tags functionality.
-  (LIBCLOUD-395)
-  [Ivan Kusalic]
-
-- Add "ex_get_metadata" method to EC2 and OpenStack driver. This method reads
-  metadata dictionary from the Node object. (LIBCLOUD-395)
-  [Ivan Kusalic]
-
-- Multiple improvements in the Softlayer driver:
-    - Map "INITIATING" node state to NodeState.PENDING
-    - If node is launching remap "halted" state to "pending"
-    - Add more node sizes
-    - Add ex_stop_node and ex_start_node method
-    - Update tests response fixtures
-
-  (LIBCLOUD-416)
-  [Markos Gogoulos]
-
-- Modify list_sizes method in the KT UCloud driver to work, even if the item
-  doesn't have 'diskofferingid' attribute. (LIBCLOUD-435)
-  [DaeMyung Kang]
-
-- Add new c3 instance types to the EC2 driver.
-  [Tomaz Muraus]
-
-- Fix an issue with the ex_list_keypairs and ex_list_security_groups method
-  in the CloudStack driver which caused an exception to be thrown if the API
-  returned no keypairs / security groups.
-  (LIBCLOUD-438)
-  [Carlos Reategui, Tomaz Muraus]
-
-- Fix a bug in the OpenStack based drivers with not correctly checking if the
-  auth token has expired before re-using it. (LIBCLOUD-428)
-
-  Reported by Michael Farrell.
-  [Tomaz Muraus,  Michael Farrell]
-
-Storage
-~~~~~~~
-
-- Deprecate CLOUDFILES_US and CLOUDFILES_UK provider constant and replace
-  it with a new CLOUDFILES constant.
-  Driver referenced by this new constant takes a "region" keyword argument
-  which can be one of 'ord', 'dfw', 'iad', 'syd', 'lon'.
-
-  Note: Deprecated constants will continue to work until the next major
-  release.
-  For more information on this change, please visit "Upgrade Notes"
-  documentation section - http://s.apache.org/lc0140un
-  [Tomaz Muraus]
-
-- Allow users to filter objects starting with a prefix by passing ex_prefix
-  argument to the list_container_objects method in the S3, Google Storage
-  and CloudFiles driver. (LIBCLOUD-369)
-  [Stefan Friesel]
-
-- Fix an issue with mutating connectionCls.host attribute in the Azure
-  driver. This bug prevented user from having multiple Azure drivers with
-  different keys instantiated at the same time. (LIBCLOUD-399)
-  [Olivier Grisel]
-
-- Add a new driver for KT UCloud based on the OpenStack Swift driver.
-  (LIBCLOUD-431).
-  [DaeMyung Kang]
-
-Load Balancer
-~~~~~~~~~~~~~
-
-- Deprecate RACKSPACE_US and RACKSPACE_UK provider constant and replace it
-  with a new RACKSPACE constant.
-  Driver referenced by this new constant takes a "region" keyword argument
-  which can be one of the following: 'ord', 'dfw', 'iad', 'syd', 'lon'.
-
-  Note: Deprecated constants will continue to work until the next major
-  release.
-  For more information on this change, please visit "Upgrade Notes"
-  documentation section - http://s.apache.org/lc0140un
-  [Tomaz Muraus]
-
-- Add new driver for Google Compute Engine (LIBCLOUD-386)
-  [Rick Wright]
-
-- Add new Hong Kong endpoint to Rackspace driver.
-  [Brian Curtin]
-
-DNS
-~~~
-
-- Deprecate RACKSPACE_US and RACKSPACE_UK provider constant and replace it
-  with a new RACKSPACE constant.
-  Driver referenced by this new constant takes a "region" keyword argument
-  which can be one of the following: 'us', 'uk'.
-
-  Note: Deprecated constants will continue to work until the next major
-  release.
-  For more information on this change, please visit "Upgrade Notes"
-  documentation section - http://s.apache.org/lc0140un
-  [Tomaz Muraus]
-
-- Use string instead of integer for RecordType ENUM value.
-
-  Note: If you directly use an integer instead of RecordType ENUM class you
-  need to update your code to use the RecordType ENUM otherwise the code
-  won't work. For more information on how to do that, see "Upgrade Notes"
-  documentation section - http://s.apache.org/lc0140un
-  [Tomaz Muraus]
-
-- Add "export_zone_to_bind_format" and export_zone_to_bind_zone_file method
-  which allows users to export Libcloud Zone to BIND zone format.
-  (LIBCLOUD-398)
-  [Tomaz Muraus]
-
-- Update issue with inexistent zone / record handling in the get_zone and
-  get_record method in the Linode driver. Those issues were related to
-  changes in the Linode API. (LIBCLOUD-425)
-  [Jon Chen]
-
-Changes with Apache Libcloud 0.13.3
------------------------------------
-
-Compute
-~~~~~~~
-
-- Send "scrub_data" query parameter when destroying a DigitalOcean node.
-  This will cause disk to be scrubbed (overwritten with 0's) when destroying
-  a node. (LIBCLOUD-487)
-
-  Note: This fixes a security issue with a potential leak of data contained
-  on the destroyed node which only affects users of the DigitalOcean driver.
-  (CVE-2013-6480)
-  [Tomaz Muraus]
-
-Changes with Apache Libcloud 0.13.2
------------------------------------
-
-General
-~~~~~~~
-
-- Don't sent Content-Length: 0 header with POST and PUT request if "raw"
-  mode is used. This fixes a regression which could cause broken behavior
-  in some storage driver when uploading a file from disk.
-  (LIBCLOUD-396)
-  [Ivan Kusalic]
-
-Compute
-~~~~~~~
-
-- Added Ubuntu Linux 12.04 image to ElasticHost driver image list.
-  (LIBCLOUD-364)
-  [Bob Thompson]
-
-- Update ElasticHosts driver to store drive UUID in the node 'extra' field.
-  (LIBCLOUD-357)
-  [Bob Thompson]
-
-Storage
-~~~~~~~
-
-- Store last_modified timestamp in the Object extra dictionary in the S3
-  driver. (LIBCLOUD-373)
-  [Stefan Friesel]
-
-Load Balancer
-~~~~~~~~~~~~~
-
-- Expose CloudStack driver directly through the Provider.CLOUDSTACK
-  constant.
-  [Tomaz Muraus]
-
-DNS
-~~~
-
-- Modify Zerigo driver to include record TTL in the record 'extra' attribute
-  if a record has a TTL set.
-  [Tomaz Muraus]
-
-- Modify values in the Record 'extra' dictionary attribute in the Zerigo DNS
-  driver to be set to None instead of an empty string ('') if a value for
-  the provided key is not set.
-  [Tomaz Muraus]
-
-Changes with Apache Libcloud 0.13.1
------------------------------------
-
-General
-~~~~~~~
-
-- Fix a regression introduced in 0.13.0 and make sure to include
-  Content-Length 0 with PUT and POST requests. (LIBCLOUD-362, LIBCLOUD-390)
-  [Tomaz Muraus]
-
-Compute
-~~~~~~~
-
-- Fix a bug in the ElasticHosts driver and check for right HTTP status
-  code when determining drive imaging success. (LIBCLOUD-363)
-  [Bob Thompson]
-
-- Update Opsource driver to include node public ip address (if available).
-  (LIBCLOUD-384)
-  [Michael Bennett]
-
-Storage
-~~~~~~~
-
-- Fix a regression with calling encode_container_name instead of
-  encode_object_name on object name in get_object method.
-  Reported by Ben Meng (LIBCLOUD-366)
-  [Tomaz Muraus]
-
-- Ensure that AWS S3 multipart upload works for small iterators.
-  (LIBCLOUD-378)
-  [Mahendra M]
-
-Changes with Apache Libcloud 0.13.0
------------------------------------
-
-General
-~~~~~~~
-
-- Add homebrew curl-ca-bundle path to CA_CERTS_PATH. This will make Libcloud
-  use homebrew curl ca bundle file (if available) for server certificate
-  validation. (LIBCLOUD-324)
-  [Robert Chiniquy]
-
-- Modify OpenStackAuthConnection and change auth_token_expires attribute to
-  be a datetime object instead of a string.
-  [Tomaz Muraus]
-
-- Modify OpenStackAuthConnection to support re-using of the existing auth
-  token if it's still valid instead of re-authenticating on every
-  authenticate() call.
-  [Tomaz Muraus]
-
-- Modify base Connection class to not send Content-Length header if body is
-  not provided.
-  [Tomaz Muraus]
-
-- Add the new error class ProviderError and modify InvalidCredsError to
-  inherit from it. (LIBCLOUD-331)
-  [Jayy Vis]
-
-Misc
-----
-
-- Add unittest2 library dependency for tests and update some tests to use
-  it.
-  [Tomaz Muraus]
-
-Compute
-~~~~~~~
-
-- Fix destroy_node method in the experimental libvirt driver.
-  [Aymen Fitati]
-
-- Add ex_start_node method to the Joyent driver. (LIBCLOUD-319)
-  [rszabo50]
-
-- Fix Python 3 compatibility issue in the ScriptFileDeployment class.
-  (LIBCLOUD-321)
-  [Arfrever Frehtes Taifersar Arahesis]
-
-- Add ex_set_metadata_entry and ex_get_metadata method to the VCloud driver.
-  (LIBCLOUD-318)
-  [Michel Samia]
-
-- Various improvements and bug-fixes in the VCloud driver. (LIBCLOUD-323)
-  [Michel Samia]
-
-- Various bug fixes and improvements in the HostVirtual driver.
-  (LIBCLOUD-249)
-  [Dinesh Bhoopathy]
-
-- Modify list_sizes method in the OpenStack driver to include
-  OpenStackNodeSize object which includes 'vcpus' attribute which holds
-  a number of virtual CPUs for this size. (LIBCLOUD-325)
-  [Carlo]
-
-- For consistency rename "ex_describe_keypairs" method in the EC2 driver to
-  "ex_describe_keypair".
-  [Tomaz Muraus]
-
-- Modify "ex_describe_keypair" method to return key fingerprint in the
-  return value. (LIBCLOUD-326)
-  [Andre Merzky, Tomaz Muraus]
-
-- Populate private_ips attribute in the CloudStack drive when returning
-  a Node object from the create_node method. (LIBCLOUD-329)
-  [Sebastien Goasguen, Tomaz Muraus]
-
-- Allow user to pass extra arguments via "extra_args" argument which are
-  then passed to the "deployVirtualMachine" call in the CloudStack driver
-  create_node method. (LIBCLOUD-330)
-  [Sebastien Goasguen, Tomaz Muraus]
-
-- Update Gandi driver to handle new billing model. (LIBCLOUD-317)
-  [Aymeric Barantal]
-
-- Fix a bug in the Linode driver and remove extra newline which is added
-  when generating a random root password in create_node. (LIBCLOUD-334)
-  [Juan Carlos Moreno]
-
-- Add extension methods for managing keypairs to the CloudStack driver.
-  (LIBCLOUD-333)
-  [sebastien goasguen]
-
-- Add extension methods for managing security groups to the CloudStack
-  driver. (LIBCLOUD-332)
-  [sebastien goasguen]
-
-- Add extension methods for starting and stoping the node to the
-  CloudStack driver. (LIBCLOUD-338)
-  [sebastien goasguen]
-
-- Fix old _wait_until_running method. (LIBCLOUD-339)
-  [Bob Thompson]
-
-- Allow user to override default async task completion timeout by
-  specifying ex_clone_timeout argument. (LIBCLOUD-340)
-  [Michal Galet]
-
-- Fix a bug in the GoGrid driver get_uuid method. (LIBCLOUD-341)
-  [Bob Thompson]
-
-- Fix a bug with deploy_node not respecting 'timeout' kwarg.
-  [Kevin Carter]
-
-- Modify create_node method in CloudStack driver to return an instance of
-  CloudStackNode and add a new "expunging" node state. (LIBCLOUD-345)
-  [sebastien goasguen]
-
-- Update API endpoint hostnames in the ElasticHost driver and use hostnames
-  which return a valid SSL certificate. (LIBCLOUD-346)
-  [Bob Thompson]
-
-- Add ex_list_networks method and missing tests for list_templates to the
-  CloudStack driver. (LIBCLOUD-349)
-  [Philipp Strube]
-
-- Correctly throw InvalidCredsError if user passes invalid credentials to
-  the DigitalOcean driver.
-  [Tomaz Muraus]
-
-Storage
-~~~~~~~
-
-- Fix an issue with double encoding the container name in the CloudFiles
-  driver upload_object method.
-  Also properly encode container and object name used in the HTTP request
-  in the get_container and get_object method. (LIBCLOUD-328)
-  [Tomaz Muraus]
-
-Load Balancer
-~~~~~~~~~~~~~
-
-- Add ex_list_current_usage method to the Rackspace driver.
-
-Changes with Apache Libcloud 0.12.4
------------------------------------
-
-Compute
-~~~~~~~
-
-- Fix a regression in Softlayer driver caused by the xmlrpclib changes.
-  (LIBCLOUD-310)
-  [Jason Johnson]
-
-- Allow user to pass alternate ssh usernames to deploy_node
-  (ssh_alternate_usernames kwarg) which are used for authentication if the
-  default one doesn't work. (LIBCLOUD-309)
-  [Chris Psaltis, Tomaz Muraus]
-
-- Fix a bug in EC2 list_locations method - 'name' attribute didn't contain a
-  the right value.
-  [Tomaz Muraus]
-
-- Add new ScriptFileDeployment deployment class which reads deploy script
-  from a file.
-  [Rudolf J Streif]
-
-- Add support for API version 5.1 to the vCloud driver and accept any value
-  which is a multiple of four for ex_vm_memory kwarg in create_node method.
-  (LIBCLOUD-314)
-  [Trevor Powell]
-
-Storage
-~~~~~~~
-
-- Fix a regression with removed ex_force_service_region constructor kwarg in
-  the CloudFiles driver. (LIBCLOUD-260)
-
-Changes with Apache Libcloud 0.12.3
------------------------------------
-
-General
-~~~~~~~
-
-- Fix Python 3.x related regressions. (LIBCLOUD-245)
-  Reported by Arfrever Frehtes Taifersar Arahesis.
-  [Tomaz Muraus]
-
-- Fix a regression introduced with recent xmlrpiclib changes which broke all
-  the Gandi.net drivers. (LIBCLOUD-288)
-
-  Reported by Hutson Betts.
-  [Tomaz Muraus]
-
-- Improve deploy code to work correctly if the ssh user doesn't have access
-  to the /root directory.
-
-  Previously the ScriptDeployment script was stored in /root folder by
-  default. Now it's stored in users home directory under filename
-  ~/libcloud_deploymeny_<random>.sh. (LIBCLOUD-302)
-
-  Reported by rotem on #libcloud.
-  [Tomaz Muraus]
-
-Compute
-~~~~~~~
-
-- Improve public and private IP address handling in OpenStack 1.1 driver.
-  Assume every IP address which doesn't have a label "public" or "internet"
-  is private. (LIBCLOUD-297)
-  [Grischa Meyer, Tomaz Muraus]
-
-- Add new driver for DigitalOcean provider - https://www.digitalocean.com/.
-  (LIBCLOUD-304)
-  [Tomaz Muraus]
-
-- Fix a regression in ParamikoSSHClient.run method which caused this methid
-  to only work as expected if you passed an absolute or a relative path to
-  the script to it. (LIBCLOUD-278)
-  [Tomaz Muraus]
-
-DNS
-~~~
-
-- Allow user to specify 'priority' extra argument when creating a MX or SRV
-  record.
-  [Brian Jinwright, Tomaz Muraus]
-
-Changes with Apache Libcloud 0.12.1
------------------------------------
-
-General
-~~~~~~~
-
-- Deprecate LazyList method of iteration over large paginated collections
-  and use a new, more efficient generator based approach which doesn't
-  require the iterator to be pre-exhausted and buffering all of the values
-  in memory.
-
-  Existing list_* methods which previously used LazyList class are
-  preserving the old behavior and new iterate_* methods which use a new
-  generator based approach have been added. (LIBCLOUD-254)
-  [Mahendra M]
-
-- Replace old ENUM style provider constants and replace them with a string
-  version.
-  This change allows users to dynamically register new drivers using a new
-  set_driver method. (LIBCLOUD-255)
-  [Mahendra M]
-
-- Allow user to explicitly specify which CA file is used for verifying
-  the server certificate by setting 'SSL_CERT_FILE' environment variable.
-
-  Note: When this variable is specified, the specified path is the only
-  CA file which is used to verifying the server certificate. (LIBCLOUD-283)
-  [Tomaz Muraus, Erinn Looney-Triggs]
-
-- Add a common module (libcloud.common.xmlrpc) for handling XML-RPC
-  requests using Libcloud http layer.
-
-  Also refactor existing drivers which use xmlrpclib directly (VCL, Gandi,
-  Softlayer) to use this module.
-
-  This change allows drivers to support LIBCLOUD_DEBUG and SSL certificate
-  validation functionality. Previously they have bypassed Libcloud http
-  layer so this functionality was not available. (LIBCLOUD-288)
-  [John Carr]
-
-Compute
-~~~~~~~
-
-- Fix string interpolation bug in __repr__ methods in the IBM SCE driver.
-  (LIBCLOUD-242)
-  [Tomaz Muraus]
-
-- Fix test failures which happened in Python 3.3 due to:
-  - hash randomization
-  - changes in xml.etree module
-  - changes in xmlrpc module
-  (LIBCLOUD-245)
-  [Tomaz Muraus]
-
-- Improvements and additions in vCloud driver:
-    - Expose generic query method (ex_query)
-    - Provide functionality to get and set control access for vApps. This way
-      created vApps can be shared between users/groups or everyone.
-
-  (LIBCLOUD-251)
-  [Michal Galet]
-
-- Update EC2 pricing data to reflect new, lower prices -
-  http://aws.typepad.com/aws/2012/10/new-ec2-second-generation-standard-instances-and-price-reductions-1.html
-  [Tomaz Muraus]
-
-- Update EC2 instance size to reflect new m3 instance types. Also refactor
-  the code to make it easier to maintain.
-  [Tomaz Muraus]
-
-- Add a new driver for HostVirtual (http://www.vr.org) provider.
-  (LIBCLOUD-249)
-  [Dinesh Bhoopathy]
-
-- Fix a bug where a numeric instead of a string value was used for the
-  content-length header in VCloud driver. (LIBCLOUD-256)
-  [Brian DeGeeter, Tomaz Muraus]
-
-- Add a new driver for new Asia Pacific (Sydney) EC2 region.
-  [Tomaz Muraus]
-
-- Add support for managing security groups to the OpenStack driver. This
-  patch adds the following extension methods:
-  - ex_list_security_groups, ex_get_node_security_groups methods
-  - ex_create_security_group, ex_delete_security_group
-  - ex_create_security_group_rule, ex_delete_security_group_rule
-  (LIBCLOUD-253)
-  [L. Schaub]
-
-- Modify ElasticStack driver class to pass 'vnc auto' instead of
-  'vnc:ip auto' argument to the API when creating a server.
-  It looks like 'vnc:ip' has been replaced with 'vnc'.
-  [Rick Copeland, Tomaz Muraus]
-
-- Add new EC2 instance type - High Storage Eight Extra Large Instance
-  (hs1.8xlarge).
-  [Tomaz Muraus]
-
-- Map 'shutting-down' node state in EC2 driver to UNKNOWN. Previously
-  it was mapped to TERMINATED. (LIBCLOUD-280)
-
-  Note: This change is backward incompatible which means you need to update
-  your code if you rely on the old behavior.
-  [Tomaz Muraus, Marcin Kuzminski]
-
-- Change _wait_until_running method so it supports waiting on multiple nodes
-  and make it public (wait_until_running). (LIBCLOUD-274)
-  [Nick Bailey]
-
-- Add new EC2 instance type - High Memory Cluster Eight Extra Large.
-  (cr1.8xlarge).
-  [Tomaz Muraus]
-
-- Add new driver for Abiquo provider - http://www.abiquo.com (LIBCLOUD-250).
-  [Jaume Devesa]
-
-- Allow user to pass 'ex_blockdevicemappings' kwarg to the EC2 driver
-  'create_node' method. (LIBCLOUD-282)
-  [Joe Miller, Tomaz Muraus]
-
-- Improve error handling in the Brightbox driver.
-  [Tomaz Muraus]
-
-- Fix the ScriptDeployment step to work correctly if user provides a
-  relative path for the script argument. (LIBCLOUD-278)
-  [Jaume Devesa]
-
-- Fix Softlayer driver and make sure all the code is up to date and works
-  with the latest version of the actual Softlayer deployment (v3).
-  (LIBCLOUD-287)
-  [Kevin McDonald]
-
-- Update EC2 driver, m3 instance types are now available in all the regions
-  except Brazil.
-
-  Also update pricing to reflect new (lower) prices.
-  [Tomaz Muraus]
-
-- Minor improvements in the HostVirtual driver and add new ex_get_node and
-  ex_build_node extension method. (LIBCLOUD-249)
-  [Dinesh Bhoopathy]
-
-- Add ex_destroy_image method to IBM SCE driver. (LIBCLOUD-291)
-  [Perry Zou]
-
-- Add the following new regions to the ElasticHosts driver: sjc-c, syd-v,
-  hkg-e. (LIBCLOUD-293)
-  [Tomaz Muraus]
-
-- Fix create_node in 

<TRUNCATED>

[48/56] [abbrv] libcloud git commit: Fix sphinx error

Posted by an...@apache.org.
Fix sphinx error


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/908aa5bf
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/908aa5bf
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/908aa5bf

Branch: refs/heads/trunk
Commit: 908aa5bfba9b47467f8c1708069981c367d0cbf9
Parents: dd0e396
Author: anthony-shaw <an...@apache.org>
Authored: Fri Apr 15 08:52:21 2016 +1000
Committer: anthony-shaw <an...@apache.org>
Committed: Fri Apr 15 08:52:21 2016 +1000

----------------------------------------------------------------------
 docs/compute/drivers/azure_arm.rst | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/908aa5bf/docs/compute/drivers/azure_arm.rst
----------------------------------------------------------------------
diff --git a/docs/compute/drivers/azure_arm.rst b/docs/compute/drivers/azure_arm.rst
index 3f111cc..6506d57 100644
--- a/docs/compute/drivers/azure_arm.rst
+++ b/docs/compute/drivers/azure_arm.rst
@@ -26,6 +26,7 @@ The following directions are based on
 https://azure.microsoft.com/en-us/documentation/articles/resource-group-authenticate-service-principal/
 
 .. sourcecode:: bash
+
   azure ad app create --name "<Your Application Display Name>" --home-page "<https://YourApplicationHomePage>" --identifier-uris "<https://YouApplicationUri>" --password <Your_Password>
   azure ad sp create "<Application_Id>"
   azure role assignment create --objectId "<Object_Id>" -o Owner -c /subscriptions/{subscriptionId}/


[36/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/abiquo.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/abiquo.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/abiquo.py
deleted file mode 100644
index fdcc59d..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/abiquo.py
+++ /dev/null
@@ -1,795 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-Abiquo Compute Driver
-
-The driver implements the compute Abiquo functionality for the Abiquo API.
-This version is compatible with the following versions of Abiquo:
-
-    * Abiquo 3.1 (http://wiki.abiquo.com/display/ABI31/The+Abiquo+API)
-"""
-import xml.etree.ElementTree as ET
-
-from libcloud.compute.base import NodeDriver, NodeSize
-from libcloud.compute.types import Provider, LibcloudError
-from libcloud.common.abiquo import (AbiquoConnection, get_href,
-                                    AbiquoResponse)
-from libcloud.compute.base import NodeLocation, NodeImage, Node
-from libcloud.utils.py3 import tostring
-
-
-class AbiquoNodeDriver(NodeDriver):
-    """
-    Implements the :class:`NodeDriver`'s for the Abiquo Compute Provider
-    """
-
-    type = Provider.ABIQUO
-    name = 'Abiquo'
-    website = 'http://www.abiquo.com/'
-    connectionCls = AbiquoConnection
-    timeout = 2000  # some images take a lot of time!
-
-    # Media Types
-    NODES_MIME_TYPE = 'application/vnd.abiquo.virtualmachines+xml'
-    NODE_MIME_TYPE = 'application/vnd.abiquo.virtualmachine+xml'
-    VAPPS_MIME_TYPE = 'application/vnd.abiquo.virtualappliances+xml'
-    VAPP_MIME_TYPE = 'application/vnd.abiquo.virtualappliance+xml'
-    VM_TASK_MIME_TYPE = 'application/vnd.abiquo.virtualmachinetask+xml'
-    USER_MIME_TYPE = 'application/vnd.abiquo.user+xml'
-    ENT_MIME_TYPE = 'application/vnd.abiquo.enterprise+xml'
-    VDCS_MIME_TYPE = 'application/vnd.abiquo.virtualdatacenters+xml'
-    VDC_MIME_TYPE = 'application/vnd.abiquo.virtualdatacenter+xml'
-    DCS_MIME_TYPE = 'application/vnd.abiquo.datacenters+xml'
-    VMTPLS_MIME_TYPE = 'application/vnd.abiquo.virtualmachinetemplates+xml'
-    VMTPL_MIME_TYPE = 'application/vnd.abiquo.virtualmachinetemplate+xml'
-    NICS_MIME_TYPE = 'application/vnd.abiquo.nics+xml'
-    DCRS_MIME_TYPE = 'application/vnd.abiquo.datacenterrepositories+xml'
-    DCR_MIME_TYPE = 'application/vnd.abiquo.datacenterrepository+xml'
-    AR_MIME_TYPE = 'application/vnd.abiquo.acceptedrequest+xml'
-
-    # Others constants
-    GIGABYTE = 1073741824
-
-    def __init__(self, user_id, secret, endpoint, **kwargs):
-        """
-        Initializes Abiquo Driver
-
-        Initializes the :class:`NodeDriver` object and populate the cache.
-
-        :param       user_id: identifier of Abiquo user (required)
-        :type        user_id: ``str``
-        :param       secret: password of the Abiquo user (required)
-        :type        secret: ``str``
-        :param       endpoint: Abiquo API endpoint (required)
-        :type        endpoint: ``str`` that can be parsed as URL
-        """
-        self.endpoint = endpoint
-        super(AbiquoNodeDriver, self).__init__(key=user_id, secret=secret,
-                                               secure=False, host=None,
-                                               port=None, **kwargs)
-        self.ex_populate_cache()
-
-    def create_node(self, **kwargs):
-        """
-        Create a new node instance in Abiquo
-
-        All the :class:`Node`s need to be defined inside a VirtualAppliance
-        (called :class:`NodeGroup` here). If there is no group name defined,
-        'libcloud' name will be used instead.
-
-        This method wraps these Abiquo actions:
-
-            1. Create a group if it does not exist.
-            2. Register a new node in the group.
-            3. Deploy the node and boot it.
-            4. Retrieves it again to get schedule-time attributes (such as ips
-               and vnc ports).
-
-        The rest of the driver methods has been created in a way that, if any
-        of these actions fail, the user can not reach an inconsistent state
-
-        :keyword    name:   The name for this new node (required)
-        :type       name:   ``str``
-
-        :keyword    size:   The size of resources allocated to this node.
-        :type       size:   :class:`NodeSize`
-
-        :keyword    image:  OS Image to boot on node. (required)
-        :type       image:  :class:`NodeImage`
-
-        :keyword    location: Which data center to create a node in. If empty,
-                              undefined behavior will be selected. (optional)
-        :type       location: :class:`NodeLocation`
-
-        :keyword   group_name:  Which group this node belongs to. If empty,
-                                 it will be created into 'libcloud' group. If
-                                 it does not found any group in the target
-                                 location (random location if you have not set
-                                 the parameter), then it will create a new
-                                 group with this name.
-        :type     group_name:  c{str}
-
-        :return:               The newly created node.
-        :rtype:                :class:`Node`
-        """
-        # Define the location
-        # To be clear:
-        #     'xml_loc' is the xml element we navigate into (we need links)
-        #     'loc' is the :class:`NodeLocation` entity
-        xml_loc, loc = self._define_create_node_location(**kwargs)
-
-        # Define the Group
-        group = self._define_create_node_group(xml_loc, loc, **kwargs)
-
-        # Register the Node
-        vm = self._define_create_node_node(group, **kwargs)
-
-        # Execute the 'create' in hypervisor action
-        self._deploy_remote(vm)
-
-        # Retrieve it again, to get some schedule-time defined values
-        edit_vm = get_href(vm, 'edit')
-        headers = {'Accept': self.NODE_MIME_TYPE}
-        vm = self.connection.request(edit_vm, headers=headers).object
-        return self._to_node(vm, self)
-
-    def destroy_node(self, node):
-        """
-        Destroy a node
-
-        Depending on the provider, this may destroy all data associated with
-        the node, including backups.
-
-        :param node: The node to be destroyed
-        :type node: :class:`Node`
-
-        :return: True if the destroy was successful, otherwise False
-        :rtype: ``bool``
-        """
-
-        # Refresh node state
-        headers = {'Accept': self.NODE_MIME_TYPE}
-        e_vm = self.connection.request(node.extra['uri_id'],
-                                       headers=headers).object
-
-        state = e_vm.findtext('state')
-
-        if state in ['ALLOCATED', 'CONFIGURED', 'LOCKED', 'UNKNOWN']:
-            raise LibcloudError('Invalid Node state', self)
-
-        if state != 'NOT_ALLOCATED':
-            # prepare the element that forces the undeploy
-            vm_task = ET.Element('virtualmachinetask')
-            force_undeploy = ET.SubElement(vm_task, 'forceUndeploy')
-            force_undeploy.text = 'True'
-            # Set the URI
-            destroy_uri = node.extra['uri_id'] + '/action/undeploy'
-            # Prepare the headers
-            headers = {'Accept': self.AR_MIME_TYPE,
-                       'Content-type': self.VM_TASK_MIME_TYPE}
-            res = self.connection.async_request(action=destroy_uri,
-                                                method='POST',
-                                                data=tostring(vm_task),
-                                                headers=headers)
-
-        if state == 'NOT_ALLOCATED' or res.async_success():
-            self.connection.request(action=node.extra['uri_id'],
-                                    method='DELETE')
-            return True
-        else:
-            return False
-
-    def ex_run_node(self, node):
-        """
-        Runs a node
-
-        Here there is a bit difference between Abiquo states and libcloud
-        states, so this method is created to have better compatibility. In
-        libcloud, if the node is not running, then it does not exist (avoiding
-        UNKNOWN and temporal states). In Abiquo, you can define a node, and
-        then deploy it.
-
-        If the node is in :class:`NodeState.TERMINATED` libcloud's state and in
-        'NOT_DEPLOYED' Abiquo state, there is a way to run and recover it
-        for libcloud using this method. There is no way to reach this state
-        if you are using only libcloud, but you may have used another Abiquo
-        client and now you want to recover your node to be used by libcloud.
-
-        :param node: The node to run
-        :type node: :class:`Node`
-
-        :return: The node itself, but with the new state
-        :rtype: :class:`Node`
-        """
-        # Refresh node state
-        e_vm = self.connection.request(node.extra['uri_id']).object
-        state = e_vm.findtext('state')
-
-        if state != 'NOT_ALLOCATED':
-            raise LibcloudError('Invalid Node state', self)
-
-        # --------------------------------------------------------
-        #     Deploy the Node
-        # --------------------------------------------------------
-        self._deploy_remote(e_vm)
-
-        # --------------------------------------------------------
-        #     Retrieve it again, to get some schedule-defined
-        #     values.
-        # --------------------------------------------------------
-        edit_vm = get_href(e_vm, 'edit')
-        headers = {'Accept': self.NODE_MIME_TYPE}
-        e_vm = self.connection.request(edit_vm, headers=headers).object
-        return self._to_node(e_vm, self)
-
-    def ex_populate_cache(self):
-        """
-        Populate the cache.
-
-        For each connection, it is good to store some objects that will be
-        useful for further requests, such as the 'user' and the 'enterprise'
-        objects.
-
-        Executes the 'login' resource after setting the connection parameters
-        and, if the execution is successful, it sets the 'user' object into
-        cache. After that, it also requests for the 'enterprise' and
-        'locations' data.
-
-        List of locations should remain the same for a single libcloud
-        connection. However, this method is public and you are able to
-        refresh the list of locations any time.
-        """
-
-        user_headers = {'Accept': self.USER_MIME_TYPE}
-        user = self.connection.request('/login', headers=user_headers).object
-        self.connection.cache['user'] = user
-        e_ent = get_href(self.connection.cache['user'],
-                         'enterprise')
-        ent_headers = {'Accept': self.ENT_MIME_TYPE}
-        ent = self.connection.request(e_ent, headers=ent_headers).object
-        self.connection.cache['enterprise'] = ent
-
-        vdcs_headers = {'Accept': self.VDCS_MIME_TYPE}
-        uri_vdcs = '/cloud/virtualdatacenters'
-        e_vdcs = self.connection.request(uri_vdcs, headers=vdcs_headers).object
-
-        params = {"idEnterprise": self._get_enterprise_id()}
-
-        dcs_headers = {'Accept': self.DCS_MIME_TYPE}
-        e_dcs = self.connection.request('/admin/datacenters',
-                                        headers=dcs_headers,
-                                        params=params).object
-        dc_dict = {}
-        for dc in e_dcs.findall('datacenter'):
-            key = get_href(dc, 'self')
-            dc_dict[key] = dc
-
-        # Populate locations name cache
-        self.connection.cache['locations'] = {}
-        for e_vdc in e_vdcs.findall('virtualDatacenter'):
-            loc = get_href(e_vdc, 'location')
-            if loc is not None:
-                self.connection.cache['locations'][loc] = get_href(e_vdc,
-                                                                   'edit')
-
-    def ex_create_group(self, name, location=None):
-        """
-        Create an empty group.
-
-        You can specify the location as well.
-
-        :param     group:     name of the group (required)
-        :type      group:     ``str``
-
-        :param     location: location were to create the group
-        :type      location: :class:`NodeLocation`
-
-        :returns:            the created group
-        :rtype:              :class:`NodeGroup`
-        """
-        # prepare the element
-        vapp = ET.Element('virtualAppliance')
-        vapp_name = ET.SubElement(vapp, 'name')
-        vapp_name.text = name
-
-        if location is None:
-            location = self.list_locations()[0]
-        elif location not in self.list_locations():
-            raise LibcloudError('Location does not exist')
-
-        link_vdc = self.connection.cache['locations'][location]
-        hdr_vdc = {'Accept': self.VDC_MIME_TYPE}
-        e_vdc = self.connection.request(link_vdc, headers=hdr_vdc).object
-
-        creation_link = get_href(e_vdc, 'virtualappliances')
-        headers = {'Accept': self.VAPP_MIME_TYPE,
-                   'Content-type': self.VAPP_MIME_TYPE}
-        vapp = self.connection.request(creation_link, data=tostring(vapp),
-                                       headers=headers, method='POST').object
-
-        uri_vapp = get_href(vapp, 'edit')
-
-        return NodeGroup(self, vapp.findtext('name'),
-                         uri=uri_vapp)
-
-    def ex_destroy_group(self, group):
-        """
-        Destroy a group.
-
-        Be careful! Destroying a group means destroying all the :class:`Node`
-        instances there and the group itself!
-
-        If there is currently any action over any :class:`Node` of the
-        :class:`NodeGroup`, then the method will raise an exception.
-
-        :param     name: The group (required)
-        :type      name: :class:`NodeGroup`
-
-        :return:         If the group was destroyed successfully
-        :rtype:          ``bool``
-        """
-        # Refresh group state
-        e_group = self.connection.request(group.uri).object
-        state = e_group.findtext('state')
-
-        if state not in ['NOT_DEPLOYED', 'DEPLOYED']:
-            error = 'Can not destroy group because of current state'
-            raise LibcloudError(error, self)
-
-        if state == 'DEPLOYED':
-            # prepare the element that forces the undeploy
-            vm_task = ET.Element('virtualmachinetask')
-            force_undeploy = ET.SubElement(vm_task, 'forceUndeploy')
-            force_undeploy.text = 'True'
-
-            # Set the URI
-            undeploy_uri = group.uri + '/action/undeploy'
-
-            # Prepare the headers
-            headers = {'Accept': self.AR_MIME_TYPE,
-                       'Content-type': self.VM_TASK_MIME_TYPE}
-            res = self.connection.async_request(action=undeploy_uri,
-                                                method='POST',
-                                                data=tostring(vm_task),
-                                                headers=headers)
-
-        if state == 'NOT_DEPLOYED' or res.async_success():
-            # The node is no longer deployed. Unregister it.
-            self.connection.request(action=group.uri,
-                                    method='DELETE')
-            return True
-        else:
-            return False
-
-    def ex_list_groups(self, location=None):
-        """
-        List all groups.
-
-        :param location: filter the groups by location (optional)
-        :type  location: a :class:`NodeLocation` instance.
-
-        :return:         the list of :class:`NodeGroup`
-        """
-        groups = []
-        for vdc in self._get_locations(location):
-            link_vdc = self.connection.cache['locations'][vdc]
-            hdr_vdc = {'Accept': self.VDC_MIME_TYPE}
-            e_vdc = self.connection.request(link_vdc, headers=hdr_vdc).object
-            apps_link = get_href(e_vdc, 'virtualappliances')
-            hdr_vapps = {'Accept': self.VAPPS_MIME_TYPE}
-            vapps = self.connection.request(apps_link,
-                                            headers=hdr_vapps).object
-            for vapp in vapps.findall('virtualAppliance'):
-                nodes = []
-                vms_link = get_href(vapp, 'virtualmachines')
-                headers = {'Accept': self.NODES_MIME_TYPE}
-                vms = self.connection.request(vms_link, headers=headers).object
-                for vm in vms.findall('virtualMachine'):
-                    nodes.append(self._to_node(vm, self))
-                group = NodeGroup(self, vapp.findtext('name'),
-                                  nodes, get_href(vapp, 'edit'))
-                groups.append(group)
-
-        return groups
-
-    def list_images(self, location=None):
-        """
-        List images on Abiquo Repositories
-
-        :keyword location: The location to list images for.
-        :type    location: :class:`NodeLocation`
-
-        :return:           list of node image objects
-        :rtype:            ``list`` of :class:`NodeImage`
-        """
-        enterprise_id = self._get_enterprise_id()
-        uri = '/admin/enterprises/%s/datacenterrepositories/' % (enterprise_id)
-        repos_hdr = {'Accept': self.DCRS_MIME_TYPE}
-        repos = self.connection.request(uri, headers=repos_hdr).object
-
-        images = []
-        for repo in repos.findall('datacenterRepository'):
-            # filter by location. Skips when the name of the location
-            # is different from the 'datacenterRepository' element
-            for vdc in self._get_locations(location):
-                # Check if the virtual datacenter belongs to this repo
-                link_vdc = self.connection.cache['locations'][vdc]
-                hdr_vdc = {'Accept': self.VDC_MIME_TYPE}
-                e_vdc = self.connection.request(link_vdc,
-                                                headers=hdr_vdc).object
-                dc_link_vdc = get_href(e_vdc, 'location')
-                dc_link_repo = get_href(repo, 'datacenter')
-
-                if dc_link_vdc.split("/")[-1] == dc_link_repo.split("/")[-1]:
-                    # Filter the template in case we don't have it yet
-                    url_templates = get_href(repo, 'virtualmachinetemplates')
-                    hypervisor_type = e_vdc.findtext('hypervisorType')
-                    params = {'hypervisorTypeName': hypervisor_type}
-                    headers = {'Accept': self.VMTPLS_MIME_TYPE}
-                    templates = self.connection.request(url_templates, params,
-                                                        headers=headers).object
-                    for templ in templates.findall('virtualMachineTemplate'):
-                        # Avoid duplicated templates
-                        id_template = templ.findtext('id')
-                        ids = [image.id for image in images]
-                        if id_template not in ids:
-                            images.append(self._to_nodeimage(templ, self,
-                                                             get_href(repo,
-                                                                      'edit')))
-
-        return images
-
-    def list_locations(self):
-        """
-        Return list of locations where the user has access to.
-
-        :return: the list of :class:`NodeLocation` available for the current
-                 user
-        :rtype:  ``list`` of :class:`NodeLocation`
-        """
-        return list(self.connection.cache['locations'].keys())
-
-    def list_nodes(self, location=None):
-        """
-        List all nodes.
-
-        :param location: Filter the groups by location (optional)
-        :type  location: a :class:`NodeLocation` instance.
-
-        :return:  List of node objects
-        :rtype: ``list`` of :class:`Node`
-        """
-        nodes = []
-
-        for group in self.ex_list_groups(location):
-            nodes.extend(group.nodes)
-
-        return nodes
-
-    def list_sizes(self, location=None):
-        """
-        List sizes on a provider.
-
-        Abiquo does not work with sizes. However, this method
-        returns a list of predefined ones (copied from :class:`DummyNodeDriver`
-        but without price neither bandwidth) to help the users to create their
-        own.
-
-        If you call the method :class:`AbiquoNodeDriver.create_node` with the
-        size informed, it will just override the 'ram' value of the 'image'
-        template. So it is no too much usefull work with sizes...
-
-        :return: The list of sizes
-        :rtype:  ``list`` of :class:`NodeSizes`
-        """
-        return [
-            NodeSize(id=1,
-                     name='Small',
-                     ram=128,
-                     disk=4,
-                     bandwidth=None,
-                     price=None,
-                     driver=self),
-            NodeSize(id=2,
-                     name='Medium',
-                     ram=512,
-                     disk=16,
-                     bandwidth=None,
-                     price=None,
-                     driver=self),
-            NodeSize(id=3,
-                     name='Big',
-                     ram=4096,
-                     disk=32,
-                     bandwidth=None,
-                     price=None,
-                     driver=self),
-            NodeSize(id=4,
-                     name="XXL Big",
-                     ram=4096 * 2,
-                     disk=32 * 4,
-                     bandwidth=None,
-                     price=None,
-                     driver=self)
-        ]
-
-    def reboot_node(self, node):
-        """
-        Reboot a node.
-
-        :param node: The node to be rebooted
-        :type node: :class:`Node`
-
-        :return: True if the reboot was successful, otherwise False
-        :rtype: ``bool``
-        """
-        reboot_uri = node.extra['uri_id'] + '/action/reset'
-        reboot_hdr = {'Accept': self.AR_MIME_TYPE}
-        res = self.connection.async_request(action=reboot_uri,
-                                            method='POST', headers=reboot_hdr)
-        return res.async_success()
-
-    # -------------------------
-    # Extenstion methods
-    # -------------------------
-
-    def _ex_connection_class_kwargs(self):
-        """
-        Set the endpoint as an extra :class:`AbiquoConnection` argument.
-
-        According to Connection code, the "url" argument should be
-        parsed properly to connection.
-
-        :return: ``dict`` of :class:`AbiquoConnection` input arguments
-        """
-
-        return {'url': self.endpoint}
-
-    def _deploy_remote(self, e_vm):
-        """
-        Asynchronous call to create the node.
-        """
-        # --------------------------------------------------------
-        #     Deploy the Node
-        # --------------------------------------------------------
-        # prepare the element that forces the deploy
-        vm_task = ET.Element('virtualmachinetask')
-        force_deploy = ET.SubElement(vm_task, 'forceEnterpriseSoftLimits')
-        force_deploy.text = 'True'
-
-        # Prepare the headers
-        headers = {'Accept': self.AR_MIME_TYPE,
-                   'Content-type': self.VM_TASK_MIME_TYPE}
-        link_deploy = get_href(e_vm, 'deploy')
-        res = self.connection.async_request(action=link_deploy, method='POST',
-                                            data=tostring(vm_task),
-                                            headers=headers)
-        if not res.async_success():
-            raise LibcloudError('Could not run the node', self)
-
-    def _to_location(self, vdc, dc, driver):
-        """
-        Generates the :class:`NodeLocation` class.
-        """
-        identifier = vdc.findtext('id')
-        name = vdc.findtext('name')
-        country = dc.findtext('name')
-        return NodeLocation(identifier, name, country, driver)
-
-    def _to_node(self, vm, driver):
-        """
-        Generates the :class:`Node` class.
-        """
-        identifier = vm.findtext('id')
-        name = vm.findtext('label')
-        state = AbiquoResponse.NODE_STATE_MAP[vm.findtext('state')]
-
-        link_image = get_href(vm, 'virtualmachinetemplate')
-        link_hdr = {'Accept': self.VMTPL_MIME_TYPE}
-        image_element = self.connection.request(link_image,
-                                                headers=link_hdr).object
-        repo_link = get_href(image_element, 'datacenterrepository')
-        image = self._to_nodeimage(image_element, self, repo_link)
-
-        # Fill the 'ips' data
-        private_ips = []
-        public_ips = []
-        nics_hdr = {'Accept': self.NICS_MIME_TYPE}
-        nics_element = self.connection.request(get_href(vm, 'nics'),
-                                               headers=nics_hdr).object
-        for nic in nics_element.findall('nic'):
-            ip = nic.findtext('ip')
-            for link in nic.findall('link'):
-                rel = link.attrib['rel']
-                if rel == 'privatenetwork':
-                    private_ips.append(ip)
-                elif rel in ['publicnetwork', 'externalnetwork',
-                             'unmanagednetwork']:
-                    public_ips.append(ip)
-
-        extra = {'uri_id': get_href(vm, 'edit')}
-
-        if vm.find('vdrpIp') is not None:
-            extra['vdrp_ip'] = vm.findtext('vdrpIP')
-            extra['vdrp_port'] = vm.findtext('vdrpPort')
-
-        return Node(identifier, name, state, public_ips, private_ips,
-                    driver, image=image, extra=extra)
-
-    def _to_nodeimage(self, template, driver, repo):
-        """
-        Generates the :class:`NodeImage` class.
-        """
-        identifier = template.findtext('id')
-        name = template.findtext('name')
-        url = get_href(template, 'edit')
-        hdreqd = template.findtext('hdRequired')
-        extra = {'repo': repo, 'url': url, 'hdrequired': hdreqd}
-        return NodeImage(identifier, name, driver, extra)
-
-    def _get_locations(self, location=None):
-        """
-        Returns the locations as a generator.
-        """
-        if location is not None:
-            yield location
-        else:
-            for loc in self.list_locations():
-                yield loc
-
-    def _get_enterprise_id(self):
-        """
-        Returns the identifier of the logged user's enterprise.
-        """
-        return self.connection.cache['enterprise'].findtext('id')
-
-    def _define_create_node_location(self, **kwargs):
-        """
-        Search for a location where to create the node.
-
-        Based on 'create_node' **kwargs argument, decide in which
-        location will be created.
-        """
-        # First, get image location
-        if 'image' not in kwargs:
-            error = "'image' parameter is mandatory"
-            raise LibcloudError(error, self)
-
-        image = kwargs['image']
-
-        # Get the location argument
-        location = None
-        if 'location' in kwargs:
-            location = kwargs['location']
-            if location not in self.list_locations():
-                raise LibcloudError('Location does not exist')
-
-        # Check if the image is compatible with any of the locations or
-        # the input location
-        loc = None
-        target_loc = None
-        for candidate_loc in self._get_locations(location):
-            link_vdc = self.connection.cache['locations'][candidate_loc]
-            hdr_vdc = {'Accept': self.VDC_MIME_TYPE}
-            e_vdc = self.connection.request(link_vdc, headers=hdr_vdc).object
-            for img in self.list_images(candidate_loc):
-                if img.id == image.id:
-                    loc = e_vdc
-                    target_loc = candidate_loc
-                    break
-
-        if loc is None:
-            error = 'The image can not be used in any location'
-            raise LibcloudError(error, self)
-
-        return loc, target_loc
-
-    def _define_create_node_group(self, xml_loc, loc, **kwargs):
-        """
-        Search for a group where to create the node.
-
-        If we can not find any group, create it into argument 'location'
-        """
-        if 'group_name' not in kwargs:
-            group_name = NodeGroup.DEFAULT_GROUP_NAME
-        else:
-            group_name = kwargs['group_name']
-
-        # We search if the group is already defined into the location
-        groups_link = get_href(xml_loc, 'virtualappliances')
-        groups_hdr = {'Accept': self.VAPPS_MIME_TYPE}
-        vapps_element = self.connection.request(groups_link,
-                                                headers=groups_hdr).object
-        target_group = None
-        for vapp in vapps_element.findall('virtualAppliance'):
-            if vapp.findtext('name') == group_name:
-                uri_vapp = get_href(vapp, 'edit')
-                return NodeGroup(self, vapp.findtext('name'), uri=uri_vapp)
-
-        # target group not found: create it. Since it is an extension of
-        # the basic 'libcloud' functionality, we try to be as flexible as
-        # possible.
-        if target_group is None:
-            return self.ex_create_group(group_name, loc)
-
-    def _define_create_node_node(self, group, **kwargs):
-        """
-        Defines the node before to create.
-
-        In Abiquo, you first need to 'register' or 'define' the node in
-        the API before to create it into the target hypervisor.
-        """
-        vm = ET.Element('virtualMachine')
-        if 'name' in kwargs:
-            vmname = ET.SubElement(vm, 'label')
-            vmname.text = kwargs['name']
-        attrib = {'type': self.VMTPL_MIME_TYPE,
-                  'rel': 'virtualmachinetemplate',
-                  'href': kwargs['image'].extra['url']}
-        ET.SubElement(vm, 'link', attrib=attrib)
-        headers = {'Accept': self.NODE_MIME_TYPE,
-                   'Content-type': self.NODE_MIME_TYPE}
-
-        if 'size' in kwargs:
-            # Override the 'NodeSize' data
-            ram = ET.SubElement(vm, 'ram')
-            ram.text = str(kwargs['size'].ram)
-            hd = ET.SubElement(vm, 'hdInBytes')
-            hd.text = str(int(kwargs['size'].disk) * self.GIGABYTE)
-
-        # Create the virtual machine
-        nodes_link = group.uri + '/virtualmachines'
-        vm = self.connection.request(nodes_link, data=tostring(vm),
-                                     headers=headers, method='POST').object
-        edit_vm = get_href(vm, 'edit')
-        headers = {'Accept': self.NODE_MIME_TYPE}
-
-        return self.connection.request(edit_vm, headers=headers).object
-
-
-class NodeGroup(object):
-    """
-    Group of virtual machines that can be managed together
-
-    All :class:`Node`s in Abiquo must be defined inside a Virtual Appliance.
-    We offer a way to handle virtual appliances (called NodeGroup to
-    maintain some kind of name conventions here) inside the
-    :class:`AbiquoNodeDriver` without breaking compatibility of the rest of
-    libcloud API.
-
-    If the user does not want to handle groups, all the virtual machines
-    will be created inside a group named 'libcloud'
-    """
-    DEFAULT_GROUP_NAME = 'libcloud'
-
-    def __init__(self, driver, name=DEFAULT_GROUP_NAME, nodes=[], uri=''):
-        """
-        Initialize a new group object.
-        """
-        self.driver = driver
-        self.name = name
-        self.nodes = nodes
-        self.uri = uri
-
-    def __repr__(self):
-        return (('<NodeGroup: name=%s, nodes=[%s] >')
-                % (self.name, ",".join(map(str, self.nodes))))
-
-    def destroy(self):
-        """
-        Destroys the group delegating the execution to
-        :class:`AbiquoNodeDriver`.
-        """
-        return self.driver.ex_destroy_group(self)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/auroracompute.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/auroracompute.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/auroracompute.py
deleted file mode 100644
index 6be67ed..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/auroracompute.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from libcloud.compute.providers import Provider
-from libcloud.compute.drivers.cloudstack import CloudStackNodeDriver
-
-__all__ = [
-    'AuroraComputeRegion',
-    'AuroraComputeNodeDriver'
-]
-
-
-class AuroraComputeRegion(object):
-    AMS = 'Amsterdam'
-    RTD = 'Rotterdam'
-    MIA = 'Miami'
-    LAX = 'Los Angeles'
-    TYO = 'Tokyo'
-
-
-REGION_ENDPOINT_MAP = {
-    AuroraComputeRegion.AMS: '/ams',
-    AuroraComputeRegion.RTD: '/rtd',
-    AuroraComputeRegion.MIA: '/mia',
-    AuroraComputeRegion.LAX: '/lax',
-    AuroraComputeRegion.TYO: '/tyo'
-}
-
-
-class AuroraComputeNodeDriver(CloudStackNodeDriver):
-    type = Provider.AURORACOMPUTE
-    name = 'PCextreme AuroraCompute'
-    website = 'https://www.pcextreme.com/aurora/compute'
-
-    def __init__(self, key, secret, path=None, host=None, url=None,
-                 region=None):
-        if host is None:
-            host = 'api.auroracompute.eu'
-
-        if path is None:
-            path = REGION_ENDPOINT_MAP.get(region, '/ams')
-
-        super(AuroraComputeNodeDriver, self).__init__(key=key, secret=secret,
-                                                      host=host, path=path,
-                                                      secure=True)


[13/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/godaddy.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/godaddy.py b/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/godaddy.py
deleted file mode 100644
index 1a18e3a..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/godaddy.py
+++ /dev/null
@@ -1,502 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-__all__ = [
-    'GoDaddyDNSDriver'
-]
-
-try:
-    import simplejson as json
-except:
-    import json
-
-from libcloud.common.base import ConnectionKey, JsonResponse
-from libcloud.common.types import LibcloudError
-from libcloud.utils.py3 import httplib
-from libcloud.dns.types import Provider, RecordType, RecordDoesNotExistError
-from libcloud.dns.base import DNSDriver, Zone, Record
-
-API_HOST = 'api.godaddy.com'
-VALID_RECORD_EXTRA_PARAMS = ['prio', 'ttl']
-
-
-class GoDaddyDNSException(LibcloudError):
-    def __init__(self, code, message):
-        self.code = code
-        self.message = message
-        self.args = (code, message)
-
-    def __str__(self):
-        return self.__repr__()
-
-    def __repr__(self):
-        return ('<GoDaddyDNSException in %s: %s>' % (self.code, self.message))
-
-
-class GoDaddyDNSResponse(JsonResponse):
-    valid_response_codes = [httplib.OK, httplib.ACCEPTED, httplib.CREATED,
-                            httplib.NO_CONTENT]
-
-    def parse_body(self):
-        if not self.body:
-            return None
-        # json.loads doesn't like the regex expressions used in godaddy schema
-        self.body = self.body.replace('\\.', '\\\\.')
-
-        data = json.loads(self.body)
-        return data
-
-    def parse_error(self):
-        data = self.parse_body()
-        raise GoDaddyDNSException(code=data['code'], message=data['message'])
-
-    def success(self):
-        return self.status in self.valid_response_codes
-
-
-class GoDaddyDNSConnection(ConnectionKey):
-    responseCls = GoDaddyDNSResponse
-    host = API_HOST
-
-    allow_insecure = False
-
-    def __init__(self, key, secret, shopper_id, secure=True, host=None,
-                 port=None, url=None, timeout=None,
-                 proxy_url=None, backoff=None, retry_delay=None):
-        super(GoDaddyDNSConnection, self).__init__(
-            key,
-            secure=secure, host=host,
-            port=port, url=url,
-            timeout=timeout,
-            proxy_url=proxy_url,
-            backoff=backoff,
-            retry_delay=retry_delay)
-        self.key = key
-        self.secret = secret
-        self.shopper_id = shopper_id
-
-    def add_default_headers(self, headers):
-        headers['X-Shopper-Id'] = self.shopper_id
-        headers['Authorization'] = "sso-key %s:%s" % \
-            (self.key, self.secret)
-        return headers
-
-
-class GoDaddyDNSDriver(DNSDriver):
-    """
-    A driver for GoDaddy DNS.
-
-    This is for customers of GoDaddy
-    who wish to purchase, update existing domains
-    and manage records for DNS zones owned by GoDaddy NS servers.
-    """
-    type = Provider.GODADDY
-    name = 'GoDaddy DNS'
-    website = 'https://www.godaddy.com/'
-    connectionCls = GoDaddyDNSConnection
-
-    RECORD_TYPE_MAP = {
-        RecordType.A: 'A',
-        RecordType.AAAA: 'AAAA',
-        RecordType.CNAME: 'CNAME',
-        RecordType.MX: 'MX',
-        RecordType.NS: 'SPF',
-        RecordType.SRV: 'SRV',
-        RecordType.TXT: 'TXT',
-    }
-
-    def __init__(self, shopper_id, key, secret,
-                 secure=True, host=None, port=None):
-        """
-        Instantiate a new `GoDaddyDNSDriver`
-
-        :param  shopper_id: Your customer ID or shopper ID with GoDaddy
-        :type   shopper_id: ``str``
-
-        :param  key: Your access key from developer.godaddy.com
-        :type   key: ``str``
-
-        :param  secret: Your access key secret
-        :type   secret: ``str``
-        """
-        super(GoDaddyDNSDriver, self).__init__(key=key, secret=secret,
-                                               secure=secure,
-                                               host=host, port=port,
-                                               shopper_id=str(shopper_id))
-
-    def list_zones(self):
-        """
-        Return a list of zones (purchased domains)
-
-        :return: ``list`` of :class:`Zone`
-        """
-        result = self.connection.request(
-            '/v1/domains/').object
-        zones = self._to_zones(result)
-        return zones
-
-    def list_records(self, zone):
-        """
-        Return a list of records for the provided zone.
-
-        :param zone: Zone to list records for.
-        :type zone: :class:`Zone`
-
-        :return: ``list`` of :class:`Record`
-        """
-        result = self.connection.request(
-            '/v1/domains/%s/records' % (zone.domain)).object
-        records = self._to_records(items=result, zone=zone)
-        return records
-
-    def create_record(self, name, zone, type, data, extra=None):
-        """
-        Create a new record.
-
-        :param name: Record name without the domain name (e.g. www).
-                     Note: If you want to create a record for a base domain
-                     name, you should specify empty string ('') for this
-                     argument.
-        :type  name: ``str``
-
-        :param zone: Zone where the requested record is created.
-        :type  zone: :class:`Zone`
-
-        :param type: DNS record type (A, AAAA, ...).
-        :type  type: :class:`RecordType`
-
-        :param data: Data for the record (depends on the record type).
-        :type  data: ``str``
-
-        :param extra: Extra attributes (driver specific). (optional)
-        :type extra: ``dict``
-
-        :rtype: :class:`Record`
-        """
-        new_record = self._format_record(name, type, data, extra)
-        self.connection.request(
-            '/v1/domains/%s/records' % (zone.domain), method='PATCH',
-            data=[new_record])
-        id = self._get_id_of_record(name, type)
-        return Record(
-            id=id, name=name,
-            type=type, data=data,
-            zone=zone, driver=self,
-            ttl=new_record['ttl'],
-            extra=extra)
-
-    def update_record(self, record, name, type, data, extra=None):
-        """
-        Update an existing record.
-
-        :param record: Record to update.
-        :type  record: :class:`Record`
-
-        :param name: Record name without the domain name (e.g. www).
-                     Note: If you want to create a record for a base domain
-                     name, you should specify empty string ('') for this
-                     argument.
-        :type  name: ``str``
-
-        :param type: DNS record type (A, AAAA, ...).
-        :type  type: :class:`RecordType`
-
-        :param data: Data for the record (depends on the record type).
-        :type  data: ``str``
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type  extra: ``dict``
-
-        :rtype: :class:`Record`
-        """
-        new_record = self._format_record(name, type, data, extra)
-        self.connection.request(
-            '/v1/domains/%s/records/%s/%s' % (record.zone.domain,
-                                              record.type,
-                                              record.name),
-            method='PUT',
-            data=[new_record])
-        id = self._get_id_of_record(name, type)
-        return Record(
-            id=id, name=name,
-            type=type, data=data,
-            zone=record.zone, driver=self,
-            ttl=new_record['ttl'],
-            extra=extra)
-
-    def get_record(self, zone_id, record_id):
-        """
-        Return a Record instance.
-
-        :param zone_id: ID of the required zone
-        :type  zone_id: ``str``
-
-        :param record_id: ID of the required record
-        :type  record_id: ``str``
-
-        :rtype: :class:`Record`
-        """
-        parts = record_id.split(':')
-        result = self.connection.request(
-            '/v1/domains/%s/records/%s/%s' % (
-                zone_id,
-                parts[1],
-                parts[0])).object
-        if len(result) == 0:
-            raise RecordDoesNotExistError(record_id,
-                                          driver=self,
-                                          record_id=record_id)
-        return self._to_record(result[0],
-                               self.get_zone(zone_id))
-
-    def get_zone(self, zone_id):
-        """
-        Get a zone (by domain)
-
-        :param  zone_id: The domain, not the ID
-        :type   zone_id: ``str``
-
-        :rtype:  :class:`Zone`
-        """
-        result = self.connection.request(
-            '/v1/domains/%s/' % zone_id).object
-        zone = self._to_zone(result)
-        return zone
-
-    def delete_zone(self, zone):
-        """
-        Delete a zone.
-
-        Note: This will CANCEL a purchased domain
-
-        :param zone: Zone to delete.
-        :type  zone: :class:`Zone`
-
-        :rtype: ``bool``
-        """
-        self.connection.request(
-            '/v1/domains/%s' % (zone.domain),
-            method='DELETE')
-        # no error means ok
-        return True
-
-    def ex_check_availability(self, domain, for_transfer=False):
-        """
-        Check the availability of the domain
-
-        :param   domain: the domain name e.g. wazzlewobbleflooble.com
-        :type    domain: ``str``
-
-        :param   for_transfer: Check if domain is available for transfer
-        :type    for_transfer: ``bool``
-
-        :rtype: `list` of :class:`GoDaddyAvailability`
-        """
-        result = self.connection.request(
-            '/v1/domains/available',
-            method='GET',
-            params={
-                'domain': domain,
-                'forTransfer': str(for_transfer)
-            }
-        ).object
-        return GoDaddyAvailability(
-            domain=result['domain'],
-            available=result['available'],
-            price=result['price'],
-            currency=result['currency'],
-            period=result['period']
-        )
-
-    def ex_list_tlds(self):
-        """
-        List available TLDs for sale
-
-        :rtype: ``list`` of :class:`GoDaddyTLD`
-        """
-        result = self.connection.request(
-            '/v1/domains/tlds',
-            method='GET'
-        ).object
-        return self._to_tlds(result)
-
-    def ex_get_purchase_schema(self, tld):
-        """
-        Get the schema that needs completing to purchase a new domain
-        Use this in conjunction with ex_purchase_domain
-
-        :param   tld: The top level domain e.g com, eu, uk
-        :type    tld: ``str``
-
-        :rtype: `dict` the JSON Schema
-        """
-        result = self.connection.request(
-            '/v1/domains/purchase/schema/%s' % tld,
-            method='GET'
-        ).object
-        return result
-
-    def ex_get_agreements(self, tld, privacy=True):
-        """
-        Get the legal agreements for a tld
-        Use this in conjunction with ex_purchase_domain
-
-        :param   tld: The top level domain e.g com, eu, uk
-        :type    tld: ``str``
-
-        :rtype: `dict` the JSON Schema
-        """
-        result = self.connection.request(
-            '/v1/domains/agreements',
-            params={
-                'tlds': tld,
-                'privacy': str(privacy)
-            },
-            method='GET'
-        ).object
-        agreements = []
-        for item in result:
-            agreements.append(
-                GoDaddyLegalAgreement(
-                    agreement_key=item['agreementKey'],
-                    title=item['title'],
-                    url=item['url'],
-                    content=item['content']))
-        return agreements
-
-    def ex_purchase_domain(self, purchase_request):
-        """
-        Purchase a domain with GoDaddy
-
-        :param  purchase_request: The completed document
-            from ex_get_purchase_schema
-        :type   purchase_request: ``dict``
-
-        :rtype: :class:`GoDaddyDomainPurchaseResponse` Your order
-        """
-        result = self.connection.request(
-            '/v1/domains/purchase',
-            data=purchase_request,
-            method='POST'
-        ).object
-        return GoDaddyDomainPurchaseResponse(
-            order_id=result['orderId'],
-            item_count=result['itemCount'],
-            total=result['total'],
-            currency=result['currency']
-        )
-
-    def _format_record(self, name, type, data, extra):
-        if extra is None:
-            extra = {}
-        new_record = {}
-        if type == RecordType.SRV:
-            new_record = {
-                'type': type,
-                'name': name,
-                'data': data,
-                'priority': 1,
-                'ttl': extra.get('ttl', 5),
-                'service': extra.get('service', ''),
-                'protocol': extra.get('protocol', ''),
-                'port': extra.get('port', ''),
-                'weight': extra.get('weight', '1')
-            }
-        else:
-            new_record = {
-                'type': type,
-                'name': name,
-                'data': data,
-                'priority': 1,
-                'ttl': extra.get('ttl', 5)
-            }
-        return new_record
-
-    def _to_zones(self, items):
-        zones = []
-        for item in items:
-            zones.append(self._to_zone(item))
-        return zones
-
-    def _to_zone(self, item):
-        extra = {"expires": item['expires']}
-        zone = Zone(id=item['domainId'], domain=item['domain'],
-                    type='master', ttl=None,
-                    driver=self, extra=extra)
-        return zone
-
-    def _to_records(self, items, zone=None):
-        records = []
-
-        for item in items:
-            records.append(self._to_record(item=item, zone=zone))
-        return records
-
-    def _to_record(self, item, zone=None):
-        ttl = item['ttl']
-        type = self._string_to_record_type(item['type'])
-        name = item['name']
-        id = self._get_id_of_record(name, type)
-        record = Record(id=id, name=name,
-                        type=type, data=item['data'],
-                        zone=zone, driver=self,
-                        ttl=ttl)
-        return record
-
-    def _to_tlds(self, items):
-        tlds = []
-        for item in items:
-            tlds.append(self._to_tld(item))
-        return tlds
-
-    def _to_tld(self, item):
-        return GoDaddyTLD(
-            name=item['name'],
-            tld_type=item['type']
-        )
-
-    def _get_id_of_record(self, name, type):
-        return '%s:%s' % (name, type)
-
-
-class GoDaddyAvailability(object):
-    def __init__(self, domain, available, price, currency, period):
-        self.domain = domain
-        self.available = bool(available)
-        # currency comes in micro-units, convert to dollars.
-        self.price = float(price) / 1000000
-        self.currency = currency
-        self.period = int(period)
-
-
-class GoDaddyTLD(object):
-    def __init__(self, name, tld_type):
-        self.name = name
-        self.type = tld_type
-
-
-class GoDaddyDomainPurchaseResponse(object):
-    def __init__(self, order_id, item_count, total, currency):
-        self.order_id = order_id
-        self.item_count = item_count
-        self.total = total
-        self.current = currency
-
-
-class GoDaddyLegalAgreement(object):
-    def __init__(self, agreement_key, title, url, content):
-        self.agreement_key = agreement_key
-        self.title = title
-        self.url = url
-        self.content = content

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/google.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/google.py b/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/google.py
deleted file mode 100644
index d0aebcb..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/google.py
+++ /dev/null
@@ -1,383 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-__all__ = [
-    'GoogleDNSDriver'
-]
-
-# API docs: https://cloud.google.com/dns/api/v1
-API_VERSION = 'v1'
-
-import re
-from libcloud.common.google import GoogleResponse, GoogleBaseConnection
-from libcloud.common.google import ResourceNotFoundError
-from libcloud.dns.types import Provider, RecordType
-from libcloud.dns.types import ZoneDoesNotExistError, RecordDoesNotExistError
-from libcloud.dns.base import DNSDriver, Zone, Record
-
-
-class GoogleDNSResponse(GoogleResponse):
-    pass
-
-
-class GoogleDNSConnection(GoogleBaseConnection):
-    host = "www.googleapis.com"
-    responseCls = GoogleDNSResponse
-
-    def __init__(self, user_id, key, secure, auth_type=None,
-                 credential_file=None, project=None, **kwargs):
-        super(GoogleDNSConnection, self).\
-            __init__(user_id, key, secure=secure, auth_type=auth_type,
-                     credential_file=credential_file, **kwargs)
-        self.request_path = '/dns/%s/projects/%s' % (API_VERSION, project)
-
-
-class GoogleDNSDriver(DNSDriver):
-    type = Provider.GOOGLE
-    name = 'Google DNS'
-    connectionCls = GoogleDNSConnection
-    website = 'https://cloud.google.com/'
-
-    RECORD_TYPE_MAP = {
-        RecordType.A: 'A',
-        RecordType.AAAA: 'AAAA',
-        RecordType.CNAME: 'CNAME',
-        RecordType.MX: 'MX',
-        RecordType.NS: 'NS',
-        RecordType.PTR: 'PTR',
-        RecordType.SOA: 'SOA',
-        RecordType.SPF: 'SPF',
-        RecordType.SRV: 'SRV',
-        RecordType.TXT: 'TXT',
-    }
-
-    def __init__(self, user_id, key, project=None, auth_type=None, scopes=None,
-                 **kwargs):
-        self.auth_type = auth_type
-        self.project = project
-        self.scopes = scopes
-        if not self.project:
-            raise ValueError('Project name must be specified using '
-                             '"project" keyword.')
-        super(GoogleDNSDriver, self).__init__(user_id, key, **kwargs)
-
-    def iterate_zones(self):
-        """
-        Return a generator to iterate over available zones.
-
-        :rtype: ``generator`` of :class:`Zone`
-        """
-        return self._get_more('zones')
-
-    def iterate_records(self, zone):
-        """
-        Return a generator to iterate over records for the provided zone.
-
-        :param zone: Zone to list records for.
-        :type zone: :class:`Zone`
-
-        :rtype: ``generator`` of :class:`Record`
-        """
-        return self._get_more('records', zone=zone)
-
-    def get_zone(self, zone_id):
-        """
-        Return a Zone instance.
-
-        :param zone_id: ID of the required zone
-        :type  zone_id: ``str``
-
-        :rtype: :class:`Zone`
-        """
-        request = '/managedZones/%s' % (zone_id)
-
-        try:
-            response = self.connection.request(request, method='GET').object
-        except ResourceNotFoundError:
-            raise ZoneDoesNotExistError(value='',
-                                        driver=self.connection.driver,
-                                        zone_id=zone_id)
-
-        return self._to_zone(response)
-
-    def get_record(self, zone_id, record_id):
-        """
-        Return a Record instance.
-
-        :param zone_id: ID of the required zone
-        :type  zone_id: ``str``
-
-        :param record_id: ID of the required record
-        :type  record_id: ``str``
-
-        :rtype: :class:`Record`
-        """
-        (record_type, record_name) = record_id.split(':', 1)
-
-        params = {
-            'name': record_name,
-            'type': record_type,
-        }
-
-        request = '/managedZones/%s/rrsets' % (zone_id)
-
-        try:
-            response = self.connection.request(request, method='GET',
-                                               params=params).object
-        except ResourceNotFoundError:
-            raise ZoneDoesNotExistError(value='',
-                                        driver=self.connection.driver,
-                                        zone_id=zone_id)
-
-        if len(response['rrsets']) > 0:
-            zone = self.get_zone(zone_id)
-            return self._to_record(response['rrsets'][0], zone)
-
-        raise RecordDoesNotExistError(value='', driver=self.connection.driver,
-                                      record_id=record_id)
-
-    def create_zone(self, domain, type='master', ttl=None, extra=None):
-        """
-        Create a new zone.
-
-        :param domain: Zone domain name (e.g. example.com.) with a \'.\'
-                       at the end.
-        :type domain: ``str``
-
-        :param type: Zone type (master is the only one supported).
-        :type  type: ``str``
-
-        :param ttl: TTL for new records. (unused)
-        :type  ttl: ``int``
-
-        :param extra: Extra attributes (driver specific). (optional)
-        :type extra: ``dict``
-
-        :rtype: :class:`Zone`
-        """
-        name = None
-        description = ''
-
-        if extra:
-            description = extra.get('description')
-            name = extra.get('name')
-
-        if name is None:
-            name = self._cleanup_domain(domain)
-
-        data = {
-            'dnsName': domain,
-            'name': name,
-            'description': description,
-        }
-
-        request = '/managedZones'
-        response = self.connection.request(request, method='POST',
-                                           data=data).object
-        return self._to_zone(response)
-
-    def create_record(self, name, zone, type, data, extra=None):
-        """
-        Create a new record.
-
-        :param name: Record name fully qualified, with a \'.\' at the end.
-        :type  name: ``str``
-
-        :param zone: Zone where the requested record is created.
-        :type  zone: :class:`Zone`
-
-        :param type: DNS record type (A, AAAA, ...).
-        :type  type: :class:`RecordType`
-
-        :param data: Data for the record (depends on the record type).
-        :type  data: ``str``
-
-        :param extra: Extra attributes. (optional)
-        :type extra: ``dict``
-
-        :rtype: :class:`Record`
-        """
-        ttl = data.get('ttl', 0)
-        rrdatas = data.get('rrdatas', [])
-
-        data = {
-            'additions': [
-                {
-                    'name': name,
-                    'type': type,
-                    'ttl': int(ttl),
-                    'rrdatas': rrdatas,
-                }
-            ]
-        }
-        request = '/managedZones/%s/changes' % (zone.id)
-        response = self.connection.request(request, method='POST',
-                                           data=data).object
-        return self._to_record(response['additions'][0], zone)
-
-    def delete_zone(self, zone):
-        """
-        Delete a zone.
-
-        Note: This will delete all the records belonging to this zone.
-
-        :param zone: Zone to delete.
-        :type  zone: :class:`Zone`
-
-        :rtype: ``bool``
-        """
-        request = '/managedZones/%s' % (zone.id)
-        response = self.connection.request(request, method='DELETE')
-        return response.success()
-
-    def delete_record(self, record):
-        """
-        Delete a record.
-
-        :param record: Record to delete.
-        :type  record: :class:`Record`
-
-        :rtype: ``bool``
-        """
-        data = {
-            'deletions': [
-                {
-                    'name': record.name,
-                    'type': record.type,
-                    'rrdatas': record.data['rrdatas'],
-                    'ttl': record.data['ttl']
-                }
-            ]
-        }
-        request = '/managedZones/%s/changes' % (record.zone.id)
-        response = self.connection.request(request, method='POST',
-                                           data=data)
-        return response.success()
-
-    def ex_bulk_record_changes(self, zone, records):
-        """
-        Bulk add and delete records.
-
-        :param zone: Zone where the requested record changes are done.
-        :type  zone: :class:`Zone`
-
-        :param records: Dictionary of additions list or deletions list, or both
-        of resourceRecordSets. For example:
-            {'additions': [{'rrdatas': ['127.0.0.1'],
-                            'kind': 'dns#resourceRecordSet',
-                            'type': 'A',
-                            'name': 'www.example.com.',
-                            'ttl': '300'}],
-             'deletions': [{'rrdatas': ['127.0.0.1'],
-                            'kind': 'dns#resourceRecordSet',
-                            'type': 'A',
-                            'name': 'www2.example.com.',
-                            'ttl': '300'}]}
-        :type  records: ``dict``
-
-        :return: A dictionary of Record additions and deletions.
-        :rtype: ``dict`` of additions and deletions of :class:`Record`
-        """
-
-        request = '/managedZones/%s/changes' % (zone.id)
-        response = self.connection.request(request, method='POST',
-                                           data=records).object
-
-        response_data = {
-            'additions': self._to_records(response.get('additions', []), zone),
-            'deletions': self._to_records(response.get('deletions', []), zone),
-        }
-
-        return response_data
-
-    def _get_more(self, rtype, **kwargs):
-        last_key = None
-        exhausted = False
-        while not exhausted:
-            items, last_key, exhausted = self._get_data(rtype, last_key,
-                                                        **kwargs)
-            for item in items:
-                yield item
-
-    def _get_data(self, rtype, last_key, **kwargs):
-        params = {}
-
-        if last_key:
-            params['pageToken'] = last_key
-
-        if rtype == 'zones':
-            request = '/managedZones'
-            transform_func = self._to_zones
-            r_key = 'managedZones'
-        elif rtype == 'records':
-            zone = kwargs['zone']
-            request = '/managedZones/%s/rrsets' % (zone.id)
-            transform_func = self._to_records
-            r_key = 'rrsets'
-
-        response = self.connection.request(request, method='GET',
-                                           params=params,)
-
-        if response.success():
-            nextpage = response.object.get('nextPageToken', None)
-            items = transform_func(response.object.get(r_key), **kwargs)
-            exhausted = False if nextpage is not None else True
-            return items, nextpage, exhausted
-        else:
-            return [], None, True
-
-    def _ex_connection_class_kwargs(self):
-        return {'auth_type': self.auth_type,
-                'project': self.project,
-                'scopes': self.scopes}
-
-    def _to_zones(self, response):
-        zones = []
-        for r in response:
-            zones.append(self._to_zone(r))
-        return zones
-
-    def _to_zone(self, r):
-        extra = {}
-
-        if 'description' in r:
-            extra['description'] = r.get('description')
-
-        extra['creationTime'] = r.get('creationTime')
-        extra['nameServers'] = r.get('nameServers')
-        extra['id'] = r.get('id')
-
-        return Zone(id=r['name'], domain=r['dnsName'],
-                    type='master', ttl=0, driver=self, extra=extra)
-
-    def _to_records(self, response, zone):
-        records = []
-        for r in response:
-            records.append(self._to_record(r, zone))
-        return records
-
-    def _to_record(self, r, zone):
-        record_id = '%s:%s' % (r['type'], r['name'])
-        return Record(id=record_id, name=r['name'],
-                      type=r['type'], data=r, zone=zone,
-                      driver=self, ttl=r.get('ttl', None),
-                      extra={})
-
-    def _cleanup_domain(self, domain):
-        # name can only contain lower case alphanumeric characters and hyphens
-        domain = re.sub(r'[^a-zA-Z0-9-]', '-', domain)
-        if domain[-1] == '-':
-            domain = domain[:-1]
-        return domain

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/hostvirtual.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/hostvirtual.py b/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/hostvirtual.py
deleted file mode 100644
index 75a3ec1..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/hostvirtual.py
+++ /dev/null
@@ -1,257 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-__all__ = [
-    'HostVirtualDNSDriver'
-]
-
-import sys
-
-try:
-    import simplejson as json
-except:
-    import json
-
-from libcloud.utils.py3 import httplib
-from libcloud.utils.misc import merge_valid_keys, get_new_obj
-from libcloud.common.hostvirtual import HostVirtualResponse
-from libcloud.common.hostvirtual import HostVirtualConnection
-from libcloud.compute.drivers.hostvirtual import API_ROOT
-from libcloud.dns.types import Provider, RecordType
-from libcloud.dns.types import ZoneDoesNotExistError, RecordDoesNotExistError
-from libcloud.dns.base import DNSDriver, Zone, Record
-
-VALID_RECORD_EXTRA_PARAMS = ['prio', 'ttl']
-
-
-class HostVirtualDNSResponse(HostVirtualResponse):
-    def parse_error(self):
-        context = self.connection.context
-        status = int(self.status)
-
-        if status == httplib.NOT_FOUND:
-            if context['resource'] == 'zone':
-                raise ZoneDoesNotExistError(
-                    value=self.parse_body()['error']['message'],
-                    driver=self, zone_id=context['id'])
-            elif context['resource'] == 'record':
-                raise RecordDoesNotExistError(
-                    value=self.parse_body()['error']['message'],
-                    driver=self, record_id=context['id'])
-
-        super(HostVirtualDNSResponse, self).parse_error()
-        return self.body
-
-
-class HostVirtualDNSConnection(HostVirtualConnection):
-    responseCls = HostVirtualDNSResponse
-
-
-class HostVirtualDNSDriver(DNSDriver):
-    type = Provider.HOSTVIRTUAL
-    name = 'Host Virtual DNS'
-    website = 'https://www.hostvirtual.com/'
-    connectionCls = HostVirtualDNSConnection
-
-    RECORD_TYPE_MAP = {
-        RecordType.A: 'A',
-        RecordType.AAAA: 'AAAA',
-        RecordType.CNAME: 'CNAME',
-        RecordType.MX: 'MX',
-        RecordType.NS: 'SPF',
-        RecordType.SRV: 'SRV',
-        RecordType.TXT: 'TXT',
-    }
-
-    def __init__(self, key, secure=True, host=None, port=None):
-        super(HostVirtualDNSDriver, self).__init__(key=key, secure=secure,
-                                                   host=host, port=port)
-
-    def _to_zones(self, items):
-        zones = []
-        for item in items:
-            zones.append(self._to_zone(item))
-        return zones
-
-    def _to_zone(self, item):
-        extra = {}
-        if 'records' in item:
-            extra['records'] = item['records']
-        if item['type'] == 'NATIVE':
-            item['type'] = 'master'
-        zone = Zone(id=item['id'], domain=item['name'],
-                    type=item['type'], ttl=item['ttl'],
-                    driver=self, extra=extra)
-        return zone
-
-    def _to_records(self, items, zone=None):
-        records = []
-
-        for item in items:
-            records.append(self._to_record(item=item, zone=zone))
-        return records
-
-    def _to_record(self, item, zone=None):
-        extra = {'ttl': item['ttl']}
-        type = self._string_to_record_type(item['type'])
-        name = item['name'][:-len(zone.domain) - 1]
-        record = Record(id=item['id'], name=name,
-                        type=type, data=item['content'],
-                        zone=zone, driver=self, ttl=item['ttl'],
-                        extra=extra)
-        return record
-
-    def list_zones(self):
-        result = self.connection.request(
-            API_ROOT + '/dns/zones/').object
-        zones = self._to_zones(result)
-        return zones
-
-    def list_records(self, zone):
-        params = {'id': zone.id}
-        self.connection.set_context({'resource': 'zone', 'id': zone.id})
-        try:
-            result = self.connection.request(
-                API_ROOT + '/dns/records/', params=params).object
-        except ZoneDoesNotExistError:
-            e = sys.exc_info()[1]
-            if 'Not Found: No Records Found' in e.value:
-                return []
-            raise e
-        records = self._to_records(items=result, zone=zone)
-        return records
-
-    def get_zone(self, zone_id):
-        params = {'id': zone_id}
-        self.connection.set_context({'resource': 'zone', 'id': zone_id})
-        result = self.connection.request(
-            API_ROOT + '/dns/zone/', params=params).object
-        if 'id' not in result:
-            raise ZoneDoesNotExistError(value='', driver=self, zone_id=zone_id)
-        zone = self._to_zone(result)
-        return zone
-
-    def get_record(self, zone_id, record_id):
-        zone = self.get_zone(zone_id=zone_id)
-        params = {'id': record_id}
-        self.connection.set_context({'resource': 'record', 'id': record_id})
-        result = self.connection.request(
-            API_ROOT + '/dns/record/', params=params).object
-        if 'id' not in result:
-            raise RecordDoesNotExistError(value='',
-                                          driver=self, record_id=record_id)
-        record = self._to_record(item=result, zone=zone)
-        return record
-
-    def delete_zone(self, zone):
-        params = {'id': zone.id}
-        self.connection.set_context({'resource': 'zone', 'id': zone.id})
-        result = self.connection.request(
-            API_ROOT + '/dns/zone/', params=params, method='DELETE').object
-        return bool(result)
-
-    def delete_record(self, record):
-        params = {'id': record.id}
-        self.connection.set_context({'resource': 'record', 'id': record.id})
-        result = self.connection.request(
-            API_ROOT + '/dns/record/', params=params, method='DELETE').object
-
-        return bool(result)
-
-    def create_zone(self, domain, type='NATIVE', ttl=None, extra=None):
-        if type == 'master':
-            type = 'NATIVE'
-        elif type == 'slave':
-            type = 'SLAVE'
-        params = {'name': domain, 'type': type, 'ttl': ttl}
-        result = self.connection.request(
-            API_ROOT + '/dns/zone/',
-            data=json.dumps(params), method='POST').object
-        extra = {
-            'soa': result['soa'],
-            'ns': result['ns']
-        }
-        zone = Zone(id=result['id'], domain=domain,
-                    type=type, ttl=ttl, extra=extra, driver=self)
-        return zone
-
-    def update_zone(self, zone, domain=None, type=None, ttl=None, extra=None):
-        params = {'id': zone.id}
-        if domain:
-            params['name'] = domain
-        if type:
-            params['type'] = type
-        self.connection.set_context({'resource': 'zone', 'id': zone.id})
-        self.connection.request(API_ROOT + '/dns/zone/',
-                                data=json.dumps(params), method='PUT').object
-        updated_zone = get_new_obj(
-            obj=zone, klass=Zone,
-            attributes={
-                'domain': domain,
-                'type': type,
-                'ttl': ttl,
-                'extra': extra
-            })
-        return updated_zone
-
-    def create_record(self, name, zone, type, data, extra=None):
-        params = {
-            'name': name,
-            'type': self.RECORD_TYPE_MAP[type],
-            'domain_id': zone.id,
-            'content': data
-        }
-        merged = merge_valid_keys(
-            params=params,
-            valid_keys=VALID_RECORD_EXTRA_PARAMS,
-            extra=extra
-        )
-        self.connection.set_context({'resource': 'zone', 'id': zone.id})
-        result = self.connection.request(
-            API_ROOT + '/dns/record/',
-            data=json.dumps(params), method='POST').object
-        record = Record(id=result['id'], name=name,
-                        type=type, data=data,
-                        extra=merged, zone=zone,
-                        ttl=merged.get('ttl', None),
-                        driver=self)
-        return record
-
-    def update_record(self, record, name=None, type=None,
-                      data=None, extra=None):
-        params = {
-            'domain_id': record.zone.id,
-            'record_id': record.id
-        }
-        if name:
-            params['name'] = name
-        if data:
-            params['content'] = data
-        if type is not None:
-            params['type'] = self.RECORD_TYPE_MAP[type]
-            merged = merge_valid_keys(
-                params=params,
-                valid_keys=VALID_RECORD_EXTRA_PARAMS,
-                extra=extra
-            )
-        self.connection.set_context({'resource': 'record', 'id': record.id})
-        self.connection.request(API_ROOT + '/dns/record/',
-                                data=json.dumps(params), method='PUT').object
-        updated_record = get_new_obj(
-            obj=record, klass=Record, attributes={
-                'name': name, 'data': data,
-                'type': type,
-                'extra': merged
-            })
-        return updated_record

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/linode.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/linode.py b/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/linode.py
deleted file mode 100644
index 5d497ed..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/linode.py
+++ /dev/null
@@ -1,273 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-__all__ = [
-    'LinodeDNSDriver'
-]
-
-from libcloud.utils.misc import merge_valid_keys, get_new_obj
-from libcloud.common.linode import (API_ROOT, LinodeException,
-                                    LinodeConnection, LinodeResponse)
-from libcloud.dns.types import Provider, RecordType
-from libcloud.dns.types import ZoneDoesNotExistError, RecordDoesNotExistError
-from libcloud.dns.base import DNSDriver, Zone, Record
-
-
-VALID_ZONE_EXTRA_PARAMS = ['SOA_Email', 'Refresh_sec', 'Retry_sec',
-                           'Expire_sec', 'status', 'master_ips']
-
-VALID_RECORD_EXTRA_PARAMS = ['Priority', 'Weight', 'Port', 'Protocol',
-                             'TTL_sec']
-
-
-class LinodeDNSResponse(LinodeResponse):
-    def _make_excp(self, error):
-        result = super(LinodeDNSResponse, self)._make_excp(error)
-        if isinstance(result, LinodeException) and result.code == 5:
-            context = self.connection.context
-
-            if context['resource'] == 'zone':
-                result = ZoneDoesNotExistError(value='',
-                                               driver=self.connection.driver,
-                                               zone_id=context['id'])
-
-            elif context['resource'] == 'record':
-                result = RecordDoesNotExistError(value='',
-                                                 driver=self.connection.driver,
-                                                 record_id=context['id'])
-        return result
-
-
-class LinodeDNSConnection(LinodeConnection):
-    responseCls = LinodeDNSResponse
-
-
-class LinodeDNSDriver(DNSDriver):
-    type = Provider.LINODE
-    name = 'Linode DNS'
-    website = 'http://www.linode.com/'
-    connectionCls = LinodeDNSConnection
-
-    RECORD_TYPE_MAP = {
-        RecordType.NS: 'NS',
-        RecordType.MX: 'MX',
-        RecordType.A: 'A',
-        RecordType.AAAA: 'AAAA',
-        RecordType.CNAME: 'CNAME',
-        RecordType.TXT: 'TXT',
-        RecordType.SRV: 'SRV',
-    }
-
-    def list_zones(self):
-        params = {'api_action': 'domain.list'}
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        zones = self._to_zones(data)
-        return zones
-
-    def list_records(self, zone):
-        params = {'api_action': 'domain.resource.list', 'DOMAINID': zone.id}
-
-        self.connection.set_context(context={'resource': 'zone',
-                                             'id': zone.id})
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        records = self._to_records(items=data, zone=zone)
-        return records
-
-    def get_zone(self, zone_id):
-        params = {'api_action': 'domain.list', 'DomainID': zone_id}
-        self.connection.set_context(context={'resource': 'zone',
-                                             'id': zone_id})
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        zones = self._to_zones(data)
-
-        if len(zones) != 1:
-            raise ZoneDoesNotExistError(value='', driver=self, zone_id=zone_id)
-
-        return zones[0]
-
-    def get_record(self, zone_id, record_id):
-        zone = self.get_zone(zone_id=zone_id)
-        params = {'api_action': 'domain.resource.list', 'DomainID': zone_id,
-                  'ResourceID': record_id}
-        self.connection.set_context(context={'resource': 'record',
-                                             'id': record_id})
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        records = self._to_records(items=data, zone=zone)
-
-        if len(records) != 1:
-            raise RecordDoesNotExistError(value='', driver=self,
-                                          record_id=record_id)
-
-        return records[0]
-
-    def create_zone(self, domain, type='master', ttl=None, extra=None):
-        """
-        Create a new zone.
-
-        API docs: http://www.linode.com/api/dns/domain.create
-        """
-        params = {'api_action': 'domain.create', 'Type': type,
-                  'Domain': domain}
-
-        if ttl:
-            params['TTL_sec'] = ttl
-
-        merged = merge_valid_keys(params=params,
-                                  valid_keys=VALID_ZONE_EXTRA_PARAMS,
-                                  extra=extra)
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        zone = Zone(id=data['DomainID'], domain=domain, type=type, ttl=ttl,
-                    extra=merged, driver=self)
-        return zone
-
-    def update_zone(self, zone, domain=None, type=None, ttl=None, extra=None):
-        """
-        Update an existing zone.
-
-        API docs: http://www.linode.com/api/dns/domain.update
-        """
-        params = {'api_action': 'domain.update', 'DomainID': zone.id}
-
-        if type:
-            params['Type'] = type
-
-        if domain:
-            params['Domain'] = domain
-
-        if ttl:
-            params['TTL_sec'] = ttl
-
-        merged = merge_valid_keys(params=params,
-                                  valid_keys=VALID_ZONE_EXTRA_PARAMS,
-                                  extra=extra)
-        self.connection.request(API_ROOT, params=params).objects[0]
-        updated_zone = get_new_obj(obj=zone, klass=Zone,
-                                   attributes={'domain': domain,
-                                               'type': type, 'ttl': ttl,
-                                               'extra': merged})
-        return updated_zone
-
-    def create_record(self, name, zone, type, data, extra=None):
-        """
-        Create a new record.
-
-        API docs: http://www.linode.com/api/dns/domain.resource.create
-        """
-        params = {'api_action': 'domain.resource.create', 'DomainID': zone.id,
-                  'Name': name, 'Target': data,
-                  'Type': self.RECORD_TYPE_MAP[type]}
-        merged = merge_valid_keys(params=params,
-                                  valid_keys=VALID_RECORD_EXTRA_PARAMS,
-                                  extra=extra)
-
-        result = self.connection.request(API_ROOT, params=params).objects[0]
-        record = Record(id=result['ResourceID'], name=name, type=type,
-                        data=data, extra=merged, zone=zone, driver=self,
-                        ttl=merged.get('TTL_sec', None))
-        return record
-
-    def update_record(self, record, name=None, type=None, data=None,
-                      extra=None):
-        """
-        Update an existing record.
-
-        API docs: http://www.linode.com/api/dns/domain.resource.update
-        """
-        params = {'api_action': 'domain.resource.update',
-                  'ResourceID': record.id, 'DomainID': record.zone.id}
-
-        if name:
-            params['Name'] = name
-
-        if data:
-            params['Target'] = data
-
-        if type is not None:
-            params['Type'] = self.RECORD_TYPE_MAP[type]
-
-        merged = merge_valid_keys(params=params,
-                                  valid_keys=VALID_RECORD_EXTRA_PARAMS,
-                                  extra=extra)
-
-        self.connection.request(API_ROOT, params=params).objects[0]
-        updated_record = get_new_obj(obj=record, klass=Record,
-                                     attributes={'name': name, 'data': data,
-                                                 'type': type,
-                                                 'extra': merged})
-        return updated_record
-
-    def delete_zone(self, zone):
-        params = {'api_action': 'domain.delete', 'DomainID': zone.id}
-
-        self.connection.set_context(context={'resource': 'zone',
-                                             'id': zone.id})
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-
-        return 'DomainID' in data
-
-    def delete_record(self, record):
-        params = {'api_action': 'domain.resource.delete',
-                  'DomainID': record.zone.id, 'ResourceID': record.id}
-
-        self.connection.set_context(context={'resource': 'record',
-                                             'id': record.id})
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-
-        return 'ResourceID' in data
-
-    def _to_zones(self, items):
-        """
-        Convert a list of items to the Zone objects.
-        """
-        zones = []
-
-        for item in items:
-            zones.append(self._to_zone(item))
-
-        return zones
-
-    def _to_zone(self, item):
-        """
-        Build an Zone object from the item dictionary.
-        """
-        extra = {'SOA_Email': item['SOA_EMAIL'], 'status': item['STATUS'],
-                 'description': item['DESCRIPTION']}
-        zone = Zone(id=item['DOMAINID'], domain=item['DOMAIN'],
-                    type=item['TYPE'], ttl=item['TTL_SEC'], driver=self,
-                    extra=extra)
-        return zone
-
-    def _to_records(self, items, zone=None):
-        """
-        Convert a list of items to the Record objects.
-        """
-        records = []
-
-        for item in items:
-            records.append(self._to_record(item=item, zone=zone))
-
-        return records
-
-    def _to_record(self, item, zone=None):
-        """
-        Build a Record object from the item dictionary.
-        """
-        extra = {'protocol': item['PROTOCOL'], 'ttl_sec': item['TTL_SEC'],
-                 'port': item['PORT'], 'weight': item['WEIGHT']}
-        type = self._string_to_record_type(item['TYPE'])
-        record = Record(id=item['RESOURCEID'], name=item['NAME'], type=type,
-                        data=item['TARGET'], zone=zone, driver=self,
-                        ttl=item['TTL_SEC'], extra=extra)
-        return record

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/liquidweb.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/liquidweb.py b/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/liquidweb.py
deleted file mode 100644
index 803849a..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/liquidweb.py
+++ /dev/null
@@ -1,388 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-Liquid Web DNS Driver
-"""
-
-import sys
-
-try:
-    import simplejson as json
-except ImportError:
-    import json
-
-from libcloud.common.liquidweb import LiquidWebResponse, LiquidWebConnection
-from libcloud.common.liquidweb import APIException
-from libcloud.dns.base import DNSDriver, Zone, Record
-from libcloud.dns.types import Provider, RecordType
-from libcloud.dns.types import ZoneDoesNotExistError, ZoneAlreadyExistsError
-from libcloud.dns.types import RecordDoesNotExistError
-from libcloud.dns.types import RecordAlreadyExistsError
-
-
-__all__ = [
-    'LiquidWebDNSDriver'
-]
-
-
-class LiquidWebDNSResponse(LiquidWebResponse):
-    pass
-
-
-class LiquidWebDNSConnection(LiquidWebConnection):
-    responseCls = LiquidWebDNSResponse
-
-
-class LiquidWebDNSDriver(DNSDriver):
-    type = Provider.LIQUIDWEB
-    name = 'Liquidweb DNS'
-    website = 'https://www.liquidweb.com'
-    connectionCls = LiquidWebDNSConnection
-
-    RECORD_TYPE_MAP = {
-        RecordType.A: 'A',
-        RecordType.AAAA: 'AAAA',
-        RecordType.CNAME: 'CNAME',
-        RecordType.MX: 'MX',
-        RecordType.NS: 'NS',
-        RecordType.PTR: 'PTR',
-        RecordType.SOA: 'SOA',
-        RecordType.SRV: 'SRV',
-        RecordType.TXT: 'TXT'
-    }
-
-    def list_zones(self):
-        """
-        Return a list of zones.
-
-        :return: ``list`` of :class:`Zone`
-        """
-        action = '/v1/Network/DNS/Zone/list'
-        response = self.connection.request(action=action,
-                                           method='POST')
-
-        zones = self._to_zones(response.objects[0])
-
-        return zones
-
-    def list_records(self, zone):
-        """
-        Return a list of records for the provided zone.
-
-        :param zone: Zone to list records for.
-        :type zone: :class:`Zone`
-
-        :return: ``list`` of :class:`Record`
-        """
-        action = '/v1/Network/DNS/Record/list'
-        data = json.dumps({'params': {'zone_id': zone.id}})
-        response = self.connection.request(action=action,
-                                           method='POST',
-                                           data=data)
-
-        records = self._to_records(response.objects[0], zone=zone)
-
-        return records
-
-    def get_zone(self, zone_id):
-        """
-        Return a Zone instance.
-
-        :param zone_id: ID of the required zone
-        :type  zone_id: ``str``
-
-        :rtype: :class:`Zone`
-        """
-        action = '/v1/Network/DNS/Zone/details'
-        data = json.dumps({'params': {'id': zone_id}})
-        try:
-            response = self.connection.request(action=action,
-                                               method='POST',
-                                               data=data)
-        except APIException:
-            e = sys.exc_info()[1]
-            if e.error_class == 'LW::Exception::RecordNotFound':
-                raise ZoneDoesNotExistError(zone_id=zone_id,
-                                            value=e.value, driver=self)
-            else:
-                raise e
-
-        zone = self._to_zone(response.objects[0])
-        return zone
-
-    def get_record(self, zone_id, record_id):
-        """
-        Return a Record instance.
-
-        :param zone_id: ID of the required zone
-        :type  zone_id: ``str``
-
-        :param record_id: ID of the required record
-        :type  record_id: ``str``
-
-        :rtype: :class:`Record`
-        """
-        zone = self.get_zone(zone_id=zone_id)
-        action = '/v1/Network/DNS/Record/details'
-        data = json.dumps({'params': {'id': record_id}})
-        try:
-            response = self.connection.request(action=action,
-                                               method='POST',
-                                               data=data)
-        except APIException:
-            e = sys.exc_info()[1]
-            if e.error_class == 'LW::Exception::RecordNotFound':
-                raise RecordDoesNotExistError(record_id=record_id, driver=self,
-                                              value=e.value)
-            else:
-                raise e
-
-        record = self._to_record(response.objects[0], zone=zone)
-        return record
-
-    def create_zone(self, domain, type='master', ttl=None, extra=None):
-        """
-        Create a new zone.
-
-        :param domain: Zone domain name (e.g. example.com)
-        :type domain: ``str``
-
-        :param type: Zone type (This is not really used. See API docs for extra
-                     parameters).
-        :type  type: ``str``
-
-        :param ttl: TTL for new records. (This is not really used)
-        :type  ttl: ``int``
-
-        :param extra: Extra attributes (driver specific). ('region_support',
-                      'zone_data')
-        :type extra: ``dict``
-
-        :rtype: :class:`Zone`
-
-        For more info, please see:
-        https://www.liquidweb.com/storm/api/docs/v1/Network/DNS/Zone.html
-        """
-        action = '/v1/Network/DNS/Zone/create'
-        data = json.dumps({'params': {'name': domain}})
-        if extra is not None:
-            params = data.get('params')
-            params.update(extra)
-        try:
-            response = self.connection.request(action=action,
-                                               method='POST',
-                                               data=data)
-        except APIException:
-            e = sys.exc_info()[1]
-            if e.error_class == 'LW::Exception::DuplicateRecord':
-                raise ZoneAlreadyExistsError(zone_id=domain,
-                                             value=e.value,
-                                             driver=self)
-            else:
-                raise e
-
-        zone = self._to_zone(response.objects[0])
-
-        return zone
-
-    def create_record(self, name, zone, type, data, extra=None):
-        """
-        Create a record.
-
-        :param name: Record name without the domain name (e.g. www).
-                     Note: If you want to create a record for a base domain
-                     name, you should specify empty string ('') for this
-                     argument.
-        :type  name: ``str``
-
-        :param zone: Zone which the records will be created for.
-        :type zone: :class:`Zone`
-
-        :param type: DNS record type ( 'A', 'AAAA', 'CNAME', 'MX', 'NS',
-                     'PTR', 'SOA', 'SRV', 'TXT').
-        :type  type: :class:`RecordType`
-
-        :param data: Data for the record (depends on the record type).
-        :type  data: ``str``
-
-        :param extra: (optional) Extra attributes ('prio', 'ttl').
-        :type  extra: ``dict``
-
-        :rtype: :class:`Record`
-        """
-        action = '/v1/Network/DNS/Record/create'
-        to_post = {'params': {'name': name,
-                              'rdata': data,
-                              'type': type,
-                              'zone': zone.domain,
-                              'zone_id': zone.id
-                              }
-                   }
-        if extra is not None:
-            to_post['params'].update(extra)
-        data = json.dumps(to_post)
-        try:
-            response = self.connection.request(action=action,
-                                               method='POST',
-                                               data=data)
-        except APIException:
-            e = sys.exc_info()[1]
-            if e.error_class == 'LW::Exception::DuplicateRecord':
-                raise RecordAlreadyExistsError(record_id=name,
-                                               value=e.value,
-                                               driver=self)
-            else:
-                raise e
-
-        record = self._to_record(response.objects[0], zone=zone)
-        return record
-
-    def update_record(self, record, name, type, data, extra=None):
-        """
-        Update an existing record.
-
-        :param record: Record to update.
-        :type  record: :class:`Record`
-
-        :param name: Record name without the domain name (e.g. www).
-                     Note: If you want to create a record for a base domain
-                     name, you should specify empty string ('') for this
-                     argument.
-        :type  name: ``str``
-
-        :param type: DNS record type ( 'A', 'AAAA', 'CNAME', 'MX', 'NS',
-                     'PTR', 'SOA', 'SRV', 'TXT').
-        :type  type: :class:`RecordType`
-
-        :param data: Data for the record (depends on the record type).
-        :type  data: ``str``
-
-        :param extra: (optional) Extra attributes ('name', 'rdata', 'prio',
-                      'ttl').
-        :type  extra: ``dict``
-
-        :rtype: :class:`Record`
-        """
-        zone = record.zone
-        action = '/v1/Network/DNS/Record/update'
-        to_post = {'params': {'id': int(record.id),
-                              'name': name,
-                              'rdata': data}}
-        if extra is not None:
-            to_post['params'].update(extra)
-        j_data = json.dumps(to_post)
-        try:
-            response = self.connection.request(action=action,
-                                               method='PUT',
-                                               data=j_data)
-        except APIException:
-            e = sys.exc_info()[1]
-            if e.error_class == 'LW::Exception::RecordNotFound':
-                raise RecordDoesNotExistError(record_id=record.id, driver=self,
-                                              value=e.value)
-            else:
-                raise e
-
-        record = self._to_record(response.objects[0], zone=zone)
-        return record
-
-    def delete_zone(self, zone):
-        """
-        Delete a zone.
-
-        Note: This will delete all the records belonging to this zone.
-
-        :param zone: Zone to delete.
-        :type  zone: :class:`Zone`
-
-        :rtype: ``bool``
-        """
-        action = '/v1/Network/DNS/Zone/delete'
-        data = json.dumps({'params': {'id': zone.id}})
-        try:
-            response = self.connection.request(action=action,
-                                               method='POST',
-                                               data=data)
-        except APIException:
-            e = sys.exc_info()[1]
-            if e.error_class == 'LW::Exception::RecordNotFound':
-                raise ZoneDoesNotExistError(zone_id=zone.id,
-                                            value=e.value, driver=self)
-            else:
-                raise e
-
-        return zone.domain in response.objects
-
-    def delete_record(self, record):
-        """
-        Delete a record.
-
-        :param record: Record to delete.
-        :type  record: :class:`Record`
-
-        :rtype: ``bool``
-        """
-        action = '/v1/Network/DNS/Record/delete'
-        data = json.dumps({'params': {'id': record.id}})
-        try:
-            response = self.connection.request(action=action,
-                                               method='POST',
-                                               data=data)
-        except APIException:
-            e = sys.exc_info()[1]
-            if e.error_class == 'LW::Exception::RecordNotFound':
-                raise RecordDoesNotExistError(record_id=record.id, driver=self,
-                                              value=e.value)
-            else:
-                raise e
-
-        return record.id in response.objects
-
-    def _to_zone(self, item):
-        common_attr = ['id', 'name', 'type']
-        extra = {}
-        for key in item:
-            if key not in common_attr:
-                extra[key] = item.get(key)
-        zone = Zone(domain=item['name'], id=item['id'], type=item['type'],
-                    ttl=None, driver=self, extra=extra)
-
-        return zone
-
-    def _to_zones(self, items):
-        zones = []
-        for item in items:
-            zones.append(self._to_zone(item))
-
-        return zones
-
-    def _to_record(self, item, zone):
-        common_attr = ['id', 'rdata', 'name', 'type']
-        extra = {}
-        for key in item:
-            if key not in common_attr:
-                extra[key] = item.get(key)
-        record = Record(id=item['id'], name=item['name'], type=item['type'],
-                        data=item['rdata'], zone=zone, driver=self,
-                        extra=extra)
-
-        return record
-
-    def _to_records(self, items, zone):
-        records = []
-        for item in items:
-            records.append(self._to_record(item, zone))
-
-        return records

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/luadns.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/luadns.py b/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/luadns.py
deleted file mode 100644
index 48ed555..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/luadns.py
+++ /dev/null
@@ -1,293 +0,0 @@
-import sys
-
-try:
-    import simplejson as json
-except ImportError:
-    import json
-
-from libcloud.common.luadns import LuadnsResponse, LuadnsConnection
-from libcloud.common.luadns import LuadnsException
-from libcloud.dns.base import DNSDriver, Zone, Record
-from libcloud.dns.types import Provider, RecordType
-from libcloud.dns.types import ZoneDoesNotExistError, ZoneAlreadyExistsError
-from libcloud.dns.types import RecordDoesNotExistError
-
-
-__all__ = [
-    'LuadnsDNSDriver'
-]
-
-
-class LuadnsDNSResponse(LuadnsResponse):
-    pass
-
-
-class LuadnsDNSConnection(LuadnsConnection):
-    responseCls = LuadnsDNSResponse
-
-
-class LuadnsDNSDriver(DNSDriver):
-    type = Provider.LUADNS
-    name = 'Luadns'
-    website = 'https://www.luadns.com'
-    connectionCls = LuadnsDNSConnection
-
-    RECORD_TYPE_MAP = {
-        RecordType.A: 'A',
-        RecordType.AAAA: 'AAAA',
-        RecordType.CNAME: 'CNAME',
-        RecordType.MX: 'MX',
-        RecordType.NS: 'NS',
-        RecordType.PTR: 'PTR',
-        RecordType.SOA: 'SOA',
-        RecordType.SRV: 'SRV',
-        RecordType.TXT: 'TXT'
-    }
-
-    def list_zones(self):
-        """
-        Return a list of zones.
-
-        :return: ``list`` of :class:`Zone`
-        """
-        action = '/v1/zones'
-        response = self.connection.request(action=action,
-                                           method='GET')
-        zones = self._to_zones(response.parse_body())
-
-        return zones
-
-    def get_zone(self, zone_id):
-        """
-        Return a Zone instance.
-
-        :param zone_id: ID of the required zone
-        :type  zone_id: ``str``
-
-        :rtype: :class:`Zone`
-        """
-        action = '/v1/zones/%s' % zone_id
-        try:
-            response = self.connection.request(action=action)
-        except LuadnsException:
-            e = sys.exc_info()[1]
-            if e.message in ['Zone not found.', 'Resource not found.']:
-                raise ZoneDoesNotExistError(zone_id=zone_id,
-                                            value='', driver=self)
-            else:
-                raise e
-
-        zone = self._to_zone(response.parse_body())
-
-        return zone
-
-    def delete_zone(self, zone):
-        """
-        Delete a zone.
-
-        Note: This will delete all the records belonging to this zone.
-
-        :param zone: Zone to delete.
-        :type  zone: :class:`Zone`
-
-        :rtype: ``bool``
-        """
-        action = '/v1/zones/%s' % zone.id
-        try:
-            response = self.connection.request(action=action,
-                                               method='DELETE')
-        except LuadnsException:
-            e = sys.exc_info()[1]
-            if e.message in ['Resource not found.', 'Zone not found.']:
-                raise ZoneDoesNotExistError(zone_id=zone.id,
-                                            value='', driver=self)
-            else:
-                raise e
-
-        return response.status == 200
-
-    def create_zone(self, domain, type='master', ttl=None, extra=None):
-        """
-        Create a new zone.
-
-        :param domain: Zone domain name (e.g. example.com)
-        :type domain: ``str``
-
-        :param type: Zone type (This is not really used. See API docs for extra
-                     parameters).
-        :type  type: ``str``
-
-        :param ttl: TTL for new records. (This is not really used)
-        :type  ttl: ``int``
-
-        :param extra: Extra attributes (driver specific). ('region_support',
-                      'zone_data')
-        :type extra: ``dict``
-
-        :rtype: :class:`Zone`
-        """
-        action = '/v1/zones'
-        data = json.dumps({'name': domain})
-        try:
-            response = self.connection.request(action=action,
-                                               method='POST',
-                                               data=data)
-        except LuadnsException:
-            e = sys.exc_info()[1]
-            if e.message == "Zone '%s' is taken already." % domain:
-                raise ZoneAlreadyExistsError(zone_id=domain,
-                                             value='',
-                                             driver=self)
-            else:
-                raise e
-        zone = self._to_zone(response.parse_body())
-
-        return zone
-
-    def list_records(self, zone):
-        """
-        Return a list of records for the provided zone.
-
-        :param zone: Zone to list records for.
-        :type zone: :class:`Zone`
-
-        :return: ``list`` of :class:`Record`
-        """
-        action = '/v1/zones/%s/records' % zone.id
-        response = self.connection.request(action=action)
-        records = self._to_records(response.parse_body(), zone=zone)
-
-        return records
-
-    def get_record(self, zone_id, record_id):
-        """
-        Return a Record instance.
-
-        :param zone_id: ID of the required zone
-        :type  zone_id: ``str``
-
-        :param record_id: ID of the required record
-        :type  record_id: ``str``
-
-        :rtype: :class:`Record`
-        """
-        zone = self.get_zone(zone_id=zone_id)
-        action = '/v1/zones/%s/records/%s' % (zone_id, record_id)
-        try:
-            response = self.connection.request(action=action)
-        except LuadnsException:
-            e = sys.exc_info()[1]
-            if e.message == 'Record not found.':
-                raise RecordDoesNotExistError(record_id=record_id, driver=self,
-                                              value='')
-            else:
-                raise e
-
-        record = self._to_record(response.parse_body(), zone=zone)
-
-        return record
-
-    def delete_record(self, record):
-        """
-        Delete a record.
-
-        :param record: Record to delete.
-        :type  record: :class:`Record`
-
-        :rtype: ``bool``
-        """
-        action = '/v1/zones/%s/records/%s' % (record.zone.id, record.id)
-        try:
-            response = self.connection.request(action=action,
-                                               method='DELETE')
-        except LuadnsException:
-            e = sys.exc_info()[1]
-            if e.message == 'Record not found.':
-                raise RecordDoesNotExistError(record_id=record.id, driver=self,
-                                              value='')
-            else:
-                raise e
-
-        return response.status == 200
-
-    def create_record(self, name, zone, type, data, extra=None):
-        """
-        Create a record.
-
-        :param name: Record name without the domain name (e.g. www).
-                     Note: If you want to create a record for a base domain
-                     name, you should specify empty string ('') for this
-                     argument.
-        :type  name: ``str``
-
-        :param zone: Zone which the records will be created for.
-        :type zone: :class:`Zone`
-
-        :param type: DNS record type ( 'A', 'AAAA', 'CNAME', 'MX', 'NS',
-                     'PTR', 'SOA', 'SRV', 'TXT').
-        :type  type: :class:`RecordType`
-
-        :param data: Data for the record (depends on the record type).
-        :type  data: ``str``
-
-        :param extra: (optional) Extra attributes ('prio', 'ttl').
-        :type  extra: ``dict``
-
-        :rtype: :class:`Record`
-        """
-        action = '/v1/zones/%s/records' % zone.id
-        to_post = {'name': name, 'content': data, 'type': type,
-                   'zone_id': int(zone.id)}
-        # ttl is required to create a record for luadns
-        # pass it through extra like this: extra={'ttl':ttl}
-        if extra is not None:
-            to_post.update(extra)
-        data = json.dumps(to_post)
-        try:
-            response = self.connection.request(action=action,
-                                               method='POST',
-                                               data=data)
-        except LuadnsException:
-            e = sys.exc_info()[1]
-            raise e
-
-        record = self._to_record(response.parse_body(), zone=zone)
-
-        return record
-
-    def _to_zone(self, item):
-        common_attr = ['id', 'name']
-        extra = {}
-        for key in item:
-            if key not in common_attr:
-                extra[key] = item.get(key)
-        zone = Zone(domain=item['name'], id=item['id'], type=None,
-                    ttl=None, driver=self, extra=extra)
-
-        return zone
-
-    def _to_zones(self, items):
-        zones = []
-        for item in items:
-            zones.append(self._to_zone(item))
-
-        return zones
-
-    def _to_record(self, item, zone):
-        common_attr = ['id', 'content', 'name', 'type']
-        extra = {}
-        for key in item:
-            if key not in common_attr:
-                extra[key] = item.get(key)
-        record = Record(id=item['id'], name=item['name'], type=item['type'],
-                        data=item['content'], zone=zone, driver=self,
-                        extra=extra)
-
-        return record
-
-    def _to_records(self, items, zone):
-        records = []
-        for item in items:
-            records.append(self._to_record(item, zone))
-
-        return records

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/nfsn.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/nfsn.py b/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/nfsn.py
deleted file mode 100644
index 0231ec4..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/nfsn.py
+++ /dev/null
@@ -1,198 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-NFSN DNS Driver
-"""
-import re
-import sys
-
-from libcloud.common.exceptions import BaseHTTPError
-from libcloud.common.nfsn import NFSNConnection
-from libcloud.dns.base import DNSDriver, Zone, Record
-from libcloud.dns.types import ZoneDoesNotExistError, RecordDoesNotExistError
-from libcloud.dns.types import RecordAlreadyExistsError
-from libcloud.dns.types import Provider, RecordType
-from libcloud.utils.py3 import httplib
-
-__all__ = [
-    'NFSNDNSDriver',
-]
-
-# The NFSN API does not return any internal "ID" strings for any DNS records.
-# This means that we must set all returned Record objects' id properties to
-# None. It also means that we cannot implement libcloud APIs that rely on
-# record_id, such as get_record(). Instead, the NFSN-specific
-# ex_get_records_by() method will return the desired Record objects.
-#
-# Additionally, the NFSN API does not provide ways to create, delete, or list
-# all zones, so create_zone(), delete_zone(), and list_zones() are not
-# implemented.
-
-
-class NFSNDNSDriver(DNSDriver):
-    type = Provider.NFSN
-    name = 'NFSN DNS'
-    website = 'https://www.nearlyfreespeech.net'
-    connectionCls = NFSNConnection
-
-    RECORD_TYPE_MAP = {
-        RecordType.A: 'A',
-        RecordType.AAAA: 'AAAA',
-        RecordType.CNAME: 'CNAME',
-        RecordType.MX: 'MX',
-        RecordType.NS: 'NS',
-        RecordType.SRV: 'SRV',
-        RecordType.TXT: 'TXT',
-        RecordType.PTR: 'PTR',
-    }
-
-    def list_records(self, zone):
-        """
-        Return a list of all records for the provided zone.
-
-        :param zone: Zone to list records for.
-        :type zone: :class:`Zone`
-
-        :return: ``list`` of :class:`Record`
-        """
-        # Just use ex_get_records_by() with no name or type filters.
-        return self.ex_get_records_by(zone)
-
-    def get_zone(self, zone_id):
-        """
-        Return a Zone instance.
-
-        :param zone_id: name of the required zone, for example "example.com".
-        :type  zone_id: ``str``
-
-        :rtype: :class:`Zone`
-        :raises: ZoneDoesNotExistError: If no zone could be found.
-        """
-        # We will check if there is a serial property for this zone. If so,
-        # then the zone exists.
-        try:
-            self.connection.request(action='/dns/%s/serial' % zone_id)
-        except BaseHTTPError:
-            e = sys.exc_info()[1]
-            if e.code == httplib.NOT_FOUND:
-                raise ZoneDoesNotExistError(zone_id=None, driver=self,
-                                            value=e.message)
-            raise e
-        return Zone(id=None, domain=zone_id, type='master', ttl=3600,
-                    driver=self)
-
-    def ex_get_records_by(self, zone, name=None, type=None):
-        """
-        Return a list of records for the provided zone, filtered by name and/or
-        type.
-
-        :param zone: Zone to list records for.
-        :type zone: :class:`Zone`
-
-        :param zone: Zone where the requested records are found.
-        :type  zone: :class:`Zone`
-
-        :param name: name of the records, for example "www". (optional)
-        :type  name: ``str``
-
-        :param type: DNS record type (A, MX, TXT). (optional)
-        :type  type: :class:`RecordType`
-
-        :return: ``list`` of :class:`Record`
-        """
-        payload = {}
-        if name is not None:
-            payload['name'] = name
-        if type is not None:
-            payload['type'] = type
-
-        action = '/dns/%s/listRRs' % zone.domain
-        response = self.connection.request(action=action, data=payload,
-                                           method='POST')
-        return self._to_records(response, zone)
-
-    def create_record(self, name, zone, type, data, extra=None):
-        """
-        Create a new record.
-
-        :param name: Record name without the domain name (e.g. www).
-                     Note: If you want to create a record for a base domain
-                     name, you should specify empty string ('') for this
-                     argument.
-        :type  name: ``str``
-
-        :param zone: Zone where the requested record is created.
-        :type  zone: :class:`Zone`
-
-        :param type: DNS record type (A, MX, TXT).
-        :type  type: :class:`RecordType`
-
-        :param data: Data for the record (depends on the record type).
-        :type  data: ``str``
-
-        :param extra: Extra attributes (driver specific, e.g. 'ttl').
-                      (optional)
-        :type extra: ``dict``
-
-        :rtype: :class:`Record`
-        """
-        action = '/dns/%s/addRR' % zone.domain
-        payload = {'name': name, 'data': data, 'type': type}
-        if extra is not None and extra.get('ttl', None) is not None:
-            payload['ttl'] = extra['ttl']
-        try:
-            self.connection.request(action=action, data=payload, method='POST')
-        except BaseHTTPError:
-            e = sys.exc_info()[1]
-            exists_re = re.compile(r'That RR already exists on the domain')
-            if e.code == httplib.BAD_REQUEST and \
-               re.search(exists_re, e.message) is not None:
-                value = '"%s" already exists in %s' % (name, zone.domain)
-                raise RecordAlreadyExistsError(value=value, driver=self,
-                                               record_id=None)
-            raise e
-        return self.ex_get_records_by(zone=zone, name=name, type=type)[0]
-
-    def delete_record(self, record):
-        """
-        Use this method to delete a record.
-
-        :param record: record to delete
-        :type record: `Record`
-
-        :rtype: Bool
-        """
-        action = '/dns/%s/removeRR' % record.zone.domain
-        payload = {'name': record.name, 'data': record.data,
-                   'type': record.type}
-        try:
-            self.connection.request(action=action, data=payload, method='POST')
-        except BaseHTTPError:
-            e = sys.exc_info()[1]
-            if e.code == httplib.NOT_FOUND:
-                raise RecordDoesNotExistError(value=e.message, driver=self,
-                                              record_id=None)
-            raise e
-        return True
-
-    def _to_record(self, item, zone):
-        ttl = int(item['ttl'])
-        return Record(id=None, name=item['name'], data=item['data'],
-                      type=item['type'], zone=zone, driver=self, ttl=ttl)
-
-    def _to_records(self, items, zone):
-        records = []
-        for item in items.object:
-            records.append(self._to_record(item, zone))
-        return records


[54/56] [abbrv] libcloud git commit: Implement the method for creating public ip Closes #943

Posted by an...@apache.org.
Implement the method for creating public ip
Closes #943


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/c726d1fb
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/c726d1fb
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/c726d1fb

Branch: refs/heads/trunk
Commit: c726d1fbb04cd924fb36b8982f014566a908e53b
Parents: f646f1c
Author: hequn <he...@hihuron.com>
Authored: Mon Nov 14 10:49:48 2016 +0800
Committer: Anthony Shaw <an...@apache.org>
Committed: Tue Nov 15 10:22:02 2016 +1100

----------------------------------------------------------------------
 libcloud/compute/drivers/ecs.py                   | 18 +++++++++++++++++-
 .../compute/fixtures/ecs/create_public_ip.xml     |  6 ++++++
 libcloud/test/compute/test_ecs.py                 | 10 ++++++++++
 3 files changed, 33 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/c726d1fb/libcloud/compute/drivers/ecs.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/ecs.py b/libcloud/compute/drivers/ecs.py
index 1dc6cb5..bb34453 100644
--- a/libcloud/compute/drivers/ecs.py
+++ b/libcloud/compute/drivers/ecs.py
@@ -477,7 +477,6 @@ class ECSDriver(NodeDriver):
     Used for Aliyun ECS service.
 
     TODO:
-    Create public IP address
     Get guest OS root password
     Adjust internet bandwidth settings
     Manage security groups and rules
@@ -1273,6 +1272,23 @@ class ECSDriver(NodeDriver):
         image_id = findtext(resp.object, 'ImageId', namespace=self.namespace)
         return self.get_image(image_id=image_id)
 
+    def create_public_ip(self, instance_id):
+            """
+            Create public ip.
+
+            :keyword instance_id: instance id for allocating public ip.
+            :type    instance_id: ``str``
+
+            :return public ip
+            :rtype ``str``
+            """
+            params = {'Action': 'AllocatePublicIpAddress',
+                      'InstanceId': instance_id}
+
+            resp = self.connection.request(self.path, params=params)
+            return findtext(resp.object, 'IpAddress',
+                            namespace=self.namespace)
+
     def _to_nodes(self, object):
         """
         Convert response to Node object list

http://git-wip-us.apache.org/repos/asf/libcloud/blob/c726d1fb/libcloud/test/compute/fixtures/ecs/create_public_ip.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/ecs/create_public_ip.xml b/libcloud/test/compute/fixtures/ecs/create_public_ip.xml
new file mode 100644
index 0000000..e723d7f
--- /dev/null
+++ b/libcloud/test/compute/fixtures/ecs/create_public_ip.xml
@@ -0,0 +1,6 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<AllocatePublicIpAddressResponse>
+    <RequestId>F2EF6A3B-E345-46B9-931E-0EA094818567</RequestId>
+    <IpAddress>10.1.149.159</IpAddress>
+</AllocatePublicIpAddressResponse>
+

http://git-wip-us.apache.org/repos/asf/libcloud/blob/c726d1fb/libcloud/test/compute/test_ecs.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_ecs.py b/libcloud/test/compute/test_ecs.py
index d1bbae9..f610da8 100644
--- a/libcloud/test/compute/test_ecs.py
+++ b/libcloud/test/compute/test_ecs.py
@@ -58,6 +58,7 @@ class ECSDriverTestCase(LibcloudTestCase):
                                             driver=self.driver)
         self.fake_location = NodeLocation(id=self.region, name=self.region,
                                           country=None, driver=self.driver)
+        self.fake_instance_id = 'fake_instance_id'
 
     def test_list_nodes(self):
         nodes = self.driver.list_nodes()
@@ -247,6 +248,11 @@ class ECSDriverTestCase(LibcloudTestCase):
         result = self.driver.ex_stop_node(self.fake_node, ex_force_stop=True)
         self.assertTrue(result)
 
+    def test_create_public_ip(self):
+        ECSMockHttp.type = 'create_public_ip'
+        result = self.driver.create_public_ip(self.fake_instance_id)
+        self.assertTrue(result)
+
     def test_list_volumes(self):
         volumes = self.driver.list_volumes()
         self.assertEqual(2, len(volumes))
@@ -930,6 +936,10 @@ class ECSMockHttp(MockHttpTestCase):
         resp_body = self.fixtures.load('describe_zones.xml')
         return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
 
+    def _create_public_ip_AllocatePublicIpAddress(self, method, url, body, headers):
+        resp_body = self.fixtures.load('create_public_ip.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
 
 if __name__ == '__main__':
     sys.exit(unittest.main())


[17/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/voxel.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/voxel.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/voxel.py
deleted file mode 100644
index 9865027..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/voxel.py
+++ /dev/null
@@ -1,307 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-Voxel VoxCloud driver
-"""
-import datetime
-import hashlib
-
-from libcloud.utils.py3 import b
-
-from libcloud.common.base import XmlResponse, ConnectionUserAndKey
-from libcloud.common.types import InvalidCredsError
-from libcloud.compute.providers import Provider
-from libcloud.compute.types import NodeState
-from libcloud.compute.base import Node, NodeDriver
-from libcloud.compute.base import NodeSize, NodeImage, NodeLocation
-
-VOXEL_API_HOST = "api.voxel.net"
-
-
-class VoxelResponse(XmlResponse):
-    def __init__(self, response, connection):
-        self.parsed = None
-        super(VoxelResponse, self).__init__(response=response,
-                                            connection=connection)
-
-    def parse_body(self):
-        if not self.body:
-            return None
-        if not self.parsed:
-            self.parsed = super(VoxelResponse, self).parse_body()
-        return self.parsed
-
-    def parse_error(self):
-        err_list = []
-        if not self.body:
-            return None
-        if not self.parsed:
-            self.parsed = super(VoxelResponse, self).parse_body()
-        for err in self.parsed.findall('err'):
-            code = err.get('code')
-            err_list.append("(%s) %s" % (code, err.get('msg')))
-            # From voxel docs:
-            # 1: Invalid login or password
-            # 9: Permission denied: user lacks access rights for this method
-            if code == "1" or code == "9":
-                # sucks, but only way to detect
-                # bad authentication tokens so far
-                raise InvalidCredsError(err_list[-1])
-        return "\n".join(err_list)
-
-    def success(self):
-        if not self.parsed:
-            self.parsed = super(VoxelResponse, self).parse_body()
-        stat = self.parsed.get('stat')
-        if stat != "ok":
-            return False
-        return True
-
-
-class VoxelConnection(ConnectionUserAndKey):
-    """
-    Connection class for the Voxel driver
-    """
-
-    host = VOXEL_API_HOST
-    responseCls = VoxelResponse
-
-    def add_default_params(self, params):
-        params = dict([(k, v) for k, v in list(params.items())
-                       if v is not None])
-        params["key"] = self.user_id
-        params["timestamp"] = datetime.datetime.utcnow().isoformat() + "+0000"
-
-        keys = list(params.keys())
-        keys.sort()
-
-        md5 = hashlib.md5()
-        md5.update(b(self.key))
-        for key in keys:
-            if params[key]:
-                if not params[key] is None:
-                    md5.update(b("%s%s" % (key, params[key])))
-                else:
-                    md5.update(b(key))
-        params['api_sig'] = md5.hexdigest()
-        return params
-
-VOXEL_INSTANCE_TYPES = {}
-RAM_PER_CPU = 2048
-
-NODE_STATE_MAP = {
-    'IN_PROGRESS': NodeState.PENDING,
-    'QUEUED': NodeState.PENDING,
-    'SUCCEEDED': NodeState.RUNNING,
-    'shutting-down': NodeState.TERMINATED,
-    'terminated': NodeState.TERMINATED,
-    'unknown': NodeState.UNKNOWN,
-}
-
-
-class VoxelNodeDriver(NodeDriver):
-    """
-    Voxel VoxCLOUD node driver
-    """
-
-    connectionCls = VoxelConnection
-    type = Provider.VOXEL
-    name = 'Voxel VoxCLOUD'
-    website = 'http://www.voxel.net/'
-
-    def _initialize_instance_types():
-        for cpus in range(1, 14):
-            if cpus == 1:
-                name = "Single CPU"
-            else:
-                name = "%d CPUs" % cpus
-            id = "%dcpu" % cpus
-            ram = cpus * RAM_PER_CPU
-
-            VOXEL_INSTANCE_TYPES[id] = {
-                'id': id,
-                'name': name,
-                'ram': ram,
-                'disk': None,
-                'bandwidth': None,
-                'price': None}
-
-    features = {"create_node": [],
-                "list_sizes": ["variable_disk"]}
-
-    _initialize_instance_types()
-
-    def list_nodes(self):
-        params = {"method": "voxel.devices.list"}
-        result = self.connection.request('/', params=params).object
-        return self._to_nodes(result)
-
-    def list_sizes(self, location=None):
-        return [NodeSize(driver=self.connection.driver, **i)
-                for i in list(VOXEL_INSTANCE_TYPES.values())]
-
-    def list_images(self, location=None):
-        params = {"method": "voxel.images.list"}
-        result = self.connection.request('/', params=params).object
-        return self._to_images(result)
-
-    def create_node(self, **kwargs):
-        """Create Voxel Node
-
-        :keyword name: the name to assign the node (mandatory)
-        :type    name: ``str``
-
-        :keyword image: distribution to deploy
-        :type    image: :class:`NodeImage`
-
-        :keyword size: the plan size to create (mandatory)
-                       Requires size.disk (GB) to be set manually
-        :type    size: :class:`NodeSize`
-
-        :keyword location: which datacenter to create the node in
-        :type    location: :class:`NodeLocation`
-
-        :keyword ex_privateip: Backend IP address to assign to node;
-                               must be chosen from the customer's
-                               private VLAN assignment.
-        :type    ex_privateip: ``str``
-
-        :keyword ex_publicip: Public-facing IP address to assign to node;
-                              must be chosen from the customer's
-                              public VLAN assignment.
-        :type    ex_publicip: ``str``
-
-        :keyword ex_rootpass: Password for root access; generated if unset.
-        :type    ex_rootpass: ``str``
-
-        :keyword ex_consolepass: Password for remote console;
-                                 generated if unset.
-        :type    ex_consolepass: ``str``
-
-        :keyword ex_sshuser: Username for SSH access
-        :type    ex_sshuser: ``str``
-
-        :keyword ex_sshpass: Password for SSH access; generated if unset.
-        :type    ex_sshpass: ``str``
-
-        :keyword ex_voxel_access: Allow access Voxel administrative access.
-                                  Defaults to False.
-        :type    ex_voxel_access: ``bool``
-
-        :rtype: :class:`Node` or ``None``
-        """
-
-        # assert that disk > 0
-        if not kwargs["size"].disk:
-            raise ValueError("size.disk must be non-zero")
-
-        # convert voxel_access to string boolean if needed
-        voxel_access = kwargs.get("ex_voxel_access", None)
-        if voxel_access is not None:
-            voxel_access = "true" if voxel_access else "false"
-
-        params = {
-            'method': 'voxel.voxcloud.create',
-            'hostname': kwargs["name"],
-            'disk_size': int(kwargs["size"].disk),
-            'facility': kwargs["location"].id,
-            'image_id': kwargs["image"].id,
-            'processing_cores': kwargs["size"].ram / RAM_PER_CPU,
-            'backend_ip': kwargs.get("ex_privateip", None),
-            'frontend_ip': kwargs.get("ex_publicip", None),
-            'admin_password': kwargs.get("ex_rootpass", None),
-            'console_password': kwargs.get("ex_consolepass", None),
-            'ssh_username': kwargs.get("ex_sshuser", None),
-            'ssh_password': kwargs.get("ex_sshpass", None),
-            'voxel_access': voxel_access,
-        }
-
-        object = self.connection.request('/', params=params).object
-
-        if self._getstatus(object):
-            return Node(
-                id=object.findtext("device/id"),
-                name=kwargs["name"],
-                state=NODE_STATE_MAP[object.findtext("device/status")],
-                public_ips=kwargs.get("publicip", None),
-                private_ips=kwargs.get("privateip", None),
-                driver=self.connection.driver
-            )
-        else:
-            return None
-
-    def reboot_node(self, node):
-        params = {'method': 'voxel.devices.power',
-                  'device_id': node.id,
-                  'power_action': 'reboot'}
-        return self._getstatus(
-            self.connection.request('/', params=params).object)
-
-    def destroy_node(self, node):
-        params = {'method': 'voxel.voxcloud.delete',
-                  'device_id': node.id}
-        return self._getstatus(
-            self.connection.request('/', params=params).object)
-
-    def list_locations(self):
-        params = {"method": "voxel.voxcloud.facilities.list"}
-        result = self.connection.request('/', params=params).object
-        nodes = self._to_locations(result)
-        return nodes
-
-    def _getstatus(self, element):
-        status = element.attrib["stat"]
-        return status == "ok"
-
-    def _to_locations(self, object):
-        return [NodeLocation(element.attrib["label"],
-                             element.findtext("description"),
-                             element.findtext("description"),
-                             self)
-                for element in object.findall('facilities/facility')]
-
-    def _to_nodes(self, object):
-        nodes = []
-        for element in object.findall('devices/device'):
-            if element.findtext("type") == "Virtual Server":
-                try:
-                    state = self.NODE_STATE_MAP[element.attrib['status']]
-                except KeyError:
-                    state = NodeState.UNKNOWN
-
-                public_ip = private_ip = None
-                ipassignments = element.findall("ipassignments/ipassignment")
-                for ip in ipassignments:
-                    if ip.attrib["type"] == "frontend":
-                        public_ip = ip.text
-                    elif ip.attrib["type"] == "backend":
-                        private_ip = ip.text
-
-                nodes.append(Node(id=element.attrib['id'],
-                                  name=element.attrib['label'],
-                                  state=state,
-                                  public_ips=public_ip,
-                                  private_ips=private_ip,
-                                  driver=self.connection.driver))
-        return nodes
-
-    def _to_images(self, object):
-        images = []
-        for element in object.findall("images/image"):
-            images.append(NodeImage(id=element.attrib["id"],
-                                    name=element.attrib["summary"],
-                                    driver=self.connection.driver))
-        return images

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/vpsnet.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/vpsnet.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/vpsnet.py
deleted file mode 100644
index 8d026a8..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/vpsnet.py
+++ /dev/null
@@ -1,193 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-VPS.net driver
-"""
-import base64
-
-try:
-    import simplejson as json
-except ImportError:
-    import json
-
-from libcloud.utils.py3 import b
-
-from libcloud.common.base import ConnectionUserAndKey, JsonResponse
-from libcloud.common.types import InvalidCredsError, MalformedResponseError
-from libcloud.compute.providers import Provider
-from libcloud.compute.types import NodeState
-from libcloud.compute.base import Node, NodeDriver
-from libcloud.compute.base import NodeSize, NodeImage, NodeLocation
-
-API_HOST = 'api.vps.net'
-API_VERSION = 'api10json'
-
-RAM_PER_NODE = 256
-DISK_PER_NODE = 10
-BANDWIDTH_PER_NODE = 250
-
-
-class VPSNetResponse(JsonResponse):
-    def parse_body(self):
-        try:
-            return super(VPSNetResponse, self).parse_body()
-        except MalformedResponseError:
-            return self.body
-
-    def success(self):
-        # vps.net wrongly uses 406 for invalid auth creds
-        if self.status == 406 or self.status == 403:
-            raise InvalidCredsError()
-        return True
-
-    def parse_error(self):
-        try:
-            errors = super(VPSNetResponse, self).parse_body()['errors'][0]
-        except MalformedResponseError:
-            return self.body
-        else:
-            return "\n".join(errors)
-
-
-class VPSNetConnection(ConnectionUserAndKey):
-    """
-    Connection class for the VPS.net driver
-    """
-
-    host = API_HOST
-    responseCls = VPSNetResponse
-
-    allow_insecure = False
-
-    def add_default_headers(self, headers):
-        user_b64 = base64.b64encode(b('%s:%s' % (self.user_id, self.key)))
-        headers['Authorization'] = 'Basic %s' % (user_b64.decode('utf-8'))
-        return headers
-
-
-class VPSNetNodeDriver(NodeDriver):
-    """
-    VPS.net node driver
-    """
-
-    type = Provider.VPSNET
-    api_name = 'vps_net'
-    name = "vps.net"
-    website = 'http://vps.net/'
-    connectionCls = VPSNetConnection
-
-    def _to_node(self, vm):
-        if vm['running']:
-            state = NodeState.RUNNING
-        else:
-            state = NodeState.PENDING
-
-        n = Node(id=vm['id'],
-                 name=vm['label'],
-                 state=state,
-                 public_ips=[vm.get('primary_ip_address', None)],
-                 private_ips=[],
-                 extra={'slices_count': vm['slices_count']},
-                 # Number of nodes consumed by VM
-                 driver=self.connection.driver)
-        return n
-
-    def _to_image(self, image, cloud):
-        image = NodeImage(id=image['id'],
-                          name="%s: %s" % (cloud, image['label']),
-                          driver=self.connection.driver)
-
-        return image
-
-    def _to_size(self, num):
-        size = NodeSize(id=num,
-                        name="%d Node" % (num,),
-                        ram=RAM_PER_NODE * num,
-                        disk=DISK_PER_NODE,
-                        bandwidth=BANDWIDTH_PER_NODE * num,
-                        price=self._get_price_per_node(num) * num,
-                        driver=self.connection.driver)
-        return size
-
-    def _get_price_per_node(self, num):
-        single_node_price = self._get_size_price(size_id='1')
-        return num * single_node_price
-
-    def create_node(self, name, image, size, **kwargs):
-        """Create a new VPS.net node
-
-        @inherits: :class:`NodeDriver.create_node`
-
-        :keyword    ex_backups_enabled: Enable automatic backups
-        :type       ex_backups_enabled: ``bool``
-
-        :keyword    ex_fqdn:   Fully Qualified domain of the node
-        :type       ex_fqdn:   ``str``
-        """
-        headers = {'Content-Type': 'application/json'}
-        request = {'virtual_machine':
-                   {'label': name,
-                    'fqdn': kwargs.get('ex_fqdn', ''),
-                    'system_template_id': image.id,
-                    'backups_enabled': kwargs.get('ex_backups_enabled', 0),
-                    'slices_required': size.id}}
-
-        res = self.connection.request('/virtual_machines.%s' % (API_VERSION,),
-                                      data=json.dumps(request),
-                                      headers=headers,
-                                      method='POST')
-        node = self._to_node(res.object['virtual_machine'])
-        return node
-
-    def reboot_node(self, node):
-        res = self.connection.request(
-            '/virtual_machines/%s/%s.%s' % (node.id,
-                                            'reboot',
-                                            API_VERSION),
-            method="POST")
-        node = self._to_node(res.object['virtual_machine'])
-        return True
-
-    def list_sizes(self, location=None):
-        res = self.connection.request('/nodes.%s' % (API_VERSION,))
-        available_nodes = len([size for size in res.object
-                               if size['slice']['virtual_machine_id']])
-        sizes = [self._to_size(i) for i in range(1, available_nodes + 1)]
-        return sizes
-
-    def destroy_node(self, node):
-        res = self.connection.request('/virtual_machines/%s.%s'
-                                      % (node.id, API_VERSION),
-                                      method='DELETE')
-        return res.status == 200
-
-    def list_nodes(self):
-        res = self.connection.request('/virtual_machines.%s' % (API_VERSION,))
-        return [self._to_node(i['virtual_machine']) for i in res.object]
-
-    def list_images(self, location=None):
-        res = self.connection.request('/available_clouds.%s' % (API_VERSION,))
-
-        images = []
-        for cloud in res.object:
-            label = cloud['cloud']['label']
-            templates = cloud['cloud']['system_templates']
-            images.extend([self._to_image(image, label)
-                           for image in templates])
-
-        return images
-
-    def list_locations(self):
-        return [NodeLocation(0, "VPS.net Western US", 'US', self)]

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/vsphere.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/vsphere.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/vsphere.py
deleted file mode 100644
index 7a79c26..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/vsphere.py
+++ /dev/null
@@ -1,552 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-VMware vSphere driver supporting vSphere v5.5.
-
-Note: This driver requires pysphere package
-(https://pypi.python.org/pypi/pysphere) which can be installed using pip. For
-more information, please refer to the official documentation.
-"""
-
-import os
-import sys
-import atexit
-
-try:
-    import pysphere
-    pysphere
-except ImportError:
-    raise ImportError('Missing "pysphere" dependency. You can install it '
-                      'using pip - pip install pysphere')
-
-from pysphere import VIServer
-from pysphere.vi_task import VITask
-from pysphere.vi_mor import VIMor, MORTypes
-from pysphere.resources import VimService_services as VI
-from pysphere.vi_virtual_machine import VIVirtualMachine
-
-from libcloud.utils.decorators import wrap_non_libcloud_exceptions
-from libcloud.common.base import ConnectionUserAndKey
-from libcloud.common.types import LibcloudError
-from libcloud.common.types import InvalidCredsError
-from libcloud.compute.base import NodeDriver
-from libcloud.compute.base import NodeLocation
-from libcloud.compute.base import NodeImage
-from libcloud.compute.base import Node
-from libcloud.compute.types import NodeState, Provider
-from libcloud.utils.networking import is_public_subnet
-
-__all__ = [
-    'VSphereNodeDriver',
-    'VSphere_5_5_NodeDriver'
-]
-
-DEFAULT_API_VERSION = '5.5'
-DEFAULT_CONNECTION_TIMEOUT = 5  # default connection timeout in seconds
-
-
-class VSphereConnection(ConnectionUserAndKey):
-    def __init__(self, user_id, key, secure=True,
-                 host=None, port=None, url=None, timeout=None):
-        if host and url:
-            raise ValueError('host and url arguments are mutually exclusive')
-
-        if host:
-            host_or_url = host
-        elif url:
-            host_or_url = url
-        else:
-            raise ValueError('Either "host" or "url" argument must be '
-                             'provided')
-
-        self.host_or_url = host_or_url
-        self.client = None
-        super(VSphereConnection, self).__init__(user_id=user_id,
-                                                key=key, secure=secure,
-                                                host=host, port=port,
-                                                url=url, timeout=timeout)
-
-    def connect(self):
-        self.client = VIServer()
-
-        trace_file = os.environ.get('LIBCLOUD_DEBUG', None)
-
-        try:
-            self.client.connect(host=self.host_or_url, user=self.user_id,
-                                password=self.key,
-                                sock_timeout=DEFAULT_CONNECTION_TIMEOUT,
-                                trace_file=trace_file)
-        except Exception:
-            e = sys.exc_info()[1]
-            message = e.message
-            fault = getattr(e, 'fault', None)
-
-            if fault == 'InvalidLoginFault':
-                raise InvalidCredsError(message)
-
-            raise LibcloudError(value=message, driver=self.driver)
-
-        atexit.register(self.disconnect)
-
-    def disconnect(self):
-        if not self.client:
-            return
-
-        try:
-            self.client.disconnect()
-        except Exception:
-            # Ignore all the disconnect errors
-            pass
-
-    def run_client_method(self, method_name, **method_kwargs):
-        method = getattr(self.client, method_name, None)
-        return method(**method_kwargs)
-
-
-class VSphereNodeDriver(NodeDriver):
-    name = 'VMware vSphere'
-    website = 'http://www.vmware.com/products/vsphere/'
-    type = Provider.VSPHERE
-    connectionCls = VSphereConnection
-
-    NODE_STATE_MAP = {
-        'POWERED ON': NodeState.RUNNING,
-        'POWERED OFF': NodeState.STOPPED,
-        'SUSPENDED': NodeState.SUSPENDED,
-        'POWERING ON': NodeState.PENDING,
-        'POWERING OFF': NodeState.PENDING,
-        'SUSPENDING': NodeState.PENDING,
-        'RESETTING': NodeState.PENDING,
-        'BLOCKED ON MSG': NodeState.ERROR,
-        'REVERTING TO SNAPSHOT': NodeState.PENDING
-    }
-
-    def __new__(cls, username, password, secure=True, host=None, port=None,
-                url=None, api_version=DEFAULT_API_VERSION, **kwargs):
-        if cls is VSphereNodeDriver:
-            if api_version == '5.5':
-                cls = VSphere_5_5_NodeDriver
-            else:
-                raise NotImplementedError('Unsupported API version: %s' %
-                                          (api_version))
-        return super(VSphereNodeDriver, cls).__new__(cls)
-
-    def __init__(self, username, password, secure=True,
-                 host=None, port=None, url=None, timeout=None):
-        self.url = url
-        super(VSphereNodeDriver, self).__init__(key=username, secret=password,
-                                                secure=secure, host=host,
-                                                port=port, url=url)
-
-    @wrap_non_libcloud_exceptions
-    def list_locations(self):
-        """
-        List available locations.
-
-        In vSphere case, a location represents a datacenter.
-        """
-        datacenters = self.connection.client.get_datacenters()
-
-        locations = []
-        for id, name in datacenters.items():
-            location = NodeLocation(id=id, name=name, country=None,
-                                    driver=self)
-            locations.append(location)
-
-        return locations
-
-    @wrap_non_libcloud_exceptions
-    def list_images(self):
-        """
-        List available images (templates).
-        """
-        server = self.connection.client
-
-        names = ['name', 'config.uuid', 'config.template']
-        properties = server._retrieve_properties_traversal(
-            property_names=names,
-            from_node=None,
-            obj_type=MORTypes.VirtualMachine)
-
-        images = []
-        for prop in properties:
-            id = None
-            name = None
-            is_template = False
-
-            for item in prop.PropSet:
-                if item.Name == 'config.uuid':
-                    id = item.Val
-                if item.Name == 'name':
-                    name = item.Val
-                elif item.Name == 'config.template':
-                    is_template = item.Val
-
-            if is_template:
-                image = NodeImage(id=id, name=name, driver=self)
-                images.append(image)
-
-            return images
-
-    @wrap_non_libcloud_exceptions
-    def list_nodes(self):
-        vm_paths = self.connection.client.get_registered_vms()
-        nodes = self._to_nodes(vm_paths=vm_paths)
-
-        return nodes
-
-    @wrap_non_libcloud_exceptions
-    @wrap_non_libcloud_exceptions
-    def ex_clone_node(self, node, name, power_on=True, template=False):
-        """
-        Clone the provided node.
-
-        :param node: Node to clone.
-        :type node: :class:`libcloud.compute.base.Node`
-
-        :param name: Name of the new node.
-        :type name: ``str``
-
-        :param power_on: Power the new node on after being created.
-        :type power_on: ``bool``
-
-        :param template: Specifies whether or not the new virtual machine
-                         should be marked as a template.
-        :type template: ``bool``
-
-        :return: New node.
-        :rtype: :class:`libcloud.compute.base.Node`
-        """
-        vm = self._get_vm_for_node(node=node)
-        new_vm = vm.clone(name=name, power_on=power_on, template=template)
-        new_node = self._to_node(vm=new_vm)
-
-        return new_node
-
-    @wrap_non_libcloud_exceptions
-    def ex_migrate_node(self, node, resource_pool=None, host=None,
-                        priority='default'):
-        """
-        Migrate provided node to a new host or resource pool.
-
-        :param node: Node to clone.
-        :type node: :class:`libcloud.compute.base.Node`
-
-        :param resource_pool: ID of the target resource pool to migrate the
-                              node into.
-        :type resource_pool: ``str``
-
-        :param host: Target host to migrate the host to.
-        :type host: ``str``
-
-        :param priority: Migration task priority. Possible values: default,
-                         high, low.
-        :type priority: ``str``
-
-        :return: True on success.
-        :rtype: ``bool``
-        """
-        vm = self._get_vm_for_node(node=node)
-        vm.migrate(priority=priority, resource_pool=resource_pool, host=host)
-
-        return True
-
-    @wrap_non_libcloud_exceptions
-    def reboot_node(self, node):
-        vm = self._get_vm_for_node(node=node)
-        vm.reset()
-
-        return True
-
-    @wrap_non_libcloud_exceptions
-    def destroy_node(self, node, ex_remove_files=True):
-        """
-        :param ex_remove_files: Remove all the files from the datastore.
-        :type ex_remove_files: ``bool``
-        """
-        ex_remove_files = False
-        vm = self._get_vm_for_node(node=node)
-
-        server = self.connection.client
-
-        # Based on code from
-        # https://pypi.python.org/pypi/pyxenter
-        if ex_remove_files:
-            request = VI.Destroy_TaskRequestMsg()
-
-            _this = request.new__this(vm._mor)
-            _this.set_attribute_type(vm._mor.get_attribute_type())
-            request.set_element__this(_this)
-            ret = server._proxy.Destroy_Task(request)._returnval
-            task = VITask(ret, server)
-
-            # Wait for the task to finish
-            status = task.wait_for_state([task.STATE_SUCCESS,
-                                          task.STATE_ERROR])
-
-            if status == task.STATE_ERROR:
-                raise LibcloudError('Error destroying node: %s' %
-                                    (task.get_error_message()))
-        else:
-            request = VI.UnregisterVMRequestMsg()
-
-            _this = request.new__this(vm._mor)
-            _this.set_attribute_type(vm._mor.get_attribute_type())
-            request.set_element__this(_this)
-            ret = server._proxy.UnregisterVM(request)
-            task = VITask(ret, server)
-
-        return True
-
-    @wrap_non_libcloud_exceptions
-    def ex_stop_node(self, node):
-        vm = self._get_vm_for_node(node=node)
-        vm.power_off()
-
-        return True
-
-    @wrap_non_libcloud_exceptions
-    def ex_start_node(self, node):
-        vm = self._get_vm_for_node(node=node)
-        vm.power_on()
-
-        return True
-
-    @wrap_non_libcloud_exceptions
-    def ex_suspend_node(self, node):
-        vm = self._get_vm_for_node(node=node)
-        vm.suspend()
-
-        return True
-
-    @wrap_non_libcloud_exceptions
-    def ex_get_resource_pools(self):
-        """
-        Return all the available resource pools.
-
-        :rtype: ``dict``
-        """
-        result = self.connection.client.get_resource_pools()
-        return result
-
-    @wrap_non_libcloud_exceptions
-    def ex_get_resource_pool_name(self, node):
-        """
-        Retrieve resource pool name for the provided node.
-
-        :rtype: ``str``
-        """
-        vm = self._get_vm_for_node(node=node)
-        return vm.get_resource_pool_name()
-
-    @wrap_non_libcloud_exceptions
-    def ex_get_hosts(self):
-        """
-        Return all the available hosts.
-
-        :rtype: ``dict``
-        """
-        result = self.connection.client.get_hosts()
-        return result
-
-    @wrap_non_libcloud_exceptions
-    def ex_get_datastores(self):
-        """
-        Return all the available datastores.
-
-        :rtype: ``dict``
-        """
-        result = self.connection.client.get_datastores()
-        return result
-
-    @wrap_non_libcloud_exceptions
-    def ex_get_node_by_path(self, path):
-        """
-        Retrieve Node object for a VM with a provided path.
-
-        :type path: ``str``
-        :rtype: :class:`libcloud.compute.base.Node`
-        """
-        vm = self.connection.client.get_vm_by_path(path)
-        node = self._to_node(vm=vm)
-        return node
-
-    def ex_get_node_by_uuid(self, uuid):
-        """
-        Retrieve Node object for a VM with a provided uuid.
-
-        :type uuid: ``str``
-        """
-        vm = self._get_vm_for_uuid(uuid=uuid)
-        node = self._to_node(vm=vm)
-        return node
-
-    @wrap_non_libcloud_exceptions
-    def ex_get_server_type(self):
-        """
-        Return VMware installation type.
-
-        :rtype: ``str``
-        """
-        return self.connection.client.get_server_type()
-
-    @wrap_non_libcloud_exceptions
-    def ex_get_api_version(self):
-        """
-        Return API version of the vmware provider.
-
-        :rtype: ``str``
-        """
-        return self.connection.client.get_api_version()
-
-    def _get_vm_for_uuid(self, uuid, datacenter=None):
-        """
-        Retrieve VM for the provided UUID.
-
-        :type uuid: ``str``
-        """
-        server = self.connection.client
-
-        dc_list = []
-        if datacenter and VIMor.is_mor(datacenter):
-            dc_list.append(datacenter)
-        else:
-            dc = server.get_datacenters()
-            if datacenter:
-                dc_list = [k for k, v in dc.iteritems() if v == datacenter]
-            else:
-                dc_list = list(dc.iterkeys())
-
-        for mor_dc in dc_list:
-            request = VI.FindByUuidRequestMsg()
-            search_index = server._do_service_content.SearchIndex
-            mor_search_index = request.new__this(search_index)
-            mor_search_index.set_attribute_type(MORTypes.SearchIndex)
-            request.set_element__this(mor_search_index)
-
-            mor_datacenter = request.new_datacenter(mor_dc)
-            mor_datacenter.set_attribute_type(MORTypes.Datacenter)
-            request.set_element_datacenter(mor_datacenter)
-
-            request.set_element_vmSearch(True)
-            request.set_element_uuid(uuid)
-
-            try:
-                vm = server._proxy.FindByUuid(request)._returnval
-            except VI.ZSI.FaultException:
-                pass
-            else:
-                if vm:
-                    return VIVirtualMachine(server, vm)
-
-            return None
-
-    def _to_nodes(self, vm_paths):
-        nodes = []
-        for vm_path in vm_paths:
-            vm = self.connection.client.get_vm_by_path(vm_path)
-            node = self._to_node(vm=vm)
-            nodes.append(node)
-
-        return nodes
-
-    def _to_node(self, vm):
-        assert(isinstance(vm, VIVirtualMachine))
-
-        properties = vm.get_properties()
-        status = vm.get_status()
-
-        uuid = vm.properties.config.uuid
-        instance_uuid = vm.properties.config.instanceUuid
-
-        id = uuid
-        name = properties['name']
-        public_ips = []
-        private_ips = []
-
-        state = self.NODE_STATE_MAP.get(status, NodeState.UNKNOWN)
-        ip_address = properties.get('ip_address', None)
-        net = properties.get('net', [])
-        resource_pool_id = str(vm.properties.resourcePool._obj)
-
-        try:
-            operating_system = vm.properties.summary.guest.guestFullName,
-        except Exception:
-            operating_system = 'unknown'
-
-        extra = {
-            'uuid': uuid,
-            'instance_uuid': instance_uuid,
-            'path': properties['path'],
-            'resource_pool_id': resource_pool_id,
-            'hostname': properties.get('hostname', None),
-            'guest_id': properties['guest_id'],
-            'devices': properties.get('devices', {}),
-            'disks': properties.get('disks', []),
-            'net': net,
-
-            'overall_status': vm.properties.overallStatus,
-            'operating_system': operating_system,
-
-            'cpus': vm.properties.config.hardware.numCPU,
-            'memory_mb': vm.properties.config.hardware.memoryMB
-        }
-
-        # Add primary IP
-        if ip_address:
-            if is_public_subnet(ip_address):
-                public_ips.append(ip_address)
-            else:
-                private_ips.append(ip_address)
-
-        # Add other IP addresses
-        for nic in net:
-            ip_addresses = nic['ip_addresses']
-            for ip_address in ip_addresses:
-                try:
-                    is_public = is_public_subnet(ip_address)
-                except Exception:
-                    # TODO: Better support for IPv6
-                    is_public = False
-
-                if is_public:
-                    public_ips.append(ip_address)
-                else:
-                    private_ips.append(ip_address)
-
-        # Remove duplicate IPs
-        public_ips = list(set(public_ips))
-        private_ips = list(set(private_ips))
-
-        node = Node(id=id, name=name, state=state, public_ips=public_ips,
-                    private_ips=private_ips, driver=self, extra=extra)
-        return node
-
-    def _get_vm_for_node(self, node):
-        uuid = node.id
-        vm = self._get_vm_for_uuid(uuid=uuid)
-        return vm
-
-    def _ex_connection_class_kwargs(self):
-        kwargs = {
-            'url': self.url
-        }
-
-        return kwargs
-
-
-class VSphere_5_5_NodeDriver(VSphereNodeDriver):
-    name = 'VMware vSphere v5.5'

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/vultr.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/vultr.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/vultr.py
deleted file mode 100644
index 3823119..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/vultr.py
+++ /dev/null
@@ -1,210 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-Vultr Driver
-"""
-
-import time
-
-from libcloud.utils.py3 import httplib
-from libcloud.utils.py3 import urlencode
-
-from libcloud.common.base import ConnectionKey, JsonResponse
-from libcloud.compute.types import Provider, NodeState
-from libcloud.common.types import LibcloudError, InvalidCredsError
-from libcloud.compute.base import NodeDriver
-from libcloud.compute.base import Node, NodeImage, NodeSize, NodeLocation
-
-
-class VultrResponse(JsonResponse):
-    def parse_error(self):
-        if self.status == httplib.OK:
-            body = self.parse_body()
-            return body
-        elif self.status == httplib.FORBIDDEN:
-            raise InvalidCredsError(self.body)
-        else:
-            raise LibcloudError(self.body)
-
-
-class SSHKey(object):
-    def __init__(self, id, name, pub_key):
-        self.id = id
-        self.name = name
-        self.pub_key = pub_key
-
-    def __repr__(self):
-        return (('<SSHKey: id=%s, name=%s, pub_key=%s>') %
-                (self.id, self.name, self.pub_key))
-
-
-class VultrConnection(ConnectionKey):
-    """
-    Connection class for the Vultr driver.
-    """
-
-    host = 'api.vultr.com'
-    responseCls = VultrResponse
-
-    def add_default_params(self, params):
-        """
-        Add parameters that are necessary for every request
-
-        This method add ``api_key`` to
-        the request.
-        """
-        params['api_key'] = self.key
-        return params
-
-    def encode_data(self, data):
-        return urlencode(data)
-
-    def get(self, url):
-        return self.request(url)
-
-    def post(self, url, data):
-        headers = {'Content-Type': 'application/x-www-form-urlencoded'}
-        return self.request(url, data=data, headers=headers, method='POST')
-
-
-class VultrNodeDriver(NodeDriver):
-    """
-    VultrNode node driver.
-    """
-
-    connectionCls = VultrConnection
-
-    type = Provider.VULTR
-    name = 'Vultr'
-    website = 'https://www.vultr.com'
-
-    NODE_STATE_MAP = {'pending': NodeState.PENDING,
-                      'active': NodeState.RUNNING}
-
-    def list_nodes(self):
-        return self._list_resources('/v1/server/list', self._to_node)
-
-    def list_key_pairs(self):
-        """
-        List all the available SSH keys.
-        :return: Available SSH keys.
-        :rtype: ``list`` of :class:`SSHKey`
-        """
-        return self._list_resources('/v1/sshkey/list', self._to_ssh_key)
-
-    def list_locations(self):
-        return self._list_resources('/v1/regions/list', self._to_location)
-
-    def list_sizes(self):
-        return self._list_resources('/v1/plans/list', self._to_size)
-
-    def list_images(self):
-        return self._list_resources('/v1/os/list', self._to_image)
-
-    def create_node(self, name, size, image, location, ex_ssh_key_ids=None):
-        params = {'DCID': location.id, 'VPSPLANID': size.id,
-                  'OSID': image.id, 'label': name}
-
-        if ex_ssh_key_ids is not None:
-            params['SSHKEYID'] = ','.join(ex_ssh_key_ids)
-
-        result = self.connection.post('/v1/server/create', params)
-        if result.status != httplib.OK:
-            return False
-
-        subid = result.object['SUBID']
-
-        retry_count = 3
-        created_node = None
-
-        for i in range(retry_count):
-            try:
-                nodes = self.list_nodes()
-                created_node = [n for n in nodes if n.id == subid][0]
-            except IndexError:
-                time.sleep(1)
-                pass
-            else:
-                break
-
-        return created_node
-
-    def reboot_node(self, node):
-        params = {'SUBID': node.id}
-        res = self.connection.post('/v1/server/reboot', params)
-
-        return res.status == httplib.OK
-
-    def destroy_node(self, node):
-        params = {'SUBID': node.id}
-        res = self.connection.post('/v1/server/destroy', params)
-
-        return res.status == httplib.OK
-
-    def _list_resources(self, url, tranform_func):
-        data = self.connection.get(url).object
-        sorted_key = sorted(data)
-        return [tranform_func(data[key]) for key in sorted_key]
-
-    def _to_node(self, data):
-        if 'status' in data:
-            state = self.NODE_STATE_MAP.get(data['status'], NodeState.UNKNOWN)
-            if state == NodeState.RUNNING and \
-               data['power_status'] != 'running':
-                state = NodeState.STOPPED
-        else:
-            state = NodeState.UNKNOWN
-
-        if 'main_ip' in data and data['main_ip'] is not None:
-            public_ips = [data['main_ip']]
-        else:
-            public_ips = []
-
-        extra_keys = []
-        extra = {}
-        for key in extra_keys:
-            if key in data:
-                extra[key] = data[key]
-
-        node = Node(id=data['SUBID'], name=data['label'], state=state,
-                    public_ips=public_ips, private_ips=None, extra=extra,
-                    driver=self)
-
-        return node
-
-    def _to_location(self, data):
-        return NodeLocation(id=data['DCID'], name=data['name'],
-                            country=data['country'], driver=self)
-
-    def _to_size(self, data):
-        extra = {'vcpu_count': int(data['vcpu_count'])}
-        ram = int(data['ram'])
-        disk = int(data['disk'])
-        bandwidth = float(data['bandwidth'])
-        price = float(data['price_per_month'])
-
-        return NodeSize(id=data['VPSPLANID'], name=data['name'],
-                        ram=ram, disk=disk,
-                        bandwidth=bandwidth, price=price,
-                        extra=extra, driver=self)
-
-    def _to_image(self, data):
-        extra = {'arch': data['arch'], 'family': data['family']}
-        return NodeImage(id=data['OSID'], name=data['name'], extra=extra,
-                         driver=self)
-
-    def _to_ssh_key(self, data):
-        return SSHKey(id=data['SSHKEYID'], name=data['name'],
-                      pub_key=data['ssh_key'])

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/providers.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/providers.py b/apache-libcloud-1.0.0rc2/libcloud/compute/providers.py
deleted file mode 100644
index 6bf4814..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/providers.py
+++ /dev/null
@@ -1,158 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-Provider related utilities
-"""
-
-from libcloud.compute.types import Provider
-from libcloud.common.providers import get_driver as _get_provider_driver
-from libcloud.common.providers import set_driver as _set_provider_driver
-from libcloud.compute.types import OLD_CONSTANT_TO_NEW_MAPPING
-from libcloud.compute.deprecated import DEPRECATED_DRIVERS
-
-__all__ = [
-    "Provider",
-    "DRIVERS",
-    "get_driver"]
-
-DRIVERS = {
-    Provider.AZURE:
-    ('libcloud.compute.drivers.azure', 'AzureNodeDriver'),
-    Provider.AZURE_ARM:
-    ('libcloud.compute.drivers.azure_arm', 'AzureNodeDriver'),
-    Provider.DUMMY:
-    ('libcloud.compute.drivers.dummy', 'DummyNodeDriver'),
-    Provider.EC2:
-    ('libcloud.compute.drivers.ec2', 'EC2NodeDriver'),
-    Provider.ECP:
-    ('libcloud.compute.drivers.ecp', 'ECPNodeDriver'),
-    Provider.ELASTICHOSTS:
-    ('libcloud.compute.drivers.elastichosts', 'ElasticHostsNodeDriver'),
-    Provider.SKALICLOUD:
-    ('libcloud.compute.drivers.skalicloud', 'SkaliCloudNodeDriver'),
-    Provider.SERVERLOVE:
-    ('libcloud.compute.drivers.serverlove', 'ServerLoveNodeDriver'),
-    Provider.CLOUDSIGMA:
-    ('libcloud.compute.drivers.cloudsigma', 'CloudSigmaNodeDriver'),
-    Provider.GCE:
-    ('libcloud.compute.drivers.gce', 'GCENodeDriver'),
-    Provider.GOGRID:
-    ('libcloud.compute.drivers.gogrid', 'GoGridNodeDriver'),
-    Provider.RACKSPACE:
-    ('libcloud.compute.drivers.rackspace', 'RackspaceNodeDriver'),
-    Provider.RACKSPACE_FIRST_GEN:
-    ('libcloud.compute.drivers.rackspace', 'RackspaceFirstGenNodeDriver'),
-    Provider.KILI:
-    ('libcloud.compute.drivers.kili', 'KiliCloudNodeDriver'),
-    Provider.VPSNET:
-    ('libcloud.compute.drivers.vpsnet', 'VPSNetNodeDriver'),
-    Provider.LINODE:
-    ('libcloud.compute.drivers.linode', 'LinodeNodeDriver'),
-    Provider.RIMUHOSTING:
-    ('libcloud.compute.drivers.rimuhosting', 'RimuHostingNodeDriver'),
-    Provider.VOXEL:
-    ('libcloud.compute.drivers.voxel', 'VoxelNodeDriver'),
-    Provider.SOFTLAYER:
-    ('libcloud.compute.drivers.softlayer', 'SoftLayerNodeDriver'),
-    Provider.EUCALYPTUS:
-    ('libcloud.compute.drivers.ec2', 'EucNodeDriver'),
-    Provider.OPENNEBULA:
-    ('libcloud.compute.drivers.opennebula', 'OpenNebulaNodeDriver'),
-    Provider.BRIGHTBOX:
-    ('libcloud.compute.drivers.brightbox', 'BrightboxNodeDriver'),
-    Provider.NIMBUS:
-    ('libcloud.compute.drivers.ec2', 'NimbusNodeDriver'),
-    Provider.BLUEBOX:
-    ('libcloud.compute.drivers.bluebox', 'BlueboxNodeDriver'),
-    Provider.GANDI:
-    ('libcloud.compute.drivers.gandi', 'GandiNodeDriver'),
-    Provider.DIMENSIONDATA:
-    ('libcloud.compute.drivers.dimensiondata', 'DimensionDataNodeDriver'),
-    Provider.OPENSTACK:
-    ('libcloud.compute.drivers.openstack', 'OpenStackNodeDriver'),
-    Provider.VCLOUD:
-    ('libcloud.compute.drivers.vcloud', 'VCloudNodeDriver'),
-    Provider.TERREMARK:
-    ('libcloud.compute.drivers.vcloud', 'TerremarkDriver'),
-    Provider.CLOUDSTACK:
-    ('libcloud.compute.drivers.cloudstack', 'CloudStackNodeDriver'),
-    Provider.LIBVIRT:
-    ('libcloud.compute.drivers.libvirt_driver', 'LibvirtNodeDriver'),
-    Provider.JOYENT:
-    ('libcloud.compute.drivers.joyent', 'JoyentNodeDriver'),
-    Provider.VCL:
-    ('libcloud.compute.drivers.vcl', 'VCLNodeDriver'),
-    Provider.KTUCLOUD:
-    ('libcloud.compute.drivers.ktucloud', 'KTUCloudNodeDriver'),
-    Provider.HOSTVIRTUAL:
-    ('libcloud.compute.drivers.hostvirtual', 'HostVirtualNodeDriver'),
-    Provider.ABIQUO:
-    ('libcloud.compute.drivers.abiquo', 'AbiquoNodeDriver'),
-    Provider.DIGITAL_OCEAN:
-    ('libcloud.compute.drivers.digitalocean', 'DigitalOceanNodeDriver'),
-    Provider.NEPHOSCALE:
-    ('libcloud.compute.drivers.nephoscale', 'NephoscaleNodeDriver'),
-    Provider.EXOSCALE:
-    ('libcloud.compute.drivers.exoscale', 'ExoscaleNodeDriver'),
-    Provider.IKOULA:
-    ('libcloud.compute.drivers.ikoula', 'IkoulaNodeDriver'),
-    Provider.OUTSCALE_SAS:
-    ('libcloud.compute.drivers.ec2', 'OutscaleSASNodeDriver'),
-    Provider.OUTSCALE_INC:
-    ('libcloud.compute.drivers.ec2', 'OutscaleINCNodeDriver'),
-    Provider.VSPHERE:
-    ('libcloud.compute.drivers.vsphere', 'VSphereNodeDriver'),
-    Provider.PROFIT_BRICKS:
-    ('libcloud.compute.drivers.profitbricks', 'ProfitBricksNodeDriver'),
-    Provider.VULTR:
-    ('libcloud.compute.drivers.vultr', 'VultrNodeDriver'),
-    Provider.AURORACOMPUTE:
-    ('libcloud.compute.drivers.auroracompute', 'AuroraComputeNodeDriver'),
-    Provider.CLOUDWATT:
-    ('libcloud.compute.drivers.cloudwatt', 'CloudwattNodeDriver'),
-    Provider.PACKET:
-    ('libcloud.compute.drivers.packet', 'PacketNodeDriver'),
-    Provider.ONAPP:
-    ('libcloud.compute.drivers.onapp', 'OnAppNodeDriver'),
-    Provider.RUNABOVE:
-    ('libcloud.compute.drivers.runabove', 'RunAboveNodeDriver'),
-    Provider.INTERNETSOLUTIONS:
-    ('libcloud.compute.drivers.internetsolutions',
-     'InternetSolutionsNodeDriver'),
-    Provider.INDOSAT:
-    ('libcloud.compute.drivers.indosat', 'IndosatNodeDriver'),
-    Provider.MEDONE:
-    ('libcloud.compute.drivers.medone', 'MedOneNodeDriver'),
-    Provider.BSNL:
-    ('libcloud.compute.drivers.bsnl', 'BSNLNodeDriver'),
-    Provider.CISCOCCS:
-    ('libcloud.compute.drivers.ciscoccs', 'CiscoCCSNodeDriver'),
-    Provider.NTTA:
-    ('libcloud.compute.drivers.ntta', 'NTTAmericaNodeDriver'),
-    Provider.ALIYUN_ECS:
-    ('libcloud.compute.drivers.ecs', 'ECSDriver'),
-}
-
-
-def get_driver(provider):
-    deprecated_constants = OLD_CONSTANT_TO_NEW_MAPPING
-    return _get_provider_driver(drivers=DRIVERS, provider=provider,
-                                deprecated_providers=DEPRECATED_DRIVERS,
-                                deprecated_constants=deprecated_constants)
-
-
-def set_driver(provider, module, klass):
-    return _set_provider_driver(drivers=DRIVERS, provider=provider,
-                                module=module, klass=klass)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/ssh.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/ssh.py b/apache-libcloud-1.0.0rc2/libcloud/compute/ssh.py
deleted file mode 100644
index c65aab2..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/ssh.py
+++ /dev/null
@@ -1,568 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-Wraps multiple ways to communicate over SSH.
-"""
-
-have_paramiko = False
-
-try:
-    import paramiko
-    have_paramiko = True
-except ImportError:
-    pass
-
-# Depending on your version of Paramiko, it may cause a deprecation
-# warning on Python 2.6.
-# Ref: https://bugs.launchpad.net/paramiko/+bug/392973
-
-import os
-import time
-import subprocess
-import logging
-import warnings
-
-from os.path import split as psplit
-from os.path import join as pjoin
-
-from libcloud.utils.logging import ExtraLogFormatter
-from libcloud.utils.py3 import StringIO
-from libcloud.utils.py3 import b
-
-__all__ = [
-    'BaseSSHClient',
-    'ParamikoSSHClient',
-    'ShellOutSSHClient',
-
-    'SSHCommandTimeoutError'
-]
-
-
-class SSHCommandTimeoutError(Exception):
-    """
-    Exception which is raised when an SSH command times out.
-    """
-    def __init__(self, cmd, timeout):
-        self.cmd = cmd
-        self.timeout = timeout
-        message = 'Command didn\'t finish in %s seconds' % (timeout)
-        super(SSHCommandTimeoutError, self).__init__(message)
-
-    def __repr__(self):
-        return ('<SSHCommandTimeoutError: cmd="%s",timeout=%s)>' %
-                (self.cmd, self.timeout))
-
-    def __str__(self):
-        return self.message
-
-
-class BaseSSHClient(object):
-    """
-    Base class representing a connection over SSH/SCP to a remote node.
-    """
-
-    def __init__(self, hostname, port=22, username='root', password=None,
-                 key=None, key_files=None, timeout=None):
-        """
-        :type hostname: ``str``
-        :keyword hostname: Hostname or IP address to connect to.
-
-        :type port: ``int``
-        :keyword port: TCP port to communicate on, defaults to 22.
-
-        :type username: ``str``
-        :keyword username: Username to use, defaults to root.
-
-        :type password: ``str``
-        :keyword password: Password to authenticate with or a password used
-                           to unlock a private key if a password protected key
-                           is used.
-
-        :param key: Deprecated in favor of ``key_files`` argument.
-
-        :type key_files: ``str`` or ``list``
-        :keyword key_files: A list of paths to the private key files to use.
-        """
-        if key is not None:
-            message = ('You are using deprecated "key" argument which has '
-                       'been replaced with "key_files" argument')
-            warnings.warn(message, DeprecationWarning)
-
-            # key_files has precedent
-            key_files = key if not key_files else key_files
-
-        self.hostname = hostname
-        self.port = port
-        self.username = username
-        self.password = password
-        self.key_files = key_files
-        self.timeout = timeout
-
-    def connect(self):
-        """
-        Connect to the remote node over SSH.
-
-        :return: True if the connection has been successfully established,
-                 False otherwise.
-        :rtype: ``bool``
-        """
-        raise NotImplementedError(
-            'connect not implemented for this ssh client')
-
-    def put(self, path, contents=None, chmod=None, mode='w'):
-        """
-        Upload a file to the remote node.
-
-        :type path: ``str``
-        :keyword path: File path on the remote node.
-
-        :type contents: ``str``
-        :keyword contents: File Contents.
-
-        :type chmod: ``int``
-        :keyword chmod: chmod file to this after creation.
-
-        :type mode: ``str``
-        :keyword mode: Mode in which the file is opened.
-
-        :return: Full path to the location where a file has been saved.
-        :rtype: ``str``
-        """
-        raise NotImplementedError(
-            'put not implemented for this ssh client')
-
-    def delete(self, path):
-        """
-        Delete/Unlink a file on the remote node.
-
-        :type path: ``str``
-        :keyword path: File path on the remote node.
-
-        :return: True if the file has been successfully deleted, False
-                 otherwise.
-        :rtype: ``bool``
-        """
-        raise NotImplementedError(
-            'delete not implemented for this ssh client')
-
-    def run(self, cmd):
-        """
-        Run a command on a remote node.
-
-        :type cmd: ``str``
-        :keyword cmd: Command to run.
-
-        :return ``list`` of [stdout, stderr, exit_status]
-        """
-        raise NotImplementedError(
-            'run not implemented for this ssh client')
-
-    def close(self):
-        """
-        Shutdown connection to the remote node.
-
-        :return: True if the connection has been successfully closed, False
-                 otherwise.
-        :rtype: ``bool``
-        """
-        raise NotImplementedError(
-            'close not implemented for this ssh client')
-
-    def _get_and_setup_logger(self):
-        logger = logging.getLogger('libcloud.compute.ssh')
-        path = os.getenv('LIBCLOUD_DEBUG')
-
-        if path:
-            handler = logging.FileHandler(path)
-            handler.setFormatter(ExtraLogFormatter())
-            logger.addHandler(handler)
-            logger.setLevel(logging.DEBUG)
-
-        return logger
-
-
-class ParamikoSSHClient(BaseSSHClient):
-    """
-    A SSH Client powered by Paramiko.
-    """
-
-    # Maximum number of bytes to read at once from a socket
-    CHUNK_SIZE = 4096
-
-    # How long to sleep while waiting for command to finish
-    SLEEP_DELAY = 1.5
-
-    def __init__(self, hostname, port=22, username='root', password=None,
-                 key=None, key_files=None, key_material=None, timeout=None):
-        """
-        Authentication is always attempted in the following order:
-
-        - The key passed in (if key is provided)
-        - Any key we can find through an SSH agent (only if no password and
-          key is provided)
-        - Any "id_rsa" or "id_dsa" key discoverable in ~/.ssh/ (only if no
-          password and key is provided)
-        - Plain username/password auth, if a password was given (if password is
-          provided)
-        """
-        if key_files and key_material:
-            raise ValueError(('key_files and key_material arguments are '
-                              'mutually exclusive'))
-
-        super(ParamikoSSHClient, self).__init__(hostname=hostname, port=port,
-                                                username=username,
-                                                password=password,
-                                                key=key,
-                                                key_files=key_files,
-                                                timeout=timeout)
-
-        self.key_material = key_material
-
-        self.client = paramiko.SSHClient()
-        self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
-        self.logger = self._get_and_setup_logger()
-
-    def connect(self):
-        conninfo = {'hostname': self.hostname,
-                    'port': self.port,
-                    'username': self.username,
-                    'allow_agent': False,
-                    'look_for_keys': False}
-
-        if self.password:
-            conninfo['password'] = self.password
-
-        if self.key_files:
-            conninfo['key_filename'] = self.key_files
-
-        if self.key_material:
-            conninfo['pkey'] = self._get_pkey_object(key=self.key_material)
-
-        if not self.password and not (self.key_files or self.key_material):
-            conninfo['allow_agent'] = True
-            conninfo['look_for_keys'] = True
-
-        if self.timeout:
-            conninfo['timeout'] = self.timeout
-
-        extra = {'_hostname': self.hostname, '_port': self.port,
-                 '_username': self.username, '_timeout': self.timeout}
-        self.logger.debug('Connecting to server', extra=extra)
-
-        self.client.connect(**conninfo)
-        return True
-
-    def put(self, path, contents=None, chmod=None, mode='w'):
-        extra = {'_path': path, '_mode': mode, '_chmod': chmod}
-        self.logger.debug('Uploading file', extra=extra)
-
-        sftp = self.client.open_sftp()
-        # less than ideal, but we need to mkdir stuff otherwise file() fails
-        head, tail = psplit(path)
-
-        if path[0] == "/":
-            sftp.chdir("/")
-        else:
-            # Relative path - start from a home directory (~)
-            sftp.chdir('.')
-
-        for part in head.split("/"):
-            if part != "":
-                try:
-                    sftp.mkdir(part)
-                except IOError:
-                    # so, there doesn't seem to be a way to
-                    # catch EEXIST consistently *sigh*
-                    pass
-                sftp.chdir(part)
-
-        cwd = sftp.getcwd()
-
-        ak = sftp.file(tail, mode=mode)
-        ak.write(contents)
-        if chmod is not None:
-            ak.chmod(chmod)
-        ak.close()
-        sftp.close()
-
-        if path[0] == '/':
-            file_path = path
-        else:
-            file_path = pjoin(cwd, path)
-
-        return file_path
-
-    def delete(self, path):
-        extra = {'_path': path}
-        self.logger.debug('Deleting file', extra=extra)
-
-        sftp = self.client.open_sftp()
-        sftp.unlink(path)
-        sftp.close()
-        return True
-
-    def run(self, cmd, timeout=None):
-        """
-        Note: This function is based on paramiko's exec_command()
-        method.
-
-        :param timeout: How long to wait (in seconds) for the command to
-                        finish (optional).
-        :type timeout: ``float``
-        """
-        extra = {'_cmd': cmd}
-        self.logger.debug('Executing command', extra=extra)
-
-        # Use the system default buffer size
-        bufsize = -1
-
-        transport = self.client.get_transport()
-        chan = transport.open_session()
-
-        start_time = time.time()
-        chan.exec_command(cmd)
-
-        stdout = StringIO()
-        stderr = StringIO()
-
-        # Create a stdin file and immediately close it to prevent any
-        # interactive script from hanging the process.
-        stdin = chan.makefile('wb', bufsize)
-        stdin.close()
-
-        # Receive all the output
-        # Note #1: This is used instead of chan.makefile approach to prevent
-        # buffering issues and hanging if the executed command produces a lot
-        # of output.
-        #
-        # Note #2: If you are going to remove "ready" checks inside the loop
-        # you are going to have a bad time. Trying to consume from a channel
-        # which is not ready will block for indefinitely.
-        exit_status_ready = chan.exit_status_ready()
-
-        if exit_status_ready:
-            # It's possible that some data is already available when exit
-            # status is ready
-            stdout.write(self._consume_stdout(chan).getvalue())
-            stderr.write(self._consume_stderr(chan).getvalue())
-
-        while not exit_status_ready:
-            current_time = time.time()
-            elapsed_time = (current_time - start_time)
-
-            if timeout and (elapsed_time > timeout):
-                # TODO: Is this the right way to clean up?
-                chan.close()
-
-                raise SSHCommandTimeoutError(cmd=cmd, timeout=timeout)
-
-            stdout.write(self._consume_stdout(chan).getvalue())
-            stderr.write(self._consume_stderr(chan).getvalue())
-
-            # We need to check the exist status here, because the command could
-            # print some output and exit during this sleep below.
-            exit_status_ready = chan.exit_status_ready()
-
-            if exit_status_ready:
-                break
-
-            # Short sleep to prevent busy waiting
-            time.sleep(self.SLEEP_DELAY)
-
-        # Receive the exit status code of the command we ran.
-        status = chan.recv_exit_status()
-
-        stdout = stdout.getvalue()
-        stderr = stderr.getvalue()
-
-        extra = {'_status': status, '_stdout': stdout, '_stderr': stderr}
-        self.logger.debug('Command finished', extra=extra)
-
-        return [stdout, stderr, status]
-
-    def close(self):
-        self.logger.debug('Closing server connection')
-
-        self.client.close()
-        return True
-
-    def _consume_stdout(self, chan):
-        """
-        Try to consume stdout data from chan if it's receive ready.
-        """
-        stdout = self._consume_data_from_channel(
-            chan=chan,
-            recv_method=chan.recv,
-            recv_ready_method=chan.recv_ready)
-        return stdout
-
-    def _consume_stderr(self, chan):
-        """
-        Try to consume stderr data from chan if it's receive ready.
-        """
-        stderr = self._consume_data_from_channel(
-            chan=chan,
-            recv_method=chan.recv_stderr,
-            recv_ready_method=chan.recv_stderr_ready)
-        return stderr
-
-    def _consume_data_from_channel(self, chan, recv_method, recv_ready_method):
-        """
-        Try to consume data from the provided channel.
-
-        Keep in mind that data is only consumed if the channel is receive
-        ready.
-        """
-        result = StringIO()
-        result_bytes = bytearray()
-
-        if recv_ready_method():
-            data = recv_method(self.CHUNK_SIZE)
-            result_bytes += b(data)
-
-            while data:
-                ready = recv_ready_method()
-
-                if not ready:
-                    break
-
-                data = recv_method(self.CHUNK_SIZE)
-                result_bytes += b(data)
-
-        # We only decode data at the end because a single chunk could contain
-        # a part of multi byte UTF-8 character (whole multi bytes character
-        # could be split over two chunks)
-        result.write(result_bytes.decode('utf-8'))
-        return result
-
-    def _get_pkey_object(self, key):
-        """
-        Try to detect private key type and return paramiko.PKey object.
-        """
-
-        for cls in [paramiko.RSAKey, paramiko.DSSKey, paramiko.ECDSAKey]:
-            try:
-                key = cls.from_private_key(StringIO(key))
-            except paramiko.ssh_exception.SSHException:
-                # Invalid key, try other key type
-                pass
-            else:
-                return key
-
-        msg = ('Invalid or unsupported key type (only RSA, DSS and ECDSA keys'
-               ' are supported)')
-        raise paramiko.ssh_exception.SSHException(msg)
-
-
-class ShellOutSSHClient(BaseSSHClient):
-    """
-    This client shells out to "ssh" binary to run commands on the remote
-    server.
-
-    Note: This client should not be used in production.
-    """
-
-    def __init__(self, hostname, port=22, username='root', password=None,
-                 key=None, key_files=None, timeout=None):
-        super(ShellOutSSHClient, self).__init__(hostname=hostname,
-                                                port=port, username=username,
-                                                password=password,
-                                                key=key,
-                                                key_files=key_files,
-                                                timeout=timeout)
-        if self.password:
-            raise ValueError('ShellOutSSHClient only supports key auth')
-
-        child = subprocess.Popen(['ssh'], stdout=subprocess.PIPE,
-                                 stderr=subprocess.PIPE)
-        child.communicate()
-
-        if child.returncode == 127:
-            raise ValueError('ssh client is not available')
-
-        self.logger = self._get_and_setup_logger()
-
-    def connect(self):
-        """
-        This client doesn't support persistent connections establish a new
-        connection every time "run" method is called.
-        """
-        return True
-
-    def run(self, cmd):
-        return self._run_remote_shell_command([cmd])
-
-    def put(self, path, contents=None, chmod=None, mode='w'):
-        if mode == 'w':
-            redirect = '>'
-        elif mode == 'a':
-            redirect = '>>'
-        else:
-            raise ValueError('Invalid mode: ' + mode)
-
-        cmd = ['echo "%s" %s %s' % (contents, redirect, path)]
-        self._run_remote_shell_command(cmd)
-        return path
-
-    def delete(self, path):
-        cmd = ['rm', '-rf', path]
-        self._run_remote_shell_command(cmd)
-        return True
-
-    def close(self):
-        return True
-
-    def _get_base_ssh_command(self):
-        cmd = ['ssh']
-
-        if self.key_files:
-            cmd += ['-i', self.key_files]
-
-        if self.timeout:
-            cmd += ['-oConnectTimeout=%s' % (self.timeout)]
-
-        cmd += ['%s@%s' % (self.username, self.hostname)]
-
-        return cmd
-
-    def _run_remote_shell_command(self, cmd):
-        """
-        Run a command on a remote server.
-
-        :param      cmd: Command to run.
-        :type       cmd: ``list`` of ``str``
-
-        :return: Command stdout, stderr and status code.
-        :rtype: ``tuple``
-        """
-        base_cmd = self._get_base_ssh_command()
-        full_cmd = base_cmd + [' '.join(cmd)]
-
-        self.logger.debug('Executing command: "%s"' % (' '.join(full_cmd)))
-
-        child = subprocess.Popen(full_cmd, stdout=subprocess.PIPE,
-                                 stderr=subprocess.PIPE)
-        stdout, stderr = child.communicate()
-        return (stdout, stderr, child.returncode)
-
-
-class MockSSHClient(BaseSSHClient):
-    pass
-
-
-SSHClient = ParamikoSSHClient
-if not have_paramiko:
-    SSHClient = MockSSHClient

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/types.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/types.py b/apache-libcloud-1.0.0rc2/libcloud/compute/types.py
deleted file mode 100644
index 9e96575..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/types.py
+++ /dev/null
@@ -1,358 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-Base types used by other parts of libcloud
-"""
-
-from libcloud.common.types import LibcloudError, MalformedResponseError
-from libcloud.common.types import InvalidCredsError, InvalidCredsException
-
-__all__ = [
-    "Provider",
-    "NodeState",
-    "DeploymentError",
-    "DeploymentException",
-
-    # @@TR: should the unused imports below be exported?
-    "LibcloudError",
-    "MalformedResponseError",
-    "InvalidCredsError",
-    "InvalidCredsException",
-
-    "OLD_CONSTANT_TO_NEW_MAPPING"
-]
-
-
-class Type(object):
-    @classmethod
-    def tostring(cls, value):
-        """Return the string representation of the state object attribute
-        :param str value: the state object to turn into string
-        :return: the uppercase string that represents the state object
-        :rtype: str
-        """
-        return value.upper()
-
-    @classmethod
-    def fromstring(cls, value):
-        """Return the state object attribute that matches the string
-        :param str value: the string to look up
-        :return: the state object attribute that matches the string
-        :rtype: str
-        """
-        return getattr(cls, value.upper(), None)
-
-
-class Provider(Type):
-    """
-    Defines for each of the supported providers
-
-    :cvar DUMMY: Example provider
-    :cvar EC2_US_EAST: Amazon AWS US N. Virgina
-    :cvar EC2_US_WEST: Amazon AWS US N. California
-    :cvar EC2_EU_WEST: Amazon AWS EU Ireland
-    :cvar RACKSPACE: Rackspace next-gen OpenStack based Cloud Servers
-    :cvar RACKSPACE_FIRST_GEN: Rackspace First Gen Cloud Servers
-    :cvar GCE: Google Compute Engine
-    :cvar GOGRID: GoGrid
-    :cvar VPSNET: VPS.net
-    :cvar LINODE: Linode.com
-    :cvar VCLOUD: vmware vCloud
-    :cvar RIMUHOSTING: RimuHosting.com
-    :cvar ECP: Enomaly
-    :cvar IBM: IBM Developer Cloud
-    :cvar OPENNEBULA: OpenNebula.org
-    :cvar ELASTICHOSTS: ElasticHosts.com
-    :cvar CLOUDSIGMA: CloudSigma
-    :cvar NIMBUS: Nimbus
-    :cvar BLUEBOX: Bluebox
-    :cvar OPSOURCE: Opsource Cloud
-    :cvar DIMENSIONDATA: Dimension Data Cloud
-    :cvar NINEFOLD: Ninefold
-    :cvar TERREMARK: Terremark
-    :cvar EC2_US_WEST_OREGON: Amazon AWS US West 2 (Oregon)
-    :cvar CLOUDSTACK: CloudStack
-    :cvar CLOUDSIGMA_US: CloudSigma US Las Vegas
-    :cvar LIBVIRT: Libvirt driver
-    :cvar JOYENT: Joyent driver
-    :cvar VCL: VCL driver
-    :cvar KTUCLOUD: kt ucloud driver
-    :cvar GRIDSPOT: Gridspot driver
-    :cvar ABIQUO: Abiquo driver
-    :cvar NEPHOSCALE: NephoScale driver
-    :cvar EXOSCALE: Exoscale driver.
-    :cvar IKOULA: Ikoula driver.
-    :cvar OUTSCALE_SAS: Outscale SAS driver.
-    :cvar OUTSCALE_INC: Outscale INC driver.
-    :cvar PROFIT_BRICKS: ProfitBricks driver.
-    :cvar VULTR: vultr driver.
-    :cvar AZURE: Azure Service Manager (classic) driver.
-    :cvar AZURE_ARM: Azure Resource Manager (modern) driver.
-    :cvar AURORACOMPUTE: Aurora Compute driver.
-    :cvar ALIYUN_ECS: Aliyun ECS driver.
-    """
-    AZURE = 'azure'
-    AZURE_ARM = 'azure_arm'
-    DUMMY = 'dummy'
-    EC2 = 'ec2'
-    RACKSPACE = 'rackspace'
-    GCE = 'gce'
-    GOGRID = 'gogrid'
-    VPSNET = 'vpsnet'
-    LINODE = 'linode'
-    VCLOUD = 'vcloud'
-    RIMUHOSTING = 'rimuhosting'
-    VOXEL = 'voxel'
-    SOFTLAYER = 'softlayer'
-    EUCALYPTUS = 'eucalyptus'
-    ECP = 'ecp'
-    IBM = 'ibm'
-    OPENNEBULA = 'opennebula'
-    ELASTICHOSTS = 'elastichosts'
-    BRIGHTBOX = 'brightbox'
-    CLOUDSIGMA = 'cloudsigma'
-    NIMBUS = 'nimbus'
-    BLUEBOX = 'bluebox'
-    GANDI = 'gandi'
-    OPSOURCE = 'opsource'
-    DIMENSIONDATA = 'dimensiondata'
-    OPENSTACK = 'openstack'
-    SKALICLOUD = 'skalicloud'
-    SERVERLOVE = 'serverlove'
-    NINEFOLD = 'ninefold'
-    TERREMARK = 'terremark'
-    CLOUDSTACK = 'cloudstack'
-    LIBVIRT = 'libvirt'
-    JOYENT = 'joyent'
-    VCL = 'vcl'
-    KTUCLOUD = 'ktucloud'
-    GRIDSPOT = 'gridspot'
-    RACKSPACE_FIRST_GEN = 'rackspace_first_gen'
-    HOSTVIRTUAL = 'hostvirtual'
-    ABIQUO = 'abiquo'
-    DIGITAL_OCEAN = 'digitalocean'
-    NEPHOSCALE = 'nephoscale'
-    CLOUDFRAMES = 'cloudframes'
-    EXOSCALE = 'exoscale'
-    IKOULA = 'ikoula'
-    OUTSCALE_SAS = 'outscale_sas'
-    OUTSCALE_INC = 'outscale_inc'
-    VSPHERE = 'vsphere'
-    PROFIT_BRICKS = 'profitbricks'
-    VULTR = 'vultr'
-    AURORACOMPUTE = 'aurora_compute'
-    CLOUDWATT = 'cloudwatt'
-    PACKET = 'packet'
-    RUNABOVE = 'runabove'
-    INTERNETSOLUTIONS = 'internetsolutions'
-    INDOSAT = 'indosat'
-    BSNL = 'bsnl'
-    NTTA = 'ntta'
-    MEDONE = 'medone'
-    CISCOCCS = 'ciscoccs'
-    ALIYUN_ECS = 'aliyun_ecs'
-
-    # OpenStack based providers
-    HPCLOUD = 'hpcloud'
-    CLOUDWATT = 'cloudwatt'
-    KILI = 'kili'
-    ONAPP = 'onapp'
-
-    # Deprecated constants which aren't supported anymore
-    RACKSPACE_UK = 'rackspace_uk'
-    RACKSPACE_NOVA_BETA = 'rackspace_nova_beta'
-    RACKSPACE_NOVA_DFW = 'rackspace_nova_dfw'
-    RACKSPACE_NOVA_LON = 'rackspace_nova_lon'
-    RACKSPACE_NOVA_ORD = 'rackspace_nova_ord'
-
-    EC2_US_EAST = 'ec2_us_east'
-    EC2_EU = 'ec2_eu_west'  # deprecated name
-    EC2_EU_WEST = 'ec2_eu_west'
-    EC2_US_WEST = 'ec2_us_west'
-    EC2_AP_SOUTHEAST = 'ec2_ap_southeast'
-    EC2_AP_NORTHEAST = 'ec2_ap_northeast'
-    EC2_AP_NORTHEAST1 = 'ec2_ap_northeast_1'
-    EC2_AP_NORTHEAST2 = 'ec2_ap_northeast_2'
-    EC2_US_WEST_OREGON = 'ec2_us_west_oregon'
-    EC2_SA_EAST = 'ec2_sa_east'
-    EC2_AP_SOUTHEAST2 = 'ec2_ap_southeast_2'
-
-    ELASTICHOSTS_UK1 = 'elastichosts_uk1'
-    ELASTICHOSTS_UK2 = 'elastichosts_uk2'
-    ELASTICHOSTS_US1 = 'elastichosts_us1'
-    ELASTICHOSTS_US2 = 'elastichosts_us2'
-    ELASTICHOSTS_US3 = 'elastichosts_us3'
-    ELASTICHOSTS_CA1 = 'elastichosts_ca1'
-    ELASTICHOSTS_AU1 = 'elastichosts_au1'
-    ELASTICHOSTS_CN1 = 'elastichosts_cn1'
-
-    CLOUDSIGMA_US = 'cloudsigma_us'
-
-    # Removed
-    # SLICEHOST = 'slicehost'
-
-
-DEPRECATED_RACKSPACE_PROVIDERS = [Provider.RACKSPACE_UK,
-                                  Provider.RACKSPACE_NOVA_BETA,
-                                  Provider.RACKSPACE_NOVA_DFW,
-                                  Provider.RACKSPACE_NOVA_LON,
-                                  Provider.RACKSPACE_NOVA_ORD]
-OLD_CONSTANT_TO_NEW_MAPPING = {
-    # Rackspace
-    Provider.RACKSPACE_UK: Provider.RACKSPACE_FIRST_GEN,
-
-    Provider.RACKSPACE_NOVA_BETA: Provider.RACKSPACE,
-    Provider.RACKSPACE_NOVA_DFW: Provider.RACKSPACE,
-    Provider.RACKSPACE_NOVA_LON: Provider.RACKSPACE,
-    Provider.RACKSPACE_NOVA_ORD: Provider.RACKSPACE,
-
-    # AWS
-    Provider.EC2_US_EAST: Provider.EC2,
-    Provider.EC2_EU: Provider.EC2,
-    Provider.EC2_EU_WEST: Provider.EC2,
-    Provider.EC2_US_WEST: Provider.EC2,
-    Provider.EC2_AP_SOUTHEAST: Provider.EC2,
-    Provider.EC2_AP_SOUTHEAST2: Provider.EC2,
-    Provider.EC2_AP_NORTHEAST: Provider.EC2,
-    Provider.EC2_AP_NORTHEAST1: Provider.EC2,
-    Provider.EC2_AP_NORTHEAST2: Provider.EC2,
-    Provider.EC2_US_WEST_OREGON: Provider.EC2,
-    Provider.EC2_SA_EAST: Provider.EC2,
-    Provider.EC2_AP_SOUTHEAST: Provider.EC2,
-
-    # ElasticHosts
-    Provider.ELASTICHOSTS_UK1: Provider.ELASTICHOSTS,
-    Provider.ELASTICHOSTS_UK2: Provider.ELASTICHOSTS,
-    Provider.ELASTICHOSTS_US1: Provider.ELASTICHOSTS,
-    Provider.ELASTICHOSTS_US2: Provider.ELASTICHOSTS,
-    Provider.ELASTICHOSTS_US3: Provider.ELASTICHOSTS,
-    Provider.ELASTICHOSTS_CA1: Provider.ELASTICHOSTS,
-    Provider.ELASTICHOSTS_AU1: Provider.ELASTICHOSTS,
-    Provider.ELASTICHOSTS_CN1: Provider.ELASTICHOSTS,
-}
-
-
-class NodeState(Type):
-    """
-    Standard states for a node
-
-    :cvar RUNNING: Node is running.
-    :cvar STARTING: Node is starting up.
-    :cvar REBOOTING: Node is rebooting.
-    :cvar TERMINATED: Node is terminated. This node can't be started later on.
-    :cvar STOPPING: Node is currently trying to stop.
-    :cvar STOPPED: Node is stopped. This node can be started later on.
-    :cvar PENDING: Node is pending.
-    :cvar SUSPENDED: Node is suspended.
-    :cvar ERROR: Node is an error state. Usually no operations can be performed
-                 on the node once it ends up in the error state.
-    :cvar PAUSED: Node is paused.
-    :cvar RECONFIGURING: Node is being reconfigured.
-    :cvar UNKNOWN: Node state is unknown.
-    """
-    RUNNING = 'running'
-    STARTING = 'starting'
-    REBOOTING = 'rebooting'
-    TERMINATED = 'terminated'
-    PENDING = 'pending'
-    UNKNOWN = 'unknown'
-    STOPPING = 'stopping'
-    STOPPED = 'stopped'
-    SUSPENDED = 'suspended'
-    ERROR = 'error'
-    PAUSED = 'paused'
-    RECONFIGURING = 'reconfiguring'
-
-
-class StorageVolumeState(Type):
-    """
-    Standard states of a StorageVolume
-    """
-    AVAILABLE = 'available'
-    ERROR = 'error'
-    INUSE = 'inuse'
-    CREATING = 'creating'
-    DELETING = 'deleting'
-    DELETED = 'deleted'
-    BACKUP = 'backup'
-    ATTACHING = 'attaching'
-    UNKNOWN = 'unknown'
-
-
-class VolumeSnapshotState(Type):
-    """
-    Standard states of VolumeSnapshots
-    """
-    AVAILABLE = 'available'
-    ERROR = 'error'
-    CREATING = 'creating'
-    DELETING = 'deleting'
-    RESTORING = 'restoring'
-    UNKNOWN = 'unknown'
-
-
-class Architecture(object):
-    """
-    Image and size architectures.
-
-    :cvar I386: i386 (32 bt)
-    :cvar X86_64: x86_64 (64 bit)
-    """
-    I386 = 0
-    X86_X64 = 1
-
-
-class DeploymentError(LibcloudError):
-    """
-    Exception used when a Deployment Task failed.
-
-    :ivar node: :class:`Node` on which this exception happened, you might want
-                to call :func:`Node.destroy`
-    """
-    def __init__(self, node, original_exception=None, driver=None):
-        self.node = node
-        self.value = original_exception
-        self.driver = driver
-
-    def __str__(self):
-        return self.__repr__()
-
-    def __repr__(self):
-        return (('<DeploymentError: node=%s, error=%s, driver=%s>'
-                % (self.node.id, str(self.value), str(self.driver))))
-
-
-class KeyPairError(LibcloudError):
-    error_type = 'KeyPairError'
-
-    def __init__(self, name, driver):
-        self.name = name
-        self.value = 'Key pair with name %s does not exist' % (name)
-        super(KeyPairError, self).__init__(value=self.value, driver=driver)
-
-    def __str__(self):
-        return self.__repr__()
-
-    def __repr__(self):
-        return ('<%s name=%s, value=%s, driver=%s>' %
-                (self.error_type, self.name, self.value, self.driver.name))
-
-
-class KeyPairDoesNotExistError(KeyPairError):
-    error_type = 'KeyPairDoesNotExistError'
-
-
-"""Deprecated alias of :class:`DeploymentException`"""
-DeploymentException = DeploymentError

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/container/__init__.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/container/__init__.py b/apache-libcloud-1.0.0rc2/libcloud/container/__init__.py
deleted file mode 100644
index e69de29..0000000


[43/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/LICENSE
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/LICENSE b/apache-libcloud-1.0.0rc2/LICENSE
deleted file mode 100644
index d645695..0000000
--- a/apache-libcloud-1.0.0rc2/LICENSE
+++ /dev/null
@@ -1,202 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   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.

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/MANIFEST.in
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/MANIFEST.in b/apache-libcloud-1.0.0rc2/MANIFEST.in
deleted file mode 100644
index d06ca0c..0000000
--- a/apache-libcloud-1.0.0rc2/MANIFEST.in
+++ /dev/null
@@ -1,24 +0,0 @@
-include LICENSE
-include NOTICE
-include example_*.py
-include CHANGES.rst
-include README.rst
-include tox.ini
-include requirements-tests.txt
-include libcloud/data/pricing.json
-prune libcloud/test/secrets.py
-include demos/*
-include libcloud/test/*.py
-include libcloud/test/pricing_test.json
-include libcloud/test/secrets.py-dist
-include libcloud/test/common/*.py
-include libcloud/test/compute/*.py
-include libcloud/test/storage/*.py
-include libcloud/test/loadbalancer/*.py
-include libcloud/test/dns/*.py
-include libcloud/test/common/fixtures/*/*
-include libcloud/test/compute/fixtures/*/*
-include libcloud/test/compute/fixtures/*/*/*
-include libcloud/test/storage/fixtures/*/*
-include libcloud/test/loadbalancer/fixtures/*/*
-include libcloud/test/dns/fixtures/*/*

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/NOTICE
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/NOTICE b/apache-libcloud-1.0.0rc2/NOTICE
deleted file mode 100644
index 0422d1f..0000000
--- a/apache-libcloud-1.0.0rc2/NOTICE
+++ /dev/null
@@ -1,8 +0,0 @@
-Apache Libcloud
-Copyright (c) 2010-2015 The Apache Software Foundation
-
-This product includes software developed at
-The Apache Software Foundation (http://www.apache.org/).
-
-This product includes software developed by
-Cloudkick (http://www.cloudkick.com/).

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/README.rst
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/README.rst b/apache-libcloud-1.0.0rc2/README.rst
deleted file mode 100644
index d961077..0000000
--- a/apache-libcloud-1.0.0rc2/README.rst
+++ /dev/null
@@ -1,70 +0,0 @@
-Apache Libcloud - a unified interface into the cloud
-====================================================
-
-.. image:: https://img.shields.io/badge/docs-latest-brightgreen.svg?style=flat
-    :target: https://libcloud.readthedocs.org
-
-.. image:: https://img.shields.io/pypi/v/apache-libcloud.svg
-    :target: https://pypi.python.org/pypi/apache-libcloud/
-
-.. image:: https://img.shields.io/pypi/dm/apache-libcloud.svg
-        :target: https://pypi.python.org/pypi/apache-libcloud/
-
-.. image:: https://img.shields.io/travis/apache/libcloud/trunk.svg
-        :target: http://travis-ci.org/apache/libcloud
-
-.. image:: https://img.shields.io/pypi/pyversions/apache-libcloud.svg
-        :target: https://pypi.python.org/pypi/apache-libcloud/
-
-.. image:: https://img.shields.io/pypi/wheel/apache-libcloud.svg
-        :target: https://pypi.python.org/pypi/apache-libcloud/
-
-.. image:: https://img.shields.io/github/license/apache/libcloud.svg
-        :target: https://github.com/apache/libcloud/blob/trunk/LICENSE
-
-.. image:: https://img.shields.io/irc/%23libcloud.png
-        :target: http://webchat.freenode.net/?channels=libcloud
-
-Apache Libcloud is a Python library which hides differences between different
-cloud provider APIs and allows you to manage different cloud resources
-through a unified and easy to use API.
-
-Resources you can manage with Libcloud are divided into the following categories:
-
-* **Compute** - Cloud Servers and Block Storage - services such as Amazon EC2 and Rackspace
-  Cloud Servers (``libcloud.compute.*``)
-* **Storage** - Cloud Object Storage and CDN  - services such as Amazon S3 and Rackspace
-  CloudFiles (``libcloud.storage.*``)
-* **Load Balancers** - Load Balancers as a Service, LBaaS (``libcloud.loadbalancer.*``)
-* **DNS** - DNS as a Service, DNSaaS (``libcloud.dns.*``)
-* **Container** - Container virtualization services (``libcloud.container.*``)
-
-
-Apache Libcloud is an Apache project, see <http://libcloud.apache.org> for
-more information.
-
-Documentation
-=============
-
-Documentation can be found at <https://libcloud.readthedocs.org>.
-
-Feedback
-========
-
-Please send feedback to the mailing list at <de...@libcloud.apache.org>,
-or the JIRA at <https://issues.apache.org/jira/browse/LIBCLOUD>.
-
-Contributing
-============
-
-For information on how to contribute, please see the Contributing
-chapter in our documentation
-<https://libcloud.readthedocs.org/en/latest/development.html#contributing>
-
-License
-=======
-
-Apache Libcloud is licensed under the Apache 2.0 license. For more information, please see LICENSE_ and NOTICE_  file.
-
-.. _LICENSE: https://github.com/apache/libcloud/blob/trunk/LICENSE
-.. _NOTICE: https://github.com/apache/libcloud/blob/trunk/NOTICE

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/demos/compute_demo.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/demos/compute_demo.py b/apache-libcloud-1.0.0rc2/demos/compute_demo.py
deleted file mode 100644
index 983b713..0000000
--- a/apache-libcloud-1.0.0rc2/demos/compute_demo.py
+++ /dev/null
@@ -1,118 +0,0 @@
-#!/usr/bin/env python
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-#
-# This example provides both a running script (invoke from command line)
-# and an importable module one can play with in Interactive Mode.
-#
-# See docstrings for usage examples.
-#
-
-try:
-    import secrets
-except ImportError:
-    secrets = None
-
-import os.path
-import sys
-
-# Add parent dir of this file's dir to sys.path (OS-agnostically)
-sys.path.append(os.path.normpath(os.path.join(os.path.dirname(__file__),
-                                 os.path.pardir)))
-
-from libcloud.common.types import InvalidCredsError
-from libcloud.compute.types import Provider
-from libcloud.providers import get_driver
-
-from pprint import pprint
-
-
-def get_demo_driver(provider_name='RACKSPACE', *args, **kwargs):
-    """An easy way to play with a driver interactively.
-
-    # Load credentials from secrets.py:
-    >>> from compute_demo import get_demo_driver
-    >>> driver = get_demo_driver('RACKSPACE')
-
-    # Or, provide credentials:
-    >>> from compute_demo import get_demo_driver
-    >>> driver = get_demo_driver('RACKSPACE', 'username', 'api_key')
-    # Note that these parameters vary by driver ^^^
-
-    # Do things like the demo:
-    >>> driver.load_nodes()
-    >>> images = driver.load_images()
-    >>> sizes = driver.load_sizes()
-
-    # And maybe do more than that:
-    >>> node = driver.create_node(
-        ... name='my_first_node',
-        ... image=images[0],
-        ... size=sizes[0],
-        ... )
-    >>> node.destroy()
-    """
-    provider_name = provider_name.upper()
-
-    DriverClass = get_driver(getattr(Provider, provider_name))
-
-    if not args:
-        args = getattr(secrets, provider_name + '_PARAMS', ())
-    if not kwargs:
-        kwargs = getattr(secrets, provider_name + '_KEYWORD_PARAMS', {})
-
-    try:
-        return DriverClass(*args, **kwargs)
-    except InvalidCredsError:
-        raise InvalidCredsError(
-            'valid values should be put in secrets.py')
-
-
-def main(argv):
-    """Main Compute Demo
-
-    When invoked from the command line, it will connect using secrets.py
-    (see secrets.py-dist for instructions and examples), and perform the
-    following tasks:
-
-    - List current nodes
-    - List available images (up to 10)
-    - List available sizes (up to 10)
-    """
-    try:
-        driver = get_demo_driver()
-    except InvalidCredsError:
-        e = sys.exc_info()[1]
-        print("Invalid Credentials: " + e.value)
-        return 1
-
-    try:
-        print(">> Loading nodes...")
-        pprint(driver.list_nodes())
-
-        print(">> Loading images... (showing up to 10)")
-        pprint(driver.list_images()[:10])
-
-        print(">> Loading sizes... (showing up to 10)")
-        pprint(driver.list_sizes()[:10])
-    except Exception:
-        e = sys.exc_info()[1]
-        print("A fatal error occurred: " + e)
-        return 1
-
-if __name__ == '__main__':
-    sys.exit(main(sys.argv))

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/demos/gce_demo.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/demos/gce_demo.py b/apache-libcloud-1.0.0rc2/demos/gce_demo.py
deleted file mode 100644
index aae7093..0000000
--- a/apache-libcloud-1.0.0rc2/demos/gce_demo.py
+++ /dev/null
@@ -1,706 +0,0 @@
-#!/usr/bin/env python
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-
-# This example performs several tasks on Google Compute Platform.  It can be
-# run directly or can be imported into an interactive python session.  This
-# can also serve as live integration tests.
-#
-# To run directly, use python 2.7 or greater:
-#    - $ python gce_demo.py --help    # to see the help screen
-#    - $ python gce_demo.py           # to run all demos / tests
-#
-# To run interactively:
-#    - Make sure you have valid values in secrets.py
-#      (For more information about setting up your credentials, see the
-#      libcloud/common/google.py docstring)
-#    - Run 'python' in this directory, then:
-#        import gce_demo
-#        gce = gce_demo.get_gce_driver()
-#        gce.list_nodes()
-#        etc.
-#    - Or, to run the full demo from the interactive python shell:
-#        import gce_demo
-#        gce_demo.CLEANUP = False               # optional
-#        gce_demo.MAX_NODES = 4                 # optional
-#        gce_demo.DATACENTER = 'us-central1-a'  # optional
-#        gce_demo.main_compute()                # 'compute' only demo
-#        gce_demo.main_load_balancer()          # 'load_balancer' only demo
-#        gce_demo.main_dns()                    # 'dns only demo
-#        gce_demo.main()                        # all demos / tests
-
-import os.path
-import sys
-import datetime
-import time
-
-try:
-    import argparse
-except:
-    print('This script uses the python "argparse" module. Please use Python '
-          '2.7 or greater.')
-    raise
-
-try:
-    import secrets
-except ImportError:
-    print('"demos/secrets.py" not found.\n\n'
-          'Please copy secrets.py-dist to secrets.py and update the GCE* '
-          'values with appropriate authentication information.\n'
-          'Additional information about setting these values can be found '
-          'in the docstring for:\n'
-          'libcloud/common/google.py\n')
-    sys.exit(1)
-
-# Add parent dir of this file's dir to sys.path (OS-agnostically)
-sys.path.append(os.path.normpath(os.path.join(os.path.dirname(__file__),
-                                 os.path.pardir)))
-
-from libcloud.compute.types import Provider
-from libcloud.compute.providers import get_driver
-from libcloud.common.google import ResourceNotFoundError
-from libcloud.loadbalancer.types import Provider as Provider_lb
-from libcloud.loadbalancer.providers import get_driver as get_driver_lb
-from libcloud.dns.types import Provider as Provider_dns
-from libcloud.dns.providers import get_driver as get_driver_dns
-from libcloud.dns.base import Record, Zone
-from libcloud.utils.py3 import PY3
-if PY3:
-    import urllib.request as url_req
-else:
-    import urllib2 as url_req
-
-# Maximum number of 1-CPU nodes to allow to run simultaneously
-MAX_NODES = 5
-
-# String that all resource names created by the demo will start with
-# WARNING: Any resource that has a matching name will be destroyed.
-DEMO_BASE_NAME = 'lct'
-
-# Datacenter to create resources in
-DATACENTER = 'us-central1-f'
-
-# Clean up resources at the end (can be set to false in order to
-# inspect resources at the end of the run). Resources will be cleaned
-# at the beginning regardless.
-CLEANUP = True
-
-args = getattr(secrets, 'GCE_PARAMS', ())
-kwargs = getattr(secrets, 'GCE_KEYWORD_PARAMS', {})
-
-# Add datacenter to kwargs for Python 2.5 compatibility
-kwargs = kwargs.copy()
-kwargs['datacenter'] = DATACENTER
-
-
-# ==== HELPER FUNCTIONS ====
-def get_gce_driver():
-    driver = get_driver(Provider.GCE)(*args, **kwargs)
-    return driver
-
-
-def get_gcelb_driver(gce_driver=None):
-    # The GCE Load Balancer driver uses the GCE Compute driver for all of its
-    # API calls.  You can either provide the driver directly, or provide the
-    # same authentication information so the LB driver can get its own
-    # Compute driver.
-    if gce_driver:
-        driver = get_driver_lb(Provider_lb.GCE)(gce_driver=gce_driver)
-    else:
-        driver = get_driver_lb(Provider_lb.GCE)(*args, **kwargs)
-    return driver
-
-
-def get_dns_driver(gce_driver=None):
-    # The Google DNS driver uses the GCE Compute driver for all of its
-    # API calls.  You can either provide the driver directly, or provide the
-    # same authentication information so the LB driver can get its own
-    # Compute driver.
-    if gce_driver:
-        driver = get_driver_dns(Provider_dns.GOOGLE)(gce_driver=gce_driver)
-    else:
-        driver = get_driver_dns(Provider_dns.GOOGLE)(*args, **kwargs)
-    return driver
-
-
-def display(title, resource_list=[]):
-    """
-    Display a list of resources.
-
-    :param  title: String to be printed at the heading of the list.
-    :type   title: ``str``
-
-    :param  resource_list: List of resources to display
-    :type   resource_list: Any ``object`` with a C{name} attribute
-    """
-    print('=> %s' % title)
-    for item in resource_list:
-        if isinstance(item, Record):
-            if item.name.startswith(DEMO_BASE_NAME):
-                print('=>   name=%s, type=%s' % (item.name, item.type))
-            else:
-                print('     name=%s, type=%s' % (item.name, item.type))
-        elif isinstance(item, Zone):
-            if item.domain.startswith(DEMO_BASE_NAME):
-                print('=>   name=%s, dnsname=%s' % (item.id, item.domain))
-            else:
-                print('     name=%s, dnsname=%s' % (item.id, item.domain))
-        elif hasattr(item, 'name'):
-            if item.name.startswith(DEMO_BASE_NAME):
-                print('=>   %s' % item.name)
-            else:
-                print('     %s' % item.name)
-        else:
-            if item.startswith(DEMO_BASE_NAME):
-                print('=>   %s' % item)
-            else:
-                print('     %s' % item)
-
-
-def cleanup_only():
-    start_time = datetime.datetime.now()
-    display('Clean-up start time: %s' % str(start_time))
-    gce = get_gce_driver()
-    # Get project info and print name
-    project = gce.ex_get_project()
-    display('Project: %s' % project.name)
-
-    # == Get Lists of Everything and Display the lists (up to 10) ==
-    # These can either just return values for the current datacenter (zone)
-    # or for everything.
-    all_nodes = gce.list_nodes(ex_zone='all')
-    display('Nodes:', all_nodes)
-
-    all_addresses = gce.ex_list_addresses(region='all')
-    display('Addresses:', all_addresses)
-
-    all_volumes = gce.list_volumes(ex_zone='all')
-    display('Volumes:', all_volumes)
-
-    # This can return everything, but there is a large amount of overlap,
-    # so we'll just get the sizes from the current zone.
-    sizes = gce.list_sizes()
-    display('Sizes:', sizes)
-
-    # These are global
-    firewalls = gce.ex_list_firewalls()
-    display('Firewalls:', firewalls)
-
-    networks = gce.ex_list_networks()
-    display('Networks:', networks)
-
-    images = gce.list_images()
-    display('Images:', images)
-
-    locations = gce.list_locations()
-    display('Locations:', locations)
-
-    zones = gce.ex_list_zones()
-    display('Zones:', zones)
-
-    snapshots = gce.ex_list_snapshots()
-    display('Snapshots:', snapshots)
-
-    # == Clean up any old demo resources ==
-    display('Cleaning up any "%s" resources' % DEMO_BASE_NAME)
-    clean_up(gce, DEMO_BASE_NAME, all_nodes,
-             all_addresses + all_volumes + firewalls + networks + snapshots)
-    volumes = gce.list_volumes()
-    clean_up(gce, DEMO_BASE_NAME, None, volumes)
-    end_time = datetime.datetime.now()
-    display('Total runtime: %s' % str(end_time - start_time))
-
-
-def clean_up(gce, base_name, node_list=None, resource_list=None):
-    """
-    Destroy all resources that have a name beginning with 'base_name'.
-
-    :param  base_name: String with the first part of the name of resources
-                       to destroy
-    :type   base_name: ``str``
-
-    :keyword  node_list: List of nodes to consider for deletion
-    :type     node_list: ``list`` of :class:`Node`
-
-    :keyword  resource_list: List of resources to consider for deletion
-    :type     resource_list: ``list`` of I{Resource Objects}
-    """
-    if node_list is None:
-        node_list = []
-    if resource_list is None:
-        resource_list = []
-    # Use ex_destroy_multiple_nodes to destroy nodes
-    del_nodes = []
-    for node in node_list:
-        if node.name.startswith(base_name):
-            del_nodes.append(node)
-
-    result = gce.ex_destroy_multiple_nodes(del_nodes)
-    for i, success in enumerate(result):
-        if success:
-            display('   Deleted %s' % del_nodes[i].name)
-        else:
-            display('   Failed to delete %s' % del_nodes[i].name)
-
-    # Destroy everything else with just the destroy method
-    for resrc in resource_list:
-        if resrc.name.startswith(base_name):
-            try:
-                resrc.destroy()
-            except ResourceNotFoundError:
-                display('   Not found: %s (%s)' % (resrc.name,
-                                                   resrc.__class__.__name__))
-            except:
-                class_name = resrc.__class__.__name__
-                display('   Failed to Delete %s (%s)' % (resrc.name,
-                                                         class_name))
-                raise
-
-
-# ==== COMPUTE CODE STARTS HERE ====
-def main_compute():
-    start_time = datetime.datetime.now()
-    display('Compute demo/test start time: %s' % str(start_time))
-    gce = get_gce_driver()
-    # Get project info and print name
-    project = gce.ex_get_project()
-    display('Project: %s' % project.name)
-
-    # == Get Lists of Everything and Display the lists (up to 10) ==
-    # These can either just return values for the current datacenter (zone)
-    # or for everything.
-    all_nodes = gce.list_nodes(ex_zone='all')
-    display('Nodes:', all_nodes)
-
-    all_addresses = gce.ex_list_addresses(region='all')
-    display('Addresses:', all_addresses)
-
-    all_volumes = gce.list_volumes(ex_zone='all')
-    display('Volumes:', all_volumes)
-
-    # This can return everything, but there is a large amount of overlap,
-    # so we'll just get the sizes from the current zone.
-    sizes = gce.list_sizes()
-    display('Sizes:', sizes)
-
-    # These are global
-    firewalls = gce.ex_list_firewalls()
-    display('Firewalls:', firewalls)
-
-    networks = gce.ex_list_networks()
-    display('Networks:', networks)
-
-    images = gce.list_images()
-    display('Images:', images)
-
-    locations = gce.list_locations()
-    display('Locations:', locations)
-
-    zones = gce.ex_list_zones()
-    display('Zones:', zones)
-
-    snapshots = gce.ex_list_snapshots()
-    display('Snapshots:', snapshots)
-
-    # == Clean up any old demo resources ==
-    display('Cleaning up any "%s" resources' % DEMO_BASE_NAME)
-    clean_up(gce, DEMO_BASE_NAME, all_nodes,
-             all_addresses + all_volumes + firewalls + networks + snapshots)
-
-    # == Create Node with disk auto-created ==
-    if MAX_NODES > 1:
-        display('Creating a node with boot/local-ssd using GCE structure:')
-        name = '%s-gstruct' % DEMO_BASE_NAME
-        img_url = "projects/debian-cloud/global/images/"
-        img_url += "backports-debian-7-wheezy-v20141205"
-        disk_type_url = "projects/%s/zones/us-central1-f/" % project.name
-        disk_type_url += "diskTypes/local-ssd"
-        gce_disk_struct = [
-            {
-                "type": "PERSISTENT",
-                "deviceName": '%s-gstruct' % DEMO_BASE_NAME,
-                "initializeParams": {
-                    "diskName": '%s-gstruct' % DEMO_BASE_NAME,
-                    "sourceImage": img_url
-                },
-                "boot": True,
-                "autoDelete": True
-            },
-            {
-                "type": "SCRATCH",
-                "deviceName": '%s-gstruct-lssd' % DEMO_BASE_NAME,
-                "initializeParams": {
-                    "diskType": disk_type_url
-                },
-                "autoDelete": True
-            }
-        ]
-        node_gstruct = gce.create_node(name, 'n1-standard-1', None,
-                                       'us-central1-f',
-                                       ex_disks_gce_struct=gce_disk_struct)
-        num_disks = len(node_gstruct.extra['disks'])
-        display('  Node %s created with %d disks' % (node_gstruct.name,
-                                                     num_disks))
-
-        display('Creating Node with auto-created SSD:')
-        name = '%s-np-node' % DEMO_BASE_NAME
-        node_1 = gce.create_node(name, 'n1-standard-1', 'debian-7',
-                                 ex_tags=['libcloud'], ex_disk_type='pd-ssd',
-                                 ex_disk_auto_delete=False)
-        display('  Node %s created' % name)
-
-        # Stop the node and change to a custom machine type (e.g. size)
-        display('Stopping node, setting custom size, starting node:')
-        name = '%s-np-node' % DEMO_BASE_NAME
-        gce.ex_stop_node(node_1)
-        gce.ex_set_machine_type(node_1, 'custom-2-4096')   # 2 vCPU, 4GB RAM
-        gce.ex_start_node(node_1)
-        node_1 = gce.ex_get_node(name)
-        display('  %s: state=%s, size=%s' % (name, node_1.extra['status'],
-                                             node_1.size))
-
-        # == Create, and attach a disk ==
-        display('Creating a new disk:')
-        disk_name = '%s-attach-disk' % DEMO_BASE_NAME
-        volume = gce.create_volume(10, disk_name)
-        if gce.attach_volume(node_1, volume, ex_auto_delete=True):
-            display('  Attached %s to %s' % (volume.name, node_1.name))
-        display('  Disabled auto-delete for %s on %s' % (volume.name,
-                                                         node_1.name))
-        gce.ex_set_volume_auto_delete(volume, node_1, auto_delete=False)
-
-        if CLEANUP:
-            # == Detach the disk ==
-            if gce.detach_volume(volume, ex_node=node_1):
-                display('  Detached %s from %s' % (volume.name,
-                                                   node_1.name))
-
-    # == Create Snapshot ==
-    display('Creating a snapshot from existing disk:')
-    # Create a disk to snapshot
-    vol_name = '%s-snap-template' % DEMO_BASE_NAME
-    image = gce.ex_get_image('debian-7')
-    vol = gce.create_volume(None, vol_name, image=image)
-    display('Created disk %s to shapshot:' % DEMO_BASE_NAME)
-    # Snapshot volume
-    snapshot = vol.snapshot('%s-snapshot' % DEMO_BASE_NAME)
-    display('  Snapshot %s created' % snapshot.name)
-
-    # == Create Node with existing disk ==
-    display('Creating Node with existing disk:')
-    name = '%s-persist-node' % DEMO_BASE_NAME
-    # Use objects this time instead of names
-    # Get latest Debian 7 image
-    image = gce.ex_get_image('debian-7')
-    # Get Machine Size
-    size = gce.ex_get_size('n1-standard-1')
-    # Create Disk from Snapshot created above
-    volume_name = '%s-boot-disk' % DEMO_BASE_NAME
-    volume = gce.create_volume(None, volume_name, snapshot=snapshot)
-    display('  Created %s from snapshot' % volume.name)
-    # Create Node with Disk
-    node_2 = gce.create_node(name, size, image, ex_tags=['libcloud'],
-                             ex_boot_disk=volume,
-                             ex_disk_auto_delete=False)
-    display('  Node %s created with attached disk %s' % (node_2.name,
-                                                         volume.name))
-
-    # == Update Tags for Node ==
-    display('Updating Tags for %s:' % node_2.name)
-    tags = node_2.extra['tags']
-    tags.append('newtag')
-    if gce.ex_set_node_tags(node_2, tags):
-        display('  Tags updated for %s' % node_2.name)
-    check_node = gce.ex_get_node(node_2.name)
-    display('  New tags: %s' % check_node.extra['tags'])
-
-    # == Setting Metadata for Node ==
-    display('Setting Metadata for %s:' % node_2.name)
-    if gce.ex_set_node_metadata(node_2, {'foo': 'bar', 'baz': 'foobarbaz'}):
-        display('  Metadata updated for %s' % node_2.name)
-    check_node = gce.ex_get_node(node_2.name)
-    display('  New Metadata: %s' % check_node.extra['metadata'])
-
-    # == Create Multiple nodes at once ==
-    base_name = '%s-multiple-nodes' % DEMO_BASE_NAME
-    number = MAX_NODES - 2
-    if number > 0:
-        display('Creating Multiple Nodes (%s):' % number)
-        multi_nodes = gce.ex_create_multiple_nodes(base_name, size, image,
-                                                   number,
-                                                   ex_tags=['libcloud'],
-                                                   ex_disk_auto_delete=True)
-        for node in multi_nodes:
-            display('  Node %s created' % node.name)
-
-    # == Create a Network ==
-    display('Creating Network:')
-    name = '%s-network' % DEMO_BASE_NAME
-    cidr = '10.10.0.0/16'
-    network_1 = gce.ex_create_network(name, cidr)
-    display('  Network %s created' % network_1.name)
-
-    # == Create a Firewall ==
-    display('Creating a Firewall:')
-    name = '%s-firewall' % DEMO_BASE_NAME
-    allowed = [{'IPProtocol': 'tcp',
-                'ports': ['3141']}]
-    firewall_1 = gce.ex_create_firewall(name, allowed, network=network_1,
-                                        source_tags=['libcloud'])
-    display('  Firewall %s created' % firewall_1.name)
-
-    # == Create a Static Address ==
-    display('Creating an Address:')
-    name = '%s-address' % DEMO_BASE_NAME
-    address_1 = gce.ex_create_address(name)
-    display('  Address %s created with IP %s' % (address_1.name,
-                                                 address_1.address))
-
-    # == List Updated Resources in current zone/region ==
-    display('Updated Resources in current zone/region')
-    nodes = gce.list_nodes()
-    display('Nodes:', nodes)
-
-    addresses = gce.ex_list_addresses()
-    display('Addresses:', addresses)
-
-    firewalls = gce.ex_list_firewalls()
-    display('Firewalls:', firewalls)
-
-    networks = gce.ex_list_networks()
-    display('Networks:', networks)
-
-    snapshots = gce.ex_list_snapshots()
-    display('Snapshots:', snapshots)
-
-    if CLEANUP:
-        display('Cleaning up %s resources created' % DEMO_BASE_NAME)
-        clean_up(gce, DEMO_BASE_NAME, nodes,
-                 addresses + firewalls + networks + snapshots)
-        volumes = gce.list_volumes()
-        clean_up(gce, DEMO_BASE_NAME, None, volumes)
-    end_time = datetime.datetime.now()
-    display('Total runtime: %s' % str(end_time - start_time))
-
-
-# ==== LOAD BALANCER CODE STARTS HERE ====
-def main_load_balancer():
-    start_time = datetime.datetime.now()
-    display('Load-balancer demo/test start time: %s' % str(start_time))
-    gce = get_gce_driver()
-    gcelb = get_gcelb_driver(gce)
-
-    # Get project info and print name
-    project = gce.ex_get_project()
-    display('Project: %s' % project.name)
-
-    # Existing Balancers
-    balancers = gcelb.list_balancers()
-    display('Load Balancers', balancers)
-
-    # Protocols
-    protocols = gcelb.list_protocols()
-    display('Protocols', protocols)
-
-    # Healthchecks
-    healthchecks = gcelb.ex_list_healthchecks()
-    display('Health Checks', healthchecks)
-
-    # This demo is based on the GCE Load Balancing Quickstart described here:
-    # https://developers.google.com/compute/docs/load-balancing/lb-quickstart
-
-    # == Clean-up and existing demo resources ==
-    all_nodes = gce.list_nodes(ex_zone='all')
-    firewalls = gce.ex_list_firewalls()
-    display('Cleaning up any "%s" resources' % DEMO_BASE_NAME)
-    clean_up(gce, DEMO_BASE_NAME, all_nodes,
-             balancers + healthchecks + firewalls)
-
-    # == Create 3 nodes to balance between ==
-    startup_script = ('apt-get -y update && '
-                      'apt-get -y install apache2 && '
-                      'hostname > /var/www/index.html')
-    tag = '%s-www' % DEMO_BASE_NAME
-    base_name = '%s-www' % DEMO_BASE_NAME
-    image = gce.ex_get_image('debian-7')
-    size = gce.ex_get_size('n1-standard-1')
-    number = 3
-    display('Creating %d nodes' % number)
-    metadata = {'items': [{'key': 'startup-script',
-                           'value': startup_script}]}
-    lb_nodes = gce.ex_create_multiple_nodes(base_name, size, image,
-                                            number, ex_tags=[tag],
-                                            ex_metadata=metadata,
-                                            ex_disk_auto_delete=True,
-                                            ignore_errors=False)
-    display('Created Nodes', lb_nodes)
-
-    # == Create a Firewall for instances ==
-    display('Creating a Firewall')
-    name = '%s-firewall' % DEMO_BASE_NAME
-    allowed = [{'IPProtocol': 'tcp',
-                'ports': ['80']}]
-    firewall = gce.ex_create_firewall(name, allowed, source_tags=[tag])
-    display('    Firewall %s created' % firewall.name)
-
-    # == Create a Health Check ==
-    display('Creating a HealthCheck')
-    name = '%s-healthcheck' % DEMO_BASE_NAME
-
-    # These are all the default values, but listed here as an example.  To
-    # create a healthcheck with the defaults, only name is required.
-    hc = gcelb.ex_create_healthcheck(name, host=None, path='/', port='80',
-                                     interval=5, timeout=5,
-                                     unhealthy_threshold=2,
-                                     healthy_threshold=2)
-    display('Healthcheck %s created' % hc.name)
-
-    # == Create Load Balancer ==
-    display('Creating Load Balancer')
-    name = '%s-lb' % DEMO_BASE_NAME
-    port = 80
-    protocol = 'tcp'
-    algorithm = None
-    members = lb_nodes[:2]  # Only attach the first two initially
-    healthchecks = [hc]
-    balancer = gcelb.create_balancer(name, port, protocol, algorithm, members,
-                                     ex_healthchecks=healthchecks)
-    display('    Load Balancer %s created' % balancer.name)
-
-    # == Attach third Node ==
-    display('Attaching additional node to Load Balancer')
-    member = balancer.attach_compute_node(lb_nodes[2])
-    display('      Attached %s to %s' % (member.id, balancer.name))
-
-    # == Show Balancer Members ==
-    members = balancer.list_members()
-    display('Load Balancer Members')
-    for member in members:
-        display('      ID: %s IP: %s' % (member.id, member.ip))
-
-    # == Remove a Member ==
-    display('Removing a Member')
-    detached = members[0]
-    detach = balancer.detach_member(detached)
-    if detach:
-        display('      Member %s detached from %s' % (detached.id,
-                                                      balancer.name))
-
-    # == Show Updated Balancer Members ==
-    members = balancer.list_members()
-    display('Updated Load Balancer Members')
-    for member in members:
-        display('      ID: %s IP: %s' % (member.id, member.ip))
-
-    # == Reattach Member ==
-    display('Reattaching Member')
-    member = balancer.attach_member(detached)
-    display('      Member %s attached to %s' % (member.id, balancer.name))
-
-    # == Test Load Balancer by connecting to it multiple times ==
-    PAUSE = 60
-    display('Sleeping for %d seconds for LB members to serve...' % PAUSE)
-    time.sleep(PAUSE)
-    rounds = 200
-    url = 'http://%s/' % balancer.ip
-    line_length = 75
-    display('Connecting to %s %s times' % (url, rounds))
-    for x in range(rounds):
-        response = url_req.urlopen(url)
-        if PY3:
-            output = str(response.read(), encoding='utf-8').strip()
-        else:
-            output = response.read().strip()
-        if 'www-001' in output:
-            padded_output = output.center(line_length)
-        elif 'www-002' in output:
-            padded_output = output.rjust(line_length)
-        else:
-            padded_output = output.ljust(line_length)
-        sys.stdout.write('\r%s' % padded_output)
-        sys.stdout.flush()
-        time.sleep(.25)
-
-    print ""
-    if CLEANUP:
-        balancers = gcelb.list_balancers()
-        healthchecks = gcelb.ex_list_healthchecks()
-        nodes = gce.list_nodes(ex_zone='all')
-        firewalls = gce.ex_list_firewalls()
-
-        display('Cleaning up %s resources created' % DEMO_BASE_NAME)
-        clean_up(gce, DEMO_BASE_NAME, nodes,
-                 balancers + healthchecks + firewalls)
-
-    end_time = datetime.datetime.now()
-    display('Total runtime: %s' % str(end_time - start_time))
-
-
-# ==== GOOGLE DNS CODE STARTS HERE ====
-def main_dns():
-    start_time = datetime.datetime.now()
-    display('DNS demo/test start time: %s' % str(start_time))
-    gce = get_gce_driver()
-    gdns = get_dns_driver()
-    # Get project info and print name
-    project = gce.ex_get_project()
-    display('Project: %s' % project.name)
-
-    # Get list of managed zones
-    zones = gdns.iterate_zones()
-    display('Zones', zones)
-
-    # Get list of records
-    zones = gdns.iterate_zones()
-    for z in zones:
-        records = gdns.iterate_records(z)
-        display('Records for managed zone "%s"' % z.id, records)
-
-    # TODO(erjohnso): Finish this DNS section. Challenging in that you need to
-    # own a domain, so testing will require user customization. Perhaps a new
-    # command-line required flag unless --skip-dns is supplied. Also, real
-    # e2e testing should try to do DNS lookups on new records, but DNS TTL
-    # and propagation delays will introduce limits on what can be tested.
-
-    end_time = datetime.datetime.now()
-    display('Total runtime: %s' % str(end_time - start_time))
-
-if __name__ == '__main__':
-    parser = argparse.ArgumentParser(
-        description='Google Cloud Platform Demo / Live Test Script')
-    parser.add_argument("--compute",
-                        help="perform compute demo / live tests",
-                        dest="compute", action="store_true")
-    parser.add_argument("--load-balancer",
-                        help="perform load-balancer demo / live tests",
-                        dest="lb", action="store_true")
-    parser.add_argument("--dns",
-                        help="perform DNS demo / live tests",
-                        dest="dns", action="store_true")
-    parser.add_argument("--cleanup-only",
-                        help="perform clean-up (skips all tests)",
-                        dest="cleanup", action="store_true")
-    cl_args = parser.parse_args()
-
-    if cl_args.cleanup:
-        cleanup_only()
-    else:
-        if cl_args.compute:
-            main_compute()
-        if cl_args.lb:
-            main_load_balancer()
-        if cl_args.dns:
-            main_dns()

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/demos/secrets.py-dist
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/demos/secrets.py-dist b/apache-libcloud-1.0.0rc2/demos/secrets.py-dist
deleted file mode 100644
index a4c52c5..0000000
--- a/apache-libcloud-1.0.0rc2/demos/secrets.py-dist
+++ /dev/null
@@ -1,38 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-# Make a copy of this file named 'secrets.py' and add your credentials there.
-# Note you can run unit tests without setting your credentials.
-
-BLUEBOX_PARAMS = ('customer_id', 'api_key')
-BRIGHTBOX_PARAMS = ('client_id', 'client_secret')
-EC2_PARAMS = ('access_id', 'secret')
-ECP_PARAMS = ('user_name', 'password')
-GANDI_PARAMS = ('user',)
-GCE_PARAMS = ('email@developer.gserviceaccount.com', 'key')  # Service Account Authentication
-#GCE_PARAMS = ('client_id', 'client_secret')  # Installed App Authentication
-GCE_KEYWORD_PARAMS = {'project': 'project_name'}
-HOSTINGCOM_PARAMS = ('user', 'secret')
-IBM_PARAMS = ('user', 'secret')
-# OPENSTACK_PARAMS = ('user_name', 'api_key', secure_bool, 'host', port_int)
-OPENSTACK_PARAMS = ('user_name', 'api_key', False, 'host', 8774)
-OPENNEBULA_PARAMS = ('user', 'key')
-OPSOURCE_PARAMS = ('user', 'password')
-RACKSPACE_PARAMS = ('user', 'key')
-SLICEHOST_PARAMS = ('key',)
-SOFTLAYER_PARAMS = ('user', 'api_key')
-VCLOUD_PARAMS = ('user', 'secret')
-VOXEL_PARAMS = ('key', 'secret')
-VPSNET_PARAMS = ('user', 'key')

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/example_aliyun_ecs.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/example_aliyun_ecs.py b/apache-libcloud-1.0.0rc2/example_aliyun_ecs.py
deleted file mode 100644
index bbaaf00..0000000
--- a/apache-libcloud-1.0.0rc2/example_aliyun_ecs.py
+++ /dev/null
@@ -1,79 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from libcloud.compute.types import Provider
-from libcloud.compute.providers import get_driver
-from libcloud.compute.base import NodeAuthPassword
-
-ECSDriver = get_driver(Provider.ALIYUN_ECS)
-
-region = 'cn-hangzhou'
-
-your_access_key_id = ''
-your_access_key_secret = ''
-ecs = ECSDriver(your_access_key_id, your_access_key_secret, region=region)
-
-sizes = ecs.list_sizes()
-small = sizes[1]
-
-locations = ecs.list_locations()
-location = None
-for each in locations:
-    if each.id == region:
-        location = each
-        break
-if location is None:
-    print('could not find cn-qingdao location')
-    sys.exit(-1)
-print(location.name)
-
-images = ecs.list_images()
-print('Found %d images' % len(images))
-for each in images:
-    if 'ubuntu' in each.id.lower():
-        image = each
-        break
-else:
-    image = images[0]
-print('Use image %s' % image)
-
-sgs = ecs.ex_list_security_groups()
-print('Found %d security groups' % len(sgs))
-sg = sgs[0]
-print('Use security group %s' % sg)
-
-nodes = ecs.list_nodes()
-print('Found %d nodes' % len(nodes))
-if len(nodes) == 0:
-    print('Starting create a new node')
-    data_disk = {
-        'size': 5,
-        'category': ecs.disk_categories.CLOUD,
-        'disk_name': 'data_disk1',
-        'delete_with_instance': True}
-
-    auth = NodeAuthPassword('P@$$w0rd')
-
-    node = ecs.create_node(image=image, size=small, name='test',
-                           ex_security_group_id=sg.id,
-                           ex_internet_charge_type=ecs.internet_charge_types.BY_TRAFFIC,
-                           ex_internet_max_bandwidth_out=1,
-                           ex_data_disk=data_disk,
-                           auth=auth)
-    print('Created node %s' % node)
-    nodes = ecs.list_nodes()
-
-for each in nodes:
-    print('Found node %s' % each)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/example_aliyun_oss.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/example_aliyun_oss.py b/apache-libcloud-1.0.0rc2/example_aliyun_oss.py
deleted file mode 100644
index 6bda227..0000000
--- a/apache-libcloud-1.0.0rc2/example_aliyun_oss.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from libcloud.storage.types import Provider
-from libcloud.storage.providers import get_driver
-
-OSSDriver = get_driver(Provider.ALIYUN_OSS)
-
-your_access_key_id = ''
-your_access_key_secret = ''
-oss = OSSDriver(your_access_key_id, your_access_key_secret)
-
-container_name = 'CONTAINER_NAME_FOR_TEST'
-object_name = 'OBJECT_NAME_FOR_TEST'
-local_file_path = 'LOCAL_FILE_FULL_PATH_TO_UPLOAD'
-upload_object_name = 'OBJECT_NAME_FOR_UPLOAD_FILE'
-for container in oss.iterate_containers():
-    print('container: %s' % container)
-
-c1 = oss.get_container(container_name)
-print('Got container %s:' % c1)
-
-objects = c1.list_objects()
-count = len(objects)
-print('Has %d objects' % count)
-
-objects = oss.list_container_objects(c1, ex_prefix='en')
-print('Has %d objects with prefix "en"' % len(objects))
-for each in objects:
-    print(each)
-
-obj = oss.get_object(container_name, object_name)
-print('Got object %s:' % obj)
-
-# Download object
-oss.download_object(obj, object_name, overwrite_existing=True)
-for trunk in oss.download_object_as_stream(obj):
-    print(trunk)
-
-# Upload object
-obj = oss.upload_object(local_file_path, c1, upload_object_name)
-
-# Upload multipart
-uploads = list(oss.ex_iterate_multipart_uploads(c1))
-print('Found %d incompleted uploads' % len(uploads))
-if len(uploads) > 0:
-    oss.ex_abort_all_multipart_uploads(c1)
-    print('Abort them all')
-
-def data_iter(limit):
-    i = 0
-    while True:
-        yield i
-        i += 1
-        if i >= limit:
-            break
-
-print('Starting to upload 1MB using multipart api')
-one_mb = 1024*1024
-obj = oss.upload_object_via_stream(data_iter(one_mb), c1, upload_object_name)
-print('Finish uploading')
-
-# Delete objects
-print('Delete object %s' % obj)
-oss.delete_object(obj)
-
-# Create container
-#c2 = oss.create_container(container_name='20160117')
-#c2 = oss.create_container(container_name='20160117', ex_location='oss-cn-beijing')
-#c2_got = oss.get_container('20160117')

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/example_aliyun_slb.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/example_aliyun_slb.py b/apache-libcloud-1.0.0rc2/example_aliyun_slb.py
deleted file mode 100644
index 0b41839..0000000
--- a/apache-libcloud-1.0.0rc2/example_aliyun_slb.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from libcloud.compute.types import Provider as NodeProvider
-from libcloud.compute.providers import get_driver as get_node_driver
-from libcloud.loadbalancer.providers import get_driver
-from libcloud.loadbalancer.base import Algorithm, Member
-from libcloud.loadbalancer.types import Provider
-
-SLBDriver = get_driver(Provider.ALIYUN_SLB)
-ECSDriver = get_node_driver(NodeProvider.ALIYUN_ECS)
-
-region = 'cn-hangzhou'
-
-your_access_key_id = ''
-your_access_key_secret = ''
-slb = SLBDriver(your_access_key_id, your_access_key_secret, region=region)
-ecs = ECSDriver(your_access_key_id, your_access_key_secret, region=region)
-
-protos = slb.list_protocols()
-print('Found %d protocols: %s' % (len(protos), protos))
-
-balancers = slb.list_balancers()
-print('Found %d load balancers' % len(balancers))
-print(balancers)
-
-if len(balancers) > 0:
-    b1 = balancers[0]
-    print('Delete %s' % b1)
-    slb.destroy_balancer(b1)
-else:
-    extra = {'AddressType': 'internet',
-             'Bandwidth': 1,
-             'StickySession': 'off',
-             'HealthCheck': 'off'}
-    nodes = ecs.list_nodes()
-    print('Found %d nodes' % len(nodes))
-    members = [Member(node.id, node.public_ips[0], 80, extra={'Weight': 50*(i+1)})
-               for i, node in enumerate(nodes)]
-    new_b = slb.create_balancer('test-balancer', 80, 'http',
-                                Algorithm.WEIGHTED_ROUND_ROBIN, members,
-                                **extra)
-    print('Created balancer %s' % new_b)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/example_compute.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/example_compute.py b/apache-libcloud-1.0.0rc2/example_compute.py
deleted file mode 100644
index 346e7d4..0000000
--- a/apache-libcloud-1.0.0rc2/example_compute.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from libcloud.compute.types import Provider
-from libcloud.compute.providers import get_driver
-
-EC2 = get_driver(Provider.EC2)
-Rackspace = get_driver(Provider.RACKSPACE)
-
-drivers = [EC2('access key id', 'secret key', region='us-east-1'),
-           Rackspace('username', 'api key', region='iad')]
-
-nodes = [driver.list_nodes() for driver in drivers]
-
-print(nodes)
-# [ <Node: provider=Amazon, status=RUNNING, name=bob, ip=1.2.3.4.5>,
-# <Node: provider=Rackspace, status=REBOOT, name=korine, ip=6.7.8.9.10>, ... ]
-
-# grab the node named "test"
-node = [n for n in nodes if n.name == 'test'][0]
-
-# reboot "test"
-node.reboot()

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/example_dns.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/example_dns.py b/apache-libcloud-1.0.0rc2/example_dns.py
deleted file mode 100644
index b99756b..0000000
--- a/apache-libcloud-1.0.0rc2/example_dns.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from pprint import pprint
-
-from libcloud.dns.types import Provider
-from libcloud.dns.providers import get_driver
-
-Zerigo = get_driver(Provider.ZERIGO)
-
-driver = Zerigo('email', 'key')
-
-zones = driver.list_zones()
-pprint(zones)
-
-records = zones[0].list_records()
-pprint(records)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/example_loadbalancer.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/example_loadbalancer.py b/apache-libcloud-1.0.0rc2/example_loadbalancer.py
deleted file mode 100644
index d47a0fe..0000000
--- a/apache-libcloud-1.0.0rc2/example_loadbalancer.py
+++ /dev/null
@@ -1,71 +0,0 @@
-#!/usr/bin/env python
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 os
-import time
-
-from libcloud.loadbalancer.base import Member, Algorithm
-from libcloud.loadbalancer.types import Provider, State
-from libcloud.loadbalancer.providers import get_driver
-
-
-def main():
-    cls = get_driver(Provider.RACKSPACE)
-    driver = cls('username', 'api key', region='ord')
-
-    balancers = driver.list_balancers()
-
-    print(balancers)
-
-    # creating a balancer which balances traffic across two
-    # nodes: 192.168.86.1:80 and 192.168.86.2:8080. Balancer
-    # itself listens on port 80/tcp
-    new_balancer_name = 'testlb' + os.urandom(4).encode('hex')
-    members = (Member(None, '192.168.86.1', 80),
-               Member(None, '192.168.86.2', 8080))
-    new_balancer = driver.create_balancer(name=new_balancer_name,
-                                          algorithm=Algorithm.ROUND_ROBIN,
-                                          port=80,
-                                          protocol='http',
-                                          members=members)
-
-    print(new_balancer)
-
-    # wait for balancer to become ready
-    # NOTE: in real life code add timeout to not end up in
-    # endless loop when things go wrong on provider side
-    while True:
-        balancer = driver.get_balancer(balancer_id=new_balancer.id)
-
-        if balancer.state == State.RUNNING:
-            break
-
-        print('sleeping for 30 seconds for balancers to become ready')
-        time.sleep(30)
-
-    # fetch list of members
-    members = balancer.list_members()
-    print(members)
-
-    # remove first member
-    balancer.detach_member(members[0])
-
-    # remove the balancer
-    driver.destroy_balancer(new_balancer)
-
-if __name__ == '__main__':
-    main()

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/example_storage.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/example_storage.py b/apache-libcloud-1.0.0rc2/example_storage.py
deleted file mode 100644
index be3058c..0000000
--- a/apache-libcloud-1.0.0rc2/example_storage.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from pprint import pprint
-
-from libcloud.storage.types import Provider
-from libcloud.storage.providers import get_driver
-
-CloudFiles = get_driver(Provider.CLOUDFILES)
-
-driver = CloudFiles('access key id', 'secret key', region='ord')
-
-containers = driver.list_containers()
-container_objects = driver.list_container_objects(containers[0])
-
-pprint(containers)
-pprint(container_objects)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/__init__.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/__init__.py b/apache-libcloud-1.0.0rc2/libcloud/__init__.py
deleted file mode 100644
index 1f90b1b..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/__init__.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-libcloud provides a unified interface to the cloud computing resources.
-
-:var __version__: Current version of libcloud
-"""
-
-__all__ = ['__version__', 'enable_debug']
-__version__ = '1.0.0-rc2'
-
-import os
-import codecs
-
-try:
-    import paramiko
-    have_paramiko = True
-except ImportError:
-    have_paramiko = False
-
-
-def enable_debug(fo):
-    """
-    Enable library wide debugging to a file-like object.
-
-    :param fo: Where to append debugging information
-    :type fo: File like object, only write operations are used.
-    """
-    from libcloud.common.base import (Connection,
-                                      LoggingHTTPConnection,
-                                      LoggingHTTPSConnection)
-    LoggingHTTPSConnection.log = fo
-    LoggingHTTPConnection.log = fo
-    Connection.conn_classes = (LoggingHTTPConnection,
-                               LoggingHTTPSConnection)
-
-
-def _init_once():
-    """
-    Utility function that is ran once on Library import.
-
-    This checks for the LIBCLOUD_DEBUG environment variable, which if it exists
-    is where we will log debug information about the provider transports.
-    """
-    path = os.getenv('LIBCLOUD_DEBUG')
-    if path:
-        mode = 'a'
-
-        # Special case for /dev/stderr and /dev/stdout on Python 3.
-        from libcloud.utils.py3 import PY3
-
-        # Opening those files in append mode will throw "illegal seek"
-        # exception there.
-        # Late import to avoid setup.py related side affects
-        if path in ['/dev/stderr', '/dev/stdout'] and PY3:
-            mode = 'w'
-
-        fo = codecs.open(path, mode, encoding='utf8')
-        enable_debug(fo)
-
-        if have_paramiko:
-            paramiko.common.logging.basicConfig(level=paramiko.common.DEBUG)
-
-_init_once()

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/backup/__init__.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/backup/__init__.py b/apache-libcloud-1.0.0rc2/libcloud/backup/__init__.py
deleted file mode 100644
index e69de29..0000000

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/backup/base.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/backup/base.py b/apache-libcloud-1.0.0rc2/libcloud/backup/base.py
deleted file mode 100644
index 8d1c5a7..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/backup/base.py
+++ /dev/null
@@ -1,489 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from libcloud.common.base import ConnectionUserAndKey, BaseDriver
-from libcloud.backup.types import BackupTargetType
-
-__all__ = [
-    'BackupTarget',
-    'BackupDriver',
-    'BackupTargetJob',
-    'BackupTargetRecoveryPoint'
-]
-
-
-class BackupTarget(object):
-    """
-    A backup target
-    """
-
-    def __init__(self, id, name, address, type, driver, extra=None):
-        """
-        :param id: Target id
-        :type id: ``str``
-
-        :param name: Name of the target
-        :type name: ``str``
-
-        :param address: Hostname, FQDN, IP, file path etc.
-        :type address: ``str``
-
-        :param type: Backup target type (Physical, Virtual, ...).
-        :type type: :class:`.BackupTargetType`
-
-        :param driver: BackupDriver instance.
-        :type driver: :class:`.BackupDriver`
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type extra: ``dict``
-        """
-        self.id = str(id) if id else None
-        self.name = name
-        self.address = address
-        self.type = type
-        self.driver = driver
-        self.extra = extra or {}
-
-    def update(self, name=None, address=None, extra=None):
-        return self.driver.update_target(target=self,
-                                         name=name,
-                                         address=address,
-                                         extra=extra)
-
-    def delete(self):
-        return self.driver.delete_target(target=self)
-
-    def _get_numeric_id(self):
-        target_id = self.id
-
-        if target_id.isdigit():
-            target_id = int(target_id)
-
-        return target_id
-
-    def __repr__(self):
-        return ('<Target: id=%s, name=%s, address=%s'
-                'type=%s, provider=%s ...>' %
-                (self.id, self.name, self.address,
-                 self.type, self.driver.name))
-
-
-class BackupTargetJob(object):
-    """
-    A backup target job
-    """
-
-    def __init__(self, id, status, progress, target, driver, extra=None):
-        """
-        :param id: Job id
-        :type id: ``str``
-
-        :param status: Status of the job
-        :type status: :class:`BackupTargetJobStatusType`
-
-        :param progress: Progress of the job, as a percentage
-        :type progress: ``int``
-
-        :param target: BackupTarget instance.
-        :type target: :class:`.BackupTarget`
-
-        :param driver: BackupDriver instance.
-        :type driver: :class:`.BackupDriver`
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type extra: ``dict``
-        """
-        self.id = str(id) if id else None
-        self.status = status
-        self.progress = progress
-        self.target = target
-        self.driver = driver
-        self.extra = extra or {}
-
-    def cancel(self):
-        return self.driver.cancel_target_job(job=self)
-
-    def suspend(self):
-        return self.driver.suspend_target_job(job=self)
-
-    def resume(self):
-        return self.driver.resume_target_job(job=self)
-
-    def __repr__(self):
-        return ('<Job: id=%s, status=%s, progress=%s'
-                'target=%s, provider=%s ...>' %
-                (self.id, self.status, self.progress,
-                 self.target.id, self.driver.name))
-
-
-class BackupTargetRecoveryPoint(object):
-    """
-    A backup target recovery point
-    """
-
-    def __init__(self, id, date, target, driver, extra=None):
-        """
-        :param id: Job id
-        :type id: ``str``
-
-        :param date: The date taken
-        :type date: :class:`datetime.datetime`
-
-        :param target: BackupTarget instance.
-        :type target: :class:`.BackupTarget`
-
-        :param driver: BackupDriver instance.
-        :type driver: :class:`.BackupDriver`
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type extra: ``dict``
-        """
-        self.id = str(id) if id else None
-        self.date = date
-        self.target = target
-        self.driver = driver
-        self.extra = extra or {}
-
-    def recover(self, path=None):
-        """
-        Recover this recovery point
-
-        :param path: The part of the recovery point to recover (optional)
-        :type  path: ``str``
-
-        :rtype: Instance of :class:`.BackupTargetJob`
-        """
-        return self.driver.recover_target(target=self.target,
-                                          recovery_point=self, path=path)
-
-    def recover_to(self, recovery_target, path=None):
-        """
-        Recover this recovery point out of place
-
-        :param recovery_target: Backup target with to recover the data to
-        :type  recovery_target: Instance of :class:`.BackupTarget`
-
-        :param path: The part of the recovery point to recover (optional)
-        :type  path: ``str``
-
-        :rtype: Instance of :class:`.BackupTargetJob`
-        """
-        return self.driver.recover_target_out_of_place(
-            target=self.target,
-            recovery_point=self,
-            recovery_target=recovery_target,
-            path=path)
-
-    def __repr__(self):
-        return ('<RecoveryPoint: id=%s, date=%s, '
-                'target=%s, provider=%s ...>' %
-                (self.id, self.date,
-                 self.target.id, self.driver.name))
-
-
-class BackupDriver(BaseDriver):
-    """
-    A base BackupDriver class to derive from
-
-    This class is always subclassed by a specific driver.
-    """
-    connectionCls = ConnectionUserAndKey
-    name = None
-    website = None
-
-    def __init__(self, key, secret=None, secure=True, host=None, port=None,
-                 **kwargs):
-        """
-        :param    key: API key or username to used (required)
-        :type     key: ``str``
-
-        :param    secret: Secret password to be used (required)
-        :type     secret: ``str``
-
-        :param    secure: Whether to use HTTPS or HTTP. Note: Some providers
-                only support HTTPS, and it is on by default.
-        :type     secure: ``bool``
-
-        :param    host: Override hostname used for connections.
-        :type     host: ``str``
-
-        :param    port: Override port used for connections.
-        :type     port: ``int``
-
-        :return: ``None``
-        """
-        super(BackupDriver, self).__init__(key=key, secret=secret,
-                                           secure=secure, host=host, port=port,
-                                           **kwargs)
-
-    def get_supported_target_types(self):
-        """
-        Get a list of backup target types this driver supports
-
-        :return: ``list`` of :class:``BackupTargetType``
-        """
-        raise NotImplementedError(
-            'get_supported_target_types not implemented for this driver')
-
-    def list_targets(self):
-        """
-        List all backuptargets
-
-        :rtype: ``list`` of :class:`.BackupTarget`
-        """
-        raise NotImplementedError(
-            'list_targets not implemented for this driver')
-
-    def create_target(self, name, address,
-                      type=BackupTargetType.VIRTUAL, extra=None):
-        """
-        Creates a new backup target
-
-        :param name: Name of the target
-        :type name: ``str``
-
-        :param address: Hostname, FQDN, IP, file path etc.
-        :type address: ``str``
-
-        :param type: Backup target type (Physical, Virtual, ...).
-        :type type: :class:`BackupTargetType`
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type extra: ``dict``
-
-        :rtype: Instance of :class:`.BackupTarget`
-        """
-        raise NotImplementedError(
-            'create_target not implemented for this driver')
-
-    def create_target_from_node(self, node, type=BackupTargetType.VIRTUAL,
-                                extra=None):
-        """
-        Creates a new backup target from an existing node.
-        By default, this will use the first public IP of the node
-
-        :param node: The Node to backup
-        :type  node: ``Node``
-
-        :param type: Backup target type (Physical, Virtual, ...).
-        :type type: :class:`BackupTargetType`
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type extra: ``dict``
-
-        :rtype: Instance of :class:`.BackupTarget`
-        """
-        return self.create_target(name=node.name,
-                                  address=node.public_ips[0],
-                                  type=type,
-                                  extra=None)
-
-    def create_target_from_storage_container(self, container,
-                                             type=BackupTargetType.OBJECT,
-                                             extra=None):
-        """
-        Creates a new backup target from an existing storage container
-
-        :param node: The Container to backup
-        :type  node: ``Container``
-
-        :param type: Backup target type (Physical, Virtual, ...).
-        :type type: :class:`BackupTargetType`
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type extra: ``dict``
-
-        :rtype: Instance of :class:`.BackupTarget`
-        """
-        return self.create_target(name=container.name,
-                                  address=container.get_cdn_url(),
-                                  type=type,
-                                  extra=None)
-
-    def update_target(self, target, name, address, extra):
-        """
-        Update the properties of a backup target
-
-        :param target: Backup target to update
-        :type  target: Instance of :class:`.BackupTarget`
-
-        :param name: Name of the target
-        :type name: ``str``
-
-        :param address: Hostname, FQDN, IP, file path etc.
-        :type address: ``str``
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type extra: ``dict``
-
-        :rtype: Instance of :class:`.BackupTarget`
-        """
-        raise NotImplementedError(
-            'update_target not implemented for this driver')
-
-    def delete_target(self, target):
-        """
-        Delete a backup target
-
-        :param target: Backup target to delete
-        :type  target: Instance of :class:`.BackupTarget`
-        """
-        raise NotImplementedError(
-            'delete_target not implemented for this driver')
-
-    def list_recovery_points(self, target, start_date=None, end_date=None):
-        """
-        List the recovery points available for a target
-
-        :param target: Backup target to delete
-        :type  target: Instance of :class:`.BackupTarget`
-
-        :param start_date: The start date to show jobs between (optional)
-        :type  start_date: :class:`datetime.datetime`
-
-        :param end_date: The end date to show jobs between (optional)
-        :type  end_date: :class:`datetime.datetime``
-
-        :rtype: ``list`` of :class:`.BackupTargetRecoveryPoint`
-        """
-        raise NotImplementedError(
-            'list_recovery_points not implemented for this driver')
-
-    def recover_target(self, target, recovery_point, path=None):
-        """
-        Recover a backup target to a recovery point
-
-        :param target: Backup target to delete
-        :type  target: Instance of :class:`.BackupTarget`
-
-        :param recovery_point: Backup target with the backup data
-        :type  recovery_point: Instance of :class:`.BackupTarget`
-
-        :param path: The part of the recovery point to recover (optional)
-        :type  path: ``str``
-
-        :rtype: Instance of :class:`.BackupTargetJob`
-        """
-        raise NotImplementedError(
-            'recover_target not implemented for this driver')
-
-    def recover_target_out_of_place(self, target, recovery_point,
-                                    recovery_target, path=None):
-        """
-        Recover a backup target to a recovery point out-of-place
-
-        :param target: Backup target with the backup data
-        :type  target: Instance of :class:`.BackupTarget`
-
-        :param recovery_point: Backup target with the backup data
-        :type  recovery_point: Instance of :class:`.BackupTarget`
-
-        :param recovery_target: Backup target with to recover the data to
-        :type  recovery_target: Instance of :class:`.BackupTarget`
-
-        :param path: The part of the recovery point to recover (optional)
-        :type  path: ``str``
-
-        :rtype: Instance of :class:`BackupTargetJob`
-        """
-        raise NotImplementedError(
-            'recover_target_out_of_place not implemented for this driver')
-
-    def get_target_job(self, target, id):
-        """
-        Get a specific backup job by ID
-
-        :param target: Backup target with the backup data
-        :type  target: Instance of :class:`.BackupTarget`
-
-        :param id: Backup target with the backup data
-        :type  id: Instance of :class:`.BackupTarget`
-
-        :rtype: :class:`BackupTargetJob`
-        """
-        jobs = self.list_target_jobs(target)
-        return list(filter(lambda x: x.id == id, jobs))[0]
-
-    def list_target_jobs(self, target):
-        """
-        List the backup jobs on a target
-
-        :param target: Backup target with the backup data
-        :type  target: Instance of :class:`.BackupTarget`
-
-        :rtype: ``list`` of :class:`.BackupTargetJob`
-        """
-        raise NotImplementedError(
-            'list_target_jobs not implemented for this driver')
-
-    def create_target_job(self, target, extra=None):
-        """
-        Create a new backup job on a target
-
-        :param target: Backup target with the backup data
-        :type  target: Instance of :class:`.BackupTarget`
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type extra: ``dict``
-
-        :rtype: Instance of :class:`BackupTargetJob`
-        """
-        raise NotImplementedError(
-            'create_target_job not implemented for this driver')
-
-    def resume_target_job(self, job):
-        """
-        Resume a suspended backup job on a target
-
-        :param target: Backup target with the backup data
-        :type  target: Instance of :class:`.BackupTarget`
-
-        :param job: Backup target job to resume
-        :type  job: Instance of :class:`.BackupTargetJob`
-
-        :rtype: ``bool``
-        """
-        raise NotImplementedError(
-            'resume_target_job not implemented for this driver')
-
-    def suspend_target_job(self, job):
-        """
-        Suspend a running backup job on a target
-
-        :param target: Backup target with the backup data
-        :type  target: Instance of :class:`.BackupTarget`
-
-        :param job: Backup target job to suspend
-        :type  job: Instance of :class:`.BackupTargetJob`
-
-        :rtype: ``bool``
-        """
-        raise NotImplementedError(
-            'suspend_target_job not implemented for this driver')
-
-    def cancel_target_job(self, job):
-        """
-        Cancel a backup job on a target
-
-        :param target: Backup target with the backup data
-        :type  target: Instance of :class:`.BackupTarget`
-
-        :param job: Backup target job to cancel
-        :type  job: Instance of :class:`.BackupTargetJob`
-
-        :rtype: ``bool``
-        """
-        raise NotImplementedError(
-            'cancel_target_job not implemented for this driver')

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/backup/drivers/__init__.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/backup/drivers/__init__.py b/apache-libcloud-1.0.0rc2/libcloud/backup/drivers/__init__.py
deleted file mode 100644
index e69de29..0000000


[31/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/cloudwatt.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/cloudwatt.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/cloudwatt.py
deleted file mode 100644
index fe256f7..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/cloudwatt.py
+++ /dev/null
@@ -1,154 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-Cloudwatt driver.
-"""
-import sys
-try:
-    import simplejson as json
-except ImportError:
-    import json
-from libcloud.utils.py3 import httplib
-from libcloud.compute.types import Provider
-from libcloud.compute.drivers.openstack import OpenStack_1_1_Connection
-from libcloud.compute.drivers.openstack import OpenStack_1_1_NodeDriver
-from libcloud.common.openstack_identity import OpenStackIdentityConnection
-from libcloud.utils.iso8601 import parse_date
-
-from libcloud.compute.types import InvalidCredsError, MalformedResponseError
-
-
-__all__ = [
-    'CloudwattNodeDriver'
-]
-
-BASE_URL = 'https://identity.fr1.cloudwatt.com/v2.0'
-AUTH_URL = BASE_URL + '/tokens'
-
-
-class CloudwattAuthConnection(OpenStackIdentityConnection):
-    """
-    AuthConnection class for the Cloudwatt driver.
-    """
-    name = 'Cloudwatt Auth'
-
-    def __init__(self, *args, **kwargs):
-        self._ex_tenant_id = kwargs.pop('ex_tenant_id')
-        super(CloudwattAuthConnection, self).__init__(*args, **kwargs)
-
-    def authenticate(self, force=False):
-        reqbody = json.dumps({'auth': {
-            'passwordCredentials': {
-                'username': self.user_id,
-                'password': self.key
-            },
-            'tenantId': self._ex_tenant_id
-        }})
-        resp = self.request('/tokens', data=reqbody, headers={},
-                            method='POST')
-
-        if resp.status == httplib.UNAUTHORIZED:
-            # HTTP UNAUTHORIZED (401): auth failed
-            raise InvalidCredsError()
-        elif resp.status != httplib.OK:
-            body = 'code: %s body:%s' % (resp.status, resp.body)
-            raise MalformedResponseError('Malformed response', body=body,
-                                         driver=self.driver)
-        else:
-            try:
-                body = json.loads(resp.body)
-            except Exception:
-                e = sys.exc_info()[1]
-                raise MalformedResponseError('Failed to parse JSON', e)
-
-            try:
-                expires = body['access']['token']['expires']
-
-                self.auth_token = body['access']['token']['id']
-                self.auth_token_expires = parse_date(expires)
-                self.urls = body['access']['serviceCatalog']
-                self.auth_user_info = None
-            except KeyError:
-                e = sys.exc_info()[1]
-                raise MalformedResponseError('Auth JSON response is \
-                                             missing required elements', e)
-
-        return self
-
-
-class CloudwattConnection(OpenStack_1_1_Connection):
-    """
-    Connection class for the Cloudwatt driver.
-    """
-    auth_url = BASE_URL
-    service_region = 'fr1'
-    service_type = 'compute'
-
-    def __init__(self, *args, **kwargs):
-        self.ex_tenant_id = kwargs.pop('ex_tenant_id')
-        super(CloudwattConnection, self).__init__(*args, **kwargs)
-        osa = CloudwattAuthConnection(
-            auth_url=AUTH_URL,
-            user_id=self.user_id,
-            key=self.key,
-            tenant_name=self._ex_tenant_name,
-            timeout=self.timeout,
-            ex_tenant_id=self.ex_tenant_id,
-            parent_conn=self
-        )
-        self._osa = osa
-        self._auth_version = '2.0'
-
-
-class CloudwattNodeDriver(OpenStack_1_1_NodeDriver):
-    """
-    Implements the :class:`NodeDriver`'s for Cloudwatt.
-    """
-    name = 'Cloudwatt'
-    website = 'https://www.cloudwatt.com/'
-    connectionCls = CloudwattConnection
-    type = Provider.CLOUDWATT
-
-    def __init__(self, key, secret, tenant_id, secure=True, tenant_name=None,
-                 host=None, port=None, **kwargs):
-        """
-        @inherits:  :class:`NodeDriver.__init__`
-
-        :param tenant_id: ID of tenant required for Cloudwatt auth
-        :type tenant_id: ``str``
-        """
-        self.ex_tenant_id = tenant_id
-        self.extra = {}
-        super(CloudwattNodeDriver, self).__init__(
-            key=key,
-            secret=secret,
-            secure=secure,
-            host=host,
-            port=port,
-            **kwargs
-        )
-
-    def attach_volume(self, node, volume, device=None):
-        return super(CloudwattNodeDriver, self)\
-            .attach_volume(node, volume, device)
-
-    def _ex_connection_class_kwargs(self):
-        """
-        Includes ``tenant_id`` in Connection.
-        """
-        return {
-            'ex_tenant_id': self.ex_tenant_id
-        }

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/digitalocean.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/digitalocean.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/digitalocean.py
deleted file mode 100644
index 0428cbb..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/digitalocean.py
+++ /dev/null
@@ -1,592 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-DigitalOcean Driver
-"""
-import json
-import warnings
-
-from libcloud.utils.iso8601 import parse_date
-from libcloud.utils.py3 import httplib
-
-from libcloud.common.digitalocean import DigitalOcean_v1_BaseDriver
-from libcloud.common.digitalocean import DigitalOcean_v2_BaseDriver
-from libcloud.common.types import InvalidCredsError
-from libcloud.compute.types import Provider, NodeState
-from libcloud.compute.base import NodeImage, NodeSize, NodeLocation, KeyPair
-from libcloud.compute.base import Node, NodeDriver
-
-__all__ = [
-    'DigitalOceanNodeDriver',
-    'DigitalOcean_v1_NodeDriver',
-    'DigitalOcean_v2_NodeDriver'
-]
-
-
-class DigitalOceanNodeDriver(NodeDriver):
-    """
-    DigitalOcean NodeDriver defaulting to using APIv2.
-
-    :keyword    key: Required for authentication. Used in both ``v1`` and
-                     ``v2`` implementations.
-    :type       key: ``str``
-
-    :keyword    secret: Used in driver authentication with key. Defaults to
-                        None and when set, will cause driver to use ``v1`` for
-                        connection and response. (optional)
-    :type       secret: ``str``
-
-    :keyword    api_version: Specifies the API version to use. ``v1`` and
-                             ``v2`` are the only valid options. Defaults to
-                             using ``v2`` (optional)
-    :type       api_version: ``str``
-    """
-    type = Provider.DIGITAL_OCEAN
-    name = 'DigitalOcean'
-    website = 'https://www.digitalocean.com'
-
-    def __new__(cls, key, secret=None, api_version='v2', **kwargs):
-        if cls is DigitalOceanNodeDriver:
-            if api_version == 'v1' or secret is not None:
-                if secret is None:
-                    raise InvalidCredsError(
-                        'secret missing for v1 authentication')
-                if secret is not None and api_version == 'v2':
-                    raise InvalidCredsError(
-                        'secret not accepted for v2 authentication')
-                cls = DigitalOcean_v1_NodeDriver
-            elif api_version == 'v2':
-                cls = DigitalOcean_v2_NodeDriver
-            else:
-                raise NotImplementedError('Unsupported API version: %s' %
-                                          (api_version))
-        return super(DigitalOceanNodeDriver, cls).__new__(cls, **kwargs)
-
-
-# TODO Implement v1 driver using KeyPair
-class SSHKey(object):
-    def __init__(self, id, name, pub_key):
-        self.id = id
-        self.name = name
-        self.pub_key = pub_key
-
-    def __repr__(self):
-        return (('<SSHKey: id=%s, name=%s, pub_key=%s>') %
-                (self.id, self.name, self.pub_key))
-
-
-class DigitalOcean_v1_NodeDriver(DigitalOcean_v1_BaseDriver,
-                                 DigitalOceanNodeDriver):
-    """
-    DigitalOcean NodeDriver using v1 of the API.
-    """
-
-    NODE_STATE_MAP = {'new': NodeState.PENDING,
-                      'off': NodeState.REBOOTING,
-                      'active': NodeState.RUNNING}
-
-    def list_nodes(self):
-        data = self.connection.request('/v1/droplets').object['droplets']
-        return list(map(self._to_node, data))
-
-    def list_locations(self):
-        data = self.connection.request('/v1/regions').object['regions']
-        return list(map(self._to_location, data))
-
-    def list_images(self):
-        data = self.connection.request('/v1/images').object['images']
-        return list(map(self._to_image, data))
-
-    def list_sizes(self):
-        data = self.connection.request('/v1/sizes').object['sizes']
-        return list(map(self._to_size, data))
-
-    def create_node(self, name, size, image, location, ex_ssh_key_ids=None):
-        """
-        Create a node.
-
-        :keyword    ex_ssh_key_ids: A list of ssh key ids which will be added
-                                   to the server. (optional)
-        :type       ex_ssh_key_ids: ``list`` of ``str``
-
-        :return: The newly created node.
-        :rtype: :class:`Node`
-        """
-        params = {'name': name, 'size_id': size.id, 'image_id': image.id,
-                  'region_id': location.id}
-
-        if ex_ssh_key_ids:
-            params['ssh_key_ids'] = ','.join(ex_ssh_key_ids)
-
-        data = self.connection.request('/v1/droplets/new', params=params)
-
-        # TODO: Handle this in the response class
-        status = data.object.get('status', 'OK')
-        if status == 'ERROR':
-            message = data.object.get('message', None)
-            error_message = data.object.get('error_message', message)
-            raise ValueError('Failed to create node: %s' % (error_message))
-
-        return self._to_node(data=data.object['droplet'])
-
-    def reboot_node(self, node):
-        res = self.connection.request('/v1/droplets/%s/reboot/' % (node.id))
-        return res.status == httplib.OK
-
-    def destroy_node(self, node):
-        params = {'scrub_data': '1'}
-        res = self.connection.request('/v1/droplets/%s/destroy/' % (node.id),
-                                      params=params)
-        return res.status == httplib.OK
-
-    def ex_rename_node(self, node, name):
-        params = {'name': name}
-        res = self.connection.request('/v1/droplets/%s/rename/' % (node.id),
-                                      params=params)
-        return res.status == httplib.OK
-
-    def list_key_pairs(self):
-        """
-        List all the available SSH keys.
-
-        :return: Available SSH keys.
-        :rtype: ``list`` of :class:`KeyPair`
-        """
-        data = self.connection.request('/v1/ssh_keys').object['ssh_keys']
-        return list(map(self._to_key_pair, data))
-
-    def ex_list_ssh_keys(self):
-        """
-        List all the available SSH keys.
-        :return: Available SSH keys.
-        :rtype: ``list`` of :class:`SSHKey`
-        """
-        warnings.warn("This method has been deprecated in "
-                      "favor of the list_key_pairs method")
-
-        data = self.connection.request('/v1/ssh_keys').object['ssh_keys']
-        return list(map(self._to_ssh_key, data))
-
-    def get_key_pair(self, name):
-        """
-        Retrieve a single key pair.
-
-        :param name: Name of the key pair to retrieve.
-        :type name: ``str``
-
-        :rtype: :class:`.KeyPair`
-        """
-        qkey = [k for k in self.list_key_pairs() if k.name == name][0]
-        data = self.connection.request('/v1/ssh_keys/%s' %
-                                       qkey.extra['id']).object['ssh_key']
-        return self._to_key_pair(data=data)
-
-    # TODO: This adds the ssh_key_pub parameter. This puts the burden of making
-    #      it within the function or on the API. The KeyPair API needs work.
-    def create_key_pair(self, name, ssh_key_pub):
-        """
-        Create a new SSH key.
-
-        :param      name: Key name (required)
-        :type       name: ``str``
-
-        :param      name: Valid public key string (required)
-        :type       name: ``str``
-        """
-        params = {'name': name, 'ssh_pub_key': ssh_key_pub}
-        data = self.connection.request('/v1/ssh_keys/new/', method='GET',
-                                       params=params).object
-        assert 'ssh_key' in data
-        # TODO: libcloud.compute.base.KeyPair.create_key_pair doesn't specify
-        #      a return value. This looks like it should return a KeyPair
-        return self._to_key_pair(data=data['ssh_key'])
-
-    def ex_create_ssh_key(self, name, ssh_key_pub):
-        """
-        Create a new SSH key.
-        :param      name: Key name (required)
-        :type       name: ``str``
-        :param      name: Valid public key string (required)
-        :type       name: ``str``
-        """
-        warnings.warn("This method has been deprecated in "
-                      "favor of the create_key_pair method")
-
-        params = {'name': name, 'ssh_pub_key': ssh_key_pub}
-        data = self.connection.request('/v1/ssh_keys/new/', method='GET',
-                                       params=params).object
-        assert 'ssh_key' in data
-        return self._to_ssh_key(data=data['ssh_key'])
-
-    def delete_key_pair(self, key_pair):
-        """
-        Delete an existing key pair.
-
-        :param key_pair: Key pair object.
-        :type key_pair: :class:`.KeyPair`
-        """
-        res = self.connection.request('/v1/ssh_keys/%s/destroy/' %
-                                      key_pair.extra['id'])
-        # TODO: This looks like it should return bool like the other delete_*
-        return res.status == httplib.OK
-
-    def ex_destroy_ssh_key(self, key_id):
-        """
-        Delete an existing SSH key.
-        :param      key_id: SSH key id (required)
-        :type       key_id: ``str``
-        """
-        warnings.warn(
-            "This method has been deprecated in "
-            "favor of the delete_key_pair method")
-
-        res = self.connection.request('/v1/ssh_keys/%s/destroy/' % (key_id))
-        return res.status == httplib.OK
-
-    def _to_node(self, data):
-        extra_keys = ['backups_active', 'region_id', 'image_id', 'size_id']
-        if 'status' in data:
-            state = self.NODE_STATE_MAP.get(data['status'], NodeState.UNKNOWN)
-        else:
-            state = NodeState.UNKNOWN
-
-        if 'ip_address' in data and data['ip_address'] is not None:
-            public_ips = [data['ip_address']]
-        else:
-            public_ips = []
-
-        extra = {}
-        for key in extra_keys:
-            if key in data:
-                extra[key] = data[key]
-
-        node = Node(id=data['id'], name=data['name'], state=state,
-                    public_ips=public_ips, private_ips=None, extra=extra,
-                    driver=self)
-        return node
-
-    def _to_image(self, data):
-        extra = {'distribution': data['distribution']}
-        return NodeImage(id=data['id'], name=data['name'], extra=extra,
-                         driver=self)
-
-    def _to_location(self, data):
-        return NodeLocation(id=data['id'], name=data['name'], country=None,
-                            driver=self)
-
-    def _to_size(self, data):
-        ram = data['name'].lower()
-
-        if 'mb' in ram:
-            ram = int(ram.replace('mb', ''))
-        elif 'gb' in ram:
-            ram = int(ram.replace('gb', '')) * 1024
-
-        return NodeSize(id=data['id'], name=data['name'], ram=ram, disk=0,
-                        bandwidth=0, price=0, driver=self)
-
-    def _to_key_pair(self, data):
-        try:
-            pubkey = data['ssh_pub_key']
-        except KeyError:
-            pubkey = None
-        return KeyPair(data['name'], public_key=pubkey, fingerprint=None,
-                       driver=self, private_key=None, extra={'id': data['id']})
-
-    def _to_ssh_key(self, data):
-        return SSHKey(id=data['id'], name=data['name'],
-                      pub_key=data.get('ssh_pub_key', None))
-
-
-class DigitalOcean_v2_NodeDriver(DigitalOcean_v2_BaseDriver,
-                                 DigitalOceanNodeDriver):
-    """
-    DigitalOcean NodeDriver using v2 of the API.
-    """
-
-    NODE_STATE_MAP = {'new': NodeState.PENDING,
-                      'off': NodeState.STOPPED,
-                      'active': NodeState.RUNNING,
-                      'archive': NodeState.TERMINATED}
-
-    EX_CREATE_ATTRIBUTES = ['backups',
-                            'ipv6',
-                            'private_networking',
-                            'ssh_keys']
-
-    def list_images(self):
-        data = self._paginated_request('/v2/images', 'images')
-        return list(map(self._to_image, data))
-
-    def list_key_pairs(self):
-        """
-        List all the available SSH keys.
-
-        :return: Available SSH keys.
-        :rtype: ``list`` of :class:`KeyPair`
-        """
-        data = self._paginated_request('/v2/account/keys', 'ssh_keys')
-        return list(map(self._to_key_pair, data))
-
-    def list_locations(self):
-        data = self._paginated_request('/v2/regions', 'regions')
-        return list(map(self._to_location, data))
-
-    def list_nodes(self):
-        data = self._paginated_request('/v2/droplets', 'droplets')
-        return list(map(self._to_node, data))
-
-    def list_sizes(self):
-        data = self._paginated_request('/v2/sizes', 'sizes')
-        return list(map(self._to_size, data))
-
-    def create_node(self, name, size, image, location, ex_create_attr=None,
-                    ex_ssh_key_ids=None, ex_user_data=None):
-        """
-        Create a node.
-
-        The `ex_create_attr` parameter can include the following dictionary
-        key and value pairs:
-
-        * `backups`: ``bool`` defaults to False
-        * `ipv6`: ``bool`` defaults to False
-        * `private_networking`: ``bool`` defaults to False
-        * `user_data`: ``str`` for cloud-config data
-        * `ssh_keys`: ``list`` of ``int`` key ids or ``str`` fingerprints
-
-        `ex_create_attr['ssh_keys']` will override `ex_ssh_key_ids` assignment.
-
-        :keyword ex_create_attr: A dictionary of optional attributes for
-                                 droplet creation
-        :type ex_create_attr: ``dict``
-
-        :keyword ex_ssh_key_ids: A list of ssh key ids which will be added
-                                 to the server. (optional)
-        :type ex_ssh_key_ids: ``list`` of ``int`` key ids or ``str``
-                              key fingerprints
-
-        :keyword    ex_user_data:  User data to be added to the node on create.
-                                     (optional)
-        :type       ex_user_data:  ``str``
-
-        :return: The newly created node.
-        :rtype: :class:`Node`
-        """
-        attr = {'name': name, 'size': size.name, 'image': image.id,
-                'region': location.id, 'user_data': ex_user_data}
-
-        if ex_ssh_key_ids:
-            warnings.warn("The ex_ssh_key_ids parameter has been deprecated in"
-                          " favor of the ex_create_attr parameter.")
-            attr['ssh_keys'] = ex_ssh_key_ids
-
-        ex_create_attr = ex_create_attr or {}
-        for key in ex_create_attr.keys():
-            if key in self.EX_CREATE_ATTRIBUTES:
-                attr[key] = ex_create_attr[key]
-
-        res = self.connection.request('/v2/droplets',
-                                      data=json.dumps(attr), method='POST')
-
-        data = res.object['droplet']
-        # TODO: Handle this in the response class
-        status = res.object.get('status', 'OK')
-        if status == 'ERROR':
-            message = res.object.get('message', None)
-            error_message = res.object.get('error_message', message)
-            raise ValueError('Failed to create node: %s' % (error_message))
-
-        return self._to_node(data=data)
-
-    def destroy_node(self, node):
-        res = self.connection.request('/v2/droplets/%s' % (node.id),
-                                      method='DELETE')
-        return res.status == httplib.NO_CONTENT
-
-    def reboot_node(self, node):
-        attr = {'type': 'reboot'}
-        res = self.connection.request('/v2/droplets/%s/actions' % (node.id),
-                                      data=json.dumps(attr), method='POST')
-        return res.status == httplib.CREATED
-
-    def create_image(self, node, name):
-        """
-        Create an image from a Node.
-
-        @inherits: :class:`NodeDriver.create_image`
-
-        :param node: Node to use as base for image
-        :type node: :class:`Node`
-
-        :param node: Name for image
-        :type node: ``str``
-
-        :rtype: ``bool``
-        """
-        attr = {'type': 'snapshot', 'name': name}
-        res = self.connection.request('/v2/droplets/%s/actions' % (node.id),
-                                      data=json.dumps(attr), method='POST')
-        return res.status == httplib.CREATED
-
-    def delete_image(self, image):
-        """Delete an image for node.
-
-        @inherits: :class:`NodeDriver.delete_image`
-
-        :param      image: the image to be deleted
-        :type       image: :class:`NodeImage`
-
-        :rtype: ``bool``
-        """
-        res = self.connection.request('/v2/images/%s' % (image.id),
-                                      method='DELETE')
-        return res.status == httplib.NO_CONTENT
-
-    def get_image(self, image_id):
-        """
-        Get an image based on an image_id
-
-        @inherits: :class:`NodeDriver.get_image`
-
-        :param image_id: Image identifier
-        :type image_id: ``int``
-
-        :return: A NodeImage object
-        :rtype: :class:`NodeImage`
-        """
-        data = self._paginated_request('/v2/images/%s' % (image_id), 'image')
-        return self._to_image(data)
-
-    def ex_rename_node(self, node, name):
-        attr = {'type': 'rename', 'name': name}
-        res = self.connection.request('/v2/droplets/%s/actions' % (node.id),
-                                      data=json.dumps(attr), method='POST')
-        return res.status == httplib.CREATED
-
-    def ex_shutdown_node(self, node):
-        attr = {'type': 'shutdown'}
-        res = self.connection.request('/v2/droplets/%s/actions' % (node.id),
-                                      data=json.dumps(attr), method='POST')
-        return res.status == httplib.CREATED
-
-    def ex_power_on_node(self, node):
-        attr = {'type': 'power_on'}
-        res = self.connection.request('/v2/droplets/%s/actions' % (node.id),
-                                      data=json.dumps(attr), method='POST')
-        return res.status == httplib.CREATED
-
-    def create_key_pair(self, name, public_key=''):
-        """
-        Create a new SSH key.
-
-        :param      name: Key name (required)
-        :type       name: ``str``
-
-        :param      public_key: Valid public key string (required)
-        :type       public_key: ``str``
-        """
-        attr = {'name': name, 'public_key': public_key}
-        res = self.connection.request('/v2/account/keys', method='POST',
-                                      data=json.dumps(attr))
-
-        data = res.object['ssh_key']
-
-        return self._to_key_pair(data=data)
-
-    def delete_key_pair(self, key):
-        """
-        Delete an existing SSH key.
-
-        :param      key: SSH key (required)
-        :type       key: :class:`KeyPair`
-        """
-        key_id = key.extra['id']
-        res = self.connection.request('/v2/account/keys/%s' % (key_id),
-                                      method='DELETE')
-        return res.status == httplib.NO_CONTENT
-
-    def get_key_pair(self, name):
-        """
-        Retrieve a single key pair.
-
-        :param name: Name of the key pair to retrieve.
-        :type name: ``str``
-
-        :rtype: :class:`.KeyPair`
-        """
-        qkey = [k for k in self.list_key_pairs() if k.name == name][0]
-        data = self.connection.request('/v2/account/keys/%s' %
-                                       qkey.extra['id']).object['ssh_key']
-        return self._to_key_pair(data=data)
-
-    def _to_node(self, data):
-        extra_keys = ['memory', 'vcpus', 'disk', 'region', 'image',
-                      'size_slug', 'locked', 'created_at', 'networks',
-                      'kernel', 'backup_ids', 'snapshot_ids', 'features']
-        if 'status' in data:
-            state = self.NODE_STATE_MAP.get(data['status'], NodeState.UNKNOWN)
-        else:
-            state = NodeState.UNKNOWN
-
-        created = parse_date(data['created_at'])
-        networks = data['networks']
-        private_ips = []
-        public_ips = []
-        if networks:
-            for net in networks['v4']:
-                if net['type'] == 'private':
-                    private_ips = [net['ip_address']]
-                if net['type'] == 'public':
-                    public_ips = [net['ip_address']]
-
-        extra = {}
-        for key in extra_keys:
-            if key in data:
-                extra[key] = data[key]
-
-        node = Node(id=data['id'], name=data['name'], state=state,
-                    public_ips=public_ips, private_ips=private_ips,
-                    created_at=created, driver=self, extra=extra)
-        return node
-
-    def _to_image(self, data):
-        extra = {'distribution': data['distribution'],
-                 'public': data['public'],
-                 'slug': data['slug'],
-                 'regions': data['regions'],
-                 'min_disk_size': data['min_disk_size'],
-                 'created_at': data['created_at']}
-        return NodeImage(id=data['id'], name=data['name'], driver=self,
-                         extra=extra)
-
-    def _to_location(self, data):
-        return NodeLocation(id=data['slug'], name=data['name'], country=None,
-                            driver=self)
-
-    def _to_size(self, data):
-        extra = {'vcpus': data['vcpus'],
-                 'regions': data['regions']}
-        return NodeSize(id=data['slug'], name=data['slug'], ram=data['memory'],
-                        disk=data['disk'], bandwidth=data['transfer'],
-                        price=data['price_hourly'], driver=self, extra=extra)
-
-    def _to_key_pair(self, data):
-        extra = {'id': data['id']}
-        return KeyPair(name=data['name'],
-                       fingerprint=data['fingerprint'],
-                       public_key=data['public_key'],
-                       private_key=None,
-                       driver=self,
-                       extra=extra)


[53/56] [abbrv] libcloud git commit: Fix the bug that created the node at ecs driver

Posted by an...@apache.org.
Fix the bug that created the node at ecs driver

1, From the official document can know parameter param['IoOptimized'] type is string and his value is ``none`` or ``optimized``


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/eafeccc4
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/eafeccc4
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/eafeccc4

Branch: refs/heads/trunk
Commit: eafeccc4baa742001ffe19e400ed7879a6537661
Parents: 1a70a26
Author: hequn <he...@hihuron.com>
Authored: Thu Nov 10 15:06:37 2016 +0800
Committer: Anthony Shaw <an...@apache.org>
Committed: Tue Nov 15 10:20:52 2016 +1100

----------------------------------------------------------------------
 libcloud/compute/drivers/ecs.py | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/eafeccc4/libcloud/compute/drivers/ecs.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/ecs.py b/libcloud/compute/drivers/ecs.py
index d55ed53..1dc6cb5 100644
--- a/libcloud/compute/drivers/ecs.py
+++ b/libcloud/compute/drivers/ecs.py
@@ -675,9 +675,9 @@ class ECSDriver(NodeDriver):
 
         if ex_io_optimized is not None:
             optimized = ex_io_optimized
-            if not isinstance(optimized, bool):
-                optimized = str(optimized).lower() == 'true'
-            params['IoOptimized'] = 'true' if optimized else 'false'
+            if isinstance(optimized, bool):
+                optimized = 'optimized' if optimized else 'none'
+            params['IoOptimized'] = optimized
 
         if ex_system_disk:
             system_disk = self._get_system_disk(ex_system_disk)


[04/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/local.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/local.py b/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/local.py
deleted file mode 100644
index a896822..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/local.py
+++ /dev/null
@@ -1,593 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-Provides storage driver for working with local filesystem
-"""
-
-from __future__ import with_statement
-
-import errno
-import os
-import shutil
-import sys
-
-try:
-    import lockfile
-    from lockfile import LockTimeout, mkdirlockfile
-except ImportError:
-    raise ImportError('Missing lockfile dependency, you can install it '
-                      'using pip: pip install lockfile')
-
-from libcloud.utils.files import read_in_chunks
-from libcloud.utils.py3 import relpath
-from libcloud.utils.py3 import u
-from libcloud.common.base import Connection
-from libcloud.storage.base import Object, Container, StorageDriver
-from libcloud.common.types import LibcloudError
-from libcloud.storage.types import ContainerAlreadyExistsError
-from libcloud.storage.types import ContainerDoesNotExistError
-from libcloud.storage.types import ContainerIsNotEmptyError
-from libcloud.storage.types import ObjectError
-from libcloud.storage.types import ObjectDoesNotExistError
-from libcloud.storage.types import InvalidContainerNameError
-
-IGNORE_FOLDERS = ['.lock', '.hash']
-
-
-class LockLocalStorage(object):
-    """
-    A class to help in locking a local path before being updated
-    """
-    def __init__(self, path):
-        self.path = path
-        self.lock = mkdirlockfile.MkdirLockFile(self.path, threaded=True)
-
-    def __enter__(self):
-        try:
-            self.lock.acquire(timeout=0.1)
-        except LockTimeout:
-            raise LibcloudError('Lock timeout')
-
-    def __exit__(self, type, value, traceback):
-        if self.lock.is_locked():
-            self.lock.release()
-
-        if value is not None:
-            raise value
-
-
-class LocalStorageDriver(StorageDriver):
-    """
-    Implementation of local file-system based storage. This is helpful
-    where the user would want to use the same code (using libcloud) and
-    switch between cloud storage and local storage
-    """
-
-    connectionCls = Connection
-    name = 'Local Storage'
-    website = 'http://example.com'
-    hash_type = 'md5'
-
-    def __init__(self, key, secret=None, secure=True, host=None, port=None,
-                 **kwargs):
-
-        # Use the key as the path to the storage
-        self.base_path = key
-
-        if not os.path.isdir(self.base_path):
-            raise LibcloudError('The base path is not a directory')
-
-        super(LocalStorageDriver, self).__init__(key=key, secret=secret,
-                                                 secure=secure, host=host,
-                                                 port=port, **kwargs)
-
-    def _make_path(self, path, ignore_existing=True):
-        """
-        Create a path by checking if it already exists
-        """
-
-        try:
-            os.makedirs(path)
-        except OSError:
-            exp = sys.exc_info()[1]
-            if exp.errno == errno.EEXIST and not ignore_existing:
-                raise exp
-
-    def _check_container_name(self, container_name):
-        """
-        Check if the container name is valid
-
-        :param container_name: Container name
-        :type container_name: ``str``
-        """
-
-        if '/' in container_name or '\\' in container_name:
-            raise InvalidContainerNameError(value=None, driver=self,
-                                            container_name=container_name)
-
-    def _make_container(self, container_name):
-        """
-        Create a container instance
-
-        :param container_name: Container name.
-        :type container_name: ``str``
-
-        :return: Container instance.
-        :rtype: :class:`Container`
-        """
-
-        self._check_container_name(container_name)
-
-        full_path = os.path.join(self.base_path, container_name)
-
-        try:
-            stat = os.stat(full_path)
-            if not os.path.isdir(full_path):
-                raise OSError('Target path is not a directory')
-        except OSError:
-            raise ContainerDoesNotExistError(value=None, driver=self,
-                                             container_name=container_name)
-
-        extra = {}
-        extra['creation_time'] = stat.st_ctime
-        extra['access_time'] = stat.st_atime
-        extra['modify_time'] = stat.st_mtime
-
-        return Container(name=container_name, extra=extra, driver=self)
-
-    def _make_object(self, container, object_name):
-        """
-        Create an object instance
-
-        :param container: Container.
-        :type container: :class:`Container`
-
-        :param object_name: Object name.
-        :type object_name: ``str``
-
-        :return: Object instance.
-        :rtype: :class:`Object`
-        """
-
-        full_path = os.path.join(self.base_path, container.name, object_name)
-
-        if os.path.isdir(full_path):
-            raise ObjectError(value=None, driver=self, object_name=object_name)
-
-        try:
-            stat = os.stat(full_path)
-        except Exception:
-            raise ObjectDoesNotExistError(value=None, driver=self,
-                                          object_name=object_name)
-
-        # Make a hash for the file based on the metadata. We can safely
-        # use only the mtime attribute here. If the file contents change,
-        # the underlying file-system will change mtime
-        data_hash = self._get_hash_function()
-        data_hash.update(u(stat.st_mtime).encode('ascii'))
-        data_hash = data_hash.hexdigest()
-
-        extra = {}
-        extra['creation_time'] = stat.st_ctime
-        extra['access_time'] = stat.st_atime
-        extra['modify_time'] = stat.st_mtime
-
-        return Object(name=object_name, size=stat.st_size, extra=extra,
-                      driver=self, container=container, hash=data_hash,
-                      meta_data=None)
-
-    def iterate_containers(self):
-        """
-        Return a generator of containers.
-
-        :return: A generator of Container instances.
-        :rtype: ``generator`` of :class:`Container`
-        """
-
-        for container_name in os.listdir(self.base_path):
-            full_path = os.path.join(self.base_path, container_name)
-            if not os.path.isdir(full_path):
-                continue
-            yield self._make_container(container_name)
-
-    def _get_objects(self, container):
-        """
-        Recursively iterate through the file-system and return the object names
-        """
-
-        cpath = self.get_container_cdn_url(container, check=True)
-
-        for folder, subfolders, files in os.walk(cpath, topdown=True):
-            # Remove unwanted subfolders
-            for subf in IGNORE_FOLDERS:
-                if subf in subfolders:
-                    subfolders.remove(subf)
-
-            for name in files:
-                full_path = os.path.join(folder, name)
-                object_name = relpath(full_path, start=cpath)
-                yield self._make_object(container, object_name)
-
-    def iterate_container_objects(self, container):
-        """
-        Returns a generator of objects for the given container.
-
-        :param container: Container instance
-        :type container: :class:`Container`
-
-        :return: A generator of Object instances.
-        :rtype: ``generator`` of :class:`Object`
-        """
-
-        return self._get_objects(container)
-
-    def get_container(self, container_name):
-        """
-        Return a container instance.
-
-        :param container_name: Container name.
-        :type container_name: ``str``
-
-        :return: :class:`Container` instance.
-        :rtype: :class:`Container`
-        """
-        return self._make_container(container_name)
-
-    def get_container_cdn_url(self, container, check=False):
-        """
-        Return a container CDN URL.
-
-        :param container: Container instance
-        :type  container: :class:`Container`
-
-        :param check: Indicates if the path's existence must be checked
-        :type check: ``bool``
-
-        :return: A CDN URL for this container.
-        :rtype: ``str``
-        """
-        path = os.path.join(self.base_path, container.name)
-
-        if check and not os.path.isdir(path):
-            raise ContainerDoesNotExistError(value=None, driver=self,
-                                             container_name=container.name)
-
-        return path
-
-    def get_object(self, container_name, object_name):
-        """
-        Return an object instance.
-
-        :param container_name: Container name.
-        :type  container_name: ``str``
-
-        :param object_name: Object name.
-        :type  object_name: ``str``
-
-        :return: :class:`Object` instance.
-        :rtype: :class:`Object`
-        """
-        container = self._make_container(container_name)
-        return self._make_object(container, object_name)
-
-    def get_object_cdn_url(self, obj):
-        """
-        Return an object CDN URL.
-
-        :param obj: Object instance
-        :type  obj: :class:`Object`
-
-        :return: A CDN URL for this object.
-        :rtype: ``str``
-        """
-        return os.path.join(self.base_path, obj.container.name, obj.name)
-
-    def enable_container_cdn(self, container):
-        """
-        Enable container CDN.
-
-        :param container: Container instance
-        :type  container: :class:`Container`
-
-        :rtype: ``bool``
-        """
-
-        path = self.get_container_cdn_url(container)
-        lockfile.MkdirFileLock(path, threaded=True)
-
-        with LockLocalStorage(path):
-            self._make_path(path)
-
-        return True
-
-    def enable_object_cdn(self, obj):
-        """
-        Enable object CDN.
-
-        :param obj: Object instance
-        :type  obj: :class:`Object`
-
-        :rtype: ``bool``
-        """
-        path = self.get_object_cdn_url(obj)
-
-        with LockLocalStorage(path):
-            if os.path.exists(path):
-                return False
-            try:
-                obj_file = open(path, 'w')
-                obj_file.close()
-            except:
-                return False
-
-        return True
-
-    def download_object(self, obj, destination_path, overwrite_existing=False,
-                        delete_on_failure=True):
-        """
-        Download an object to the specified destination path.
-
-        :param obj: Object instance.
-        :type obj: :class:`Object`
-
-        :param destination_path: Full path to a file or a directory where the
-                                incoming file will be saved.
-        :type destination_path: ``str``
-
-        :param overwrite_existing: True to overwrite an existing file,
-            defaults to False.
-        :type overwrite_existing: ``bool``
-
-        :param delete_on_failure: True to delete a partially downloaded file if
-        the download was not successful (hash mismatch / file size).
-        :type delete_on_failure: ``bool``
-
-        :return: True if an object has been successfully downloaded, False
-        otherwise.
-        :rtype: ``bool``
-        """
-
-        obj_path = self.get_object_cdn_url(obj)
-        base_name = os.path.basename(destination_path)
-
-        if not base_name and not os.path.exists(destination_path):
-            raise LibcloudError(
-                value='Path %s does not exist' % (destination_path),
-                driver=self)
-
-        if not base_name:
-            file_path = os.path.join(destination_path, obj.name)
-        else:
-            file_path = destination_path
-
-        if os.path.exists(file_path) and not overwrite_existing:
-            raise LibcloudError(
-                value='File %s already exists, but ' % (file_path) +
-                'overwrite_existing=False',
-                driver=self)
-
-        try:
-            shutil.copy(obj_path, file_path)
-        except IOError:
-            if delete_on_failure:
-                try:
-                    os.unlink(file_path)
-                except Exception:
-                    pass
-            return False
-
-        return True
-
-    def download_object_as_stream(self, obj, chunk_size=None):
-        """
-        Return a generator which yields object data.
-
-        :param obj: Object instance
-        :type obj: :class:`Object`
-
-        :param chunk_size: Optional chunk size (in bytes).
-        :type chunk_size: ``int``
-
-        :return: A stream of binary chunks of data.
-        :rtype: ``object``
-        """
-        path = self.get_object_cdn_url(obj)
-        with open(path, 'rb') as obj_file:
-            for data in read_in_chunks(obj_file, chunk_size=chunk_size):
-                yield data
-
-    def upload_object(self, file_path, container, object_name, extra=None,
-                      verify_hash=True):
-        """
-        Upload an object currently located on a disk.
-
-        :param file_path: Path to the object on disk.
-        :type file_path: ``str``
-
-        :param container: Destination container.
-        :type container: :class:`Container`
-
-        :param object_name: Object name.
-        :type object_name: ``str``
-
-        :param verify_hash: Verify hast
-        :type verify_hash: ``bool``
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type extra: ``dict``
-
-        :rtype: ``object``
-        """
-
-        path = self.get_container_cdn_url(container, check=True)
-        obj_path = os.path.join(path, object_name)
-        base_path = os.path.dirname(obj_path)
-
-        self._make_path(base_path)
-
-        with LockLocalStorage(obj_path):
-            shutil.copy(file_path, obj_path)
-
-        os.chmod(obj_path, int('664', 8))
-
-        return self._make_object(container, object_name)
-
-    def upload_object_via_stream(self, iterator, container,
-                                 object_name,
-                                 extra=None):
-        """
-        Upload an object using an iterator.
-
-        If a provider supports it, chunked transfer encoding is used and you
-        don't need to know in advance the amount of data to be uploaded.
-
-        Otherwise if a provider doesn't support it, iterator will be exhausted
-        so a total size for data to be uploaded can be determined.
-
-        Note: Exhausting the iterator means that the whole data must be
-        buffered in memory which might result in memory exhausting when
-        uploading a very large object.
-
-        If a file is located on a disk you are advised to use upload_object
-        function which uses fs.stat function to determine the file size and it
-        doesn't need to buffer whole object in the memory.
-
-        :type iterator: ``object``
-        :param iterator: An object which implements the iterator
-                         interface and yields binary chunks of data.
-
-        :type container: :class:`Container`
-        :param container: Destination container.
-
-        :type object_name: ``str``
-        :param object_name: Object name.
-
-        :type extra: ``dict``
-        :param extra: (optional) Extra attributes (driver specific). Note:
-            This dictionary must contain a 'content_type' key which represents
-            a content type of the stored object.
-
-        :rtype: ``object``
-        """
-        path = self.get_container_cdn_url(container, check=True)
-        obj_path = os.path.join(path, object_name)
-        base_path = os.path.dirname(obj_path)
-        self._make_path(base_path)
-        with LockLocalStorage(obj_path):
-            with open(obj_path, 'wb') as obj_file:
-                for data in iterator:
-                    obj_file.write(data)
-        os.chmod(obj_path, int('664', 8))
-        return self._make_object(container, object_name)
-
-    def delete_object(self, obj):
-        """
-        Delete an object.
-
-        :type obj: :class:`Object`
-        :param obj: Object instance.
-
-        :return: ``bool`` True on success.
-        :rtype: ``bool``
-        """
-
-        path = self.get_object_cdn_url(obj)
-
-        with LockLocalStorage(path):
-            try:
-                os.unlink(path)
-            except Exception:
-                return False
-
-        # Check and delete all the empty parent folders
-        path = os.path.dirname(path)
-        container_url = obj.container.get_cdn_url()
-
-        # Delete the empty parent folders till the container's level
-        while path != container_url:
-            try:
-                os.rmdir(path)
-            except OSError:
-                exp = sys.exc_info()[1]
-                if exp.errno == errno.ENOTEMPTY:
-                    break
-                raise exp
-
-            path = os.path.dirname(path)
-
-        return True
-
-    def create_container(self, container_name):
-        """
-        Create a new container.
-
-        :type container_name: ``str``
-        :param container_name: Container name.
-
-        :return: :class:`Container` instance on success.
-        :rtype: :class:`Container`
-        """
-
-        self._check_container_name(container_name)
-
-        path = os.path.join(self.base_path, container_name)
-
-        try:
-            self._make_path(path, ignore_existing=False)
-        except OSError:
-            exp = sys.exc_info()[1]
-            if exp.errno == errno.EEXIST:
-                raise ContainerAlreadyExistsError(
-                    value='Container with this name already exists. The name '
-                          'must be unique among all the containers in the '
-                          'system',
-                    container_name=container_name, driver=self)
-            else:
-                raise LibcloudError(
-                    'Error creating container %s' % container_name,
-                    driver=self)
-        except Exception:
-            raise LibcloudError(
-                'Error creating container %s' % container_name, driver=self)
-
-        return self._make_container(container_name)
-
-    def delete_container(self, container):
-        """
-        Delete a container.
-
-        :type container: :class:`Container`
-        :param container: Container instance
-
-        :return: True on success, False otherwise.
-        :rtype: ``bool``
-        """
-
-        # Check if there are any objects inside this
-        for obj in self._get_objects(container):
-            raise ContainerIsNotEmptyError(value='Container is not empty',
-                                           container_name=container.name,
-                                           driver=self)
-
-        path = self.get_container_cdn_url(container, check=True)
-
-        with LockLocalStorage(path):
-            try:
-                shutil.rmtree(path)
-            except Exception:
-                return False
-
-        return True

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/nimbus.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/nimbus.py b/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/nimbus.py
deleted file mode 100644
index 583aefb..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/nimbus.py
+++ /dev/null
@@ -1,114 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 time
-import hashlib
-import hmac
-
-try:
-    import simplejson as json
-except ImportError:
-    import json  # NOQA
-
-from libcloud.utils.py3 import httplib
-from libcloud.utils.py3 import urlencode
-
-from libcloud.common.base import ConnectionUserAndKey, JsonResponse
-from libcloud.common.types import InvalidCredsError, LibcloudError
-from libcloud.storage.base import Container, StorageDriver
-
-
-class NimbusResponse(JsonResponse):
-    valid_response_codes = [httplib.OK, httplib.NOT_FOUND, httplib.CONFLICT,
-                            httplib.BAD_REQUEST]
-
-    def success(self):
-        return self.status in self.valid_response_codes
-
-    def parse_error(self):
-        if self.status in [httplib.UNAUTHORIZED]:
-            raise InvalidCredsError(self.body)
-        raise LibcloudError('Unknown error. Status code: %d' % (self.status),
-                            driver=self.connection.driver)
-
-
-class NimbusConnection(ConnectionUserAndKey):
-    host = 'nimbus.io'
-    responseCls = NimbusResponse
-
-    def __init__(self, *args, **kwargs):
-        self.id = kwargs.pop('id')
-        super(NimbusConnection, self).__init__(*args, **kwargs)
-
-    def pre_connect_hook(self, params, headers):
-        timestamp = str(int(time.time()))
-        signature = self._calculate_signature(user_id=self.user_id,
-                                              method=self.method,
-                                              params=params,
-                                              path=self.action,
-                                              timestamp=timestamp,
-                                              key=self.key)
-        headers['X-NIMBUS-IO-Timestamp'] = timestamp
-        headers['Authorization'] = 'NIMBUS.IO %s:%s' % (self.id, signature)
-        return params, headers
-
-    def _calculate_signature(self, user_id, method, params, path, timestamp,
-                             key):
-        if params:
-            uri_path = path + '?' + urlencode(params)
-        else:
-            uri_path = path
-
-        string_to_sign = [user_id, method, str(timestamp), uri_path]
-        string_to_sign = '\n'.join(string_to_sign)
-
-        hmac_value = hmac.new(key, string_to_sign, hashlib.sha256)
-        return hmac_value.hexdigest()
-
-
-class NimbusStorageDriver(StorageDriver):
-    name = 'Nimbus.io'
-    website = 'https://nimbus.io/'
-    connectionCls = NimbusConnection
-
-    def __init__(self, *args, **kwargs):
-        self.user_id = kwargs['user_id']
-        super(NimbusStorageDriver, self).__init__(*args, **kwargs)
-
-    def iterate_containers(self):
-        response = self.connection.request('/customers/%s/collections' %
-                                           (self.user_id))
-        return self._to_containers(response.object)
-
-    def create_container(self, container_name):
-        params = {'action': 'create', 'name': container_name}
-        response = self.connection.request('/customers/%s/collections' %
-                                           (self.user_id),
-                                           params=params,
-                                           method='POST')
-        return self._to_container(response.object)
-
-    def _to_containers(self, data):
-        for item in data:
-            yield self._to_container(item)
-
-    def _to_container(self, data):
-        name = data[0]
-        extra = {'date_created': data[2]}
-        return Container(name=name, extra=extra, driver=self)
-
-    def _ex_connection_class_kwargs(self):
-        result = {'id': self.user_id}
-        return result

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/ninefold.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/ninefold.py b/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/ninefold.py
deleted file mode 100644
index fbdf567..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/ninefold.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from libcloud.storage.providers import Provider
-from libcloud.storage.drivers.atmos import AtmosDriver
-
-
-class NinefoldStorageDriver(AtmosDriver):
-    host = 'api.ninefold.com'
-    path = '/storage/v1.0'
-
-    type = Provider.NINEFOLD
-    name = 'Ninefold'
-    website = 'http://ninefold.com/'

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/oss.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/oss.py b/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/oss.py
deleted file mode 100644
index 84df44f..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/oss.py
+++ /dev/null
@@ -1,1069 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 base64
-import codecs
-import hmac
-import os
-import time
-import sys
-from hashlib import sha1
-
-try:
-    from lxml import etree as ET
-except ImportError:
-    from xml.etree import ElementTree as ET
-
-try:
-    from lxml.etree import Element, SubElement
-except ImportError:
-    from xml.etree.ElementTree import Element, SubElement
-
-from libcloud.utils.py3 import httplib
-from libcloud.utils.py3 import urlquote
-from libcloud.utils.py3 import urlencode
-from libcloud.utils.py3 import b
-from libcloud.utils.py3 import tostring
-from libcloud.utils.py3 import PY3
-from libcloud.utils.xml import fixxpath, findtext
-from libcloud.utils.files import guess_file_mime_type, read_in_chunks, \
-    exhaust_iterator
-from libcloud.common.types import InvalidCredsError, LibcloudError
-from libcloud.common.base import ConnectionUserAndKey, RawResponse, \
-    XmlResponse
-from libcloud.common.types import MalformedResponseError
-from libcloud.storage.base import Object, Container, StorageDriver, \
-    DEFAULT_CONTENT_TYPE
-from libcloud.storage.types import ContainerError
-from libcloud.storage.types import ContainerIsNotEmptyError
-from libcloud.storage.types import InvalidContainerNameError
-from libcloud.storage.types import ContainerDoesNotExistError
-from libcloud.storage.types import ObjectDoesNotExistError
-from libcloud.storage.types import ObjectHashMismatchError
-
-__all__ = [
-    'OSSStorageDriver',
-    'OSSMultipartUpload',
-
-    'EXPIRATION_SECONDS',
-    'CHUNK_SIZE',
-    'MAX_UPLOADS_PER_RESPONSE'
-]
-
-GMT_TIME_FORMAT = "%a, %d %b %Y %H:%M:%S GMT"
-EXPIRATION_SECONDS = 15 * 60
-
-# OSS multi-part chunks must be great than 100KB except the last one
-CHUNK_SIZE = 100 * 1024
-
-# Desired number of items in each response inside a paginated request in
-# ex_iterate_multipart_uploads.
-MAX_UPLOADS_PER_RESPONSE = 1000
-
-
-class OSSResponse(XmlResponse):
-    namespace = None
-    valid_response_codes = [httplib.NOT_FOUND, httplib.CONFLICT,
-                            httplib.BAD_REQUEST]
-
-    def success(self):
-        i = int(self.status)
-        return i >= 200 and i <= 299 or i in self.valid_response_codes
-
-    def parse_body(self):
-        """
-        OSSResponse body is in utf-8 encoding.
-        """
-        if len(self.body) == 0 and not self.parse_zero_length_body:
-            return self.body
-
-        try:
-            if PY3:
-                parser = ET.XMLParser(encoding='utf-8')
-                body = ET.XML(self.body.encode('utf-8'), parser=parser)
-            else:
-                body = ET.XML(self.body)
-        except:
-            raise MalformedResponseError('Failed to parse XML',
-                                         body=self.body,
-                                         driver=self.connection.driver)
-        return body
-
-    def parse_error(self):
-        if self.status in [httplib.UNAUTHORIZED, httplib.FORBIDDEN]:
-            raise InvalidCredsError(self.body)
-        elif self.status == httplib.MOVED_PERMANENTLY:
-            raise LibcloudError('This bucket is located in a different ' +
-                                'region. Please use the correct driver.',
-                                driver=OSSStorageDriver)
-        elif self.status == httplib.METHOD_NOT_ALLOWED:
-            raise LibcloudError('The method is not allowed. Status code: %d, '
-                                'headers: %s' % (self.status, self.headers))
-        raise LibcloudError('Unknown error. Status code: %d, body: %s' %
-                            (self.status, self.body),
-                            driver=OSSStorageDriver)
-
-
-class OSSRawResponse(OSSResponse, RawResponse):
-    pass
-
-
-class OSSConnection(ConnectionUserAndKey):
-    """
-    Represents a single connection to the Aliyun OSS Endpoint
-    """
-
-    _domain = 'aliyuncs.com'
-    _default_location = 'oss'
-    responseCls = OSSResponse
-    rawResponseCls = OSSRawResponse
-
-    @staticmethod
-    def _get_auth_signature(method, headers, params, expires, secret_key, path,
-                            vendor_prefix):
-        """
-        Signature = base64(hmac-sha1(AccessKeySecret,
-          VERB + "\n"
-          + CONTENT-MD5 + "\n"
-          + CONTENT-TYPE + "\n"
-          + EXPIRES + "\n"
-          + CanonicalizedOSSHeaders
-          + CanonicalizedResource))
-        """
-        special_headers = {'content-md5': '',
-                           'content-type': '',
-                           'expires': ''}
-        vendor_headers = {}
-
-        for key, value in list(headers.items()):
-            key_lower = key.lower()
-            if key_lower in special_headers:
-                special_headers[key_lower] = value.strip()
-            elif key_lower.startswith(vendor_prefix):
-                vendor_headers[key_lower] = value.strip()
-
-        if expires:
-            special_headers['expires'] = str(expires)
-
-        buf = [method]
-        for _, value in sorted(special_headers.items()):
-            buf.append(value)
-        string_to_sign = '\n'.join(buf)
-
-        buf = []
-        for key, value in sorted(vendor_headers.items()):
-            buf.append('%s:%s' % (key, value))
-        header_string = '\n'.join(buf)
-
-        values_to_sign = []
-        for value in [string_to_sign, header_string, path]:
-            if value:
-                values_to_sign.append(value)
-
-        string_to_sign = '\n'.join(values_to_sign)
-        b64_hmac = base64.b64encode(
-            hmac.new(b(secret_key), b(string_to_sign), digestmod=sha1).digest()
-        )
-        return b64_hmac
-
-    @staticmethod
-    def _get_expires(params):
-        """
-        Get expires timeout seconds from parameters.
-        """
-        expires = None
-        if 'expires' in params:
-            expires = params['expires']
-        elif 'Expires' in params:
-            expires = params['Expires']
-        if expires:
-            try:
-                return int(expires)
-            except Exception:
-                pass
-        return int(time.time()) + EXPIRATION_SECONDS
-
-    def add_default_params(self, params):
-        expires_at = self._get_expires(params)
-        expires = str(expires_at)
-        params['OSSAccessKeyId'] = self.user_id
-        params['Expires'] = expires
-        return params
-
-    def add_default_headers(self, headers):
-        headers['Date'] = time.strftime(GMT_TIME_FORMAT, time.gmtime())
-        return headers
-
-    def pre_connect_hook(self, params, headers):
-        if self._container:
-            path = '/%s%s' % (self._container.name, self.action)
-        else:
-            path = self.action
-        params['Signature'] = self._get_auth_signature(
-            method=self.method, headers=headers, params=params,
-            expires=params['Expires'], secret_key=self.key, path=path,
-            vendor_prefix=self.driver.http_vendor_prefix)
-        return params, headers
-
-    def request(self, action, params=None, data=None, headers=None,
-                method='GET', raw=False, container=None):
-        self.host = '%s.%s' % (self._default_location, self._domain)
-        self._container = container
-        if container and container.name:
-            if 'location' in container.extra:
-                self.host = '%s.%s.%s' % (container.name,
-                                          container.extra['location'],
-                                          self._domain)
-            else:
-                self.host = '%s.%s' % (container.name, self.host)
-        return super(OSSConnection, self).request(action=action,
-                                                  params=params,
-                                                  data=data,
-                                                  headers=headers,
-                                                  method=method,
-                                                  raw=raw)
-
-
-class OSSMultipartUpload(object):
-    """
-    Class representing an Aliyun OSS multipart upload
-    """
-
-    def __init__(self, key, id, initiated):
-        """
-        Class representing an Aliyun OSS multipart upload
-
-        :param key: The object/key that was being uploaded
-        :type key: ``str``
-
-        :param id: The upload id assigned by Aliyun
-        :type id: ``str``
-
-        :param initiated: The date/time at which the upload was started
-        :type created_at: ``str``
-        """
-        self.key = key
-        self.id = id
-        self.initiated = initiated
-
-    def __repr__(self):
-        return ('<OSSMultipartUpload: key=%s>' % (self.key))
-
-
-class OSSStorageDriver(StorageDriver):
-    name = 'Aliyun OSS'
-    website = 'http://www.aliyun.com/product/oss'
-    connectionCls = OSSConnection
-    hash_type = 'md5'
-    supports_chunked_encoding = False
-    supports_multipart_upload = True
-    namespace = None
-    http_vendor_prefix = 'x-oss-'
-
-    def iterate_containers(self):
-        response = self.connection.request('/')
-        if response.status == httplib.OK:
-            containers = self._to_containers(obj=response.object,
-                                             xpath='Buckets/Bucket')
-            return containers
-
-        raise LibcloudError('Unexpected status code: %s' % (response.status),
-                            driver=self)
-
-    def list_container_objects(self, container, ex_prefix=None):
-        """
-        Return a list of objects for the given container.
-
-        :param container: Container instance.
-        :type container: :class:`Container`
-
-        :keyword ex_prefix: Only return objects starting with ex_prefix
-        :type ex_prefix: ``str``
-
-        :return: A list of Object instances.
-        :rtype: ``list`` of :class:`Object`
-        """
-        return list(self.iterate_container_objects(container,
-                    ex_prefix=ex_prefix))
-
-    def iterate_container_objects(self, container, ex_prefix=None):
-        """
-        Return a generator of objects for the given container.
-
-        :param container: Container instance
-        :type container: :class:`Container`
-
-        :keyword ex_prefix: Only return objects starting with ex_prefix
-        :type ex_prefix: ``str``
-
-        :return: A generator of Object instances.
-        :rtype: ``generator`` of :class:`Object`
-        """
-        params = {}
-        if ex_prefix:
-            params['prefix'] = ex_prefix
-
-        last_key = None
-        exhausted = False
-
-        while not exhausted:
-            if last_key:
-                params['marker'] = last_key
-
-            response = self.connection.request('/',
-                                               params=params,
-                                               container=container)
-
-            if response.status != httplib.OK:
-                raise LibcloudError('Unexpected status code: %s' %
-                                    (response.status), driver=self)
-
-            objects = self._to_objs(obj=response.object,
-                                    xpath='Contents', container=container)
-            is_truncated = response.object.findtext(fixxpath(
-                xpath='IsTruncated', namespace=self.namespace)).lower()
-            exhausted = (is_truncated == 'false')
-
-            last_key = None
-            for obj in objects:
-                last_key = obj.name
-                yield obj
-
-    def get_container(self, container_name):
-        for container in self.iterate_containers():
-            if container.name == container_name:
-                return container
-        raise ContainerDoesNotExistError(value=None,
-                                         driver=self,
-                                         container_name=container_name)
-
-    def get_object(self, container_name, object_name):
-        container = self.get_container(container_name=container_name)
-        object_path = self._get_object_path(container, object_name)
-        response = self.connection.request(object_path,
-                                           method='HEAD',
-                                           container=container)
-
-        if response.status == httplib.OK:
-            obj = self._headers_to_object(object_name=object_name,
-                                          container=container,
-                                          headers=response.headers)
-            return obj
-
-        raise ObjectDoesNotExistError(value=None, driver=self,
-                                      object_name=object_name)
-
-    def create_container(self, container_name, ex_location=None):
-        """
-        @inherits :class:`StorageDriver.create_container`
-
-        :keyword ex_location: The desired location where to create container
-        :type keyword: ``str``
-        """
-        extra = None
-        if ex_location:
-            root = Element('CreateBucketConfiguration')
-            child = SubElement(root, 'LocationConstraint')
-            child.text = ex_location
-
-            data = tostring(root)
-            extra = {'location': ex_location}
-        else:
-            data = ''
-
-        container = Container(name=container_name, extra=extra, driver=self)
-        response = self.connection.request('/',
-                                           data=data,
-                                           method='PUT',
-                                           container=container)
-
-        if response.status == httplib.OK:
-            return container
-        elif response.status == httplib.CONFLICT:
-            raise InvalidContainerNameError(
-                value='Container with this name already exists. The name must '
-                      'be unique among all the containers in the system',
-                container_name=container_name, driver=self)
-        elif response.status == httplib.BAD_REQUEST:
-            raise ContainerError(
-                value='Bad request when creating container: %s' %
-                      response.body,
-                container_name=container_name, driver=self)
-
-        raise LibcloudError('Unexpected status code: %s' % (response.status),
-                            driver=self)
-
-    def delete_container(self, container):
-        # Note: All the objects in the container must be deleted first
-        response = self.connection.request('/',
-                                           method='DELETE',
-                                           container=container)
-        if response.status == httplib.NO_CONTENT:
-            return True
-        elif response.status == httplib.CONFLICT:
-            raise ContainerIsNotEmptyError(
-                value='Container must be empty before it can be deleted.',
-                container_name=container.name, driver=self)
-        elif response.status == httplib.NOT_FOUND:
-            raise ContainerDoesNotExistError(value=None,
-                                             driver=self,
-                                             container_name=container.name)
-
-        return False
-
-    def download_object(self, obj, destination_path, overwrite_existing=False,
-                        delete_on_failure=True):
-        obj_path = self._get_object_path(obj.container, obj.name)
-
-        response = self.connection.request(obj_path,
-                                           method='GET',
-                                           raw=True,
-                                           container=obj.container)
-
-        return self._get_object(obj=obj, callback=self._save_object,
-                                response=response,
-                                callback_kwargs={
-                                    'obj': obj,
-                                    'response': response.response,
-                                    'destination_path': destination_path,
-                                    'overwrite_existing': overwrite_existing,
-                                    'delete_on_failure': delete_on_failure},
-                                success_status_code=httplib.OK)
-
-    def download_object_as_stream(self, obj, chunk_size=None):
-        obj_path = self._get_object_path(obj.container, obj.name)
-        response = self.connection.request(obj_path,
-                                           method='GET',
-                                           raw=True,
-                                           container=obj.container)
-
-        return self._get_object(obj=obj, callback=read_in_chunks,
-                                response=response,
-                                callback_kwargs={'iterator': response.response,
-                                                 'chunk_size': chunk_size},
-                                success_status_code=httplib.OK)
-
-    def upload_object(self, file_path, container, object_name, extra=None,
-                      verify_hash=True, headers=None):
-        upload_func = self._upload_file
-        upload_func_kwargs = {'file_path': file_path}
-
-        return self._put_object(container=container, object_name=object_name,
-                                upload_func=upload_func,
-                                upload_func_kwargs=upload_func_kwargs,
-                                extra=extra, file_path=file_path,
-                                verify_hash=verify_hash)
-
-    def upload_object_via_stream(self, iterator, container, object_name,
-                                 extra=None, headers=None):
-        method = 'PUT'
-        params = None
-
-        if self.supports_multipart_upload:
-            # Initiate the multipart request and get an upload id
-            upload_func = self._upload_multipart
-            upload_func_kwargs = {'iterator': iterator,
-                                  'container': container,
-                                  'object_name': object_name}
-            method = 'POST'
-            iterator = iter('')
-            params = 'uploads'
-
-        elif self.supports_chunked_encoding:
-            upload_func = self._stream_data
-            upload_func_kwargs = {'iterator': iterator}
-        else:
-            # In this case, we have to load the entire object to
-            # memory and send it as normal data
-            upload_func = self._upload_data
-            upload_func_kwargs = {}
-
-        return self._put_object(container=container, object_name=object_name,
-                                upload_func=upload_func,
-                                upload_func_kwargs=upload_func_kwargs,
-                                extra=extra, method=method, query_args=params,
-                                iterator=iterator, verify_hash=False)
-
-    def delete_object(self, obj):
-        object_path = self._get_object_path(obj.container, obj.name)
-        response = self.connection.request(object_path, method='DELETE',
-                                           container=obj.container)
-        if response.status == httplib.NO_CONTENT:
-            return True
-        elif response.status == httplib.NOT_FOUND:
-            raise ObjectDoesNotExistError(value=None, driver=self,
-                                          object_name=obj.name)
-
-        return False
-
-    def ex_iterate_multipart_uploads(self, container, prefix=None,
-                                     delimiter=None,
-                                     max_uploads=MAX_UPLOADS_PER_RESPONSE):
-        """
-        Extension method for listing all in-progress OSS multipart uploads.
-
-        Each multipart upload which has not been committed or aborted is
-        considered in-progress.
-
-        :param container: The container holding the uploads
-        :type container: :class:`Container`
-
-        :keyword prefix: Print only uploads of objects with this prefix
-        :type prefix: ``str``
-
-        :keyword delimiter: The object/key names are grouped based on
-            being split by this delimiter
-        :type delimiter: ``str``
-
-        :keyword max_uploads: The max uplod items returned for one request
-        :type max_uploads: ``int``
-
-        :return: A generator of OSSMultipartUpload instances.
-        :rtype: ``generator`` of :class:`OSSMultipartUpload`
-        """
-
-        if not self.supports_multipart_upload:
-            raise LibcloudError('Feature not supported', driver=self)
-
-        request_path = '/?uploads'
-        params = {'max-uploads': max_uploads}
-
-        if prefix:
-            params['prefix'] = prefix
-
-        if delimiter:
-            params['delimiter'] = delimiter
-
-        def finder(node, text):
-            return node.findtext(fixxpath(xpath=text,
-                                          namespace=self.namespace))
-
-        while True:
-            response = self.connection.request(request_path, params=params,
-                                               container=container)
-
-            if response.status != httplib.OK:
-                raise LibcloudError('Error fetching multipart uploads. '
-                                    'Got code: %s' % response.status,
-                                    driver=self)
-
-            body = response.parse_body()
-            # pylint: disable=maybe-no-member
-            for node in body.findall(fixxpath(xpath='Upload',
-                                              namespace=self.namespace)):
-
-                key = finder(node, 'Key')
-                upload_id = finder(node, 'UploadId')
-                initiated = finder(node, 'Initiated')
-
-                yield OSSMultipartUpload(key, upload_id, initiated)
-
-            # Check if this is the last entry in the listing
-            # pylint: disable=maybe-no-member
-            is_truncated = body.findtext(fixxpath(xpath='IsTruncated',
-                                                  namespace=self.namespace))
-
-            if is_truncated.lower() == 'false':
-                break
-
-            # Provide params for the next request
-            upload_marker = body.findtext(fixxpath(xpath='NextUploadIdMarker',
-                                                   namespace=self.namespace))
-            key_marker = body.findtext(fixxpath(xpath='NextKeyMarker',
-                                                namespace=self.namespace))
-
-            params['key-marker'] = key_marker
-            params['upload-id-marker'] = upload_marker
-
-    def ex_abort_all_multipart_uploads(self, container, prefix=None):
-        """
-        Extension method for removing all partially completed OSS multipart
-        uploads.
-
-        :param container: The container holding the uploads
-        :type container: :class:`Container`
-
-        :keyword prefix: Delete only uploads of objects with this prefix
-        :type prefix: ``str``
-        """
-
-        # Iterate through the container and delete the upload ids
-        for upload in self.ex_iterate_multipart_uploads(container, prefix,
-                                                        delimiter=None):
-            object_path = self._get_object_path(container, upload.key)
-            self._abort_multipart(object_path, upload.id, container=container)
-
-    def _clean_object_name(self, name):
-        name = urlquote(name)
-        return name
-
-    def _put_object(self, container, object_name, upload_func,
-                    upload_func_kwargs, method='PUT', query_args=None,
-                    extra=None, file_path=None, iterator=None,
-                    verify_hash=False):
-        """
-        Create an object and upload data using the given function.
-        """
-        headers = {}
-        extra = extra or {}
-
-        content_type = extra.get('content_type', None)
-        meta_data = extra.get('meta_data', None)
-        acl = extra.get('acl', None)
-
-        if meta_data:
-            for key, value in list(meta_data.items()):
-                key = self.http_vendor_prefix + 'meta-%s' % (key)
-                headers[key] = value
-
-        if acl:
-            if acl not in ['public-read', 'private', 'public-read-write']:
-                raise AttributeError('invalid acl value: %s' % acl)
-            headers[self.http_vendor_prefix + 'object-acl'] = acl
-
-        request_path = self._get_object_path(container, object_name)
-
-        if query_args:
-            request_path = '?'.join((request_path, query_args))
-
-        # TODO: Let the underlying exceptions bubble up and capture the SIGPIPE
-        # here.
-        # SIGPIPE is thrown if the provided container does not exist or the
-        # user does not have correct permission
-        result_dict = self._upload_object(
-            object_name=object_name, content_type=content_type,
-            upload_func=upload_func, upload_func_kwargs=upload_func_kwargs,
-            request_path=request_path, request_method=method,
-            headers=headers, file_path=file_path, iterator=iterator,
-            container=container)
-
-        response = result_dict['response']
-        bytes_transferred = result_dict['bytes_transferred']
-        headers = response.headers
-        response = response.response
-        server_hash = headers['etag'].replace('"', '')
-
-        if (verify_hash and result_dict['data_hash'].upper() != server_hash):
-            raise ObjectHashMismatchError(
-                value='MD5 hash checksum does not match',
-                object_name=object_name, driver=self)
-        elif response.status == httplib.OK:
-            obj = Object(
-                name=object_name, size=bytes_transferred, hash=server_hash,
-                extra={'acl': acl}, meta_data=meta_data, container=container,
-                driver=self)
-
-            return obj
-        else:
-            raise LibcloudError(
-                'Unexpected status code, status_code=%s' % (response.status),
-                driver=self)
-
-    def _upload_multipart(self, response, data, iterator, container,
-                          object_name, calculate_hash=True):
-        """
-        Callback invoked for uploading data to OSS using Aliyun's
-        multipart upload mechanism
-
-        :param response: Response object from the initial POST request
-        :type response: :class:`OSSRawResponse`
-
-        :param data: Any data from the initial POST request
-        :type data: ``str``
-
-        :param iterator: The generator for fetching the upload data
-        :type iterator: ``generator``
-
-        :param container: The container owning the object to which data is
-            being uploaded
-        :type container: :class:`Container`
-
-        :param object_name: The name of the object to which we are uploading
-        :type object_name: ``str``
-
-        :keyword calculate_hash: Indicates if we must calculate the data hash
-        :type calculate_hash: ``bool``
-
-        :return: A tuple of (status, checksum, bytes transferred)
-        :rtype: ``tuple``
-        """
-
-        object_path = self._get_object_path(container, object_name)
-
-        # Get the upload id from the response xml
-        response.body = response.response.read()
-        body = response.parse_body()
-        upload_id = body.find(fixxpath(xpath='UploadId',
-                                       namespace=self.namespace)).text
-
-        try:
-            # Upload the data through the iterator
-            result = self._upload_from_iterator(iterator, object_path,
-                                                upload_id, calculate_hash,
-                                                container=container)
-            (chunks, data_hash, bytes_transferred) = result
-
-            # Commit the chunk info and complete the upload
-            etag = self._commit_multipart(object_path, upload_id, chunks,
-                                          container=container)
-        except Exception:
-            exc = sys.exc_info()[1]
-            # Amazon provides a mechanism for aborting an upload.
-            self._abort_multipart(object_path, upload_id, container=container)
-            raise exc
-
-        # Modify the response header of the first request. This is used
-        # by other functions once the callback is done
-        response.headers['etag'] = etag
-
-        return (True, data_hash, bytes_transferred)
-
-    def _upload_from_iterator(self, iterator, object_path, upload_id,
-                              calculate_hash=True, container=None):
-        """
-        Uploads data from an interator in fixed sized chunks to OSS
-
-        :param iterator: The generator for fetching the upload data
-        :type iterator: ``generator``
-
-        :param object_path: The path of the object to which we are uploading
-        :type object_name: ``str``
-
-        :param upload_id: The upload id allocated for this multipart upload
-        :type upload_id: ``str``
-
-        :keyword calculate_hash: Indicates if we must calculate the data hash
-        :type calculate_hash: ``bool``
-
-        :keyword container: the container object to upload object to
-        :type container: :class:`Container`
-
-        :return: A tuple of (chunk info, checksum, bytes transferred)
-        :rtype: ``tuple``
-        """
-
-        data_hash = None
-        if calculate_hash:
-            data_hash = self._get_hash_function()
-
-        bytes_transferred = 0
-        count = 1
-        chunks = []
-        params = {'uploadId': upload_id}
-
-        # Read the input data in chunk sizes suitable for AWS
-        for data in read_in_chunks(iterator, chunk_size=CHUNK_SIZE,
-                                   fill_size=True, yield_empty=True):
-            bytes_transferred += len(data)
-
-            if calculate_hash:
-                data_hash.update(data)
-
-            chunk_hash = self._get_hash_function()
-            chunk_hash.update(data)
-            chunk_hash = base64.b64encode(chunk_hash.digest()).decode('utf-8')
-
-            # OSS will calculate hash of the uploaded data and
-            # check this header.
-            headers = {'Content-MD5': chunk_hash}
-            params['partNumber'] = count
-
-            request_path = '?'.join((object_path, urlencode(params)))
-
-            resp = self.connection.request(request_path, method='PUT',
-                                           data=data, headers=headers,
-                                           container=container)
-
-            if resp.status != httplib.OK:
-                raise LibcloudError('Error uploading chunk', driver=self)
-
-            server_hash = resp.headers['etag']
-
-            # Keep this data for a later commit
-            chunks.append((count, server_hash))
-            count += 1
-
-        if calculate_hash:
-            data_hash = data_hash.hexdigest()
-
-        return (chunks, data_hash, bytes_transferred)
-
-    def _commit_multipart(self, object_path, upload_id, chunks,
-                          container=None):
-        """
-        Makes a final commit of the data.
-
-        :param object_path: Server side object path.
-        :type object_path: ``str``
-
-        :param upload_id: ID of the multipart upload.
-        :type upload_id: ``str``
-
-        :param upload_id: A list of (chunk_number, chunk_hash) tuples.
-        :type upload_id: ``list``
-
-        :keyword container: The container owning the object to which data is
-            being uploaded
-        :type container: :class:`Container`
-        """
-
-        root = Element('CompleteMultipartUpload')
-
-        for (count, etag) in chunks:
-            part = SubElement(root, 'Part')
-            part_no = SubElement(part, 'PartNumber')
-            part_no.text = str(count)
-
-            etag_id = SubElement(part, 'ETag')
-            etag_id.text = str(etag)
-
-        data = tostring(root)
-
-        params = {'uploadId': upload_id}
-        request_path = '?'.join((object_path, urlencode(params)))
-        response = self.connection.request(request_path, data=data,
-                                           method='POST', container=container)
-
-        if response.status != httplib.OK:
-            element = response.object
-            # pylint: disable=maybe-no-member
-            code, message = response._parse_error_details(element=element)
-            msg = 'Error in multipart commit: %s (%s)' % (message, code)
-            raise LibcloudError(msg, driver=self)
-
-        # Get the server's etag to be passed back to the caller
-        body = response.parse_body()
-        server_hash = body.find(fixxpath(xpath='ETag',
-                                         namespace=self.namespace)).text
-        return server_hash
-
-    def _abort_multipart(self, object_path, upload_id, container=None):
-        """
-        Aborts an already initiated multipart upload
-
-        :param object_path: Server side object path.
-        :type object_path: ``str``
-
-        :param upload_id: ID of the multipart upload.
-        :type upload_id: ``str``
-
-        :keyword container: The container owning the object to which data is
-            being uploaded
-        :type container: :class:`Container`
-        """
-
-        params = {'uploadId': upload_id}
-        request_path = '?'.join((object_path, urlencode(params)))
-        resp = self.connection.request(request_path, method='DELETE',
-                                       container=container)
-
-        if resp.status != httplib.NO_CONTENT:
-            raise LibcloudError('Error in multipart abort. status_code=%d' %
-                                (resp.status), driver=self)
-
-    def _upload_object(self, object_name, content_type, upload_func,
-                       upload_func_kwargs, request_path, request_method='PUT',
-                       headers=None, file_path=None, iterator=None,
-                       container=None):
-        """
-        Helper function for setting common request headers and calling the
-        passed in callback which uploads an object.
-        """
-        headers = headers or {}
-
-        if file_path and not os.path.exists(file_path):
-            raise OSError('File %s does not exist' % (file_path))
-
-        if iterator is not None and not hasattr(iterator, 'next') and not \
-                hasattr(iterator, '__next__'):
-            raise AttributeError('iterator object must implement next() ' +
-                                 'method.')
-
-        if not content_type:
-            if file_path:
-                name = file_path
-            else:
-                name = object_name
-            content_type, _ = guess_file_mime_type(name)
-
-            if not content_type:
-                if self.strict_mode:
-                    raise AttributeError('File content-type could not be '
-                                         'guessed and no content_type value '
-                                         'is provided')
-                else:
-                    # Fallback to a content-type
-                    content_type = DEFAULT_CONTENT_TYPE
-
-        file_size = None
-
-        if iterator:
-            if self.supports_chunked_encoding:
-                headers['Transfer-Encoding'] = 'chunked'
-                upload_func_kwargs['chunked'] = True
-            else:
-                # Chunked transfer encoding is not supported. Need to buffer
-                # all the data in memory so we can determine file size.
-                iterator = read_in_chunks(
-                    iterator=iterator)
-                data = exhaust_iterator(iterator=iterator)
-
-                file_size = len(data)
-                upload_func_kwargs['data'] = data
-        else:
-            file_size = os.path.getsize(file_path)
-            upload_func_kwargs['chunked'] = False
-
-        if file_size is not None and 'Content-Length' not in headers:
-            headers['Content-Length'] = file_size
-
-        headers['Content-Type'] = content_type
-        response = self.connection.request(request_path,
-                                           method=request_method, data=None,
-                                           headers=headers, raw=True,
-                                           container=container)
-
-        upload_func_kwargs['response'] = response
-        success, data_hash, bytes_transferred = upload_func(
-            **upload_func_kwargs)
-
-        if not success:
-            raise LibcloudError(
-                value='Object upload failed, Perhaps a timeout?', driver=self)
-
-        result_dict = {'response': response, 'data_hash': data_hash,
-                       'bytes_transferred': bytes_transferred}
-        return result_dict
-
-    def _to_containers(self, obj, xpath):
-        for element in obj.findall(fixxpath(xpath=xpath,
-                                   namespace=self.namespace)):
-            yield self._to_container(element)
-
-    def _to_container(self, element):
-        extra = {
-            'creation_date': findtext(element=element, xpath='CreationDate',
-                                      namespace=self.namespace),
-            'location': findtext(element=element, xpath='Location',
-                                 namespace=self.namespace)
-        }
-
-        container = Container(name=findtext(element=element, xpath='Name',
-                                            namespace=self.namespace),
-                              extra=extra,
-                              driver=self
-                              )
-
-        return container
-
-    def _to_objs(self, obj, xpath, container):
-        return [self._to_obj(element, container) for element in
-                obj.findall(fixxpath(xpath=xpath, namespace=self.namespace))]
-
-    def _to_obj(self, element, container):
-        owner_id = findtext(element=element, xpath='Owner/ID',
-                            namespace=self.namespace)
-        owner_display_name = findtext(element=element,
-                                      xpath='Owner/DisplayName',
-                                      namespace=self.namespace)
-        meta_data = {'owner': {'id': owner_id,
-                               'display_name': self._safe_decode(
-                                   owner_display_name)}}
-        last_modified = findtext(element=element,
-                                 xpath='LastModified',
-                                 namespace=self.namespace)
-        extra = {'last_modified': last_modified}
-
-        name = self._safe_decode(findtext(element=element, xpath='Key',
-                                          namespace=self.namespace))
-        obj = Object(name=name,
-                     size=int(findtext(element=element, xpath='Size',
-                                       namespace=self.namespace)),
-                     hash=findtext(element=element, xpath='ETag',
-                                   namespace=self.namespace).replace('"', ''),
-                     extra=extra,
-                     meta_data=meta_data,
-                     container=container,
-                     driver=self
-                     )
-
-        return obj
-
-    def _safe_decode(self, encoded):
-        """
-        Decode it as an escaped string and then treate the content as
-        UTF-8 encoded.
-        """
-        try:
-            if encoded:
-                unescaped, _ign = codecs.escape_decode(encoded)
-                return unescaped.decode('utf-8')
-            return encoded
-        except Exception:
-            return encoded
-
-    def _get_container_path(self, container):
-        """
-        Return a container path
-
-        :param container: Container instance
-        :type  container: :class:`Container`
-
-        :return: A path for this container.
-        :rtype: ``str``
-        """
-        return '/%s' % (container.name)
-
-    def _get_object_path(self, container, object_name):
-        """
-        Return an object's path.
-        Aliyun OSS api puts the container name in the host,
-        so ignore container here.
-
-        :param container: Container instance
-        :type  container: :class:`Container`
-
-        :param object_name: Object name
-        :type  object_name: :class:`str`
-
-        :return: A  path for this object.
-        :rtype: ``str``
-        """
-        object_name_cleaned = self._clean_object_name(object_name)
-        object_path = '/%s' % object_name_cleaned
-        return object_path
-
-    def _headers_to_object(self, object_name, container, headers):
-        hash = headers['etag'].replace('"', '')
-        extra = {'content_type': headers['content-type'],
-                 'etag': headers['etag']}
-        meta_data = {}
-
-        if 'last-modified' in headers:
-            extra['last_modified'] = headers['last-modified']
-
-        for key, value in headers.items():
-            if not key.lower().startswith(self.http_vendor_prefix + 'meta-'):
-                continue
-
-            key = key.replace(self.http_vendor_prefix + 'meta-', '')
-            meta_data[key] = value
-
-        obj = Object(name=object_name, size=int(headers['content-length']),
-                     hash=hash, extra=extra,
-                     meta_data=meta_data,
-                     container=container,
-                     driver=self)
-        return obj


[56/56] [abbrv] libcloud git commit: changes for #943

Posted by an...@apache.org.
changes for #943


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/32558b52
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/32558b52
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/32558b52

Branch: refs/heads/trunk
Commit: 32558b522b6b19041fce28985b8fb048fdef7505
Parents: 04a0981
Author: Anthony Shaw <an...@apache.org>
Authored: Tue Nov 15 10:26:29 2016 +1100
Committer: Anthony Shaw <an...@apache.org>
Committed: Tue Nov 15 10:26:29 2016 +1100

----------------------------------------------------------------------
 CHANGES.rst | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/32558b52/CHANGES.rst
----------------------------------------------------------------------
diff --git a/CHANGES.rst b/CHANGES.rst
index 50eada0..a56a8c7 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -8,6 +8,10 @@ Changes in current version of Apache Libcloud
 Compute
 ~~~~~~~
 
+- [ec2] Fix the bug that created the node at ecs driver and implement the method for creating public ip
+  (GITHUB-943)
+  [watermelo]
+
 - [profitbricks] changes to the ProfitBricks compute driver to drop support for the old SOAP api (now end of life) and provide support for v3 of the REST api.
   (GITHUB-938)
   [Matt Finucane]
@@ -4663,4 +4667,4 @@ Changes with Apache Libcloud 0.3.0 [Tagged May 6, 2010, not released]
 Changes with Apache Libcloud 0.2.0 [Tagged February 2, 2010]
 ------------------------------------------------------------
 
-- First public release.
\ No newline at end of file
+- First public release.


[03/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/s3.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/s3.py b/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/s3.py
deleted file mode 100644
index c4c249c..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/s3.py
+++ /dev/null
@@ -1,1037 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 base64
-import hmac
-import time
-import sys
-
-from hashlib import sha1
-
-try:
-    from lxml.etree import Element, SubElement
-except ImportError:
-    from xml.etree.ElementTree import Element, SubElement
-
-from libcloud.utils.py3 import httplib
-from libcloud.utils.py3 import urlquote
-from libcloud.utils.py3 import urlencode
-from libcloud.utils.py3 import b
-from libcloud.utils.py3 import tostring
-
-from libcloud.utils.xml import fixxpath, findtext
-from libcloud.utils.files import read_in_chunks
-from libcloud.common.types import InvalidCredsError, LibcloudError
-from libcloud.common.base import ConnectionUserAndKey, RawResponse
-from libcloud.common.aws import AWSBaseResponse, AWSDriver, \
-    AWSTokenConnection, SignedAWSConnection
-
-from libcloud.storage.base import Object, Container, StorageDriver
-from libcloud.storage.types import ContainerError
-from libcloud.storage.types import ContainerIsNotEmptyError
-from libcloud.storage.types import InvalidContainerNameError
-from libcloud.storage.types import ContainerDoesNotExistError
-from libcloud.storage.types import ObjectDoesNotExistError
-from libcloud.storage.types import ObjectHashMismatchError
-
-
-# How long before the token expires
-EXPIRATION_SECONDS = 15 * 60
-
-S3_US_STANDARD_HOST = 's3.amazonaws.com'
-S3_US_WEST_HOST = 's3-us-west-1.amazonaws.com'
-S3_US_WEST_OREGON_HOST = 's3-us-west-2.amazonaws.com'
-S3_EU_WEST_HOST = 's3-eu-west-1.amazonaws.com'
-S3_AP_SOUTHEAST_HOST = 's3-ap-southeast-1.amazonaws.com'
-S3_AP_NORTHEAST1_HOST = 's3-ap-northeast-1.amazonaws.com'
-S3_AP_NORTHEAST2_HOST = 's3-ap-northeast-2.amazonaws.com'
-S3_AP_NORTHEAST_HOST = S3_AP_NORTHEAST1_HOST
-S3_SA_EAST_HOST = 's3-sa-east-1.amazonaws.com'
-
-S3_RGW_OUTSCALE_HOSTS_BY_REGION =\
-    {'eu-west-1': 'osu.eu-west-1.outscale.com',
-     'eu-west-2': 'osu.eu-west-2.outscale.com',
-     'us-west-1': 'osu.us-west-1.outscale.com',
-     'us-east-2': 'osu.us-east-2.outscale.com',
-     'cn-southeast-1': 'osu.cn-southeast-1.outscale.hk'}
-
-S3_RGW_OUTSCALE_DEFAULT_REGION = 'eu-west-2'
-
-API_VERSION = '2006-03-01'
-NAMESPACE = 'http://s3.amazonaws.com/doc/%s/' % (API_VERSION)
-
-# AWS multi-part chunks must be minimum 5MB
-CHUNK_SIZE = 5 * 1024 * 1024
-
-# Desired number of items in each response inside a paginated request in
-# ex_iterate_multipart_uploads.
-RESPONSES_PER_REQUEST = 100
-
-
-class S3Response(AWSBaseResponse):
-    namespace = None
-    valid_response_codes = [httplib.NOT_FOUND, httplib.CONFLICT,
-                            httplib.BAD_REQUEST]
-
-    def success(self):
-        i = int(self.status)
-        return i >= 200 and i <= 299 or i in self.valid_response_codes
-
-    def parse_error(self):
-        if self.status in [httplib.UNAUTHORIZED, httplib.FORBIDDEN]:
-            raise InvalidCredsError(self.body)
-        elif self.status == httplib.MOVED_PERMANENTLY:
-            raise LibcloudError('This bucket is located in a different ' +
-                                'region. Please use the correct driver.',
-                                driver=S3StorageDriver)
-        raise LibcloudError('Unknown error. Status code: %d' % (self.status),
-                            driver=S3StorageDriver)
-
-
-class S3RawResponse(S3Response, RawResponse):
-    pass
-
-
-class BaseS3Connection(ConnectionUserAndKey):
-    """
-    Represents a single connection to the S3 Endpoint
-    """
-
-    host = 's3.amazonaws.com'
-    responseCls = S3Response
-    rawResponseCls = S3RawResponse
-
-    @staticmethod
-    def get_auth_signature(method, headers, params, expires, secret_key, path,
-                           vendor_prefix):
-        """
-        Signature = URL-Encode( Base64( HMAC-SHA1( YourSecretAccessKeyID,
-                                    UTF-8-Encoding-Of( StringToSign ) ) ) );
-
-        StringToSign = HTTP-VERB + "\n" +
-            Content-MD5 + "\n" +
-            Content-Type + "\n" +
-            Expires + "\n" +
-            CanonicalizedVendorHeaders +
-            CanonicalizedResource;
-        """
-        special_headers = {'content-md5': '', 'content-type': '', 'date': ''}
-        vendor_headers = {}
-
-        for key, value in list(headers.items()):
-            key_lower = key.lower()
-            if key_lower in special_headers:
-                special_headers[key_lower] = value.strip()
-            elif key_lower.startswith(vendor_prefix):
-                vendor_headers[key_lower] = value.strip()
-
-        if expires:
-            special_headers['date'] = str(expires)
-
-        buf = [method]
-        for _, value in sorted(special_headers.items()):
-            buf.append(value)
-        string_to_sign = '\n'.join(buf)
-
-        buf = []
-        for key, value in sorted(vendor_headers.items()):
-            buf.append('%s:%s' % (key, value))
-        header_string = '\n'.join(buf)
-
-        values_to_sign = []
-        for value in [string_to_sign, header_string, path]:
-            if value:
-                values_to_sign.append(value)
-
-        string_to_sign = '\n'.join(values_to_sign)
-        b64_hmac = base64.b64encode(
-            hmac.new(b(secret_key), b(string_to_sign), digestmod=sha1).digest()
-        )
-        return b64_hmac.decode('utf-8')
-
-    def add_default_params(self, params):
-        expires = str(int(time.time()) + EXPIRATION_SECONDS)
-        params['AWSAccessKeyId'] = self.user_id
-        params['Expires'] = expires
-        return params
-
-    def pre_connect_hook(self, params, headers):
-        params['Signature'] = self.get_auth_signature(
-            method=self.method, headers=headers, params=params,
-            expires=params['Expires'], secret_key=self.key, path=self.action,
-            vendor_prefix=self.driver.http_vendor_prefix)
-        return params, headers
-
-
-class S3Connection(AWSTokenConnection, BaseS3Connection):
-    """
-    Represents a single connection to the S3 endpoint, with AWS-specific
-    features.
-    """
-    pass
-
-
-class S3MultipartUpload(object):
-    """
-    Class representing an amazon s3 multipart upload
-    """
-
-    def __init__(self, key, id, created_at, initiator, owner):
-        """
-        Class representing an amazon s3 multipart upload
-
-        :param key: The object/key that was being uploaded
-        :type key: ``str``
-
-        :param id: The upload id assigned by amazon
-        :type id: ``str``
-
-        :param created_at: The date/time at which the upload was started
-        :type created_at: ``str``
-
-        :param initiator: The AWS owner/IAM user who initiated this
-        :type initiator: ``str``
-
-        :param owner: The AWS owner/IAM who will own this object
-        :type owner: ``str``
-        """
-        self.key = key
-        self.id = id
-        self.created_at = created_at
-        self.initiator = initiator
-        self.owner = owner
-
-    def __repr__(self):
-        return ('<S3MultipartUpload: key=%s>' % (self.key))
-
-
-class BaseS3StorageDriver(StorageDriver):
-    name = 'Amazon S3 (standard)'
-    website = 'http://aws.amazon.com/s3/'
-    connectionCls = BaseS3Connection
-    hash_type = 'md5'
-    supports_chunked_encoding = False
-    supports_s3_multipart_upload = True
-    ex_location_name = ''
-    namespace = NAMESPACE
-    http_vendor_prefix = 'x-amz'
-
-    def iterate_containers(self):
-        response = self.connection.request('/')
-        if response.status == httplib.OK:
-            containers = self._to_containers(obj=response.object,
-                                             xpath='Buckets/Bucket')
-            return containers
-
-        raise LibcloudError('Unexpected status code: %s' % (response.status),
-                            driver=self)
-
-    def list_container_objects(self, container, ex_prefix=None):
-        """
-        Return a list of objects for the given container.
-
-        :param container: Container instance.
-        :type container: :class:`Container`
-
-        :param ex_prefix: Only return objects starting with ex_prefix
-        :type ex_prefix: ``str``
-
-        :return: A list of Object instances.
-        :rtype: ``list`` of :class:`Object`
-        """
-        return list(self.iterate_container_objects(container,
-                    ex_prefix=ex_prefix))
-
-    def iterate_container_objects(self, container, ex_prefix=None):
-        """
-        Return a generator of objects for the given container.
-
-        :param container: Container instance
-        :type container: :class:`Container`
-
-        :param ex_prefix: Only return objects starting with ex_prefix
-        :type ex_prefix: ``str``
-
-        :return: A generator of Object instances.
-        :rtype: ``generator`` of :class:`Object`
-        """
-        params = {}
-        if ex_prefix:
-            params['prefix'] = ex_prefix
-
-        last_key = None
-        exhausted = False
-        container_path = self._get_container_path(container)
-
-        while not exhausted:
-            if last_key:
-                params['marker'] = last_key
-
-            response = self.connection.request(container_path,
-                                               params=params)
-
-            if response.status != httplib.OK:
-                raise LibcloudError('Unexpected status code: %s' %
-                                    (response.status), driver=self)
-
-            objects = self._to_objs(obj=response.object,
-                                    xpath='Contents', container=container)
-            is_truncated = response.object.findtext(fixxpath(
-                xpath='IsTruncated', namespace=self.namespace)).lower()
-            exhausted = (is_truncated == 'false')
-
-            last_key = None
-            for obj in objects:
-                last_key = obj.name
-                yield obj
-
-    def get_container(self, container_name):
-        try:
-            response = self.connection.request('/%s' % container_name,
-                                               method='HEAD')
-            if response.status == httplib.NOT_FOUND:
-                raise ContainerDoesNotExistError(value=None, driver=self,
-                                                 container_name=container_name)
-        except InvalidCredsError:
-            # This just means the user doesn't have IAM permissions to do a
-            # HEAD request but other requests might work.
-            pass
-        return Container(name=container_name, extra=None, driver=self)
-
-    def get_object(self, container_name, object_name):
-        container = self.get_container(container_name=container_name)
-        object_path = self._get_object_path(container, object_name)
-        response = self.connection.request(object_path, method='HEAD')
-
-        if response.status == httplib.OK:
-            obj = self._headers_to_object(object_name=object_name,
-                                          container=container,
-                                          headers=response.headers)
-            return obj
-
-        raise ObjectDoesNotExistError(value=None, driver=self,
-                                      object_name=object_name)
-
-    def _get_container_path(self, container):
-        """
-        Return a container path
-
-        :param container: Container instance
-        :type  container: :class:`Container`
-
-        :return: A path for this container.
-        :rtype: ``str``
-        """
-        return '/%s' % (container.name)
-
-    def _get_object_path(self, container, object_name):
-        """
-        Return an object's CDN path.
-
-        :param container: Container instance
-        :type  container: :class:`Container`
-
-        :param object_name: Object name
-        :type  object_name: :class:`str`
-
-        :return: A  path for this object.
-        :rtype: ``str``
-        """
-        container_url = self._get_container_path(container)
-        object_name_cleaned = self._clean_object_name(object_name)
-        object_path = '%s/%s' % (container_url, object_name_cleaned)
-        return object_path
-
-    def create_container(self, container_name):
-        if self.ex_location_name:
-            root = Element('CreateBucketConfiguration')
-            child = SubElement(root, 'LocationConstraint')
-            child.text = self.ex_location_name
-
-            data = tostring(root)
-        else:
-            data = ''
-
-        response = self.connection.request('/%s' % (container_name),
-                                           data=data,
-                                           method='PUT')
-
-        if response.status == httplib.OK:
-            container = Container(name=container_name, extra=None, driver=self)
-            return container
-        elif response.status == httplib.CONFLICT:
-            raise InvalidContainerNameError(
-                value='Container with this name already exists. The name must '
-                      'be unique among all the containers in the system',
-                container_name=container_name, driver=self)
-        elif response.status == httplib.BAD_REQUEST:
-            raise ContainerError(
-                value='Bad request when creating container: %s' %
-                      response.body,
-                container_name=container_name, driver=self)
-
-        raise LibcloudError('Unexpected status code: %s' % (response.status),
-                            driver=self)
-
-    def delete_container(self, container):
-        # Note: All the objects in the container must be deleted first
-        response = self.connection.request('/%s' % (container.name),
-                                           method='DELETE')
-        if response.status == httplib.NO_CONTENT:
-            return True
-        elif response.status == httplib.CONFLICT:
-            raise ContainerIsNotEmptyError(
-                value='Container must be empty before it can be deleted.',
-                container_name=container.name, driver=self)
-        elif response.status == httplib.NOT_FOUND:
-            raise ContainerDoesNotExistError(value=None,
-                                             driver=self,
-                                             container_name=container.name)
-
-        return False
-
-    def download_object(self, obj, destination_path, overwrite_existing=False,
-                        delete_on_failure=True):
-        obj_path = self._get_object_path(obj.container, obj.name)
-
-        response = self.connection.request(obj_path, method='GET', raw=True)
-
-        return self._get_object(obj=obj, callback=self._save_object,
-                                response=response,
-                                callback_kwargs={
-                                    'obj': obj,
-                                    'response': response.response,
-                                    'destination_path': destination_path,
-                                    'overwrite_existing': overwrite_existing,
-                                    'delete_on_failure': delete_on_failure},
-                                success_status_code=httplib.OK)
-
-    def download_object_as_stream(self, obj, chunk_size=None):
-        obj_path = self._get_object_path(obj.container, obj.name)
-        response = self.connection.request(obj_path, method='GET', raw=True)
-
-        return self._get_object(obj=obj, callback=read_in_chunks,
-                                response=response,
-                                callback_kwargs={'iterator': response.response,
-                                                 'chunk_size': chunk_size},
-                                success_status_code=httplib.OK)
-
-    def upload_object(self, file_path, container, object_name, extra=None,
-                      verify_hash=True, ex_storage_class=None):
-        """
-        @inherits: :class:`StorageDriver.upload_object`
-
-        :param ex_storage_class: Storage class
-        :type ex_storage_class: ``str``
-        """
-        upload_func = self._upload_file
-        upload_func_kwargs = {'file_path': file_path}
-
-        return self._put_object(container=container, object_name=object_name,
-                                upload_func=upload_func,
-                                upload_func_kwargs=upload_func_kwargs,
-                                extra=extra, file_path=file_path,
-                                verify_hash=verify_hash,
-                                storage_class=ex_storage_class)
-
-    def _upload_multipart(self, response, data, iterator, container,
-                          object_name, calculate_hash=True):
-        """
-        Callback invoked for uploading data to S3 using Amazon's
-        multipart upload mechanism
-
-        :param response: Response object from the initial POST request
-        :type response: :class:`S3RawResponse`
-
-        :param data: Any data from the initial POST request
-        :type data: ``str``
-
-        :param iterator: The generator for fetching the upload data
-        :type iterator: ``generator``
-
-        :param container: The container owning the object to which data is
-            being uploaded
-        :type container: :class:`Container`
-
-        :param object_name: The name of the object to which we are uploading
-        :type object_name: ``str``
-
-        :keyword calculate_hash: Indicates if we must calculate the data hash
-        :type calculate_hash: ``bool``
-
-        :return: A tuple of (status, checksum, bytes transferred)
-        :rtype: ``tuple``
-        """
-
-        object_path = self._get_object_path(container, object_name)
-
-        # Get the upload id from the response xml
-        response.body = response.response.read()
-        body = response.parse_body()
-        upload_id = body.find(fixxpath(xpath='UploadId',
-                                       namespace=self.namespace)).text
-
-        try:
-            # Upload the data through the iterator
-            result = self._upload_from_iterator(iterator, object_path,
-                                                upload_id, calculate_hash)
-            (chunks, data_hash, bytes_transferred) = result
-
-            # Commit the chunk info and complete the upload
-            etag = self._commit_multipart(object_path, upload_id, chunks)
-        except Exception:
-            exc = sys.exc_info()[1]
-            # Amazon provides a mechanism for aborting an upload.
-            self._abort_multipart(object_path, upload_id)
-            raise exc
-
-        # Modify the response header of the first request. This is used
-        # by other functions once the callback is done
-        response.headers['etag'] = etag
-
-        return (True, data_hash, bytes_transferred)
-
-    def _upload_from_iterator(self, iterator, object_path, upload_id,
-                              calculate_hash=True):
-        """
-        Uploads data from an iterator in fixed sized chunks to S3
-
-        :param iterator: The generator for fetching the upload data
-        :type iterator: ``generator``
-
-        :param object_path: The path of the object to which we are uploading
-        :type object_name: ``str``
-
-        :param upload_id: The upload id allocated for this multipart upload
-        :type upload_id: ``str``
-
-        :keyword calculate_hash: Indicates if we must calculate the data hash
-        :type calculate_hash: ``bool``
-
-        :return: A tuple of (chunk info, checksum, bytes transferred)
-        :rtype: ``tuple``
-        """
-
-        data_hash = None
-        if calculate_hash:
-            data_hash = self._get_hash_function()
-
-        bytes_transferred = 0
-        count = 1
-        chunks = []
-        params = {'uploadId': upload_id}
-
-        # Read the input data in chunk sizes suitable for AWS
-        for data in read_in_chunks(iterator, chunk_size=CHUNK_SIZE,
-                                   fill_size=True, yield_empty=True):
-            bytes_transferred += len(data)
-
-            if calculate_hash:
-                data_hash.update(data)
-
-            chunk_hash = self._get_hash_function()
-            chunk_hash.update(data)
-            chunk_hash = base64.b64encode(chunk_hash.digest()).decode('utf-8')
-
-            # This provides an extra level of data check and is recommended
-            # by amazon
-            headers = {'Content-MD5': chunk_hash}
-            params['partNumber'] = count
-
-            request_path = '?'.join((object_path, urlencode(params)))
-
-            resp = self.connection.request(request_path, method='PUT',
-                                           data=data, headers=headers)
-
-            if resp.status != httplib.OK:
-                raise LibcloudError('Error uploading chunk', driver=self)
-
-            server_hash = resp.headers['etag']
-
-            # Keep this data for a later commit
-            chunks.append((count, server_hash))
-            count += 1
-
-        if calculate_hash:
-            data_hash = data_hash.hexdigest()
-
-        return (chunks, data_hash, bytes_transferred)
-
-    def _commit_multipart(self, object_path, upload_id, chunks):
-        """
-        Makes a final commit of the data.
-
-        :param object_path: Server side object path.
-        :type object_path: ``str``
-
-        :param upload_id: ID of the multipart upload.
-        :type upload_id: ``str``
-
-        :param upload_id: A list of (chunk_number, chunk_hash) tuples.
-        :type upload_id: ``list``
-        """
-
-        root = Element('CompleteMultipartUpload')
-
-        for (count, etag) in chunks:
-            part = SubElement(root, 'Part')
-            part_no = SubElement(part, 'PartNumber')
-            part_no.text = str(count)
-
-            etag_id = SubElement(part, 'ETag')
-            etag_id.text = str(etag)
-
-        data = tostring(root)
-
-        params = {'uploadId': upload_id}
-        request_path = '?'.join((object_path, urlencode(params)))
-        response = self.connection.request(request_path, data=data,
-                                           method='POST')
-
-        if response.status != httplib.OK:
-            element = response.object
-            # pylint: disable=maybe-no-member
-            code, message = response._parse_error_details(element=element)
-            msg = 'Error in multipart commit: %s (%s)' % (message, code)
-            raise LibcloudError(msg, driver=self)
-
-        # Get the server's etag to be passed back to the caller
-        body = response.parse_body()
-        server_hash = body.find(fixxpath(xpath='ETag',
-                                         namespace=self.namespace)).text
-        return server_hash
-
-    def _abort_multipart(self, object_path, upload_id):
-        """
-        Aborts an already initiated multipart upload
-
-        :param object_path: Server side object path.
-        :type object_path: ``str``
-
-        :param upload_id: ID of the multipart upload.
-        :type upload_id: ``str``
-        """
-
-        params = {'uploadId': upload_id}
-        request_path = '?'.join((object_path, urlencode(params)))
-        resp = self.connection.request(request_path, method='DELETE')
-
-        if resp.status != httplib.NO_CONTENT:
-            raise LibcloudError('Error in multipart abort. status_code=%d' %
-                                (resp.status), driver=self)
-
-    def upload_object_via_stream(self, iterator, container, object_name,
-                                 extra=None, ex_storage_class=None):
-        """
-        @inherits: :class:`StorageDriver.upload_object_via_stream`
-
-        :param ex_storage_class: Storage class
-        :type ex_storage_class: ``str``
-        """
-
-        method = 'PUT'
-        params = None
-
-        # This driver is used by other S3 API compatible drivers also.
-        # Amazon provides a different (complex?) mechanism to do multipart
-        # uploads
-        if self.supports_s3_multipart_upload:
-            # Initiate the multipart request and get an upload id
-            upload_func = self._upload_multipart
-            upload_func_kwargs = {'iterator': iterator,
-                                  'container': container,
-                                  'object_name': object_name}
-            method = 'POST'
-            iterator = iter('')
-            params = 'uploads'
-
-        elif self.supports_chunked_encoding:
-            upload_func = self._stream_data
-            upload_func_kwargs = {'iterator': iterator}
-        else:
-            # In this case, we have to load the entire object to
-            # memory and send it as normal data
-            upload_func = self._upload_data
-            upload_func_kwargs = {}
-
-        return self._put_object(container=container, object_name=object_name,
-                                upload_func=upload_func,
-                                upload_func_kwargs=upload_func_kwargs,
-                                extra=extra, method=method, query_args=params,
-                                iterator=iterator, verify_hash=False,
-                                storage_class=ex_storage_class)
-
-    def delete_object(self, obj):
-        object_path = self._get_object_path(obj.container, obj.name)
-        response = self.connection.request(object_path, method='DELETE')
-        if response.status == httplib.NO_CONTENT:
-            return True
-        elif response.status == httplib.NOT_FOUND:
-            raise ObjectDoesNotExistError(value=None, driver=self,
-                                          object_name=obj.name)
-
-        return False
-
-    def ex_iterate_multipart_uploads(self, container, prefix=None,
-                                     delimiter=None):
-        """
-        Extension method for listing all in-progress S3 multipart uploads.
-
-        Each multipart upload which has not been committed or aborted is
-        considered in-progress.
-
-        :param container: The container holding the uploads
-        :type container: :class:`Container`
-
-        :keyword prefix: Print only uploads of objects with this prefix
-        :type prefix: ``str``
-
-        :keyword delimiter: The object/key names are grouped based on
-            being split by this delimiter
-        :type delimiter: ``str``
-
-        :return: A generator of S3MultipartUpload instances.
-        :rtype: ``generator`` of :class:`S3MultipartUpload`
-        """
-
-        if not self.supports_s3_multipart_upload:
-            raise LibcloudError('Feature not supported', driver=self)
-
-        # Get the data for a specific container
-        request_path = '%s/?uploads' % (self._get_container_path(container))
-        params = {'max-uploads': RESPONSES_PER_REQUEST}
-
-        if prefix:
-            params['prefix'] = prefix
-
-        if delimiter:
-            params['delimiter'] = delimiter
-
-        def finder(node, text):
-            return node.findtext(fixxpath(xpath=text,
-                                          namespace=self.namespace))
-
-        while True:
-            response = self.connection.request(request_path, params=params)
-
-            if response.status != httplib.OK:
-                raise LibcloudError('Error fetching multipart uploads. '
-                                    'Got code: %s' % response.status,
-                                    driver=self)
-
-            body = response.parse_body()
-            # pylint: disable=maybe-no-member
-            for node in body.findall(fixxpath(xpath='Upload',
-                                              namespace=self.namespace)):
-
-                initiator = node.find(fixxpath(xpath='Initiator',
-                                               namespace=self.namespace))
-                owner = node.find(fixxpath(xpath='Owner',
-                                           namespace=self.namespace))
-
-                key = finder(node, 'Key')
-                upload_id = finder(node, 'UploadId')
-                created_at = finder(node, 'Initiated')
-                initiator = finder(initiator, 'DisplayName')
-                owner = finder(owner, 'DisplayName')
-
-                yield S3MultipartUpload(key, upload_id, created_at,
-                                        initiator, owner)
-
-            # Check if this is the last entry in the listing
-            # pylint: disable=maybe-no-member
-            is_truncated = body.findtext(fixxpath(xpath='IsTruncated',
-                                                  namespace=self.namespace))
-
-            if is_truncated.lower() == 'false':
-                break
-
-            # Provide params for the next request
-            upload_marker = body.findtext(fixxpath(xpath='NextUploadIdMarker',
-                                                   namespace=self.namespace))
-            key_marker = body.findtext(fixxpath(xpath='NextKeyMarker',
-                                                namespace=self.namespace))
-
-            params['key-marker'] = key_marker
-            params['upload-id-marker'] = upload_marker
-
-    def ex_cleanup_all_multipart_uploads(self, container, prefix=None):
-        """
-        Extension method for removing all partially completed S3 multipart
-        uploads.
-
-        :param container: The container holding the uploads
-        :type container: :class:`Container`
-
-        :keyword prefix: Delete only uploads of objects with this prefix
-        :type prefix: ``str``
-        """
-
-        # Iterate through the container and delete the upload ids
-        for upload in self.ex_iterate_multipart_uploads(container, prefix,
-                                                        delimiter=None):
-            object_path = '/%s/%s' % (container.name, upload.key)
-            self._abort_multipart(object_path, upload.id)
-
-    def _clean_object_name(self, name):
-        name = urlquote(name)
-        return name
-
-    def _put_object(self, container, object_name, upload_func,
-                    upload_func_kwargs, method='PUT', query_args=None,
-                    extra=None, file_path=None, iterator=None,
-                    verify_hash=True, storage_class=None):
-        headers = {}
-        extra = extra or {}
-        storage_class = storage_class or 'standard'
-        if storage_class not in ['standard', 'reduced_redundancy']:
-            raise ValueError(
-                'Invalid storage class value: %s' % (storage_class))
-
-        key = self.http_vendor_prefix + '-storage-class'
-        headers[key] = storage_class.upper()
-
-        content_type = extra.get('content_type', None)
-        meta_data = extra.get('meta_data', None)
-        acl = extra.get('acl', None)
-
-        if meta_data:
-            for key, value in list(meta_data.items()):
-                key = self.http_vendor_prefix + '-meta-%s' % (key)
-                headers[key] = value
-
-        if acl:
-            headers[self.http_vendor_prefix + '-acl'] = acl
-
-        request_path = self._get_object_path(container, object_name)
-
-        if query_args:
-            request_path = '?'.join((request_path, query_args))
-
-        # TODO: Let the underlying exceptions bubble up and capture the SIGPIPE
-        # here.
-        # SIGPIPE is thrown if the provided container does not exist or the
-        # user does not have correct permission
-        result_dict = self._upload_object(
-            object_name=object_name, content_type=content_type,
-            upload_func=upload_func, upload_func_kwargs=upload_func_kwargs,
-            request_path=request_path, request_method=method,
-            headers=headers, file_path=file_path, iterator=iterator)
-
-        response = result_dict['response']
-        bytes_transferred = result_dict['bytes_transferred']
-        headers = response.headers
-        response = response.response
-        server_hash = headers['etag'].replace('"', '')
-
-        if (verify_hash and result_dict['data_hash'] != server_hash):
-            raise ObjectHashMismatchError(
-                value='MD5 hash checksum does not match',
-                object_name=object_name, driver=self)
-        elif response.status == httplib.OK:
-            obj = Object(
-                name=object_name, size=bytes_transferred, hash=server_hash,
-                extra={'acl': acl}, meta_data=meta_data, container=container,
-                driver=self)
-
-            return obj
-        else:
-            raise LibcloudError(
-                'Unexpected status code, status_code=%s' % (response.status),
-                driver=self)
-
-    def _to_containers(self, obj, xpath):
-        for element in obj.findall(fixxpath(xpath=xpath,
-                                   namespace=self.namespace)):
-            yield self._to_container(element)
-
-    def _to_objs(self, obj, xpath, container):
-        return [self._to_obj(element, container) for element in
-                obj.findall(fixxpath(xpath=xpath, namespace=self.namespace))]
-
-    def _to_container(self, element):
-        extra = {
-            'creation_date': findtext(element=element, xpath='CreationDate',
-                                      namespace=self.namespace)
-        }
-
-        container = Container(name=findtext(element=element, xpath='Name',
-                                            namespace=self.namespace),
-                              extra=extra,
-                              driver=self
-                              )
-
-        return container
-
-    def _headers_to_object(self, object_name, container, headers):
-        hash = headers['etag'].replace('"', '')
-        extra = {'content_type': headers['content-type'],
-                 'etag': headers['etag']}
-        meta_data = {}
-
-        if 'last-modified' in headers:
-            extra['last_modified'] = headers['last-modified']
-
-        for key, value in headers.items():
-            if not key.lower().startswith(self.http_vendor_prefix + '-meta-'):
-                continue
-
-            key = key.replace(self.http_vendor_prefix + '-meta-', '')
-            meta_data[key] = value
-
-        obj = Object(name=object_name, size=headers['content-length'],
-                     hash=hash, extra=extra,
-                     meta_data=meta_data,
-                     container=container,
-                     driver=self)
-        return obj
-
-    def _to_obj(self, element, container):
-        owner_id = findtext(element=element, xpath='Owner/ID',
-                            namespace=self.namespace)
-        owner_display_name = findtext(element=element,
-                                      xpath='Owner/DisplayName',
-                                      namespace=self.namespace)
-        meta_data = {'owner': {'id': owner_id,
-                               'display_name': owner_display_name}}
-        last_modified = findtext(element=element,
-                                 xpath='LastModified',
-                                 namespace=self.namespace)
-        extra = {'last_modified': last_modified}
-
-        obj = Object(name=findtext(element=element, xpath='Key',
-                                   namespace=self.namespace),
-                     size=int(findtext(element=element, xpath='Size',
-                                       namespace=self.namespace)),
-                     hash=findtext(element=element, xpath='ETag',
-                                   namespace=self.namespace).replace('"', ''),
-                     extra=extra,
-                     meta_data=meta_data,
-                     container=container,
-                     driver=self
-                     )
-
-        return obj
-
-
-class S3StorageDriver(AWSDriver, BaseS3StorageDriver):
-    connectionCls = S3Connection
-
-
-class S3USWestConnection(S3Connection):
-    host = S3_US_WEST_HOST
-
-
-class S3USWestStorageDriver(S3StorageDriver):
-    name = 'Amazon S3 (us-west-1)'
-    connectionCls = S3USWestConnection
-    ex_location_name = 'us-west-1'
-
-
-class S3USWestOregonConnection(S3Connection):
-    host = S3_US_WEST_OREGON_HOST
-
-
-class S3USWestOregonStorageDriver(S3StorageDriver):
-    name = 'Amazon S3 (us-west-2)'
-    connectionCls = S3USWestOregonConnection
-    ex_location_name = 'us-west-2'
-
-
-class S3EUWestConnection(S3Connection):
-    host = S3_EU_WEST_HOST
-
-
-class S3EUWestStorageDriver(S3StorageDriver):
-    name = 'Amazon S3 (eu-west-1)'
-    connectionCls = S3EUWestConnection
-    ex_location_name = 'EU'
-
-
-class S3APSEConnection(S3Connection):
-    host = S3_AP_SOUTHEAST_HOST
-
-
-class S3APSEStorageDriver(S3StorageDriver):
-    name = 'Amazon S3 (ap-southeast-1)'
-    connectionCls = S3APSEConnection
-    ex_location_name = 'ap-southeast-1'
-
-
-class S3APNE1Connection(S3Connection):
-    host = S3_AP_NORTHEAST1_HOST
-
-S3APNEConnection = S3APNE1Connection
-
-
-class S3APNE1StorageDriver(S3StorageDriver):
-    name = 'Amazon S3 (ap-northeast-1)'
-    connectionCls = S3APNEConnection
-    ex_location_name = 'ap-northeast-1'
-
-S3APNEStorageDriver = S3APNE1StorageDriver
-
-
-class S3APNE2Connection(SignedAWSConnection, BaseS3Connection):
-    host = S3_AP_NORTHEAST2_HOST
-    service_name = 's3'
-    version = API_VERSION
-
-    def __init__(self, user_id, key, secure=True, host=None, port=None,
-                 url=None, timeout=None, proxy_url=None, token=None,
-                 retry_delay=None, backoff=None):
-        super(S3APNE2Connection, self).__init__(user_id, key, secure, host,
-                                                port, url, timeout, proxy_url,
-                                                token, retry_delay, backoff,
-                                                4)  # force version 4
-
-
-class S3APNE2StorageDriver(S3StorageDriver):
-    name = 'Amazon S3 (ap-northeast-2)'
-    connectionCls = S3APNE2Connection
-    ex_location_name = 'ap-northeast-2'
-    region_name = 'ap-northeast-2'
-
-
-class S3SAEastConnection(S3Connection):
-    host = S3_SA_EAST_HOST
-
-
-class S3SAEastStorageDriver(S3StorageDriver):
-    name = 'Amazon S3 (sa-east-1)'
-    connectionCls = S3SAEastConnection
-    ex_location_name = 'sa-east-1'
-
-
-class S3RGWOutscaleConnection(S3Connection):
-    pass
-
-
-class S3RGWOutscaleStorageDriver(S3StorageDriver):
-
-    def __init__(self, key, secret=None, secure=True, host=None, port=None,
-                 api_version=None, region=S3_RGW_OUTSCALE_DEFAULT_REGION,
-                 **kwargs):
-        if region not in S3_RGW_OUTSCALE_HOSTS_BY_REGION:
-            raise LibcloudError('Unknown region (%s)' % (region), driver=self)
-        self.name = 'OUTSCALE Ceph RGW S3 (%s)' % (region)
-        self.ex_location_name = region
-        self.region_name = region
-        self.connectionCls = S3RGWOutscaleConnection
-        self.connectionCls.host = S3_RGW_OUTSCALE_HOSTS_BY_REGION[region]
-        super(S3RGWOutscaleStorageDriver, self).__init__(key, secret,
-                                                         secure, host, port,
-                                                         api_version, region,
-                                                         **kwargs)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/storage/providers.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/storage/providers.py b/apache-libcloud-1.0.0rc2/libcloud/storage/providers.py
deleted file mode 100644
index eddd470..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/storage/providers.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from libcloud.storage.types import Provider
-from libcloud.storage.types import OLD_CONSTANT_TO_NEW_MAPPING
-from libcloud.common.providers import get_driver as _get_provider_driver
-from libcloud.common.providers import set_driver as _set_provider_driver
-
-DRIVERS = {
-    Provider.DUMMY:
-    ('libcloud.storage.drivers.dummy', 'DummyStorageDriver'),
-    Provider.CLOUDFILES:
-    ('libcloud.storage.drivers.cloudfiles', 'CloudFilesStorageDriver'),
-    Provider.OPENSTACK_SWIFT:
-    ('libcloud.storage.drivers.cloudfiles', 'OpenStackSwiftStorageDriver'),
-    Provider.S3:
-    ('libcloud.storage.drivers.s3', 'S3StorageDriver'),
-    Provider.S3_US_WEST:
-    ('libcloud.storage.drivers.s3', 'S3USWestStorageDriver'),
-    Provider.S3_US_WEST_OREGON:
-    ('libcloud.storage.drivers.s3', 'S3USWestOregonStorageDriver'),
-    Provider.S3_EU_WEST:
-    ('libcloud.storage.drivers.s3', 'S3EUWestStorageDriver'),
-    Provider.S3_AP_SOUTHEAST:
-    ('libcloud.storage.drivers.s3', 'S3APSEStorageDriver'),
-    Provider.S3_AP_NORTHEAST:
-    ('libcloud.storage.drivers.s3', 'S3APNE1StorageDriver'),
-    Provider.S3_AP_NORTHEAST1:
-    ('libcloud.storage.drivers.s3', 'S3APNE1StorageDriver'),
-    Provider.S3_AP_NORTHEAST2:
-    ('libcloud.storage.drivers.s3', 'S3APNE2StorageDriver'),
-    Provider.S3_SA_EAST:
-    ('libcloud.storage.drivers.s3', 'S3SAEastStorageDriver'),
-    Provider.S3_RGW_OUTSCALE:
-    ('libcloud.storage.drivers.s3', 'S3RGWOutscaleStorageDriver'),
-    Provider.NINEFOLD:
-    ('libcloud.storage.drivers.ninefold', 'NinefoldStorageDriver'),
-    Provider.GOOGLE_STORAGE:
-    ('libcloud.storage.drivers.google_storage', 'GoogleStorageDriver'),
-    Provider.NIMBUS:
-    ('libcloud.storage.drivers.nimbus', 'NimbusStorageDriver'),
-    Provider.LOCAL:
-    ('libcloud.storage.drivers.local', 'LocalStorageDriver'),
-    Provider.AZURE_BLOBS:
-    ('libcloud.storage.drivers.azure_blobs', 'AzureBlobsStorageDriver'),
-    Provider.KTUCLOUD:
-    ('libcloud.storage.drivers.ktucloud', 'KTUCloudStorageDriver'),
-    Provider.AURORAOBJECTS:
-    ('libcloud.storage.drivers.auroraobjects', 'AuroraObjectsStorageDriver'),
-    Provider.BACKBLAZE_B2:
-    ('libcloud.storage.drivers.backblaze_b2', 'BackblazeB2StorageDriver'),
-    Provider.ALIYUN_OSS:
-    ('libcloud.storage.drivers.oss', 'OSSStorageDriver'),
-}
-
-
-def get_driver(provider):
-    deprecated_constants = OLD_CONSTANT_TO_NEW_MAPPING
-    return _get_provider_driver(drivers=DRIVERS, provider=provider,
-                                deprecated_constants=deprecated_constants)
-
-
-def set_driver(provider, module, klass):
-    return _set_provider_driver(drivers=DRIVERS, provider=provider,
-                                module=module, klass=klass)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/storage/types.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/storage/types.py b/apache-libcloud-1.0.0rc2/libcloud/storage/types.py
deleted file mode 100644
index ea8f645..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/storage/types.py
+++ /dev/null
@@ -1,141 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from libcloud.common.types import LibcloudError
-
-__all__ = [
-    'Provider',
-    'ContainerError',
-    'ObjectError',
-    'ContainerAlreadyExistsError',
-    'ContainerDoesNotExistError',
-    'ContainerIsNotEmptyError',
-    'ObjectDoesNotExistError',
-    'ObjectHashMismatchError',
-    'InvalidContainerNameError',
-
-    'OLD_CONSTANT_TO_NEW_MAPPING'
-]
-
-
-class Provider(object):
-    """
-    Defines for each of the supported providers
-
-    :cvar DUMMY: Example provider
-    :cvar CLOUDFILES: CloudFiles
-    :cvar S3: Amazon S3 US
-    :cvar S3_US_WEST: Amazon S3 US West (Northern California)
-    :cvar S3_EU_WEST: Amazon S3 EU West (Ireland)
-    :cvar S3_AP_SOUTHEAST_HOST: Amazon S3 Asia South East (Singapore)
-    :cvar S3_AP_NORTHEAST_HOST: Amazon S3 Asia South East (Tokyo)
-    :cvar S3_RGW_OUTSCALE: OUTSCALE RGW S3
-    :cvar NINEFOLD: Ninefold
-    :cvar GOOGLE_STORAGE Google Storage
-    :cvar S3_US_WEST_OREGON: Amazon S3 US West 2 (Oregon)
-    :cvar NIMBUS: Nimbus.io driver
-    :cvar LOCAL: Local storage driver
-    :cvar AURORAOBJECTS: AuroraObjects storage driver
-    :cvar ALIYUN_OSS: Aliyun OSS storage driver
-    """
-    DUMMY = 'dummy'
-    S3 = 's3'
-    S3_US_WEST = 's3_us_west'
-    S3_EU_WEST = 's3_eu_west'
-    S3_AP_SOUTHEAST = 's3_ap_southeast'
-    S3_AP_NORTHEAST = 's3_ap_northeast'
-    S3_AP_NORTHEAST1 = 's3_ap_northeast_1'
-    S3_AP_NORTHEAST2 = 's3_ap_northeast_2'
-    S3_SA_EAST = 's3_sa_east'
-    S3_RGW_OUTSCALE = 's3_rgw_outscale'
-    NINEFOLD = 'ninefold'
-    GOOGLE_STORAGE = 'google_storage'
-    S3_US_WEST_OREGON = 's3_us_west_oregon'
-    NIMBUS = 'nimbus'
-    LOCAL = 'local'
-    OPENSTACK_SWIFT = 'openstack_swift'
-    CLOUDFILES = 'cloudfiles'
-    AZURE_BLOBS = 'azure_blobs'
-    KTUCLOUD = 'ktucloud'
-    AURORAOBJECTS = 'auroraobjects'
-    BACKBLAZE_B2 = 'backblaze_b2'
-    ALIYUN_OSS = 'aliyun_oss'
-
-    # Deperecated
-    CLOUDFILES_US = 'cloudfiles_us'
-    CLOUDFILES_UK = 'cloudfiles_uk'
-    CLOUDFILES_SWIFT = 'cloudfiles_swift'
-
-
-OLD_CONSTANT_TO_NEW_MAPPING = {
-    # CloudFiles
-    Provider.CLOUDFILES_US: Provider.CLOUDFILES,
-    Provider.CLOUDFILES_UK: Provider.CLOUDFILES_UK,
-    Provider.CLOUDFILES_SWIFT: Provider.OPENSTACK_SWIFT
-}
-
-
-class ContainerError(LibcloudError):
-    error_type = 'ContainerError'
-
-    def __init__(self, value, driver, container_name):
-        self.container_name = container_name
-        super(ContainerError, self).__init__(value=value, driver=driver)
-
-    def __str__(self):
-        return ('<%s in %s, container=%s, value=%s>' %
-                (self.error_type, repr(self.driver),
-                 self.container_name, self.value))
-
-
-class ObjectError(LibcloudError):
-    error_type = 'ContainerError'
-
-    def __init__(self, value, driver, object_name):
-        self.object_name = object_name
-        super(ObjectError, self).__init__(value=value, driver=driver)
-
-    def __str__(self):
-        return self.__repr__()
-
-    def __repr__(self):
-        return '<%s in %s, value=%s, object = %s>' % (self.error_type,
-                                                      repr(self.driver),
-                                                      self.value,
-                                                      self.object_name)
-
-
-class ContainerAlreadyExistsError(ContainerError):
-    error_type = 'ContainerAlreadyExistsError'
-
-
-class ContainerDoesNotExistError(ContainerError):
-    error_type = 'ContainerDoesNotExistError'
-
-
-class ContainerIsNotEmptyError(ContainerError):
-    error_type = 'ContainerIsNotEmptyError'
-
-
-class ObjectDoesNotExistError(ObjectError):
-    error_type = 'ObjectDoesNotExistError'
-
-
-class ObjectHashMismatchError(ObjectError):
-    error_type = 'ObjectHashMismatchError'
-
-
-class InvalidContainerNameError(ContainerError):
-    error_type = 'InvalidContainerNameError'

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/test/__init__.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/test/__init__.py b/apache-libcloud-1.0.0rc2/libcloud/test/__init__.py
deleted file mode 100644
index 747b02c..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/test/__init__.py
+++ /dev/null
@@ -1,353 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 sys
-import random
-
-from libcloud.utils.py3 import httplib
-from libcloud.utils.py3 import StringIO
-from libcloud.utils.py3 import urlparse
-from libcloud.utils.py3 import parse_qs
-from libcloud.utils.py3 import parse_qsl
-from libcloud.utils.py3 import u
-from libcloud.utils.py3 import unittest2_required
-
-if unittest2_required:
-    import unittest2 as unittest
-else:
-    import unittest
-
-
-XML_HEADERS = {'content-type': 'application/xml'}
-
-
-class LibcloudTestCase(unittest.TestCase):
-    def __init__(self, *args, **kwargs):
-        self._visited_urls = []
-        self._executed_mock_methods = []
-        super(LibcloudTestCase, self).__init__(*args, **kwargs)
-
-    def setUp(self):
-        self._visited_urls = []
-        self._executed_mock_methods = []
-
-    def _add_visited_url(self, url):
-        self._visited_urls.append(url)
-
-    def _add_executed_mock_method(self, method_name):
-        self._executed_mock_methods.append(method_name)
-
-    def assertExecutedMethodCount(self, expected):
-        actual = len(self._executed_mock_methods)
-        self.assertEqual(actual, expected,
-                         'expected %d, but %d mock methods were executed'
-                         % (expected, actual))
-
-
-class multipleresponse(object):
-    """
-    A decorator that allows MockHttp objects to return multi responses
-    """
-    count = 0
-    func = None
-
-    def __init__(self, f):
-        self.func = f
-
-    def __call__(self, *args, **kwargs):
-        ret = self.func(self.func.__class__, *args, **kwargs)
-        response = ret[self.count]
-        self.count = self.count + 1
-        return response
-
-
-class MockResponse(object):
-    """
-    A mock HTTPResponse
-    """
-    headers = {}
-    body = StringIO()
-    status = 0
-    reason = ''
-    version = 11
-
-    def __init__(self, status, body=None, headers=None, reason=None):
-        self.status = status
-        self.body = StringIO(u(body)) if body else StringIO()
-        self.headers = headers or self.headers
-        self.reason = reason or self.reason
-
-    def read(self, *args, **kwargs):
-        return self.body.read(*args, **kwargs)
-
-    def next(self):
-        if sys.version_info >= (2, 5) and sys.version_info <= (2, 6):
-            return self.body.next()
-        else:
-            return next(self.body)
-
-    def __next__(self):
-        return self.next()
-
-    def getheader(self, name, *args, **kwargs):
-        return self.headers.get(name, *args, **kwargs)
-
-    def getheaders(self):
-        return list(self.headers.items())
-
-    def msg(self):
-        raise NotImplemented
-
-
-class BaseMockHttpObject(object):
-    def _get_method_name(self, type, use_param, qs, path):
-        path = path.split('?')[0]
-        meth_name = path.replace('/', '_').replace('.', '_').replace('-', '_')
-
-        if type:
-            meth_name = '%s_%s' % (meth_name, self.type)
-
-        if use_param and use_param in qs:
-            param = qs[use_param][0].replace('.', '_').replace('-', '_')
-            meth_name = '%s_%s' % (meth_name, param)
-
-        if meth_name == '':
-            meth_name = 'root'
-
-        return meth_name
-
-
-class MockHttp(BaseMockHttpObject):
-    """
-    A mock HTTP client/server suitable for testing purposes. This replaces
-    `HTTPConnection` by implementing its API and returning a mock response.
-
-    Define methods by request path, replacing slashes (/) with underscores (_).
-    Each of these mock methods should return a tuple of:
-
-        (int status, str body, dict headers, str reason)
-
-    >>> mock = MockHttp('localhost', 8080)
-    >>> mock.request('GET', '/example/')
-    >>> response = mock.getresponse()
-    >>> response.body.read()
-    'Hello World!'
-    >>> response.status
-    200
-    >>> response.getheaders()
-    [('X-Foo', 'libcloud')]
-    >>> MockHttp.type = 'fail'
-    >>> mock.request('GET', '/example/')
-    >>> response = mock.getresponse()
-    >>> response.body.read()
-    'Oh Noes!'
-    >>> response.status
-    403
-    >>> response.getheaders()
-    [('X-Foo', 'fail')]
-
-    """
-    responseCls = MockResponse
-    host = None
-    port = None
-    response = None
-
-    type = None
-    use_param = None  # will use this param to namespace the request function
-
-    test = None  # TestCase instance which is using this mock
-
-    proxy_url = None
-
-    def __init__(self, host, port, *args, **kwargs):
-        self.host = host
-        self.port = port
-
-    def request(self, method, url, body=None, headers=None, raw=False):
-        # Find a method we can use for this request
-        parsed = urlparse.urlparse(url)
-        scheme, netloc, path, params, query, fragment = parsed
-        qs = parse_qs(query)
-        if path.endswith('/'):
-            path = path[:-1]
-        meth_name = self._get_method_name(type=self.type,
-                                          use_param=self.use_param,
-                                          qs=qs, path=path)
-        meth = getattr(self, meth_name.replace('%', '_'))
-
-        if self.test and isinstance(self.test, LibcloudTestCase):
-            self.test._add_visited_url(url=url)
-            self.test._add_executed_mock_method(method_name=meth_name)
-
-        status, body, headers, reason = meth(method, url, body, headers)
-        self.response = self.responseCls(status, body, headers, reason)
-
-    def getresponse(self):
-        return self.response
-
-    def connect(self):
-        """
-        Can't think of anything to mock here.
-        """
-        pass
-
-    def close(self):
-        pass
-
-    def set_http_proxy(self, proxy_url):
-        self.proxy_url = proxy_url
-
-    # Mock request/response example
-    def _example(self, method, url, body, headers):
-        """
-        Return a simple message and header, regardless of input.
-        """
-        return (httplib.OK, 'Hello World!', {'X-Foo': 'libcloud'},
-                httplib.responses[httplib.OK])
-
-    def _example_fail(self, method, url, body, headers):
-        return (httplib.FORBIDDEN, 'Oh Noes!', {'X-Foo': 'fail'},
-                httplib.responses[httplib.FORBIDDEN])
-
-
-class MockHttpTestCase(MockHttp, unittest.TestCase):
-    # Same as the MockHttp class, but you can also use assertions in the
-    # classes which inherit from this one.
-    def __init__(self, *args, **kwargs):
-        unittest.TestCase.__init__(self)
-
-        if kwargs.get('host', None) and kwargs.get('port', None):
-            MockHttp.__init__(self, *args, **kwargs)
-
-    def runTest(self):
-        pass
-
-    def assertUrlContainsQueryParams(self, url, expected_params, strict=False):
-        """
-        Assert that provided url contains provided query parameters.
-
-        :param url: URL to assert.
-        :type url: ``str``
-
-        :param expected_params: Dictionary of expected query parameters.
-        :type expected_params: ``dict``
-
-        :param strict: Assert that provided url contains only expected_params.
-                       (defaults to ``False``)
-        :type strict: ``bool``
-        """
-        question_mark_index = url.find('?')
-
-        if question_mark_index != -1:
-            url = url[question_mark_index + 1:]
-
-        params = dict(parse_qsl(url))
-
-        if strict:
-            self.assertDictEqual(params, expected_params)
-        else:
-            for key, value in expected_params.items():
-                self.assertEqual(params[key], value)
-
-
-class StorageMockHttp(MockHttp):
-    def putrequest(self, method, action, skip_host=0, skip_accept_encoding=0):
-        pass
-
-    def putheader(self, key, value):
-        pass
-
-    def endheaders(self):
-        pass
-
-    def send(self, data):
-        pass
-
-
-class MockRawResponse(BaseMockHttpObject):
-    """
-    Mock RawResponse object suitable for testing.
-    """
-
-    type = None
-    responseCls = MockResponse
-
-    def __init__(self, connection):
-        super(MockRawResponse, self).__init__()
-        self._data = []
-        self._current_item = 0
-
-        self._status = None
-        self._response = None
-        self._headers = None
-        self._reason = None
-        self.connection = connection
-
-    def next(self):
-        if self._current_item == len(self._data):
-            raise StopIteration
-
-        value = self._data[self._current_item]
-        self._current_item += 1
-        return value
-
-    def __next__(self):
-        return self.next()
-
-    def _generate_random_data(self, size):
-        data = ''
-        current_size = 0
-        while current_size < size:
-            value = str(random.randint(0, 9))
-            value_size = len(value)
-            data += value
-            current_size += value_size
-
-        return data
-
-    @property
-    def response(self):
-        return self._get_response_if_not_availale()
-
-    @property
-    def status(self):
-        self._get_response_if_not_availale()
-        return self._status
-
-    @property
-    def headers(self):
-        self._get_response_if_not_availale()
-        return self._headers
-
-    @property
-    def reason(self):
-        self._get_response_if_not_availale()
-        return self._reason
-
-    def _get_response_if_not_availale(self):
-        if not self._response:
-            meth_name = self._get_method_name(type=self.type,
-                                              use_param=False, qs=None,
-                                              path=self.connection.action)
-            meth = getattr(self, meth_name.replace('%', '_'))
-            result = meth(self.connection.method, None, None, None)
-            self._status, self._body, self._headers, self._reason = result
-            self._response = self.responseCls(self._status, self._body,
-                                              self._headers, self._reason)
-        return self._response
-
-if __name__ == "__main__":
-    import doctest
-    doctest.testmod()

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/test/backup/__init__.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/test/backup/__init__.py b/apache-libcloud-1.0.0rc2/libcloud/test/backup/__init__.py
deleted file mode 100644
index 007c333..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/test/backup/__init__.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from libcloud.backup.base import BackupTarget, BackupTargetType
-
-
-class TestCaseMixin(object):
-
-    def get_supported_target_types(self):
-        targets = self.driver.get_supported_target_types()
-        self.assertTrue(isinstance(targets, list))
-        for target in targets:
-            self.assertTrue(isinstance(target, BackupTargetType))
-
-    def test_list_targets_response(self):
-        targets = self.driver.list_targets()
-        self.assertTrue(isinstance(targets, list))
-        for target in targets:
-            self.assertTrue(isinstance(target, BackupTarget))
-
-
-if __name__ == "__main__":
-    import doctest
-    doctest.testmod()

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/_remove_backup_client.xml
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/_remove_backup_client.xml b/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/_remove_backup_client.xml
deleted file mode 100644
index 4ce51c6..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/_remove_backup_client.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<ns6:Status xmlns:ns16="http://oec.api.opsource.net/schemas/storage" xmlns="http://oec.api.opsource.net/schemas/admin" xmlns:ns14="http://oec.api.opsource.net/schemas/directory" xmlns:ns15="http://oec.api.opsource.net/schemas/multigeo" xmlns:ns9="http://oec.api.opsource.net/schemas/backup" xmlns:ns5="http://oec.api.opsource.net/schemas/datacenter" xmlns:ns12="http://oec.api.opsource.net/schemas/support" xmlns:ns13="http://oec.api.opsource.net/schemas/manualimport" xmlns:ns6="http://oec.api.opsource.net/schemas/general" xmlns:ns7="http://oec.api.opsource.net/schemas/reset" xmlns:ns10="http://oec.api.opsource.net/schemas/server" xmlns:ns8="http://oec.api.opsource.net/schemas/network" xmlns:ns11="http://oec.api.opsource.net/schemas/whitelabel" xmlns:ns2="http://oec.api.opsource.net/schemas/organization" xmlns:ns4="http://oec.api.opsource.net/schemas/serverbootstrap" xmlns:ns3="http://oec.api.opsource.net/schemas/vip">
-    <ns6:operation>Disable Backup Client</ns6:operation>
-    <ns6:result>SUCCESS</ns6:result>
-    <ns6:resultDetail>Backup Client disabled</ns6:resultDetail>
-    <ns6:resultCode>REASON_0</ns6:resultCode>
-</ns6:Status>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/_remove_backup_client_FAIL.xml
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/_remove_backup_client_FAIL.xml b/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/_remove_backup_client_FAIL.xml
deleted file mode 100644
index 6c2db63..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/_remove_backup_client_FAIL.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<ns6:Status xmlns:ns16="http://oec.api.opsource.net/schemas/storage" xmlns="http://oec.api.opsource.net/schemas/admin" xmlns:ns14="http://oec.api.opsource.net/schemas/directory" xmlns:ns15="http://oec.api.opsource.net/schemas/multigeo" xmlns:ns9="http://oec.api.opsource.net/schemas/backup" xmlns:ns5="http://oec.api.opsource.net/schemas/datacenter" xmlns:ns12="http://oec.api.opsource.net/schemas/support" xmlns:ns13="http://oec.api.opsource.net/schemas/manualimport" xmlns:ns6="http://oec.api.opsource.net/schemas/general" xmlns:ns7="http://oec.api.opsource.net/schemas/reset" xmlns:ns10="http://oec.api.opsource.net/schemas/server" xmlns:ns8="http://oec.api.opsource.net/schemas/network" xmlns:ns11="http://oec.api.opsource.net/schemas/whitelabel" xmlns:ns2="http://oec.api.opsource.net/schemas/organization" xmlns:ns4="http://oec.api.opsource.net/schemas/serverbootstrap" xmlns:ns3="http://oec.api.opsource.net/schemas/vip">
-    <ns6:operation>Disable Backup Client</ns6:operation>
-    <ns6:result>ERROR</ns6:result>
-    <ns6:resultDetail>DISABLE_BACKUP_CLIENT 'didata-backup-test6[172-16-1-14]' - failed - Unexpected error occurred with NA9 Backup system at 2016-02-12 00:03:50.952, TransactionId: (9d483a7a-1cc9-441b-920c-e11fb0e94ba6), PCSOperation: DeprovisionBackupClient, Backup Client is currently performing another operation: Backup client is currently busy</ns6:resultDetail>
-    <ns6:resultCode>REASON_547</ns6:resultCode>
-</ns6:Status>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server.xml
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server.xml b/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server.xml
deleted file mode 100644
index c3d607f..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<servers xmlns="urn:didata.com:api:cloud:types" pageNumber="1" pageCount="2" totalCount="2" pageSize="250">
-    <!-- MCP 1.0 Server -->
-    <server id="e75ead52-692f-4314-8725-c8a4f4d13a87" datacenterId="NA1">
-        <name>Production Web Server MCP 1</name>
-        <description>nopassword0</description>
-        <operatingSystem id="REDHAT632" displayName="REDHAT6/32" family="UNIX" />
-        <cpu count="4" speed="STANDARD" coresPerSocket="1" />
-        <memoryGb>2</memoryGb>
-        <disk id="74f81c56-96cc-4cca-b4d7-a88f641a6ea2" scsiId="0" sizeGb="10" speed="STANDARD" state="NORMAL" />
-        <nic id="43b24e9e-c1c9-4d53-965b-89bcaa725103" privateIpv4="10.160.117.25" networkId="c550be0e-65c1-11e4-811f-005056806999" networkName="Test1" state="NORMAL" />
-        <backup assetId="5579f3a7-4c32-4cf5-8a7e-b45c36a35c10" servicePlan="Enterprise" state="NORMAL" />
-        <monitoring monitoringId="11049" servicePlan="ESSENTIALS" state="NORMAL" />
-        <sourceImageId>e9ec6eb4-4634-49de-b914-01eb74da5fb9</sourceImageId>
-        <createTime>2015-08-11T16:51:05.000Z</createTime>
-        <deployed>true</deployed>
-        <started>true</started>
-        <state>NORMAL</state>
-        <vmwareTools versionStatus="NEED_UPGRADE" runningStatus="RUNNING" apiVersion="8389" />
-        <virtualHardware version="vmx-08" upToDate="false" />
-    </server>
-    <!-- MCP 2.0 Server -->
-    <server id="5a32d6e4-9707-4813-a269-56ab4d989f4d" datacenterId="NA9">
-        <name>Production Web Server MCP 2</name>
-        <description>Server to host our main web application.</description>
-        <operatingSystem id="WIN2008S32" displayName="WIN2008S/32" family="WINDOWS" />
-        <cpu count="2" speed="STANDARD" coresPerSocket="1" />
-        <memoryGb>4</memoryGb>
-        <disk id="c2e1f199-116e-4dbc-9960-68720b832b0a" scsiId="0" sizeGb="50" speed="STANDARD" state="NORMAL" />
-        <networkInfo networkDomainId="553f26b6-2a73-42c3-a78b-6116f11291d0">
-            <primaryNic id="5e869800-df7b-4626-bcbf-8643b8be11fd" privateIpv4="10.0.4.8" ipv6="2607:f480:1111:1282:2960:fb72:7154:6160" vlanId="bc529e20-dc6f-42ba-be20-0ffe44d1993f" vlanName="Production VLAN" state="NORMAL" />
-        </networkInfo>
-        <backup assetId="91002e08-8dc1-47a1-ad33-04f501c06f87" servicePlan="Advanced" state="NORMAL" />
-        <monitoring monitoringId="11039" servicePlan="ESSENTIALS" state="NORMAL" />
-        <softwareLabel>MSSQL2008R2S</softwareLabel>
-        <sourceImageId>3ebf3c0f-90fe-4a8b-8585-6e65b316592c</sourceImageId>
-        <createTime>2015-12-02T10:31:33.000Z</createTime>
-        <deployed>true</deployed>
-        <started>true</started>
-        <state>PENDING_CHANGE</state>
-        <progress>
-            <action>SHUTDOWN_SERVER</action>
-            <requestTime>2015-12-02T11:07:40.000Z</requestTime>
-            <userName>devuser1</userName>
-        </progress>
-        <vmwareTools versionStatus="CURRENT" runningStatus="RUNNING" apiVersion="9354" />
-        <virtualHardware version="vmx-08" upToDate="false" />
-    </server>
-</servers>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server_e75ead52_692f_4314_8725_c8a4f4d13a87.xml
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server_e75ead52_692f_4314_8725_c8a4f4d13a87.xml b/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server_e75ead52_692f_4314_8725_c8a4f4d13a87.xml
deleted file mode 100644
index 07b1319..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server_e75ead52_692f_4314_8725_c8a4f4d13a87.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<server xmlns="urn:didata.com:api:cloud:types" id="e75ead52-692f-4314-8725-c8a4f4d13a87" datacenterId="NA9">
-        <name>Production Web Server</name>
-        <description>Server to host our main web application.</description>
-        <operatingSystem id="WIN2008S32" displayName="WIN2008S/32" family="WINDOWS" />
-        <cpu count="2" speed="STANDARD" coresPerSocket="1" />
-        <memoryGb>4</memoryGb>
-        <disk id="c2e1f199-116e-4dbc-9960-68720b832b0a" scsiId="0" sizeGb="50" speed="STANDARD" state="NORMAL" />
-        <networkInfo networkDomainId="553f26b6-2a73-42c3-a78b-6116f11291d0">
-            <primaryNic id="5e869800-df7b-4626-bcbf-8643b8be11fd" privateIpv4="10.0.4.8" ipv6="2607:f480:1111:1282:2960:fb72:7154:6160" vlanId="bc529e20-dc6f-42ba-be20-0ffe44d1993f" vlanName="Production VLAN" state="NORMAL" />
-        </networkInfo>
-        <backup assetId="5579f3a7-4c32-4cf5-8a7e-b45c36a35c10" servicePlan="Essentials" state="NORMAL" />
-        <monitoring monitoringId="11049" servicePlan="ESSENTIALS" state="NORMAL" />
-        <softwareLabel>MSSQL2008R2S</softwareLabel>
-        <sourceImageId>3ebf3c0f-90fe-4a8b-8585-6e65b316592c</sourceImageId>
-        <createTime>2015-12-02T10:31:33.000Z</createTime>
-        <deployed>true</deployed>
-        <started>true</started>
-        <state>PENDING_CHANGE</state>
-        <progress>
-            <action>DEPLOY_SERVER</action>
-            <requestTime>2015-12-02T11:07:40.000Z</requestTime>
-            <userName>devuser1</userName>
-        </progress>
-        <vmwareTools versionStatus="CURRENT" runningStatus="RUNNING" apiVersion="9354" />
-        <virtualHardware version="vmx-08" upToDate="false" />
-    </server>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server_e75ead52_692f_4314_8725_c8a4f4d13a87_DEFAULT.xml
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server_e75ead52_692f_4314_8725_c8a4f4d13a87_DEFAULT.xml b/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server_e75ead52_692f_4314_8725_c8a4f4d13a87_DEFAULT.xml
deleted file mode 100644
index c64c530..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server_e75ead52_692f_4314_8725_c8a4f4d13a87_DEFAULT.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<server xmlns="urn:didata.com:api:cloud:types" id="e75ead52-692f-4314-8725-c8a4f4d13a87" datacenterId="NA9">
-        <name>Production Web Server</name>
-        <description>Server to host our main web application.</description>
-        <operatingSystem id="WIN2008S32" displayName="WIN2008S/32" family="WINDOWS" />
-        <cpu count="2" speed="STANDARD" coresPerSocket="1" />
-        <memoryGb>4</memoryGb>
-        <disk id="c2e1f199-116e-4dbc-9960-68720b832b0a" scsiId="0" sizeGb="50" speed="STANDARD" state="NORMAL" />
-        <networkInfo networkDomainId="553f26b6-2a73-42c3-a78b-6116f11291d0">
-            <primaryNic id="5e869800-df7b-4626-bcbf-8643b8be11fd" privateIpv4="10.0.4.8" ipv6="2607:f480:1111:1282:2960:fb72:7154:6160" vlanId="bc529e20-dc6f-42ba-be20-0ffe44d1993f" vlanName="Production VLAN" state="NORMAL" />
-        </networkInfo>
-        <backup assetId="5579f3a7-4c32-4cf5-8a7e-b45c36a35c10" servicePlan="Advanced" state="NORMAL" />
-        <monitoring monitoringId="11049" servicePlan="ESSENTIALS" state="NORMAL" />
-        <softwareLabel>MSSQL2008R2S</softwareLabel>
-        <sourceImageId>3ebf3c0f-90fe-4a8b-8585-6e65b316592c</sourceImageId>
-        <createTime>2015-12-02T10:31:33.000Z</createTime>
-        <deployed>true</deployed>
-        <started>true</started>
-        <state>PENDING_CHANGE</state>
-        <progress>
-            <action>DEPLOY_SERVER</action>
-            <requestTime>2015-12-02T11:07:40.000Z</requestTime>
-            <userName>devuser1</userName>
-        </progress>
-        <vmwareTools versionStatus="CURRENT" runningStatus="RUNNING" apiVersion="9354" />
-        <virtualHardware version="vmx-08" upToDate="false" />
-    </server>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_DISABLE.xml
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_DISABLE.xml b/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_DISABLE.xml
deleted file mode 100644
index bfc949d..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_DISABLE.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<ns13:Status xmlns:ns16="http://oec.api.opsource.net/schemas/serverbootstrap" xmlns="http://oec.api.opsource.net/schemas/server" xmlns:ns14="http://oec.api.opsource.net/schemas/datacenter" xmlns:ns15="http://oec.api.opsource.net/schemas/reset" xmlns:ns9="http://oec.api.opsource.net/schemas/storage" xmlns:ns5="http://oec.api.opsource.net/schemas/backup" xmlns:ns12="http://oec.api.opsource.net/schemas/whitelabel" xmlns:ns13="http://oec.api.opsource.net/schemas/general" xmlns:ns6="http://oec.api.opsource.net/schemas/support" xmlns:ns7="http://oec.api.opsource.net/schemas/organization" xmlns:ns10="http://oec.api.opsource.net/schemas/manualimport" xmlns:ns8="http://oec.api.opsource.net/schemas/multigeo" xmlns:ns11="http://oec.api.opsource.net/schemas/vip" xmlns:ns2="http://oec.api.opsource.net/schemas/network" xmlns:ns4="http://oec.api.opsource.net/schemas/directory" xmlns:ns3="http://oec.api.opsource.net/schemas/admin">
-    <ns13:operation>Disable Backup for Server</ns13:operation>
-    <ns13:result>SUCCESS</ns13:result>
-    <ns13:resultDetail>Backup disabled for Server</ns13:resultDetail>
-    <ns13:resultCode>REASON_0</ns13:resultCode>
-</ns13:Status>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_ENABLE.xml
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_ENABLE.xml b/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_ENABLE.xml
deleted file mode 100644
index 6012447..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_ENABLE.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<ns6:Status xmlns:ns16="http://oec.api.opsource.net/schemas/storage"
-            xmlns="http://oec.api.opsource.net/schemas/server"
-            xmlns:ns14="http://oec.api.opsource.net/schemas/support"
-            xmlns:ns15="http://oec.api.opsource.net/schemas/multigeo"
-            xmlns:ns9="http://oec.api.opsource.net/schemas/admin"
-            xmlns:ns5="http://oec.api.opsource.net/schemas/vip"
-            xmlns:ns12="http://oec.api.opsource.net/schemas/whitelabel"
-            xmlns:ns13="http://oec.api.opsource.net/schemas/reset"
-            xmlns:ns6="http://oec.api.opsource.net/schemas/general" xmlns:ns7="http://oec.api.opsource.net/schemas/datacenter" xmlns:ns10="http://oec.api.opsource.net/schemas/serverbootstrap" xmlns:ns8="http://oec.api.opsource.net/schemas/manualimport" xmlns:ns11="http://oec.api.opsource.net/schemas/backup" xmlns:ns2="http://oec.api.opsource.net/schemas/directory" xmlns:ns4="http://oec.api.opsource.net/schemas/network" xmlns:ns3="http://oec.api.opsource.net/schemas/organization">
-    <ns6:operation>Enable Backup for Server</ns6:operation>
-    <ns6:result>SUCCESS</ns6:result>
-    <ns6:resultDetail>Backup enabled for Server - see additional Information for Asset ID</ns6:resultDetail>
-    <ns6:resultCode>REASON_0</ns6:resultCode>
-    <ns6:additionalInformation name="assetId">
-        <ns6:value>ee7c4b64-f7af-4a4f-8384-be362273530f</ns6:value>
-    </ns6:additionalInformation>
-</ns6:Status>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_EXISTS.xml
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_EXISTS.xml b/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_EXISTS.xml
deleted file mode 100644
index 5ffa67e..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_EXISTS.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<ns0:Status xmlns:ns0="http://oec.api.opsource.net/schemas/general">
-    <ns0:operation>Enable Backup for Server</ns0:operation>
-    <ns0:result>ERROR</ns0:result>
-    <ns0:resultDetail>Cloud backup for this server is already enabled or being enabled (state: NORMAL).</ns0:resultDetail>
-    <ns0:resultCode>REASON_550</ns0:resultCode>
-</ns0:Status>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO.xml
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO.xml b/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO.xml
deleted file mode 100644
index fc61cce..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<ns9:BackupDetails assetId="12769311-938c-4669-9460-7723eb194269" servicePlan="Enterprise" state="NORMAL" xmlns:ns16="http://oec.api.opsource.net/schemas/storage" xmlns="http://oec.api.opsource.net/schemas/admin" xmlns:ns14="http://oec.api.opsource.net/schemas/directory" xmlns:ns15="http://oec.api.opsource.net/schemas/multigeo" xmlns:ns9="http://oec.api.opsource.net/schemas/backup" xmlns:ns5="http://oec.api.opsource.net/schemas/datacenter" xmlns:ns12="http://oec.api.opsource.net/schemas/support" xmlns:ns13="http://oec.api.opsource.net/schemas/manualimport" xmlns:ns6="http://oec.api.opsource.net/schemas/general" xmlns:ns7="http://oec.api.opsource.net/schemas/reset" xmlns:ns10="http://oec.api.opsource.net/schemas/server" xmlns:ns8="http://oec.api.opsource.net/schemas/network" xmlns:ns11="http://oec.api.opsource.net/schemas/whitelabel" xmlns:ns2="http://oec.api.opsource.net/schemas/organization" xmlns:ns4="http://oec.api.opsource.net/schemas/serverbootstrap" xmlns:ns3="http://oec.api.o
 psource.net/schemas/vip">
-    <ns9:backupClient id="30b1ff76-c76d-4d7c-b39d-3b72be0384c8" type="FA.Linux" isFileSystem="true" status="Unregistered">
-        <ns9:description>Linux File Agent</ns9:description>
-        <ns9:schedulePolicyName>12AM - 6AM</ns9:schedulePolicyName>
-        <ns9:storagePolicyName>14 Day Storage Policy</ns9:storagePolicyName>
-        <ns9:alerting trigger="ON_FAILURE">
-            <ns9:emailAddress>fake_email@example.com</ns9:emailAddress>
-            <ns9:emailAddress>fake_email2@example.com</ns9:emailAddress>
-        </ns9:alerting>
-        <ns9:times nextBackup="2016-02-09T00:00:00" lastOnline="2016-02-08T06:10:25"/>
-        <ns9:totalBackupSizeGb>0</ns9:totalBackupSizeGb>
-        <ns9:downloadUrl>https://backups-na.cloud-vpn.net/PCS/BackupClientInstallerDownload/cbb8a8c607ca4144e8828814edfc1634c8dd8782</ns9:downloadUrl>
-        <ns9:runningJob id="106130" name="Backup" percentageComplete="5" status="Waiting"/>
-    </ns9:backupClient>
-</ns9:BackupDetails>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO_DISABLED.xml
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO_DISABLED.xml b/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO_DISABLED.xml
deleted file mode 100644
index 51e4494..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO_DISABLED.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<ns6:Status xmlns:ns16="http://oec.api.opsource.net/schemas/storage" xmlns="http://oec.api.opsource.net/schemas/admin" xmlns:ns14="http://oec.api.opsource.net/schemas/directory" xmlns:ns15="http://oec.api.opsource.net/schemas/multigeo" xmlns:ns9="http://oec.api.opsource.net/schemas/backup" xmlns:ns5="http://oec.api.opsource.net/schemas/datacenter" xmlns:ns12="http://oec.api.opsource.net/schemas/support" xmlns:ns13="http://oec.api.opsource.net/schemas/manualimport" xmlns:ns6="http://oec.api.opsource.net/schemas/general" xmlns:ns7="http://oec.api.opsource.net/schemas/reset" xmlns:ns10="http://oec.api.opsource.net/schemas/server" xmlns:ns8="http://oec.api.opsource.net/schemas/network" xmlns:ns11="http://oec.api.opsource.net/schemas/whitelabel" xmlns:ns2="http://oec.api.opsource.net/schemas/organization" xmlns:ns4="http://oec.api.opsource.net/schemas/serverbootstrap" xmlns:ns3="http://oec.api.opsource.net/schemas/vip">
-    <ns6:operation>Get Backup Details</ns6:operation>
-    <ns6:result>ERROR</ns6:result>
-    <ns6:resultDetail>Server e75ead52-692f-4314-8725-c8a4f4d13a87 has not been provisioned for backup</ns6:resultDetail>
-    <ns6:resultCode>REASON_543</ns6:resultCode>
-</ns6:Status>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO_NOCLIENT.xml
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO_NOCLIENT.xml b/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO_NOCLIENT.xml
deleted file mode 100644
index 0f62576..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO_NOCLIENT.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<ns9:BackupDetails assetId="71febbbc-337a-40c4-8c29-0afe85ccb3ea" servicePlan="Essentials" state="NORMAL" xmlns:ns16="http://oec.api.opsource.net/schemas/storage" xmlns="http://oec.api.opsource.net/schemas/admin" xmlns:ns14="http://oec.api.opsource.net/schemas/directory" xmlns:ns15="http://oec.api.opsource.net/schemas/multigeo" xmlns:ns9="http://oec.api.opsource.net/schemas/backup" xmlns:ns5="http://oec.api.opsource.net/schemas/datacenter" xmlns:ns12="http://oec.api.opsource.net/schemas/support" xmlns:ns13="http://oec.api.opsource.net/schemas/manualimport" xmlns:ns6="http://oec.api.opsource.net/schemas/general" xmlns:ns7="http://oec.api.opsource.net/schemas/reset" xmlns:ns10="http://oec.api.opsource.net/schemas/server" xmlns:ns8="http://oec.api.opsource.net/schemas/network" xmlns:ns11="http://oec.api.opsource.net/schemas/whitelabel" xmlns:ns2="http://oec.api.opsource.net/schemas/organization" xmlns:ns4="http://oec.api.opsource.net/schemas/serverbootstrap" xmlns:ns3="http://oec.api.o
 psource.net/schemas/vip"/>


[02/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO_NOJOB.xml
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO_NOJOB.xml b/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO_NOJOB.xml
deleted file mode 100644
index 45c97ce..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO_NOJOB.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<ns9:BackupDetails assetId="12769311-938c-4669-9460-7723eb194269" servicePlan="Enterprise" state="NORMAL" xmlns:ns16="http://oec.api.opsource.net/schemas/storage" xmlns="http://oec.api.opsource.net/schemas/admin" xmlns:ns14="http://oec.api.opsource.net/schemas/directory" xmlns:ns15="http://oec.api.opsource.net/schemas/multigeo" xmlns:ns9="http://oec.api.opsource.net/schemas/backup" xmlns:ns5="http://oec.api.opsource.net/schemas/datacenter" xmlns:ns12="http://oec.api.opsource.net/schemas/support" xmlns:ns13="http://oec.api.opsource.net/schemas/manualimport" xmlns:ns6="http://oec.api.opsource.net/schemas/general" xmlns:ns7="http://oec.api.opsource.net/schemas/reset" xmlns:ns10="http://oec.api.opsource.net/schemas/server" xmlns:ns8="http://oec.api.opsource.net/schemas/network" xmlns:ns11="http://oec.api.opsource.net/schemas/whitelabel" xmlns:ns2="http://oec.api.opsource.net/schemas/organization" xmlns:ns4="http://oec.api.opsource.net/schemas/serverbootstrap" xmlns:ns3="http://oec.api.o
 psource.net/schemas/vip">
-    <ns9:backupClient id="30b1ff76-c76d-4d7c-b39d-3b72be0384c8" type="FA.Linux" isFileSystem="true" status="Unregistered">
-        <ns9:description>Linux File Agent</ns9:description>
-        <ns9:schedulePolicyName>12AM - 6AM</ns9:schedulePolicyName>
-        <ns9:storagePolicyName>14 Day Storage Policy</ns9:storagePolicyName>
-        <ns9:times nextBackup="2016-02-09T00:00:00" lastOnline="2016-02-08T06:10:25"/>
-        <ns9:totalBackupSizeGb>0</ns9:totalBackupSizeGb>
-        <ns9:downloadUrl>https://backups-na.cloud-vpn.net/PCS/BackupClientInstallerDownload/cbb8a8c607ca4144e8828814edfc1634c8dd8782</ns9:downloadUrl>
-    </ns9:backupClient>
-</ns9:BackupDetails>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/test/backup/test_base.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/test/backup/test_base.py b/apache-libcloud-1.0.0rc2/libcloud/test/backup/test_base.py
deleted file mode 100644
index e254e6d..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/test/backup/test_base.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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
-
-from __future__ import with_statement
-
-import sys
-
-from libcloud.test import unittest
-from libcloud.backup.base import BackupDriver
-
-
-class BaseTestCase(unittest.TestCase):
-    def setUp(self):
-        self.driver = BackupDriver('none', 'none')
-
-
-if __name__ == '__main__':
-    sys.exit(unittest.main())

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/test/backup/test_dimensiondata.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/test/backup/test_dimensiondata.py b/apache-libcloud-1.0.0rc2/libcloud/test/backup/test_dimensiondata.py
deleted file mode 100644
index 6a80fd4..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/test/backup/test_dimensiondata.py
+++ /dev/null
@@ -1,490 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-try:
-    from lxml import etree as ET
-except ImportError:
-    from xml.etree import ElementTree as ET
-
-import sys
-from libcloud.utils.py3 import httplib
-
-from libcloud.common.dimensiondata import DimensionDataAPIException
-from libcloud.common.types import InvalidCredsError
-from libcloud.backup.base import BackupTargetJob
-from libcloud.backup.drivers.dimensiondata import DimensionDataBackupDriver as DimensionData
-from libcloud.backup.drivers.dimensiondata import DEFAULT_BACKUP_PLAN
-
-from libcloud.test import MockHttp, unittest
-from libcloud.test.backup import TestCaseMixin
-from libcloud.test.file_fixtures import BackupFileFixtures
-
-from libcloud.test.secrets import DIMENSIONDATA_PARAMS
-
-
-class DimensionDataTests(unittest.TestCase, TestCaseMixin):
-
-    def setUp(self):
-        DimensionData.connectionCls.conn_classes = (None, DimensionDataMockHttp)
-        DimensionDataMockHttp.type = None
-        self.driver = DimensionData(*DIMENSIONDATA_PARAMS)
-
-    def test_invalid_region(self):
-        with self.assertRaises(ValueError):
-            self.driver = DimensionData(*DIMENSIONDATA_PARAMS, region='blah')
-
-    def test_invalid_creds(self):
-        DimensionDataMockHttp.type = 'UNAUTHORIZED'
-        with self.assertRaises(InvalidCredsError):
-            self.driver.list_targets()
-
-    def test_list_targets(self):
-        targets = self.driver.list_targets()
-        self.assertEqual(len(targets), 2)
-        self.assertEqual(targets[0].id, '5579f3a7-4c32-4cf5-8a7e-b45c36a35c10')
-        self.assertEqual(targets[0].address, 'e75ead52-692f-4314-8725-c8a4f4d13a87')
-        self.assertEqual(targets[0].extra['servicePlan'], 'Enterprise')
-
-    def test_create_target(self):
-        target = self.driver.create_target(
-            'name',
-            'e75ead52-692f-4314-8725-c8a4f4d13a87',
-            extra={'servicePlan': 'Enterprise'})
-        self.assertEqual(target.id, 'ee7c4b64-f7af-4a4f-8384-be362273530f')
-        self.assertEqual(target.address, 'e75ead52-692f-4314-8725-c8a4f4d13a87')
-        self.assertEqual(target.extra['servicePlan'], 'Enterprise')
-
-    def test_create_target_DEFAULT(self):
-        DimensionDataMockHttp.type = 'DEFAULT'
-        target = self.driver.create_target(
-            'name',
-            'e75ead52-692f-4314-8725-c8a4f4d13a87')
-        self.assertEqual(target.id, 'ee7c4b64-f7af-4a4f-8384-be362273530f')
-        self.assertEqual(target.address, 'e75ead52-692f-4314-8725-c8a4f4d13a87')
-
-    def test_create_target_EXISTS(self):
-        DimensionDataMockHttp.type = 'EXISTS'
-        with self.assertRaises(DimensionDataAPIException) as context:
-            self.driver.create_target(
-                'name',
-                'e75ead52-692f-4314-8725-c8a4f4d13a87',
-                extra={'servicePlan': 'Enterprise'})
-        self.assertEqual(context.exception.code, 'ERROR')
-        self.assertEqual(context.exception.msg, 'Cloud backup for this server is already enabled or being enabled (state: NORMAL).')
-
-    def test_update_target(self):
-        target = self.driver.list_targets()[0]
-        extra = {'servicePlan': 'Essentials'}
-        new_target = self.driver.update_target(target, extra=extra)
-        self.assertEqual(new_target.extra['servicePlan'], 'Essentials')
-
-    def test_update_target_DEFAULT(self):
-        DimensionDataMockHttp.type = 'DEFAULT'
-        target = 'e75ead52-692f-4314-8725-c8a4f4d13a87'
-        self.driver.update_target(target)
-
-    def test_update_target_STR(self):
-        target = 'e75ead52-692f-4314-8725-c8a4f4d13a87'
-        extra = {'servicePlan': 'Essentials'}
-        new_target = self.driver.update_target(target, extra=extra)
-        self.assertEqual(new_target.extra['servicePlan'], 'Essentials')
-
-    def test_delete_target(self):
-        target = self.driver.list_targets()[0]
-        self.assertTrue(self.driver.delete_target(target))
-
-    def test_ex_add_client_to_target(self):
-        target = self.driver.list_targets()[0]
-        client = self.driver.ex_list_available_client_types(target)[0]
-        storage_policy = self.driver.ex_list_available_storage_policies(target)[0]
-        schedule_policy = self.driver.ex_list_available_schedule_policies(target)[0]
-        self.assertTrue(
-            self.driver.ex_add_client_to_target(target, client, storage_policy,
-                                                schedule_policy, 'ON_FAILURE', 'nobody@example.com')
-        )
-
-    def test_ex_add_client_to_target_STR(self):
-        self.assertTrue(
-            self.driver.ex_add_client_to_target('e75ead52-692f-4314-8725-c8a4f4d13a87', 'FA.Linux', '14 Day Storage Policy',
-                                                '12AM - 6AM', 'ON_FAILURE', 'nobody@example.com')
-        )
-
-    def test_ex_get_backup_details_for_target(self):
-        target = self.driver.list_targets()[0]
-        response = self.driver.ex_get_backup_details_for_target(target)
-        self.assertEqual(response.service_plan, 'Enterprise')
-        client = response.clients[0]
-        self.assertEqual(client.id, '30b1ff76-c76d-4d7c-b39d-3b72be0384c8')
-        self.assertEqual(client.type.type, 'FA.Linux')
-        self.assertEqual(client.running_job.progress, 5)
-        self.assertTrue(isinstance(client.running_job, BackupTargetJob))
-        self.assertEqual(len(client.alert.notify_list), 2)
-        self.assertTrue(isinstance(client.alert.notify_list, list))
-
-    def test_ex_cancel_target_job(self):
-        target = self.driver.list_targets()[0]
-        response = self.driver.ex_get_backup_details_for_target(target)
-        client = response.clients[0]
-        self.assertTrue(isinstance(client.running_job, BackupTargetJob))
-        success = client.running_job.cancel()
-        self.assertTrue(success)
-
-    def test_ex_cancel_target_job_with_extras(self):
-        success = self.driver.cancel_target_job(
-            None,
-            ex_client='30b1ff76_c76d_4d7c_b39d_3b72be0384c8',
-            ex_target='e75ead52_692f_4314_8725_c8a4f4d13a87'
-        )
-        self.assertTrue(success)
-
-    def test_ex_cancel_target_job_FAIL(self):
-        DimensionDataMockHttp.type = 'FAIL'
-        with self.assertRaises(DimensionDataAPIException) as context:
-            self.driver.cancel_target_job(
-                None,
-                ex_client='30b1ff76_c76d_4d7c_b39d_3b72be0384c8',
-                ex_target='e75ead52_692f_4314_8725_c8a4f4d13a87'
-            )
-        self.assertEqual(context.exception.code, 'ERROR')
-
-    """Test a backup info for a target that does not have a client"""
-    def test_ex_get_backup_details_for_target_NO_CLIENT(self):
-        DimensionDataMockHttp.type = 'NOCLIENT'
-        response = self.driver.ex_get_backup_details_for_target('e75ead52-692f-4314-8725-c8a4f4d13a87')
-        self.assertEqual(response.service_plan, 'Essentials')
-        self.assertEqual(len(response.clients), 0)
-
-    """Test a backup details that has a client, but no alerting or running jobs"""
-    def test_ex_get_backup_details_for_target_NO_JOB_OR_ALERT(self):
-        DimensionDataMockHttp.type = 'NOJOB'
-        response = self.driver.ex_get_backup_details_for_target('e75ead52-692f-4314_8725-c8a4f4d13a87')
-        self.assertEqual(response.service_plan, 'Enterprise')
-        self.assertTrue(isinstance(response.clients, list))
-        self.assertEqual(len(response.clients), 1)
-        client = response.clients[0]
-        self.assertEqual(client.id, '30b1ff76-c76d-4d7c-b39d-3b72be0384c8')
-        self.assertEqual(client.type.type, 'FA.Linux')
-        self.assertIsNone(client.running_job)
-        self.assertIsNone(client.alert)
-
-    """Test getting backup info for a server that doesn't exist"""
-    def test_ex_get_backup_details_for_target_DISABLED(self):
-        DimensionDataMockHttp.type = 'DISABLED'
-        with self.assertRaises(DimensionDataAPIException) as context:
-            self.driver.ex_get_backup_details_for_target('e75ead52-692f-4314-8725-c8a4f4d13a87')
-        self.assertEqual(context.exception.code, 'ERROR')
-        self.assertEqual(context.exception.msg, 'Server e75ead52-692f-4314-8725-c8a4f4d13a87 has not been provisioned for backup')
-
-    def test_ex_list_available_client_types(self):
-        target = self.driver.list_targets()[0]
-        answer = self.driver.ex_list_available_client_types(target)
-        self.assertEqual(len(answer), 1)
-        self.assertEqual(answer[0].type, 'FA.Linux')
-        self.assertEqual(answer[0].is_file_system, True)
-        self.assertEqual(answer[0].description, 'Linux File system')
-
-    def test_ex_list_available_storage_policies(self):
-        target = self.driver.list_targets()[0]
-        answer = self.driver.ex_list_available_storage_policies(target)
-        self.assertEqual(len(answer), 1)
-        self.assertEqual(answer[0].name,
-                         '30 Day Storage Policy + Secondary Copy')
-        self.assertEqual(answer[0].retention_period, 30)
-        self.assertEqual(answer[0].secondary_location, 'Primary')
-
-    def test_ex_list_available_schedule_policies(self):
-        target = self.driver.list_targets()[0]
-        answer = self.driver.ex_list_available_schedule_policies(target)
-        self.assertEqual(len(answer), 1)
-        self.assertEqual(answer[0].name, '12AM - 6AM')
-        self.assertEqual(answer[0].description, 'Daily backup will start between 12AM - 6AM')
-
-    def test_ex_remove_client_from_target(self):
-        target = self.driver.list_targets()[0]
-        client = self.driver.ex_get_backup_details_for_target('e75ead52-692f-4314-8725-c8a4f4d13a87').clients[0]
-        self.assertTrue(self.driver.ex_remove_client_from_target(target, client))
-
-    def test_ex_remove_client_from_target_STR(self):
-        self.assertTrue(
-            self.driver.ex_remove_client_from_target(
-                'e75ead52-692f-4314-8725-c8a4f4d13a87',
-                '30b1ff76-c76d-4d7c-b39d-3b72be0384c8'
-            )
-        )
-
-    def test_ex_remove_client_from_target_FAIL(self):
-        DimensionDataMockHttp.type = 'FAIL'
-        with self.assertRaises(DimensionDataAPIException) as context:
-            self.driver.ex_remove_client_from_target(
-                'e75ead52-692f-4314-8725-c8a4f4d13a87',
-                '30b1ff76-c76d-4d7c-b39d-3b72be0384c8'
-            )
-        self.assertEqual(context.exception.code, 'ERROR')
-        self.assertTrue('Backup Client is currently performing another operation' in context.exception.msg)
-
-    def test_priv_target_to_target_address(self):
-        target = self.driver.list_targets()[0]
-        self.assertEqual(
-            self.driver._target_to_target_address(target),
-            'e75ead52-692f-4314-8725-c8a4f4d13a87'
-        )
-
-    def test_priv_target_to_target_address_STR(self):
-        self.assertEqual(
-            self.driver._target_to_target_address('e75ead52-692f-4314-8725-c8a4f4d13a87'),
-            'e75ead52-692f-4314-8725-c8a4f4d13a87'
-        )
-
-    def test_priv_target_to_target_address_TYPEERROR(self):
-        with self.assertRaises(TypeError):
-            self.driver._target_to_target_address([1, 2, 3])
-
-    def test_priv_client_to_client_id(self):
-        client = self.driver.ex_get_backup_details_for_target('e75ead52-692f-4314-8725-c8a4f4d13a87').clients[0]
-        self.assertEqual(
-            self.driver._client_to_client_id(client),
-            '30b1ff76-c76d-4d7c-b39d-3b72be0384c8'
-        )
-
-    def test_priv_client_to_client_id_STR(self):
-        self.assertEqual(
-            self.driver._client_to_client_id('30b1ff76-c76d-4d7c-b39d-3b72be0384c8'),
-            '30b1ff76-c76d-4d7c-b39d-3b72be0384c8'
-        )
-
-    def test_priv_client_to_client_id_TYPEERROR(self):
-        with self.assertRaises(TypeError):
-            self.driver._client_to_client_id([1, 2, 3])
-
-
-class InvalidRequestError(Exception):
-    def __init__(self, tag):
-        super(InvalidRequestError, self).__init__("Invalid Request - %s" % tag)
-
-
-class DimensionDataMockHttp(MockHttp):
-
-    fixtures = BackupFileFixtures('dimensiondata')
-
-    def _oec_0_9_myaccount_UNAUTHORIZED(self, method, url, body, headers):
-        return (httplib.UNAUTHORIZED, "", {}, httplib.responses[httplib.UNAUTHORIZED])
-
-    def _oec_0_9_myaccount(self, method, url, body, headers):
-        body = self.fixtures.load('oec_0_9_myaccount.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _oec_0_9_myaccount_EXISTS(self, method, url, body, headers):
-        body = self.fixtures.load('oec_0_9_myaccount.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _oec_0_9_myaccount_DEFAULT(self, method, url, body, headers):
-        body = self.fixtures.load('oec_0_9_myaccount.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _oec_0_9_myaccount_INPROGRESS(self, method, url, body, headers):
-        body = self.fixtures.load('oec_0_9_myaccount.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _oec_0_9_myaccount_FAIL(self, method, url, body, headers):
-        body = self.fixtures.load('oec_0_9_myaccount.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _oec_0_9_myaccount_NOCLIENT(self, method, url, body, headers):
-        body = self.fixtures.load('oec_0_9_myaccount.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _oec_0_9_myaccount_DISABLED(self, method, url, body, headers):
-        body = self.fixtures.load('oec_0_9_myaccount.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _oec_0_9_myaccount_NOJOB(self, method, url, body, headers):
-        body = self.fixtures.load('oec_0_9_myaccount.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server_e75ead52_692f_4314_8725_c8a4f4d13a87(self, method, url, body, headers):
-        body = self.fixtures.load(
-            'caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server_e75ead52_692f_4314_8725_c8a4f4d13a87.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server_e75ead52_692f_4314_8725_c8a4f4d13a87_DEFAULT(self, method, url, body, headers):
-        body = self.fixtures.load(
-            'caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server_e75ead52_692f_4314_8725_c8a4f4d13a87_DEFAULT.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server_e75ead52_692f_4314_8725_c8a4f4d13a87_NOCLIENT(self, method, url, body, headers):
-        body = self.fixtures.load(
-            'caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server_e75ead52_692f_4314_8725_c8a4f4d13a87_DEFAULT.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server_e75ead52_692f_4314_8725_c8a4f4d13a87_NOJOB(self, method, url, body, headers):
-        body = self.fixtures.load(
-            'caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server_e75ead52_692f_4314_8725_c8a4f4d13a87_DEFAULT.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server_e75ead52_692f_4314_8725_c8a4f4d13a87_DISABLED(self, method, url, body, headers):
-        body = self.fixtures.load(
-            'caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server_e75ead52_692f_4314_8725_c8a4f4d13a87_DEFAULT.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server(self, method, url, body, headers):
-        body = self.fixtures.load(
-            'caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_client_type(self, method, url, body, headers):
-        body = self.fixtures.load(
-            'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_client_type.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_client_storagePolicy(
-            self, method, url, body, headers):
-        body = self.fixtures.load(
-            'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_client_storagePolicy.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_client_schedulePolicy(
-            self, method, url, body, headers):
-        body = self.fixtures.load(
-            'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_client_schedulePolicy.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_client(
-            self, method, url, body, headers):
-        if method == 'POST':
-            body = self.fixtures.load(
-                'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_client_SUCCESS_PUT.xml')
-            return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-        else:
-            raise ValueError("Unknown Method {0}".format(method))
-
-    def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_NOCLIENT(
-            self, method, url, body, headers):
-        # only gets here are implemented
-        # If we get any other method something has gone wrong
-        assert(method == 'GET')
-        body = self.fixtures.load(
-            'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO_NOCLIENT.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_DISABLED(
-            self, method, url, body, headers):
-        # only gets here are implemented
-        # If we get any other method something has gone wrong
-        assert(method == 'GET')
-        body = self.fixtures.load(
-            'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO_DISABLED.xml')
-        return (httplib.BAD_REQUEST, body, {}, httplib.responses[httplib.OK])
-
-    def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_NOJOB(
-            self, method, url, body, headers):
-        # only gets here are implemented
-        # If we get any other method something has gone wrong
-        assert(method == 'GET')
-        body = self.fixtures.load(
-            'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO_NOJOB.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_DEFAULT(
-            self, method, url, body, headers):
-        if method != 'POST':
-            raise InvalidRequestError('Only POST is accepted for this test')
-        request = ET.fromstring(body)
-        service_plan = request.get('servicePlan')
-        if service_plan != DEFAULT_BACKUP_PLAN:
-            raise InvalidRequestError('The default plan %s should have been passed in.  Not %s' % (DEFAULT_BACKUP_PLAN, service_plan))
-        body = self.fixtures.load(
-            'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_ENABLE.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup(
-            self, method, url, body, headers):
-        if method == 'POST':
-            body = self.fixtures.load(
-                'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_ENABLE.xml')
-            return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-        elif method == 'GET':
-            if url.endswith('disable'):
-                body = self.fixtures.load(
-                    'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_DISABLE.xml')
-                return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-            body = self.fixtures.load(
-                'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO.xml')
-            return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-        else:
-            raise ValueError("Unknown Method {0}".format(method))
-
-    def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_EXISTS(
-            self, method, url, body, headers):
-        # only POSTs are implemented
-        # If we get any other method something has gone wrong
-        assert(method == 'POST')
-        body = self.fixtures.load(
-            'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_EXISTS.xml')
-        return (httplib.BAD_REQUEST, body, {}, httplib.responses[httplib.OK])
-
-    def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_modify(
-            self, method, url, body, headers):
-        request = ET.fromstring(body)
-        service_plan = request.get('servicePlan')
-        if service_plan != 'Essentials':
-            raise InvalidRequestError("Expected Essentials backup plan in request")
-        body = self.fixtures.load('oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_modify.xml')
-
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_modify_DEFAULT(
-            self, method, url, body, headers):
-        request = ET.fromstring(body)
-        service_plan = request.get('servicePlan')
-        if service_plan != DEFAULT_BACKUP_PLAN:
-            raise InvalidRequestError("Expected % backup plan in test" % DEFAULT_BACKUP_PLAN)
-        body = self.fixtures.load('oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_modify.xml')
-
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_client_30b1ff76_c76d_4d7c_b39d_3b72be0384c8(
-            self, method, url, body, headers):
-        if url.endswith('disable'):
-            body = self.fixtures.load(
-                ('_remove_backup_client.xml')
-            )
-        elif url.endswith('cancelJob'):
-            body = self.fixtures.load(
-                ('oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87'
-                 '_backup_client_30b1ff76_c76d_4d7c_b39d_3b72be0384c8_cancelJob.xml')
-            )
-        else:
-            raise ValueError("Unknown URL: %s" % url)
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_client_30b1ff76_c76d_4d7c_b39d_3b72be0384c8_FAIL(
-            self, method, url, body, headers):
-        if url.endswith('disable'):
-            body = self.fixtures.load(
-                ('_remove_backup_client_FAIL.xml')
-            )
-        elif url.endswith('cancelJob'):
-            body = self.fixtures.load(
-                ('oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87'
-                 '_backup_client_30b1ff76_c76d_4d7c_b39d_3b72be0384c8_cancelJob_FAIL.xml')
-            )
-        else:
-            raise ValueError("Unknown URL: %s" % url)
-        return (httplib.BAD_REQUEST, body, {}, httplib.responses[httplib.OK])
-
-
-if __name__ == '__main__':
-    sys.exit(unittest.main())

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/test/file_fixtures.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/test/file_fixtures.py b/apache-libcloud-1.0.0rc2/libcloud/test/file_fixtures.py
deleted file mode 100644
index 59f8e2e..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/test/file_fixtures.py
+++ /dev/null
@@ -1,97 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-# Helper class for loading large fixture data
-from __future__ import with_statement
-
-import os
-
-from libcloud.utils.py3 import PY3
-from libcloud.utils.py3 import u
-
-FIXTURES_ROOT = {
-    'common': 'common/fixtures',
-    'compute': 'compute/fixtures',
-    'storage': 'storage/fixtures',
-    'loadbalancer': 'loadbalancer/fixtures',
-    'dns': 'dns/fixtures',
-    'backup': 'backup/fixtures',
-    'openstack': 'compute/fixtures/openstack',
-    'container': 'container/fixtures'
-}
-
-
-class FileFixtures(object):
-    def __init__(self, fixtures_type, sub_dir=''):
-        script_dir = os.path.abspath(os.path.split(__file__)[0])
-        self.root = os.path.join(script_dir, FIXTURES_ROOT[fixtures_type],
-                                 sub_dir)
-
-    def load(self, file):
-        path = os.path.join(self.root, file)
-        if os.path.exists(path):
-            if PY3:
-                kwargs = {'encoding': 'utf-8'}
-            else:
-                kwargs = {}
-
-            with open(path, 'r', **kwargs) as fh:
-                content = fh.read()
-            return u(content)
-        else:
-            raise IOError(path)
-
-
-class ComputeFileFixtures(FileFixtures):
-    def __init__(self, sub_dir=''):
-        super(ComputeFileFixtures, self).__init__(fixtures_type='compute',
-                                                  sub_dir=sub_dir)
-
-
-class StorageFileFixtures(FileFixtures):
-    def __init__(self, sub_dir=''):
-        super(StorageFileFixtures, self).__init__(fixtures_type='storage',
-                                                  sub_dir=sub_dir)
-
-
-class LoadBalancerFileFixtures(FileFixtures):
-    def __init__(self, sub_dir=''):
-        super(LoadBalancerFileFixtures, self).__init__(
-            fixtures_type='loadbalancer',
-            sub_dir=sub_dir)
-
-
-class DNSFileFixtures(FileFixtures):
-    def __init__(self, sub_dir=''):
-        super(DNSFileFixtures, self).__init__(fixtures_type='dns',
-                                              sub_dir=sub_dir)
-
-
-class OpenStackFixtures(FileFixtures):
-    def __init__(self, sub_dir=''):
-        super(OpenStackFixtures, self).__init__(fixtures_type='openstack',
-                                                sub_dir=sub_dir)
-
-
-class ContainerFileFixtures(FileFixtures):
-    def __init__(self, sub_dir=''):
-        super(ContainerFileFixtures, self).__init__(fixtures_type='container',
-                                                    sub_dir=sub_dir)
-
-
-class BackupFileFixtures(FileFixtures):
-    def __init__(self, sub_dir=''):
-        super(BackupFileFixtures, self).__init__(fixtures_type='backup',
-                                                 sub_dir=sub_dir)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/test/pricing_test.json
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/test/pricing_test.json b/apache-libcloud-1.0.0rc2/libcloud/test/pricing_test.json
deleted file mode 100644
index 9277874..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/test/pricing_test.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-    "compute": {
-        "foo": {
-            "1": 1.00,
-            "2": 2.00
-        }
-    },
-
-    "updated": 1309019791
-}

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/test/secrets.py-dist
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/test/secrets.py-dist b/apache-libcloud-1.0.0rc2/libcloud/test/secrets.py-dist
deleted file mode 100644
index 4412f13..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/test/secrets.py-dist
+++ /dev/null
@@ -1,94 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-# Make a copy of this file named 'secrets.py' and add your credentials there.
-# Note you can run unit tests without setting your credentials.
-
-BLUEBOX_PARAMS = ('customer_id', 'api_key')
-BRIGHTBOX_PARAMS = ('client_id', 'client_secret')
-EC2_PARAMS = ('access_id', 'secret')
-ECP_PARAMS = ('user_name', 'password')
-GANDI_PARAMS = ('user',)
-GCE_PARAMS = ('email@developer.gserviceaccount.com', 'key')  # Service Account Authentication
-# GCE_PARAMS = ('client_id', 'client_secret')  # Installed App Authentication
-GCE_KEYWORD_PARAMS = {'project': 'project_name'}
-HOSTINGCOM_PARAMS = ('user', 'secret')
-IBM_PARAMS = ('user', 'secret')
-ONAPP_PARAMS = ('key',)
-# OPENSTACK_PARAMS = ('user_name', 'api_key', secure_bool, 'host', port_int)
-OPENSTACK_PARAMS = ('user_name', 'api_key', False, 'host', 8774)
-OPENNEBULA_PARAMS = ('user', 'key')
-DIMENSIONDATA_PARAMS = ('user', 'password')
-OPSOURCE_PARAMS = ('user', 'password')
-RUNABOVE_PARAMS = ('application_key', 'application_secret', 'consumer_key')
-RACKSPACE_PARAMS = ('user', 'key')
-RACKSPACE_NOVA_PARAMS = ('user_name', 'api_key', False, 'host', 8774)
-SLICEHOST_PARAMS = ('key',)
-SOFTLAYER_PARAMS = ('user', 'api_key')
-VCLOUD_PARAMS = ('user', 'secret')
-VOXEL_PARAMS = ('key', 'secret')
-VPSNET_PARAMS = ('user', 'key')
-JOYENT_PARAMS = ('user', 'key')
-VCL_PARAMS = ('user', 'pass', True, 'foo.bar.com')
-GRIDSPOT_PARAMS = ('key',)
-HOSTVIRTUAL_PARAMS = ('key',)
-DIGITALOCEAN_v1_PARAMS = ('user', 'key')
-DIGITALOCEAN_v2_PARAMS = ('token',)
-CLOUDFRAMES_PARAMS = ('key', 'secret', False, 'host', 8888)
-PROFIT_BRICKS_PARAMS = ('user', 'key')
-VULTR_PARAMS = ('key')
-PACKET_PARAMS = ('api_key')
-ECS_PARAMS = ('access_key', 'access_secret')
-
-# Storage
-STORAGE_S3_PARAMS = ('key', 'secret')
-STORAGE_OSS_PARAMS = ('key', 'secret')
-# Google key = 20 char alphanumeric string starting with GOOG
-STORAGE_GOOGLE_STORAGE_PARAMS = ('GOOG0123456789ABCXYZ', 'secret')
-
-# Azure key is b64 encoded and must be decoded before signing requests
-STORAGE_AZURE_BLOBS_PARAMS = ('account', 'cGFzc3dvcmQ=')
-
-# Loadbalancer
-LB_BRIGHTBOX_PARAMS = ('user', 'key')
-LB_ELB_PARAMS = ('access_id', 'secret', 'region')
-LB_SLB_PARAMS = ('access_id', 'secret', 'region')
-
-# DNS
-DNS_PARAMS_LINODE = ('user', 'key')
-DNS_PARAMS_ZERIGO = ('email', 'api token')
-DNS_PARAMS_RACKSPACE = ('user', 'key')
-DNS_PARAMS_HOSTVIRTUAL = ('key',)
-DNS_PARAMS_ROUTE53 = ('access_id', 'secret')
-DNS_GANDI = ('user', )
-DNS_PARAMS_GOOGLE = ('email_address', 'key')
-DNS_KEYWORD_PARAMS_GOOGLE = {'project': 'project_name'}
-DNS_PARAMS_WORLDWIDEDNS = ('user', 'key')
-DNS_PARAMS_DNSIMPLE = ('user', 'key')
-DNS_PARAMS_POINTDNS = ('user', 'key')
-DNS_PARAMS_LIQUIDWEB = ('user', 'key')
-DNS_PARAMS_ZONOMI = ('key')
-DNS_PARAMS_DURABLEDNS = ('api_user', 'api_key')
-DNS_PARAMS_GODADDY = ('customer-id', 'api_user', 'api_key')
-DNS_PARAMS_CLOUDFLARE = ('user@example.com', 'key')
-DNS_PARAMS_AURORADNS = ('apikey', 'secretkey')
-DNS_PARAMS_NSONE = ('key', )
-DNS_PARAMS_LUADNS = ('user', 'key')
-DNS_PARAMS_BUDDYNS = ('key', )
-
-# Container
-CONTAINER_PARAMS_DOCKER = ('user', 'password')
-CONTAINER_PARAMS_ECS = ('user', 'password', 'region')
-CONTAINER_PARAMS_KUBERNETES = ('user', 'password')

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/test/test_connection.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/test/test_connection.py b/apache-libcloud-1.0.0rc2/libcloud/test/test_connection.py
deleted file mode 100644
index 96e86ce..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/test/test_connection.py
+++ /dev/null
@@ -1,334 +0,0 @@
-# -*- coding: utf-8 -*-
-# Licensed to the Apache Software Foundation (ASF) under one or more�
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 os
-import socket
-import sys
-import ssl
-
-from mock import Mock, call, patch
-
-from libcloud.test import unittest
-from libcloud.common.base import Connection
-from libcloud.common.base import LoggingConnection
-from libcloud.httplib_ssl import LibcloudBaseConnection
-from libcloud.httplib_ssl import LibcloudHTTPConnection
-from libcloud.utils.misc import retry
-
-
-class BaseConnectionClassTestCase(unittest.TestCase):
-    def test_parse_proxy_url(self):
-        conn = LibcloudBaseConnection()
-
-        proxy_url = 'http://127.0.0.1:3128'
-        result = conn._parse_proxy_url(proxy_url=proxy_url)
-        self.assertEqual(result[0], 'http')
-        self.assertEqual(result[1], '127.0.0.1')
-        self.assertEqual(result[2], 3128)
-        self.assertEqual(result[3], None)
-        self.assertEqual(result[4], None)
-
-        proxy_url = 'http://user1:pass1@127.0.0.1:3128'
-        result = conn._parse_proxy_url(proxy_url=proxy_url)
-        self.assertEqual(result[0], 'http')
-        self.assertEqual(result[1], '127.0.0.1')
-        self.assertEqual(result[2], 3128)
-        self.assertEqual(result[3], 'user1')
-        self.assertEqual(result[4], 'pass1')
-
-        proxy_url = 'https://127.0.0.1:3128'
-        expected_msg = 'Only http proxies are supported'
-        self.assertRaisesRegexp(ValueError, expected_msg,
-                                conn._parse_proxy_url,
-                                proxy_url=proxy_url)
-
-        proxy_url = 'http://127.0.0.1'
-        expected_msg = 'proxy_url must be in the following format'
-        self.assertRaisesRegexp(ValueError, expected_msg,
-                                conn._parse_proxy_url,
-                                proxy_url=proxy_url)
-
-        proxy_url = 'http://@127.0.0.1:3128'
-        expected_msg = 'URL is in an invalid format'
-        self.assertRaisesRegexp(ValueError, expected_msg,
-                                conn._parse_proxy_url,
-                                proxy_url=proxy_url)
-
-        proxy_url = 'http://user@127.0.0.1:3128'
-        expected_msg = 'URL is in an invalid format'
-        self.assertRaisesRegexp(ValueError, expected_msg,
-                                conn._parse_proxy_url,
-                                proxy_url=proxy_url)
-
-    def test_constructor(self):
-        conn = LibcloudHTTPConnection(host='localhost', port=80)
-        self.assertEqual(conn.proxy_scheme, None)
-        self.assertEqual(conn.proxy_host, None)
-        self.assertEqual(conn.proxy_port, None)
-
-        proxy_url = 'http://127.0.0.3:3128'
-        conn.set_http_proxy(proxy_url=proxy_url)
-        self.assertEqual(conn.proxy_scheme, 'http')
-        self.assertEqual(conn.proxy_host, '127.0.0.3')
-        self.assertEqual(conn.proxy_port, 3128)
-
-        proxy_url = 'http://127.0.0.4:3128'
-        conn = LibcloudHTTPConnection(host='localhost', port=80,
-                                      proxy_url=proxy_url)
-        self.assertEqual(conn.proxy_scheme, 'http')
-        self.assertEqual(conn.proxy_host, '127.0.0.4')
-        self.assertEqual(conn.proxy_port, 3128)
-
-        os.environ['http_proxy'] = proxy_url
-        proxy_url = 'http://127.0.0.5:3128'
-        conn = LibcloudHTTPConnection(host='localhost', port=80,
-                                      proxy_url=proxy_url)
-        self.assertEqual(conn.proxy_scheme, 'http')
-        self.assertEqual(conn.proxy_host, '127.0.0.5')
-        self.assertEqual(conn.proxy_port, 3128)
-
-
-class ConnectionClassTestCase(unittest.TestCase):
-    def setUp(self):
-        self.originalConnect = Connection.connect
-        self.originalResponseCls = Connection.responseCls
-
-        Connection.connect = Mock()
-        Connection.responseCls = Mock()
-        Connection.allow_insecure = True
-
-    def tearDown(self):
-        Connection.connect = self.originalConnect
-        Connection.responseCls = Connection.responseCls
-        Connection.allow_insecure = True
-
-    def test_dont_allow_insecure(self):
-        Connection.allow_insecure = True
-        Connection(secure=False)
-
-        Connection.allow_insecure = False
-
-        expected_msg = (r'Non https connections are not allowed \(use '
-                        'secure=True\)')
-        self.assertRaisesRegexp(ValueError, expected_msg, Connection,
-                                secure=False)
-
-    def test_content_length(self):
-        con = Connection()
-        con.connection = Mock()
-
-        # GET method
-        # No data, no content length should be present
-        con.request('/test', method='GET', data=None)
-        call_kwargs = con.connection.request.call_args[1]
-        self.assertTrue('Content-Length' not in call_kwargs['headers'])
-
-        # '' as data, no content length should be present
-        con.request('/test', method='GET', data='')
-        call_kwargs = con.connection.request.call_args[1]
-        self.assertTrue('Content-Length' not in call_kwargs['headers'])
-
-        # 'a' as data, content length should be present (data in GET is not
-        # correct, but anyways)
-        con.request('/test', method='GET', data='a')
-        call_kwargs = con.connection.request.call_args[1]
-        self.assertEqual(call_kwargs['headers']['Content-Length'], '1')
-
-        # POST, PUT method
-        # No data, content length should be present
-        for method in ['POST', 'PUT', 'post', 'put']:
-            con.request('/test', method=method, data=None)
-            call_kwargs = con.connection.request.call_args[1]
-            self.assertEqual(call_kwargs['headers']['Content-Length'], '0')
-
-        # '' as data, content length should be present
-        for method in ['POST', 'PUT', 'post', 'put']:
-            con.request('/test', method=method, data='')
-            call_kwargs = con.connection.request.call_args[1]
-            self.assertEqual(call_kwargs['headers']['Content-Length'], '0')
-
-        # No data, raw request, do not touch Content-Length if present
-        for method in ['POST', 'PUT', 'post', 'put']:
-            con.request('/test', method=method, data=None,
-                        headers={'Content-Length': '42'}, raw=True)
-            putheader_call_list = con.connection.putheader.call_args_list
-            self.assertIn(call('Content-Length', '42'), putheader_call_list)
-
-        # '' as data, raw request, do not touch Content-Length if present
-        for method in ['POST', 'PUT', 'post', 'put']:
-            con.request('/test', method=method, data=None,
-                        headers={'Content-Length': '42'}, raw=True)
-            putheader_call_list = con.connection.putheader.call_args_list
-            self.assertIn(call('Content-Length', '42'), putheader_call_list)
-
-        # 'a' as data, content length should be present
-        for method in ['POST', 'PUT', 'post', 'put']:
-            con.request('/test', method=method, data='a')
-            call_kwargs = con.connection.request.call_args[1]
-            self.assertEqual(call_kwargs['headers']['Content-Length'], '1')
-
-    def test_cache_busting(self):
-        params1 = {'foo1': 'bar1', 'foo2': 'bar2'}
-        params2 = [('foo1', 'bar1'), ('foo2', 'bar2')]
-
-        con = Connection()
-        con.connection = Mock()
-        con.pre_connect_hook = Mock()
-        con.pre_connect_hook.return_value = {}, {}
-        con.cache_busting = False
-
-        con.request(action='/path', params=params1)
-        args, kwargs = con.pre_connect_hook.call_args
-        self.assertFalse('cache-busting' in args[0])
-        self.assertEqual(args[0], params1)
-
-        con.request(action='/path', params=params2)
-        args, kwargs = con.pre_connect_hook.call_args
-        self.assertFalse('cache-busting' in args[0])
-        self.assertEqual(args[0], params2)
-
-        con.cache_busting = True
-
-        con.request(action='/path', params=params1)
-        args, kwargs = con.pre_connect_hook.call_args
-        self.assertTrue('cache-busting' in args[0])
-
-        con.request(action='/path', params=params2)
-        args, kwargs = con.pre_connect_hook.call_args
-        self.assertTrue('cache-busting' in args[0][len(params2)])
-
-    def test_context_is_reset_after_request_has_finished(self):
-        context = {'foo': 'bar'}
-
-        def responseCls(connection, response):
-            connection.called = True
-            self.assertEqual(connection.context, context)
-
-        con = Connection()
-        con.called = False
-        con.connection = Mock()
-        con.responseCls = responseCls
-
-        con.set_context(context)
-        self.assertEqual(con.context, context)
-
-        con.request('/')
-
-        # Context should have been reset
-        self.assertTrue(con.called)
-        self.assertEqual(con.context, {})
-
-        # Context should also be reset if a method inside request throws
-        con = Connection(timeout=1, retry_delay=0.1)
-        con.connection = Mock()
-
-        con.set_context(context)
-        self.assertEqual(con.context, context)
-        con.connection.request = Mock(side_effect=ssl.SSLError())
-
-        try:
-            con.request('/')
-        except ssl.SSLError:
-            pass
-
-        self.assertEqual(con.context, {})
-
-        con.connection = Mock()
-        con.set_context(context)
-        self.assertEqual(con.context, context)
-
-        con.responseCls = Mock(side_effect=ValueError())
-
-        try:
-            con.request('/')
-        except ValueError:
-            pass
-
-        self.assertEqual(con.context, {})
-
-    def test_log_curl(self):
-        url = '/test/path'
-        body = None
-        headers = {}
-
-        con = LoggingConnection()
-        con.protocol = 'http'
-        con.host = 'example.com'
-        con.port = 80
-
-        for method in ['GET', 'POST', 'PUT', 'DELETE']:
-            cmd = con._log_curl(method=method, url=url, body=body,
-                                headers=headers)
-            self.assertEqual(cmd, 'curl -i -X %s --compress http://example.com:80/test/path' %
-                             (method))
-
-        # Should use --head for head requests
-        cmd = con._log_curl(method='HEAD', url=url, body=body, headers=headers)
-        self.assertEqual(cmd, 'curl -i --head --compress http://example.com:80/test/path')
-
-    def _raise_socket_error(self):
-        raise socket.gaierror('')
-
-    def test_retry_with_sleep(self):
-        con = Connection()
-        con.connection = Mock()
-        connect_method = 'libcloud.common.base.Connection.request'
-
-        with patch(connect_method) as mock_connect:
-            mock_connect.__name__ = 'mock_connect'
-            with self.assertRaises(socket.gaierror):
-                mock_connect.side_effect = socket.gaierror('')
-                retry_request = retry(timeout=1, retry_delay=.1,
-                                      backoff=1)
-                retry_request(con.request)(action='/')
-
-            self.assertGreater(mock_connect.call_count, 1,
-                               'Retry logic failed')
-
-    def test_retry_with_timeout(self):
-        con = Connection()
-        con.connection = Mock()
-        connect_method = 'libcloud.common.base.Connection.request'
-
-        with patch(connect_method) as mock_connect:
-            mock_connect.__name__ = 'mock_connect'
-            with self.assertRaises(socket.gaierror):
-                mock_connect.side_effect = socket.gaierror('')
-                retry_request = retry(timeout=2, retry_delay=.1,
-                                      backoff=1)
-                retry_request(con.request)(action='/')
-
-            self.assertGreater(mock_connect.call_count, 1,
-                               'Retry logic failed')
-
-    def test_retry_with_backoff(self):
-        con = Connection()
-        con.connection = Mock()
-        connect_method = 'libcloud.common.base.Connection.request'
-
-        with patch(connect_method) as mock_connect:
-            mock_connect.__name__ = 'mock_connect'
-            with self.assertRaises(socket.gaierror):
-                mock_connect.side_effect = socket.gaierror('')
-                retry_request = retry(timeout=2, retry_delay=.1,
-                                      backoff=1)
-                retry_request(con.request)(action='/')
-
-            self.assertGreater(mock_connect.call_count, 1,
-                               'Retry logic failed')
-
-if __name__ == '__main__':
-    sys.exit(unittest.main())

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/test/test_file_fixtures.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/test/test_file_fixtures.py b/apache-libcloud-1.0.0rc2/libcloud/test/test_file_fixtures.py
deleted file mode 100644
index 395f315..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/test/test_file_fixtures.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 sys
-import unittest
-
-from libcloud.test.file_fixtures import ComputeFileFixtures
-
-
-class FileFixturesTests(unittest.TestCase):
-
-    def test_success(self):
-        f = ComputeFileFixtures('meta')
-        self.assertEqual("Hello, World!", f.load('helloworld.txt'))
-
-    def test_failure(self):
-        f = ComputeFileFixtures('meta')
-        self.assertRaises(IOError, f.load, 'nil')
-
-if __name__ == '__main__':
-    sys.exit(unittest.main())

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/test/test_httplib_ssl.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/test/test_httplib_ssl.py b/apache-libcloud-1.0.0rc2/libcloud/test/test_httplib_ssl.py
deleted file mode 100644
index 996498f..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/test/test_httplib_ssl.py
+++ /dev/null
@@ -1,157 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 os
-import sys
-import os.path
-import socket
-
-import mock
-from mock import patch
-
-import libcloud.security
-
-from libcloud.utils.py3 import reload
-from libcloud.httplib_ssl import LibcloudHTTPSConnection
-
-from libcloud.test import unittest
-
-ORIGINAL_CA_CERS_PATH = libcloud.security.CA_CERTS_PATH
-
-
-class TestHttpLibSSLTests(unittest.TestCase):
-
-    def setUp(self):
-        libcloud.security.VERIFY_SSL_CERT = False
-        libcloud.security.CA_CERTS_PATH = ORIGINAL_CA_CERS_PATH
-        self.httplib_object = LibcloudHTTPSConnection('foo.bar')
-
-    def test_custom_ca_path_using_env_var_doesnt_exist(self):
-        os.environ['SSL_CERT_FILE'] = '/foo/doesnt/exist'
-
-        try:
-            reload(libcloud.security)
-        except ValueError:
-            e = sys.exc_info()[1]
-            msg = 'Certificate file /foo/doesnt/exist doesn\'t exist'
-            self.assertEqual(str(e), msg)
-        else:
-            self.fail('Exception was not thrown')
-
-    def test_custom_ca_path_using_env_var_is_directory(self):
-        file_path = os.path.dirname(os.path.abspath(__file__))
-        os.environ['SSL_CERT_FILE'] = file_path
-
-        expected_msg = 'Certificate file can\'t be a directory'
-        self.assertRaisesRegexp(ValueError, expected_msg,
-                                reload, libcloud.security)
-
-    def test_custom_ca_path_using_env_var_exist(self):
-        # When setting a path we don't actually check that a valid CA file is
-        # provided.
-        # This happens later in the code in httplib_ssl.connect method
-        file_path = os.path.abspath(__file__)
-        os.environ['SSL_CERT_FILE'] = file_path
-
-        reload(libcloud.security)
-
-        self.assertEqual(libcloud.security.CA_CERTS_PATH, [file_path])
-
-    @patch('warnings.warn')
-    def test_setup_verify(self, _):
-        libcloud.security.CA_CERTS_PATH = []
-
-        # Should throw a runtime error
-        libcloud.security.VERIFY_SSL_CERT = True
-
-        expected_msg = libcloud.security.CA_CERTS_UNAVAILABLE_ERROR_MSG
-        self.assertRaisesRegexp(RuntimeError, expected_msg,
-                                self.httplib_object._setup_verify)
-
-        libcloud.security.VERIFY_SSL_CERT = False
-        self.httplib_object._setup_verify()
-
-    @patch('warnings.warn')
-    def test_setup_ca_cert(self, _):
-        # verify = False, _setup_ca_cert should be a no-op
-        self.httplib_object.verify = False
-        self.httplib_object._setup_ca_cert()
-
-        self.assertEqual(self.httplib_object.ca_cert, None)
-
-        # verify = True, a valid path is provided, self.ca_cert should be set to
-        # a valid path
-        self.httplib_object.verify = True
-
-        libcloud.security.CA_CERTS_PATH = [os.path.abspath(__file__)]
-        self.httplib_object._setup_ca_cert()
-
-        self.assertTrue(self.httplib_object.ca_cert is not None)
-
-        # verify = True, no CA certs are available, exception should be thrown
-        libcloud.security.CA_CERTS_PATH = []
-
-        expected_msg = libcloud.security.CA_CERTS_UNAVAILABLE_ERROR_MSG
-        self.assertRaisesRegexp(RuntimeError, expected_msg,
-                                self.httplib_object._setup_ca_cert)
-
-    @mock.patch('socket.create_connection', mock.MagicMock())
-    @mock.patch('socket.socket', mock.MagicMock())
-    @mock.patch('ssl.wrap_socket')
-    def test_connect_throws_friendly_error_message_on_ssl_wrap_connection_reset_by_peer(self, mock_wrap_socket):
-        # Test that we re-throw a more friendly error message in case
-        # "connection reset by peer" error occurs when trying to establish a
-        # SSL connection
-        libcloud.security.VERIFY_SSL_CERT = True
-        self.httplib_object.verify = True
-        self.httplib_object.http_proxy_used = False
-
-        # No connection reset by peer, original exception should be thrown
-        mock_wrap_socket.side_effect = Exception('foo bar fail')
-
-        expected_msg = 'foo bar fail'
-        self.assertRaisesRegexp(Exception, expected_msg,
-                                self.httplib_object.connect)
-
-        # Connection reset by peer, wrapped exception with friendly error
-        # message should be thrown
-        mock_wrap_socket.side_effect = socket.error('Connection reset by peer')
-
-        expected_msg = 'Failed to establish SSL / TLS connection'
-        self.assertRaisesRegexp(socket.error, expected_msg,
-                                self.httplib_object.connect)
-
-        # Same error but including errno
-        with self.assertRaises(socket.error) as cm:
-            mock_wrap_socket.side_effect = socket.error(104, 'Connection reset by peer')
-            self.httplib_object.connect()
-
-        e = cm.exception
-        self.assertEqual(e.errno, 104)
-        self.assertTrue(expected_msg in str(e))
-
-        # Test original exception is propagated correctly on non reset by peer
-        # error
-        with self.assertRaises(socket.error) as cm:
-            mock_wrap_socket.side_effect = socket.error(105, 'Some random error')
-            self.httplib_object.connect()
-
-        e = cm.exception
-        self.assertEqual(e.errno, 105)
-        self.assertTrue('Some random error' in str(e))
-
-
-if __name__ == '__main__':
-    sys.exit(unittest.main())

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/test/test_init.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/test/test_init.py b/apache-libcloud-1.0.0rc2/libcloud/test/test_init.py
deleted file mode 100644
index ad709d7..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/test/test_init.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# -*- coding: utf-8 -*-
-# Licensed to the Apache Software Foundation (ASF) under one or more�
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 os
-import sys
-import logging
-
-try:
-    import paramiko
-    have_paramiko = True
-except ImportError:
-    have_paramiko = False
-
-from libcloud import _init_once
-from libcloud.common.base import LoggingHTTPConnection
-from libcloud.common.base import LoggingHTTPSConnection
-
-from libcloud.test import unittest
-
-
-class TestUtils(unittest.TestCase):
-    def test_init_once_and_debug_mode(self):
-        # Debug mode is disabled
-        _init_once()
-
-        self.assertEqual(LoggingHTTPConnection.log, None)
-        self.assertEqual(LoggingHTTPSConnection.log, None)
-
-        if have_paramiko:
-            logger = paramiko.util.logging.getLogger()
-            paramiko_log_level = logger.getEffectiveLevel()
-            self.assertEqual(paramiko_log_level, logging.WARNING)
-
-        # Enable debug mode
-        os.environ['LIBCLOUD_DEBUG'] = '/dev/null'
-        _init_once()
-
-        self.assertTrue(LoggingHTTPConnection.log is not None)
-        self.assertTrue(LoggingHTTPSConnection.log is not None)
-
-        if have_paramiko:
-            logger = paramiko.util.logging.getLogger()
-            paramiko_log_level = logger.getEffectiveLevel()
-            self.assertEqual(paramiko_log_level, logging.DEBUG)
-
-
-if __name__ == '__main__':
-    sys.exit(unittest.main())

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/test/test_pricing.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/test/test_pricing.py b/apache-libcloud-1.0.0rc2/libcloud/test/test_pricing.py
deleted file mode 100644
index 5b6d132..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/test/test_pricing.py
+++ /dev/null
@@ -1,106 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 os.path
-import sys
-import unittest
-
-import libcloud.pricing
-
-PRICING_FILE_PATH = os.path.join(os.path.dirname(__file__), 'pricing_test.json')
-
-
-class PricingTestCase(unittest.TestCase):
-
-    def test_get_pricing_success(self):
-        self.assertFalse('foo' in libcloud.pricing.PRICING_DATA['compute'])
-
-        pricing = libcloud.pricing.get_pricing(driver_type='compute',
-                                               driver_name='foo',
-                                               pricing_file_path=PRICING_FILE_PATH)
-        self.assertEqual(pricing['1'], 1.0)
-        self.assertEqual(pricing['2'], 2.0)
-
-        self.assertEqual(libcloud.pricing.PRICING_DATA['compute']['foo']['1'], 1.0)
-        self.assertEqual(libcloud.pricing.PRICING_DATA['compute']['foo']['2'], 2.0)
-
-    def test_get_pricing_invalid_file_path(self):
-        try:
-            libcloud.pricing.get_pricing(driver_type='compute', driver_name='bar',
-                                         pricing_file_path='inexistent.json')
-        except IOError:
-            pass
-        else:
-            self.fail('Invalid pricing file path provided, but an exception was not'
-                      ' thrown')
-
-    def test_get_pricing_invalid_driver_type(self):
-        try:
-            libcloud.pricing.get_pricing(driver_type='invalid_type', driver_name='bar',
-                                         pricing_file_path='inexistent.json')
-        except AttributeError:
-            pass
-        else:
-            self.fail('Invalid driver_type provided, but an exception was not'
-                      ' thrown')
-
-    def test_get_pricing_not_in_cache(self):
-        try:
-            libcloud.pricing.get_pricing(driver_type='compute', driver_name='inexistent',
-                                         pricing_file_path=PRICING_FILE_PATH)
-        except KeyError:
-            pass
-        else:
-            self.fail('Invalid driver provided, but an exception was not'
-                      ' thrown')
-
-    def test_get_size_price(self):
-        libcloud.pricing.PRICING_DATA['compute']['foo'] = {2: 2, '3': 3}
-        price1 = libcloud.pricing.get_size_price(driver_type='compute',
-                                                 driver_name='foo',
-                                                 size_id=2)
-        price2 = libcloud.pricing.get_size_price(driver_type='compute',
-                                                 driver_name='foo',
-                                                 size_id='3')
-        self.assertEqual(price1, 2)
-        self.assertEqual(price2, 3)
-
-    def test_invalid_pricing_cache(self):
-        libcloud.pricing.PRICING_DATA['compute']['foo'] = {2: 2}
-        self.assertTrue('foo' in libcloud.pricing.PRICING_DATA['compute'])
-
-        libcloud.pricing.invalidate_pricing_cache()
-        self.assertFalse('foo' in libcloud.pricing.PRICING_DATA['compute'])
-
-    def test_invalid_module_pricing_cache(self):
-        libcloud.pricing.PRICING_DATA['compute']['foo'] = {1: 1}
-
-        self.assertTrue('foo' in libcloud.pricing.PRICING_DATA['compute'])
-
-        libcloud.pricing.invalidate_module_pricing_cache(driver_type='compute',
-                                                         driver_name='foo')
-        self.assertFalse('foo' in libcloud.pricing.PRICING_DATA['compute'])
-        libcloud.pricing.invalidate_module_pricing_cache(driver_type='compute',
-                                                         driver_name='foo1')
-
-    def test_set_pricing(self):
-        self.assertFalse('foo' in libcloud.pricing.PRICING_DATA['compute'])
-
-        libcloud.pricing.set_pricing(driver_type='compute', driver_name='foo',
-                                     pricing={'foo': 1})
-        self.assertTrue('foo' in libcloud.pricing.PRICING_DATA['compute'])
-
-if __name__ == '__main__':
-    sys.exit(unittest.main())

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/test/test_response_classes.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/test/test_response_classes.py b/apache-libcloud-1.0.0rc2/libcloud/test/test_response_classes.py
deleted file mode 100644
index ceeab4c..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/test/test_response_classes.py
+++ /dev/null
@@ -1,151 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 sys
-import unittest
-import zlib
-import gzip
-
-from mock import Mock
-
-from libcloud.utils.py3 import httplib, b, StringIO, PY3
-from libcloud.common.base import Response, XmlResponse, JsonResponse
-from libcloud.common.types import MalformedResponseError
-
-
-class ResponseClassesTests(unittest.TestCase):
-    def setUp(self):
-        self._mock_response = Mock()
-        self._mock_response.getheaders.return_value = []
-        self._mock_response.status = httplib.OK
-        self._mock_response._original_data = None
-        self._mock_connection = Mock()
-
-    def test_XmlResponse_class(self):
-        self._mock_response.read.return_value = '<foo>bar</foo>'
-        response = XmlResponse(response=self._mock_response,
-                               connection=self._mock_connection)
-
-        parsed = response.parse_body()
-        self.assertEqual(parsed.tag, 'foo')
-        self.assertEqual(parsed.text, 'bar')
-
-    def test_XmlResponse_class_malformed_response(self):
-        self._mock_response.read.return_value = '<foo>'
-
-        try:
-            XmlResponse(response=self._mock_response,
-                        connection=self._mock_connection)
-        except MalformedResponseError:
-            pass
-        else:
-            self.fail('Exception was not thrown')
-
-    def test_XmlResponse_class_zero_length_body_strip(self):
-        self._mock_response.read.return_value = ' '
-
-        response = XmlResponse(response=self._mock_response,
-                               connection=self._mock_connection)
-
-        parsed = response.parse_body()
-        self.assertEqual(parsed, '')
-
-    def test_JsonResponse_class_success(self):
-        self._mock_response.read.return_value = '{"foo": "bar"}'
-        response = JsonResponse(response=self._mock_response,
-                                connection=self._mock_connection)
-
-        parsed = response.parse_body()
-        self.assertEqual(parsed, {'foo': 'bar'})
-
-    def test_JsonResponse_class_malformed_response(self):
-        self._mock_response.read.return_value = '{"foo": "bar'
-
-        try:
-            JsonResponse(response=self._mock_response,
-                         connection=self._mock_connection)
-        except MalformedResponseError:
-            pass
-        else:
-            self.fail('Exception was not thrown')
-
-    def test_JsonResponse_class_zero_length_body_strip(self):
-        self._mock_response.read.return_value = ' '
-
-        response = JsonResponse(response=self._mock_response,
-                                connection=self._mock_connection)
-
-        parsed = response.parse_body()
-        self.assertEqual(parsed, '')
-
-    def test_deflate_encoding(self):
-        original_data = 'foo bar ponies, wooo zlib'
-        compressed_data = zlib.compress(b(original_data))
-
-        self._mock_response.read.return_value = compressed_data
-        self._mock_response.getheaders.return_value = \
-            {'Content-Encoding': 'deflate'}
-
-        response = Response(response=self._mock_response,
-                            connection=self._mock_connection)
-
-        body = response.parse_body()
-        self.assertEqual(body, original_data)
-
-        self._mock_response.getheaders.return_value = \
-            {'Content-Encoding': 'zlib'}
-
-        response = Response(response=self._mock_response,
-                            connection=self._mock_connection)
-
-        body = response.parse_body()
-        self.assertEqual(body, original_data)
-
-    def test_gzip_encoding(self):
-        original_data = 'foo bar ponies, wooo gzip'
-
-        if PY3:
-            from io import BytesIO
-            string_io = BytesIO()
-        else:
-            string_io = StringIO()
-
-        stream = gzip.GzipFile(fileobj=string_io, mode='w')
-        stream.write(b(original_data))
-        stream.close()
-        compressed_data = string_io.getvalue()
-
-        self._mock_response.read.return_value = compressed_data
-        self._mock_response.getheaders.return_value = \
-            {'Content-Encoding': 'gzip'}
-
-        response = Response(response=self._mock_response,
-                            connection=self._mock_connection)
-
-        body = response.parse_body()
-        self.assertEqual(body, original_data)
-
-        self._mock_response.getheaders.return_value = \
-            {'Content-Encoding': 'x-gzip'}
-
-        response = Response(response=self._mock_response,
-                            connection=self._mock_connection)
-
-        body = response.parse_body()
-        self.assertEqual(body, original_data)
-
-
-if __name__ == '__main__':
-    sys.exit(unittest.main())

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/test/test_types.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/test/test_types.py b/apache-libcloud-1.0.0rc2/libcloud/test/test_types.py
deleted file mode 100644
index 453ffcc..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/test/test_types.py
+++ /dev/null
@@ -1,112 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 sys
-import unittest
-
-from libcloud.common.types import LazyList
-
-
-class TestLazyList(unittest.TestCase):
-    def setUp(self):
-        super(TestLazyList, self).setUp
-        self._get_more_counter = 0
-
-    def tearDown(self):
-        super(TestLazyList, self).tearDown
-
-    def test_init(self):
-        data = [1, 2, 3, 4, 5]
-        ll = LazyList(get_more=self._get_more_exhausted)
-        ll_list = list(ll)
-        self.assertEqual(ll_list, data)
-
-    def test_iterator(self):
-        data = [1, 2, 3, 4, 5]
-        ll = LazyList(get_more=self._get_more_exhausted)
-        for i, d in enumerate(ll):
-            self.assertEqual(d, data[i])
-
-    def test_empty_list(self):
-        ll = LazyList(get_more=self._get_more_empty)
-
-        self.assertEqual(list(ll), [])
-        self.assertEqual(len(ll), 0)
-        self.assertTrue(10 not in ll)
-
-    def test_iterator_not_exhausted(self):
-        data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
-        ll = LazyList(get_more=self._get_more_not_exhausted)
-        number_of_iterations = 0
-        for i, d in enumerate(ll):
-            self.assertEqual(d, data[i])
-            number_of_iterations += 1
-        self.assertEqual(number_of_iterations, 10)
-
-    def test_len(self):
-        ll = LazyList(get_more=self._get_more_not_exhausted)
-        ll = LazyList(get_more=self._get_more_not_exhausted)
-
-        self.assertEqual(len(ll), 10)
-
-    def test_contains(self):
-        ll = LazyList(get_more=self._get_more_not_exhausted)
-
-        self.assertTrue(40 not in ll)
-        self.assertTrue(1 in ll)
-        self.assertTrue(5 in ll)
-        self.assertTrue(10 in ll)
-
-    def test_indexing(self):
-        ll = LazyList(get_more=self._get_more_not_exhausted)
-
-        self.assertEqual(ll[0], 1)
-        self.assertEqual(ll[9], 10)
-        self.assertEqual(ll[-1], 10)
-
-        try:
-            ll[11]
-        except IndexError:
-            pass
-        else:
-            self.fail('Exception was not thrown')
-
-    def test_repr(self):
-        ll1 = LazyList(get_more=self._get_more_empty)
-        ll2 = LazyList(get_more=self._get_more_exhausted)
-        ll3 = LazyList(get_more=self._get_more_not_exhausted)
-
-        self.assertEqual(repr(ll1), '[]')
-        self.assertEqual(repr(ll2), '[1, 2, 3, 4, 5]')
-        self.assertEqual(repr(ll3), '[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]')
-
-    def _get_more_empty(self, last_key, value_dict):
-        return [], None, True
-
-    def _get_more_exhausted(self, last_key, value_dict):
-        data = [1, 2, 3, 4, 5]
-        return data, 5, True
-
-    def _get_more_not_exhausted(self, last_key, value_dict):
-        self._get_more_counter += 1
-        if not last_key:
-            data, last_key, exhausted = [1, 2, 3, 4, 5], 5, False
-        else:
-            data, last_key, exhausted = [6, 7, 8, 9, 10], 10, True
-
-        return data, last_key, exhausted
-
-if __name__ == '__main__':
-    sys.exit(unittest.main())


[14/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/cloudflare.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/cloudflare.py b/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/cloudflare.py
deleted file mode 100644
index ee2d8eb..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/cloudflare.py
+++ /dev/null
@@ -1,429 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-__all__ = [
-    'CloudFlareDNSDriver'
-]
-
-import copy
-
-from libcloud.common.base import JsonResponse, ConnectionUserAndKey
-from libcloud.common.types import InvalidCredsError, LibcloudError
-from libcloud.utils.py3 import httplib
-from libcloud.dns.base import DNSDriver, Zone, Record
-from libcloud.dns.types import Provider, RecordType
-from libcloud.dns.types import ZoneDoesNotExistError, RecordDoesNotExistError
-
-API_URL = 'https://www.cloudflare.com/api_json.html'
-API_HOST = 'www.cloudflare.com'
-API_PATH = '/api_json.html'
-
-ZONE_EXTRA_ATTRIBUTES = [
-    'display_name',
-    'zone_status',
-    'zone_type',
-    'host_id',
-    'host_pubname',
-    'host_website',
-    'fqdns',
-    'vtxt',
-    'step',
-    'zone_status_class',
-    'zone_status_desc',
-    'orig_registrar',
-    'orig_dnshost',
-    'orig_ns_names'
-]
-
-RECORD_EXTRA_ATTRIBUTES = [
-    'rec_tag',
-    'display_name',
-    'pro',
-    'display_content',
-    'ttl_ceil',
-    'ssl_id',
-    'ssl_status',
-    'ssl_expires_on',
-    'auto_ttl',
-    'service_mode'
-]
-
-
-class CloudFlareDNSResponse(JsonResponse):
-    def success(self):
-        return self.status in [httplib.OK, httplib.CREATED, httplib.ACCEPTED]
-
-    def parse_body(self):
-        body = super(CloudFlareDNSResponse, self).parse_body()
-
-        result = body.get('result', None)
-        error_code = body.get('err_code', None)
-        msg = body.get('msg', None)
-        is_error_result = result == 'error'
-
-        context = self.connection.context or {}
-        context_record_id = context.get('record_id', None)
-        context_zone_domain = context.get('zone_domain', None)
-
-        if (is_error_result and 'invalid record id' in msg.lower() and
-                context_record_id):
-            raise RecordDoesNotExistError(value=msg,
-                                          driver=self.connection.driver,
-                                          record_id=context_record_id)
-        elif (is_error_result and 'invalid zone' in msg.lower() and
-              context_zone_domain):
-            raise ZoneDoesNotExistError(value=msg,
-                                        driver=self.connection.driver,
-                                        zone_id=context_zone_domain)
-
-        if error_code == 'E_UNAUTH':
-            raise InvalidCredsError(msg)
-        elif result == 'error' or error_code is not None:
-            msg = 'Request failed: %s' % (self.body)
-            raise LibcloudError(value=msg, driver=self.connection.driver)
-
-        return body
-
-
-class CloudFlareDNSConnection(ConnectionUserAndKey):
-    host = API_HOST
-    secure = True
-    responseCls = CloudFlareDNSResponse
-
-    def request(self, action, params=None, data=None, headers=None,
-                method='GET'):
-        params = params or {}
-        data = data or {}
-
-        base_params = {
-            'email': self.user_id,
-            'tkn': self.key,
-            'a': action
-        }
-        params = copy.deepcopy(params)
-        params.update(base_params)
-
-        return super(CloudFlareDNSConnection, self).request(action=API_PATH,
-                                                            params=params,
-                                                            data=None,
-                                                            method=method,
-                                                            headers=headers)
-
-
-class CloudFlareDNSDriver(DNSDriver):
-    type = Provider.CLOUDFLARE
-    name = 'CloudFlare DNS'
-    website = 'https://www.cloudflare.com'
-    connectionCls = CloudFlareDNSConnection
-
-    RECORD_TYPE_MAP = {
-        RecordType.A: 'A',
-        RecordType.AAAA: 'AAAA',
-        RecordType.CNAME: 'CNAME',
-        RecordType.MX: 'MX',
-        RecordType.TXT: 'TXT',
-        RecordType.SPF: 'SPF',
-        RecordType.NS: 'NS',
-        RecordType.SRV: 'SRV',
-        RecordType.URL: 'LOC'
-    }
-
-    def iterate_zones(self):
-        # TODO: Support pagination
-        result = self.connection.request(action='zone_load_multi').object
-        zones = self._to_zones(data=result['response']['zones']['objs'])
-
-        return zones
-
-    def iterate_records(self, zone):
-        # TODO: Support pagination
-        params = {'z': zone.domain}
-        self.connection.set_context({'zone_domain': zone.domain})
-        resp = self.connection.request(action='rec_load_all', params=params)
-        data = resp.object['response']['recs']['objs']
-        records = self._to_records(zone=zone, data=data)
-        return records
-
-    def get_zone(self, zone_id):
-        # TODO: This is not efficient
-        zones = self.list_zones()
-
-        try:
-            zone = [z for z in zones if z.id == zone_id][0]
-        except IndexError:
-            raise ZoneDoesNotExistError(value='', driver=self, zone_id=zone_id)
-
-        return zone
-
-    def create_record(self, name, zone, type, data, extra=None):
-        extra = extra or {}
-        params = {'name': name, 'z': zone.domain, 'type': type,
-                  'content': data}
-
-        params['ttl'] = extra.get('ttl', 120)
-
-        if 'priority' in extra:
-            # For MX and SRV records
-            params['prio'] = extra['priority']
-
-        self.connection.set_context({'zone_domain': zone.domain})
-        resp = self.connection.request(action='rec_new', params=params)
-        item = resp.object['response']['rec']['obj']
-        record = self._to_record(zone=zone, item=item)
-        return record
-
-    def update_record(self, record, name=None, type=None, data=None,
-                      extra=None):
-        extra = extra or {}
-        params = {'z': record.zone.domain, 'id': record.id}
-
-        params['name'] = name or record.name
-        params['type'] = type or record.type
-        params['content'] = data or record.data
-        params['ttl'] = extra.get('ttl', None) or record.extra['ttl']
-
-        self.connection.set_context({'zone_domain': record.zone.domain})
-        self.connection.set_context({'record_id': record.id})
-        resp = self.connection.request(action='rec_edit', params=params)
-        item = resp.object['response']['rec']['obj']
-        record = self._to_record(zone=record.zone, item=item)
-        return record
-
-    def delete_record(self, record):
-        params = {'z': record.zone.domain, 'id': record.id}
-        self.connection.set_context({'zone_domain': record.zone.domain})
-        self.connection.set_context({'record_id': record.id})
-        resp = self.connection.request(action='rec_delete', params=params)
-        result = resp.object
-        return result.get('result', None) == 'success'
-
-    def ex_get_zone_stats(self, zone, interval=30):
-        params = {'z': zone.domain, 'interval': interval}
-        self.connection.set_context({'zone_domain': zone.domain})
-        resp = self.connection.request(action='stats', params=params)
-        result = resp.object['response']['result']['objs'][0]
-        return result
-
-    def ex_zone_check(self, zones):
-        zone_domains = [zone.domain for zone in zones]
-        zone_domains = ','.join(zone_domains)
-        params = {'zones': zone_domains}
-        resp = self.connection.request(action='zone_check', params=params)
-        result = resp.object['response']['zones']
-        return result
-
-    def ex_get_ip_threat_score(self, ip):
-        """
-        Retrieve current threat score for a given IP. Note that scores are on
-        a logarithmic scale, where a higher score indicates a higher threat.
-        """
-        params = {'ip': ip}
-        resp = self.connection.request(action='ip_lkup', params=params)
-        result = resp.object['response']
-        return result
-
-    def ex_get_zone_settings(self, zone):
-        """
-        Retrieve all current settings for a given zone.
-        """
-        params = {'z': zone.domain}
-        self.connection.set_context({'zone_domain': zone.domain})
-        resp = self.connection.request(action='zone_settings', params=params)
-        result = resp.object['response']['result']['objs'][0]
-        return result
-
-    def ex_set_zone_security_level(self, zone, level):
-        """
-        Set the zone Basic Security Level to I'M UNDER ATTACK! / HIGH /
-        MEDIUM / LOW / ESSENTIALLY OFF.
-
-        :param level: Security level. Valid values are: help, high, med, low,
-                      eoff.
-        :type level: ``str``
-        """
-        params = {'z': zone.domain, 'v': level}
-        self.connection.set_context({'zone_domain': zone.domain})
-        resp = self.connection.request(action='sec_lvl', params=params)
-        result = resp.object
-        return result.get('result', None) == 'success'
-
-    def ex_set_zone_cache_level(self, zone, level):
-        """
-        Set the zone caching level.
-
-        :param level: Caching level. Valid values are: agg (aggresive), basic.
-        :type level: ``str``
-        """
-        params = {'z': zone.domain, 'v': level}
-        self.connection.set_context({'zone_domain': zone.domain})
-        resp = self.connection.request(action='cache_lvl', params=params)
-        result = resp.object
-        return result.get('result', None) == 'success'
-
-    def ex_enable_development_mode(self, zone):
-        """
-        Enable development mode. When Development Mode is on the cache is
-        bypassed. Development mode remains on for 3 hours or until when it is
-        toggled back off.
-        """
-        params = {'z': zone.domain, 'v': 1}
-        self.connection.set_context({'zone_domain': zone.domain})
-        resp = self.connection.request(action='devmode', params=params)
-        result = resp.object
-        return result.get('result', None) == 'success'
-
-    def ex_disable_development_mode(self, zone):
-        """
-        Disable development mode.
-        """
-        params = {'z': zone.domain, 'v': 0}
-        self.connection.set_context({'zone_domain': zone.domain})
-        resp = self.connection.request(action='devmode', params=params)
-        result = resp.object
-        return result.get('result', None) == 'success'
-
-    def ex_purge_cached_files(self, zone):
-        """
-        Purge CloudFlare of any cached files.
-        """
-        params = {'z': zone.domain, 'v': 1}
-        self.connection.set_context({'zone_domain': zone.domain})
-        resp = self.connection.request(action='fpurge_ts', params=params)
-        result = resp.object
-        return result.get('result', None) == 'success'
-
-    def ex_purge_cached_file(self, zone, url):
-        """
-        Purge single file from CloudFlare's cache.
-
-        :param url: URL to the file to purge from cache.
-        :type url: ``str``
-        """
-        params = {'z': zone.domain, 'url': url}
-        self.connection.set_context({'zone_domain': zone.domain})
-        resp = self.connection.request(action='zone_file_purge', params=params)
-        result = resp.object
-        return result.get('result', None) == 'success'
-
-    def ex_whitelist_ip(self, zone, ip):
-        """
-        Whitelist the provided IP.
-        """
-        params = {'z': zone.domain, 'key': ip}
-        self.connection.set_context({'zone_domain': zone.domain})
-        resp = self.connection.request(action='wl', params=params)
-        result = resp.object
-        return result.get('result', None) == 'success'
-
-    def ex_blacklist_ip(self, zone, ip):
-        """
-        Blacklist the provided IP.
-        """
-        params = {'z': zone.domain, 'key': ip}
-        self.connection.set_context({'zone_domain': zone.domain})
-        resp = self.connection.request(action='ban', params=params)
-        result = resp.object
-        return result.get('result', None) == 'success'
-
-    def ex_unlist_ip(self, zone, ip):
-        """
-        Remove provided ip from the whitelist and blacklist.
-        """
-        params = {'z': zone.domain, 'key': ip}
-        self.connection.set_context({'zone_domain': zone.domain})
-        resp = self.connection.request(action='nul', params=params)
-        result = resp.object
-        return result.get('result', None) == 'success'
-
-    def ex_enable_ipv6_support(self, zone):
-        """
-        Enable IPv6 support for the provided zone.
-        """
-        params = {'z': zone.domain, 'v': 3}
-        self.connection.set_context({'zone_domain': zone.domain})
-        resp = self.connection.request(action='ipv46', params=params)
-        result = resp.object
-        return result.get('result', None) == 'success'
-
-    def ex_disable_ipv6_support(self, zone):
-        """
-        Disable IPv6 support for the provided zone.
-        """
-        params = {'z': zone.domain, 'v': 0}
-        self.connection.set_context({'zone_domain': zone.domain})
-        resp = self.connection.request(action='ipv46', params=params)
-        result = resp.object
-        return result.get('result', None) == 'success'
-
-    def _to_zones(self, data):
-        zones = []
-
-        for item in data:
-            zone = self._to_zone(item=item)
-            zones.append(zone)
-
-        return zones
-
-    def _to_zone(self, item):
-        type = 'master'
-
-        extra = {}
-        extra['props'] = item.get('props', {})
-        extra['confirm_code'] = item.get('confirm_code', {})
-        extra['allow'] = item.get('allow', {})
-        for attribute in ZONE_EXTRA_ATTRIBUTES:
-            value = item.get(attribute, None)
-            extra[attribute] = value
-
-        zone = Zone(id=str(item['zone_id']), domain=item['zone_name'],
-                    type=type, ttl=None, driver=self, extra=extra)
-        return zone
-
-    def _to_records(self, zone, data):
-        records = []
-
-        for item in data:
-            record = self._to_record(zone=zone, item=item)
-            records.append(record)
-
-        return records
-
-    def _to_record(self, zone, item):
-        name = self._get_record_name(item=item)
-        type = item['type']
-        data = item['content']
-
-        if item.get('ttl', None):
-            ttl = int(item['ttl'])
-        else:
-            ttl = None
-
-        extra = {}
-        extra['ttl'] = ttl
-        extra['props'] = item.get('props', {})
-        for attribute in RECORD_EXTRA_ATTRIBUTES:
-            value = item.get(attribute, None)
-            extra[attribute] = value
-
-        record = Record(id=str(item['rec_id']), name=name, type=type,
-                        data=data, zone=zone, driver=self, ttl=ttl,
-                        extra=extra)
-        return record
-
-    def _get_record_name(self, item):
-        name = item['name'].replace('.' + item['zone_name'], '') or None
-        if name:
-            name = name.replace(item['zone_name'], '') or None
-        return name

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/digitalocean.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/digitalocean.py b/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/digitalocean.py
deleted file mode 100644
index ad8a297..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/digitalocean.py
+++ /dev/null
@@ -1,292 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-Digital Ocean DNS Driver
-"""
-
-__all__ = [
-    'DigitalOceanDNSDriver'
-]
-
-from libcloud.utils.py3 import httplib
-
-from libcloud.common.digitalocean import DigitalOcean_v2_BaseDriver
-from libcloud.common.digitalocean import DigitalOcean_v2_Connection
-from libcloud.dns.types import Provider, RecordType
-from libcloud.dns.base import DNSDriver, Zone, Record
-
-
-class DigitalOceanDNSDriver(DigitalOcean_v2_BaseDriver, DNSDriver):
-    connectionCls = DigitalOcean_v2_Connection
-    type = Provider.DIGITAL_OCEAN
-    name = "DigitalOcean"
-    website = 'https://www.digitalocean.com'
-
-    RECORD_TYPE_MAP = {
-        RecordType.NS: 'NS',
-        RecordType.A: 'A',
-        RecordType.AAAA: 'AAAA',
-        RecordType.CNAME: 'CNAME',
-        RecordType.MX: 'MX',
-        RecordType.TXT: 'TXT',
-        RecordType.SRV: 'SRV',
-    }
-
-    def list_zones(self):
-        """
-        Return a list of zones.
-
-        :return: ``list`` of :class:`Zone`
-        """
-        data = self._paginated_request('/v2/domains', 'domains')
-        return list(map(self._to_zone, data))
-
-    def list_records(self, zone):
-        """
-        Return a list of records for the provided zone.
-
-        :param zone: Zone to list records for.
-        :type zone: :class:`Zone`
-
-        :return: ``list`` of :class:`Record`
-        """
-        data = self._paginated_request('/v2/domains/%s/records' % (zone.id),
-                                       'domain_records')
-# TODO: Not use list comprehension to add zone to record for proper data map
-#       functionality? This passes a reference to zone for each data currently
-#       to _to_record which returns a Record. map() does not take keywords
-        return list(map(self._to_record, data, [zone for z in data]))
-
-    def get_zone(self, zone_id):
-        """
-        Return a Zone instance.
-
-        :param zone_id: ID of the required zone
-        :type  zone_id: ``str``
-
-        :rtype: :class:`Zone`
-        """
-        data = self.connection.request('/v2/domains/%s' %
-                                       (zone_id)).object['domain']
-
-        return self._to_zone(data)
-
-    def get_record(self, zone_id, record_id):
-        """
-        Return a Record instance.
-
-        :param zone_id: ID of the required zone
-        :type  zone_id: ``str``
-
-        :param record_id: ID of the required record
-        :type  record_id: ``str``
-
-        :rtype: :class:`Record`
-        """
-        data = self.connection.request('/v2/domains/%s/records/%s' % (zone_id,
-                                       record_id)).object['domain_record']
-
-# TODO: Any way of not using get_zone which polls the API again
-#       without breaking the DNSDriver.get_record parameters?
-        return self._to_record(data, self.get_zone(zone_id))
-
-    def create_zone(self, domain, type='master', ttl=None, extra=None):
-        """
-        Create a new zone.
-
-        :param domain: Zone domain name (e.g. example.com)
-        :type domain: ``str``
-
-        :param type: Zone type (master / slave) (does nothing).
-        :type  type: ``str``
-
-        :param ttl: TTL for new records. (does nothing)
-        :type  ttl: ``int``
-
-        :param extra: Extra attributes (to set ip). (optional)
-                      Note: This can be used to set the default A record with
-                      {"ip" : "IP.AD.DR.ESS"} otherwise 127.0.0.1 is used
-        :type extra: ``dict``
-
-        :rtype: :class:`Zone`
-        """
-        params = {'name': domain}
-        try:
-            params['ip_address'] = extra['ip']
-        except:
-            params['ip_address'] = '127.0.0.1'
-
-        res = self.connection.request('/v2/domains', params=params,
-                                      method='POST')
-
-        return Zone(id=res.object['domain']['name'],
-                    domain=res.object['domain']['name'],
-                    type='master', ttl=1800, driver=self, extra={})
-
-    def create_record(self, name, zone, type, data, extra=None):
-        """
-        Create a new record.
-
-        :param name: Record name without the domain name (e.g. www).
-                     Note: If you want to create a record for a base domain
-                     name, you should specify empty string ('') for this
-                     argument.
-        :type  name: ``str``
-
-        :param zone: Zone where the requested record is created.
-        :type  zone: :class:`Zone`
-
-        :param type: DNS record type (A, AAAA, ...).
-        :type  type: :class:`RecordType`
-
-        :param data: Data for the record (depends on the record type).
-        :type  data: ``str``
-
-        :param extra: Extra attributes for MX and SRV. (Depends on record)
-                      {"priority" : 0, "port" : 443, "weight" : 100}
-        :type extra: ``dict``
-
-        :rtype: :class:`Record`
-        """
-        params = {
-            "type": self.RECORD_TYPE_MAP[type],
-            "name": name,
-            "data": data
-        }
-        if extra:
-            try:
-                params['priority'] = extra['priority']
-            except KeyError:
-                params['priority'] = 'null'
-            try:
-                params['port'] = extra['port']
-            except KeyError:
-                params['port'] = 'null'
-            try:
-                params['weight'] = extra['weight']
-            except KeyError:
-                params['weight'] = 'null'
-
-        res = self.connection.request('/v2/domains/%s/records' % zone.id,
-                                      params=params,
-                                      method='POST')
-
-        return Record(id=res.object['domain_record']['id'],
-                      name=res.object['domain_record']['name'],
-                      type=type, data=data, zone=zone,
-                      driver=self, extra=extra)
-
-    def update_record(self, record, name=None, type=None,
-                      data=None, extra=None):
-        """
-        Update an existing record.
-
-        :param record: Record to update.
-        :type  record: :class:`Record`
-
-        :param name: Record name without the domain name (e.g. www). (Ignored)
-                     Note: The value is pulled from the record being updated
-        :type  name: ``str``
-
-        :param type: DNS record type (A, AAAA, ...). (Ignored)
-                     Note: Updating records does not support changing type
-                     so this value is ignored
-        :type  type: :class:`RecordType`
-
-        :param data: Data for the record (depends on the record type).
-        :type  data: ``str``
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type  extra: ``dict``
-
-        :rtype: :class:`Record`
-        """
-        params = {
-            "type": record.type,
-            "name": record.name,
-            "data": data
-        }
-        if data is None:
-            params['data'] = record.data
-        if extra:
-            try:
-                params['priority'] = extra['priority']
-            except KeyError:
-                params['priority'] = 'null'
-            try:
-                params['port'] = extra['port']
-            except KeyError:
-                params['port'] = 'null'
-            try:
-                params['weight'] = extra['weight']
-            except KeyError:
-                params['weight'] = 'null'
-
-        res = self.connection.request('/v2/domains/%s/records/%s' %
-                                      (record.zone.id, record.id),
-                                      params=params,
-                                      method='PUT')
-
-        return Record(id=res.object['domain_record']['id'],
-                      name=res.object['domain_record']['name'],
-                      type=record.type, data=data, zone=record.zone,
-                      driver=self, extra=extra)
-
-    def delete_zone(self, zone):
-        """
-        Delete a zone.
-
-        Note: This will delete all the records belonging to this zone.
-
-        :param zone: Zone to delete.
-        :type  zone: :class:`Zone`
-
-        :rtype: ``bool``
-        """
-        params = {}
-
-        res = self.connection.request('/v2/domains/%s' % zone.id,
-                                      params=params, method='DELETE')
-
-        return res.status == httplib.NO_CONTENT
-
-    def delete_record(self, record):
-        """
-        Delete a record.
-
-        :param record: Record to delete.
-        :type  record: :class:`Record`
-
-        :rtype: ``bool``
-        """
-        params = {}
-
-        res = self.connection.request('/v2/domains/%s/records/%s' % (
-                                      record.zone.id, record.id),
-                                      params=params,
-                                      method='DELETE')
-        return res.status == httplib.NO_CONTENT
-
-    def _to_record(self, data, zone=None):
-        extra = {'port': data['port'], 'priority': data['priority'],
-                 'weight': data['weight']}
-        return Record(id=data['id'], name=data['name'],
-                      type=self._string_to_record_type(data['type']),
-                      data=data['data'], zone=zone, driver=self, extra=extra)
-
-    def _to_zone(self, data):
-        extra = {'zone_file': data['zone_file']}
-        return Zone(id=data['name'], domain=data['name'], type='master',
-                    ttl=data['ttl'], driver=self, extra=extra)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/dnsimple.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/dnsimple.py b/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/dnsimple.py
deleted file mode 100644
index 7edbdfe..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/dnsimple.py
+++ /dev/null
@@ -1,294 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-DNSimple DNS Driver
-"""
-
-__all__ = [
-    'DNSimpleDNSDriver'
-]
-
-try:
-    import simplejson as json
-except ImportError:
-    import json
-
-from libcloud.common.dnsimple import DNSimpleDNSConnection
-from libcloud.dns.types import Provider, RecordType
-from libcloud.dns.base import DNSDriver, Zone, Record
-
-
-DEFAULT_ZONE_TTL = 3600
-
-
-class DNSimpleDNSDriver(DNSDriver):
-    type = Provider.DNSIMPLE
-    name = 'DNSimple'
-    website = 'https://dnsimple.com/'
-    connectionCls = DNSimpleDNSConnection
-
-    RECORD_TYPE_MAP = {
-        RecordType.A: 'A',
-        RecordType.AAAA: 'AAAA',
-        RecordType.ALIAS: 'ALIAS',
-        RecordType.CNAME: 'CNAME',
-        RecordType.HINFO: 'HINFO',
-        RecordType.MX: 'MX',
-        RecordType.NAPTR: 'NAPTR',
-        RecordType.NS: 'NS',
-        'POOL': 'POOL',
-        RecordType.SOA: 'SOA',
-        RecordType.SPF: 'SPF',
-        RecordType.SRV: 'SRV',
-        RecordType.SSHFP: 'SSHFP',
-        RecordType.TXT: 'TXT',
-        RecordType.URL: 'URL'
-    }
-
-    def list_zones(self):
-        """
-        Return a list of zones.
-
-        :return: ``list`` of :class:`Zone`
-        """
-        response = self.connection.request('/v1/domains')
-
-        zones = self._to_zones(response.object)
-        return zones
-
-    def list_records(self, zone):
-        """
-        Return a list of records for the provided zone.
-
-        :param zone: Zone to list records for.
-        :type zone: :class:`Zone`
-
-        :return: ``list`` of :class:`Record`
-        """
-        response = self.connection.request('/v1/domains/%s/records' % zone.id)
-        records = self._to_records(response.object, zone)
-        return records
-
-    def get_zone(self, zone_id):
-        """
-        Return a Zone instance.
-
-        :param zone_id: ID of the required zone
-        :type  zone_id: ``str``
-
-        :rtype: :class:`Zone`
-        """
-        response = self.connection.request('/v1/domains/%s' % zone_id)
-        zone = self._to_zone(response.object)
-        return zone
-
-    def get_record(self, zone_id, record_id):
-        """
-        Return a Record instance.
-
-        :param zone_id: ID of the required zone
-        :type  zone_id: ``str``
-
-        :param record_id: ID of the required record
-        :type  record_id: ``str``
-
-        :rtype: :class:`Record`
-        """
-        response = self.connection.request('/v1/domains/%s/records/%s' %
-                                           (zone_id, record_id))
-        record = self._to_record(response.object, zone_id=zone_id)
-        return record
-
-    def create_zone(self, domain, type='master', ttl=None, extra=None):
-        """
-        Create a new zone.
-
-        :param domain: Zone domain name (e.g. example.com)
-        :type domain: ``str``
-
-        :param type: Zone type (All zones are master by design).
-        :type  type: ``str``
-
-        :param ttl: TTL for new records. (This is not really used)
-        :type  ttl: ``int``
-
-        :param extra: Extra attributes (driver specific). (optional)
-        :type extra: ``dict``
-
-        :rtype: :class:`Zone`
-
-        For more info, please see:
-        http://developer.dnsimple.com/v1/domains/
-        """
-        r_json = {'name': domain}
-        if extra is not None:
-            r_json.update(extra)
-        r_data = json.dumps({'domain': r_json})
-        response = self.connection.request(
-            '/v1/domains', method='POST', data=r_data)
-        zone = self._to_zone(response.object)
-        return zone
-
-    def create_record(self, name, zone, type, data, extra=None):
-        """
-        Create a new record.
-
-        :param name: Record name without the domain name (e.g. www).
-                     Note: If you want to create a record for a base domain
-                     name, you should specify empty string ('') for this
-                     argument.
-        :type  name: ``str``
-
-        :param zone: Zone where the requested record is created.
-        :type  zone: :class:`Zone`
-
-        :param type: DNS record type (A, AAAA, ...).
-        :type  type: :class:`RecordType`
-
-        :param data: Data for the record (depends on the record type).
-        :type  data: ``str``
-
-        :param extra: Extra attributes (driver specific). (optional)
-        :type extra: ``dict``
-
-        :rtype: :class:`Record`
-        """
-        r_json = {'name': name, 'record_type': type, 'content': data}
-        if extra is not None:
-            r_json.update(extra)
-        r_data = json.dumps({'record': r_json})
-        response = self.connection.request('/v1/domains/%s/records' % zone.id,
-                                           method='POST', data=r_data)
-        record = self._to_record(response.object, zone=zone)
-        return record
-
-    def update_record(self, record, name, type, data, extra=None):
-        """
-        Update an existing record.
-
-        :param record: Record to update.
-        :type  record: :class:`Record`
-
-        :param name: Record name without the domain name (e.g. www).
-                     Note: If you want to create a record for a base domain
-                     name, you should specify empty string ('') for this
-                     argument.
-        :type  name: ``str``
-
-        :param type: DNS record type (A, AAAA, ...).
-        :type  type: :class:`RecordType`
-
-        :param data: Data for the record (depends on the record type).
-        :type  data: ``str``
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type  extra: ``dict``
-
-        :rtype: :class:`Record`
-        """
-        zone = record.zone
-        r_json = {'name': name, 'content': data}
-        if extra is not None:
-            r_json.update(extra)
-        r_data = json.dumps({'record': r_json})
-        response = self.connection.request('/v1/domains/%s/records/%s' %
-                                           (zone.id, record.id),
-                                           method='PUT', data=r_data)
-        record = self._to_record(response.object, zone=zone)
-        return record
-
-    def delete_zone(self, zone):
-        """
-        Delete a zone.
-
-        Note: This will delete all the records belonging to this zone.
-
-        :param zone: Zone to delete.
-        :type  zone: :class:`Zone`
-
-        :rtype: ``bool``
-        """
-        self.connection.request('/v1/domains/%s' % zone.id, method='DELETE')
-        return True
-
-    def delete_record(self, record):
-        """
-        Delete a record.
-
-        :param record: Record to delete.
-        :type  record: :class:`Record`
-
-        :rtype: ``bool``
-        """
-        zone_id = record.zone.id
-        self.connection.request('/v1/domains/%s/records/%s' % (zone_id,
-                                record.id), method='DELETE')
-        return True
-
-    def _to_zones(self, data):
-        zones = []
-        for zone in data:
-            _zone = self._to_zone(zone)
-            zones.append(_zone)
-
-        return zones
-
-    def _to_zone(self, data):
-        domain = data.get('domain')
-        id = domain.get('id')
-        name = domain.get('name')
-        extra = {'registrant_id': domain.get('registrant_id'),
-                 'user_id': domain.get('user_id'),
-                 'unicode_name': domain.get('unicode_name'),
-                 'token': domain.get('token'),
-                 'state': domain.get('state'),
-                 'language': domain.get('language'),
-                 'lockable': domain.get('lockable'),
-                 'auto_renew': domain.get('auto_renew'),
-                 'whois_protected': domain.get('whois_protected'),
-                 'record_count': domain.get('record_count'),
-                 'service_count': domain.get('service_count'),
-                 'expires_on': domain.get('expires_on'),
-                 'created_at': domain.get('created_at'),
-                 'updated_at': domain.get('updated_at')}
-
-        # All zones are primary by design
-        type = 'master'
-
-        return Zone(id=id, domain=name, type=type, ttl=DEFAULT_ZONE_TTL,
-                    driver=self, extra=extra)
-
-    def _to_records(self, data, zone):
-        records = []
-        for item in data:
-            record = self._to_record(item, zone=zone)
-            records.append(record)
-        return records
-
-    def _to_record(self, data, zone_id=None, zone=None):
-        if not zone:  # We need zone_id or zone
-            zone = self.get_zone(zone_id)
-        record = data.get('record')
-        id = record.get('id')
-        name = record.get('name')
-        type = record.get('record_type')
-        data = record.get('content')
-        extra = {'ttl': record.get('ttl'),
-                 'created_at': record.get('created_at'),
-                 'updated_at': record.get('updated_at'),
-                 'domain_id': record.get('domain_id'),
-                 'priority': record.get('prio')}
-        return Record(id=id, name=name, type=type, data=data, zone=zone,
-                      driver=self, ttl=record.get('ttl', None), extra=extra)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/dummy.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/dummy.py b/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/dummy.py
deleted file mode 100644
index 5a1f4da..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/dummy.py
+++ /dev/null
@@ -1,218 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from libcloud.dns.base import DNSDriver, Zone, Record
-from libcloud.dns.types import RecordType
-from libcloud.dns.types import ZoneDoesNotExistError, ZoneAlreadyExistsError
-from libcloud.dns.types import RecordDoesNotExistError
-from libcloud.dns.types import RecordAlreadyExistsError
-
-
-class DummyDNSDriver(DNSDriver):
-    """
-    Dummy DNS driver.
-
-    >>> from libcloud.dns.drivers.dummy import DummyDNSDriver
-    >>> driver = DummyDNSDriver('key', 'secret')
-    >>> driver.name
-    'Dummy DNS Provider'
-    """
-
-    name = 'Dummy DNS Provider'
-    website = 'http://example.com'
-
-    def __init__(self, api_key, api_secret):
-        """
-        :param    api_key:    API key or username to used (required)
-        :type     api_key:    ``str``
-
-        :param    api_secret: Secret password to be used (required)
-        :type     api_secret: ``str``
-
-        :rtype: ``None``
-        """
-        self._zones = {}
-
-    def list_record_types(self):
-        """
-        >>> driver = DummyDNSDriver('key', 'secret')
-        >>> driver.list_record_types()
-        ['A']
-
-        @inherits: :class:`DNSDriver.list_record_types`
-        """
-        return [RecordType.A]
-
-    def list_zones(self):
-        """
-        >>> driver = DummyDNSDriver('key', 'secret')
-        >>> driver.list_zones()
-        []
-
-        @inherits: :class:`DNSDriver.list_zones`
-        """
-
-        return [zone['zone'] for zone in list(self._zones.values())]
-
-    def list_records(self, zone):
-        """
-        >>> driver = DummyDNSDriver('key', 'secret')
-        >>> zone = driver.create_zone(domain='apache.org', type='master',
-        ...                           ttl=100)
-        >>> list(zone.list_records())
-        []
-        >>> record = driver.create_record(name='libcloud', zone=zone,
-        ...                               type=RecordType.A, data='127.0.0.1')
-        >>> list(zone.list_records()) #doctest: +ELLIPSIS
-        [<Record: zone=apache.org, name=libcloud, type=A...>]
-        """
-        return self._zones[zone.id]['records'].values()
-
-    def get_zone(self, zone_id):
-        """
-        >>> driver = DummyDNSDriver('key', 'secret')
-        >>> driver.get_zone(zone_id='foobar')
-        ... #doctest: +IGNORE_EXCEPTION_DETAIL
-        Traceback (most recent call last):
-        ZoneDoesNotExistError:
-
-        @inherits: :class:`DNSDriver.get_zone`
-        """
-
-        if zone_id not in self._zones:
-            raise ZoneDoesNotExistError(driver=self, value=None,
-                                        zone_id=zone_id)
-
-        return self._zones[zone_id]['zone']
-
-    def get_record(self, zone_id, record_id):
-        """
-        >>> driver = DummyDNSDriver('key', 'secret')
-        >>> driver.get_record(zone_id='doesnotexist', record_id='exists')
-        ... #doctest: +IGNORE_EXCEPTION_DETAIL
-        Traceback (most recent call last):
-        ZoneDoesNotExistError:
-
-        @inherits: :class:`DNSDriver.get_record`
-        """
-
-        self.get_zone(zone_id=zone_id)
-        zone_records = self._zones[zone_id]['records']
-
-        if record_id not in zone_records:
-            raise RecordDoesNotExistError(record_id=record_id, value=None,
-                                          driver=self)
-
-        return zone_records[record_id]
-
-    def create_zone(self, domain, type='master', ttl=None, extra=None):
-        """
-        >>> driver = DummyDNSDriver('key', 'secret')
-        >>> zone = driver.create_zone(domain='apache.org', type='master',
-        ...                           ttl=100)
-        >>> zone
-        <Zone: domain=apache.org, ttl=100, provider=Dummy DNS Provider ...>
-        >>> zone = driver.create_zone(domain='apache.org', type='master',
-        ...                           ttl=100)
-        ... #doctest: +IGNORE_EXCEPTION_DETAIL
-        Traceback (most recent call last):
-        ZoneAlreadyExistsError:
-
-        @inherits: :class:`DNSDriver.create_zone`
-        """
-
-        id = 'id-%s' % (domain)
-
-        if id in self._zones:
-            raise ZoneAlreadyExistsError(zone_id=id, value=None, driver=self)
-
-        zone = Zone(id=id, domain=domain, type=type, ttl=ttl, extra={},
-                    driver=self)
-        self._zones[id] = {'zone': zone,
-                           'records': {}}
-        return zone
-
-    def create_record(self, name, zone, type, data, extra=None):
-        """
-        >>> driver = DummyDNSDriver('key', 'secret')
-        >>> zone = driver.create_zone(domain='apache.org', type='master',
-        ...                           ttl=100)
-        >>> record = driver.create_record(name='libcloud', zone=zone,
-        ...                               type=RecordType.A, data='127.0.0.1')
-        >>> record #doctest: +ELLIPSIS
-        <Record: zone=apache.org, name=libcloud, type=A, data=127.0.0.1...>
-        >>> record = driver.create_record(name='libcloud', zone=zone,
-        ...                               type=RecordType.A, data='127.0.0.1')
-        ... #doctest: +IGNORE_EXCEPTION_DETAIL
-        Traceback (most recent call last):
-        RecordAlreadyExistsError:
-
-        @inherits: :class:`DNSDriver.create_record`
-        """
-        id = 'id-%s' % (name)
-
-        zone = self.get_zone(zone_id=zone.id)
-
-        if id in self._zones[zone.id]['records']:
-            raise RecordAlreadyExistsError(record_id=id, value=None,
-                                           driver=self)
-
-        record = Record(id=id, name=name, type=type, data=data, extra=extra,
-                        zone=zone, driver=self)
-        self._zones[zone.id]['records'][id] = record
-        return record
-
-    def delete_zone(self, zone):
-        """
-        >>> driver = DummyDNSDriver('key', 'secret')
-        >>> zone = driver.create_zone(domain='apache.org', type='master',
-        ...                           ttl=100)
-        >>> driver.delete_zone(zone)
-        True
-        >>> driver.delete_zone(zone) #doctest: +IGNORE_EXCEPTION_DETAIL
-        Traceback (most recent call last):
-        ZoneDoesNotExistError:
-
-        @inherits: :class:`DNSDriver.delete_zone`
-        """
-        self.get_zone(zone_id=zone.id)
-
-        del self._zones[zone.id]
-        return True
-
-    def delete_record(self, record):
-        """
-        >>> driver = DummyDNSDriver('key', 'secret')
-        >>> zone = driver.create_zone(domain='apache.org', type='master',
-        ...                           ttl=100)
-        >>> record = driver.create_record(name='libcloud', zone=zone,
-        ...                               type=RecordType.A, data='127.0.0.1')
-        >>> driver.delete_record(record)
-        True
-        >>> driver.delete_record(record) #doctest: +IGNORE_EXCEPTION_DETAIL
-        Traceback (most recent call last):
-        RecordDoesNotExistError:
-
-        @inherits: :class:`DNSDriver.delete_record`
-        """
-        self.get_record(zone_id=record.zone.id, record_id=record.id)
-
-        del self._zones[record.zone.id]['records'][record.id]
-        return True
-
-
-if __name__ == "__main__":
-    import doctest
-    doctest.testmod()

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/durabledns.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/durabledns.py b/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/durabledns.py
deleted file mode 100644
index 5d2fbe8..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/durabledns.py
+++ /dev/null
@@ -1,660 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-DurableDNS Driver
-"""
-import sys
-
-from libcloud.utils.py3 import httplib
-from libcloud.utils.py3 import ensure_string
-from libcloud.dns.types import Provider, RecordType
-from libcloud.dns.base import Record, Zone
-from libcloud.dns.base import DNSDriver
-from libcloud.dns.types import ZoneDoesNotExistError, ZoneAlreadyExistsError
-from libcloud.dns.types import RecordDoesNotExistError
-from xml.etree.ElementTree import tostring
-from libcloud.common.durabledns import DurableConnection, DurableResponse
-from libcloud.common.durabledns import DurableDNSException
-from libcloud.common.durabledns import _schema_builder as api_schema_builder
-from libcloud.common.durabledns import SCHEMA_BUILDER_MAP
-
-
-__all__ = [
-    'ZONE_EXTRA_PARAMS_DEFAULT_VALUES',
-    'RECORD_EXTRA_PARAMS_DEFAULT_VALUES',
-    'DEFAULT_TTL',
-    'DurableDNSResponse',
-    'DurableDNSConnection',
-    'DurableDNSDriver'
-]
-
-# This will be the default values for each extra attributes when are not
-# specified in the 'extra' parameter
-ZONE_EXTRA_PARAMS_DEFAULT_VALUES = {
-    'ns': 'ns1.durabledns.com.', 'mbox': 'support.durabledns.com',
-    'refresh': '28800', 'retry': 7200, 'expire': 604800, 'minimum': 82000,
-    'xfer': '', 'update_acl': ''
-}
-
-RECORD_EXTRA_PARAMS_DEFAULT_VALUES = {'aux': 0, 'ttl': 3600}
-
-DEFAULT_TTL = 3600
-
-
-class DurableDNSResponse(DurableResponse):
-    pass
-
-
-class DurableDNSConnection(DurableConnection):
-    responseCls = DurableDNSResponse
-
-
-class DurableDNSDriver(DNSDriver):
-    type = Provider.DURABLEDNS
-    name = 'DurableDNS'
-    website = 'https://durabledns.com'
-    connectionCls = DurableDNSConnection
-
-    RECORD_TYPE_MAP = {
-        RecordType.A: 'A',
-        RecordType.AAAA: 'AAAA',
-        RecordType.CNAME: 'CNAME',
-        RecordType.HINFO: 'HINFO',
-        RecordType.MX: 'MX',
-        RecordType.NS: 'NS',
-        RecordType.PTR: 'PTR',
-        RecordType.RP: 'RP',
-        RecordType.SRV: 'SRV',
-        RecordType.TXT: 'TXT'
-    }
-
-    def list_zones(self):
-        """
-        Return a list of zones.
-
-        :return: ``list`` of :class:`Zone`
-        """
-        schema_params = SCHEMA_BUILDER_MAP.get('list_zones')
-        attributes = schema_params.get('attributes')
-        schema = api_schema_builder(schema_params.get('urn_nid'),
-                                    schema_params.get('method'),
-                                    attributes)
-        params = {'apiuser': self.key, 'apikey': self.secret}
-        urn = schema.getchildren()[0]
-        for child in urn:
-            key = child.tag.split(':')[2]
-            if key in attributes:
-                child.text = str(params.get(key))
-        req_data = tostring(schema)
-        action = '/services/dns/listZones.php'
-        params = {}
-        headers = {"SOAPAction": "urn:listZoneswsdl#listZones"}
-        response = self.connection.request(action=action, params=params,
-                                           data=req_data, method="POST",
-                                           headers=headers)
-        # listZones method doens't return full data in zones as getZone
-        # method does.
-        zones = []
-        for data in response.objects:
-            zone = self.get_zone(data.get('id'))
-            zones.append(zone)
-        return zones
-
-    def list_records(self, zone):
-        """
-        Return a list of records for the provided zone.
-
-        :param zone: Zone to list records for.
-        :type zone: :class:`Zone`
-
-        :return: ``list`` of :class:`Record`
-        """
-        schema_params = SCHEMA_BUILDER_MAP.get('list_records')
-        attributes = schema_params.get('attributes')
-        schema = api_schema_builder(schema_params.get('urn_nid'),
-                                    schema_params.get('method'),
-                                    attributes)
-        params = {'apiuser': self.key, 'apikey': self.secret,
-                  'zonename': zone.id}
-        urn = schema.getchildren()[0]
-        for child in urn:
-            key = child.tag.split(':')[2]
-            if key in attributes:
-                child.text = str(params.get(key))
-        req_data = tostring(schema)
-        action = '/services/dns/listRecords.php?'
-        params = {}
-        headers = {"SOAPAction": "urn:listRecordswsdl#listRecords"}
-        try:
-            response = self.connection.request(action=action, params=params,
-                                               data=req_data, method="POST",
-                                               headers=headers)
-        except DurableDNSException:
-            e = sys.exc_info()[1]
-            if 'Zone does not exist' in e.message:
-                raise ZoneDoesNotExistError(zone_id=zone.id, driver=self,
-                                            value=e.message)
-            raise e
-
-        # listRecords method doens't return full data in records as getRecord
-        # method does.
-        records = []
-        for data in response.objects:
-            record = self.get_record(zone.id, data.get('id'))
-            records.append(record)
-
-        return records
-
-    def get_zone(self, zone_id):
-        """
-        Return a Zone instance.
-
-        :param zone_id: ID of the required zone
-        :type  zone_id: ``str``
-
-        :rtype: :class:`Zone`
-        """
-        schema_params = SCHEMA_BUILDER_MAP.get('get_zone')
-        attributes = schema_params.get('attributes')
-        schema = api_schema_builder(schema_params.get('urn_nid'),
-                                    schema_params.get('method'),
-                                    attributes)
-        params = {'apiuser': self.key, 'apikey': self.secret,
-                  'zonename': zone_id}
-        urn = schema.getchildren()[0]
-        for child in urn:
-            key = child.tag.split(':')[2]
-            if key in attributes:
-                child.text = str(params.get(key))
-        req_data = tostring(schema)
-        action = '/services/dns/getZone.php?'
-        params = {}
-        headers = {"SOAPAction": "urn:getZonewsdl#getZone"}
-        try:
-            response = self.connection.request(action=action, params=params,
-                                               data=req_data, method="POST",
-                                               headers=headers)
-        except DurableDNSException:
-            e = sys.exc_info()[1]
-            if 'Zone does not exist' in e.message:
-                raise ZoneDoesNotExistError(zone_id=zone_id, driver=self,
-                                            value=e.message)
-            raise e
-
-        zones = self._to_zones(response.objects)
-
-        return zones[0]
-
-    def get_record(self, zone_id, record_id):
-        """
-        Return a Record instance.
-
-        :param zone_id: ID of the required zone
-        :type  zone_id: ``str``
-
-        :param record_id: ID of the required record
-        :type  record_id: ``str``
-
-        :rtype: :class:`Record`
-        """
-        schema_params = SCHEMA_BUILDER_MAP.get('get_record')
-        attributes = schema_params.get('attributes')
-        schema = api_schema_builder(schema_params.get('urn_nid'),
-                                    schema_params.get('method'),
-                                    attributes)
-        params = {'apiuser': self.key, 'apikey': self.secret,
-                  'zonename': zone_id, 'recordid': record_id}
-        urn = schema.getchildren()[0]
-        for child in urn:
-            key = child.tag.split(':')[2]
-            if key in attributes:
-                child.text = str(params.get(key))
-        req_data = tostring(schema)
-        action = '/services/dns/getRecord.php?'
-        params = {}
-        headers = {"SOAPAction": "urn:getRecordwsdl#getRecord"}
-        try:
-            response = self.connection.request(action=action, params=params,
-                                               data=req_data, method="POST",
-                                               headers=headers)
-        except DurableDNSException:
-            e = sys.exc_info()[1]
-            if 'Zone does not exist' in e.message:
-                raise ZoneDoesNotExistError(zone_id=zone_id, driver=self,
-                                            value=e.message)
-            if 'Record does not exist' in e.message:
-                raise RecordDoesNotExistError(record_id=record_id, driver=self,
-                                              value=e.message)
-            raise e
-
-        zone = self.get_zone(zone_id)
-        record = self._to_record(response.objects[0], zone)
-        return record
-
-    def create_zone(self, domain, type='master', ttl=None, extra=None):
-        """
-        Create a new zone.
-
-        :param domain: Name of zone, followed by a dot (.) (e.g. example.com.)
-        :type  domain: ``str``
-
-        :param type: Zone type (Only master available). (optional)
-        :type  type: ``str``
-
-        :param ttl: TTL for new records. (optional)
-        :type  ttl: ``int``
-
-        :param extra: Extra attributes ('mbox', 'ns', 'minimum', 'refresh',
-                                        'expire', 'update_acl', 'xfer').
-                      (optional)
-        :type extra: ``dict``
-
-        :rtype: :class:`Zone`
-        """
-        if extra is None:
-            extra = ZONE_EXTRA_PARAMS_DEFAULT_VALUES
-        else:
-            extra_fields = ZONE_EXTRA_PARAMS_DEFAULT_VALUES.keys()
-            missing = set(extra_fields).difference(set(extra.keys()))
-            for field in missing:
-                extra[field] = ZONE_EXTRA_PARAMS_DEFAULT_VALUES.get(field)
-        schema_params = SCHEMA_BUILDER_MAP.get('create_zone')
-        attributes = schema_params.get('attributes')
-        schema = api_schema_builder(schema_params.get('urn_nid'),
-                                    schema_params.get('method'),
-                                    attributes)
-        params = {'apiuser': self.key, 'apikey': self.secret,
-                  'zonename': domain, 'ttl': ttl or DEFAULT_TTL}
-        params.update(extra)
-        urn = schema.getchildren()[0]
-        for child in urn:
-            key = child.tag.split(':')[2]
-            if key in attributes:
-                if isinstance(params.get(key), int):
-                    child.text = "%d"
-                else:
-                    child.text = "%s"
-        # We can't insert values directly in child.text because API raises
-        # and exception for values that need to be integers. And tostring
-        # method from ElementTree can't handle int values.
-        skel = ensure_string(tostring(schema))  # Deal with PY3
-        req_data = skel % (self.key, self.secret, domain, extra.get('ns'),
-                           extra.get('mbox'), extra.get('refresh'),
-                           extra.get('retry'), extra.get('expire'),
-                           extra.get('minimum'), ttl or DEFAULT_TTL,
-                           extra.get('xfer'), extra.get('update_acl'))
-        action = '/services/dns/createZone.php?'
-        params = {}
-        headers = {"SOAPAction": "urn:createZonewsdl#createZone"}
-        try:
-            self.connection.request(action=action, params=params,
-                                    data=req_data, method="POST",
-                                    headers=headers)
-        except DurableDNSException:
-            e = sys.exc_info()[1]
-            if 'Zone Already Exist' in e.message:
-                raise ZoneAlreadyExistsError(zone_id=domain, driver=self,
-                                             value=e.message)
-            raise e
-
-        zone = self.get_zone(domain)
-        return zone
-
-    def create_record(self, name, zone, type, data, extra=None):
-        """
-        Create a new record.
-
-        :param name: Record name without the domain name (e.g. www).
-                     Note: If you want to create a record for a base domain
-                     name, you should specify empty string ('') for this
-                     argument.
-        :type  name: ``str``
-
-        :param zone: Zone where the requested record is created.
-        :type  zone: :class:`Zone`
-
-        :param type: DNS record type (A, AAAA, ...).
-        :type  type: :class:`RecordType`
-
-        :param data: Data for the record (depends on the record type).
-        :type  data: ``str``
-
-        :param extra: Extra attributes (e.g. 'aux', 'ttl'). (optional)
-        :type extra: ``dict``
-
-        :rtype: :class:`Record`
-        """
-        if extra is None:
-            extra = RECORD_EXTRA_PARAMS_DEFAULT_VALUES
-        else:
-            if 'aux' not in extra:
-                extra['aux'] = RECORD_EXTRA_PARAMS_DEFAULT_VALUES.get('aux')
-            if 'ttl' not in extra:
-                extra['ttl'] = RECORD_EXTRA_PARAMS_DEFAULT_VALUES.get('ttl')
-        extra['ddns_enabled'] = 'N'
-        schema_params = SCHEMA_BUILDER_MAP.get('create_record')
-        attributes = schema_params.get('attributes')
-        schema = api_schema_builder(schema_params.get('urn_nid'),
-                                    schema_params.get('method'),
-                                    attributes)
-        params = {'apiuser': self.key, 'apikey': self.secret,
-                  'zonename': zone.id, 'name': name, 'type': type,
-                  'data': data}
-        params.update(extra)
-        urn = schema.getchildren()[0]
-        for child in urn:
-            key = child.tag.split(':')[2]
-            if key in attributes:
-                if isinstance(params.get(key), int):
-                    child.text = "%d"
-                else:
-                    child.text = "%s"
-        # We can't insert values directly in child.text because API raises
-        # and exception for values that need to be integers. And tostring
-        # method from ElementTree can't handle int values.
-        skel = ensure_string(tostring(schema))  # Deal with PY3
-        req_data = skel % (self.key, self.secret, zone.id, name, type, data,
-                           extra.get('aux'), extra.get('ttl'),
-                           extra.get('ddns_enabled'))
-        action = '/services/dns/createRecord.php?'
-        headers = {"SOAPAction": "urn:createRecordwsdl#createRecord"}
-        try:
-            response = self.connection.request(action=action, data=req_data,
-                                               method="POST", headers=headers)
-            objects = response.objects
-        except DurableDNSException:
-            e = sys.exc_info()[1]
-            # In DurableDNS is possible to create records with same data.
-            # Their ID's will be different but the API does not implement
-            # the RecordAlreadyExist exception. Only ZoneDoesNotExist will
-            # be handled.
-            if 'Zone does not exist' in e.message:
-                raise ZoneDoesNotExistError(zone_id=zone.id, driver=self,
-                                            value=e.message)
-            raise e
-
-        record_item = objects[0]
-        record_item['name'] = name
-        record_item['type'] = type
-        record_item['data'] = data
-        record_item['ttl'] = extra.get('ttl')
-        record_item['aux'] = extra.get('aux')
-
-        record = self._to_record(record_item, zone)
-        return record
-
-    def update_zone(self, zone, domain, type='master', ttl=None, extra=None):
-        """
-        Update en existing zone.
-
-        :param zone: Zone to update.
-        :type  zone: :class:`Zone`
-
-        :param domain: Name of zone, followed by a dot (.) (e.g. example.com.)
-        :type  domain: ``str``
-
-        :param type: Zone type (master / slave).
-        :type  type: ``str``
-
-        :param ttl: TTL for new records. (optional)
-        :type  ttl: ``int``
-
-        :param extra: Extra attributes ('ns', 'mbox', 'refresh', 'retry',
-                      'expire', 'minimum', 'xfer', 'update_acl'). (optional)
-        :type  extra: ``dict``
-
-        :rtype: :class:`Zone`
-        """
-        if ttl is None:
-            ttl = zone.ttl
-        if extra is None:
-            extra = zone.extra
-        else:
-            extra_fields = ZONE_EXTRA_PARAMS_DEFAULT_VALUES.keys()
-            missing = set(extra_fields).difference(set(extra.keys()))
-            for field in missing:
-                extra[field] = zone.extra.get(field)
-        schema_params = SCHEMA_BUILDER_MAP.get('update_zone')
-        attributes = schema_params.get('attributes')
-        schema = api_schema_builder(schema_params.get('urn_nid'),
-                                    schema_params.get('method'),
-                                    attributes)
-        params = {'apiuser': self.key, 'apikey': self.secret,
-                  'zonename': domain, 'ttl': ttl}
-        params.update(extra)
-        urn = schema.getchildren()[0]
-        for child in urn:
-            key = child.tag.split(':')[2]
-            if key in attributes:
-                if isinstance(params.get(key), int):
-                    child.text = "%d"
-                else:
-                    child.text = "%s"
-        # We can't insert values directly in child.text because API raises
-        # and exception for values that need to be integers. And tostring
-        # method from ElementTree can't handle int values.
-        skel = ensure_string(tostring(schema))  # Deal with PY3
-        req_data = skel % (self.key, self.secret, domain, extra['ns'],
-                           extra['mbox'], extra['refresh'], extra['retry'],
-                           extra['expire'], extra['minimum'], ttl,
-                           extra['xfer'], extra['update_acl'])
-        action = '/services/dns/updateZone.php?'
-        headers = {"SOAPAction": "urn:updateZonewsdl#updateZone"}
-        try:
-            self.connection.request(action=action,
-                                    data=req_data,
-                                    method="POST",
-                                    headers=headers)
-        except DurableDNSException:
-            e = sys.exc_info()[1]
-            if 'Zone does not exist' in e.message:
-                raise ZoneDoesNotExistError(zone_id=zone.id, driver=self,
-                                            value=e.message)
-            raise e
-
-        # After update the zone, serial number change. In order to have it
-        # updated, we need to get again the zone data.
-        zone = self.get_zone(zone.id)
-        return zone
-
-    def update_record(self, record, name, type, data, extra=None):
-        """
-        Update an existing record.
-
-        :param record: Record to update.
-        :type  record: :class:`Record`
-
-        :param name: Record name without the domain name (e.g. www).
-                     Note: If you want to create a record for a base domain
-                     name, you should specify empty string ('') for this
-                     argument.
-        :type  name: ``str``
-
-        :param type: DNS record type (A, AAAA, ...).
-        :type  type: :class:`RecordType`
-
-        :param data: Data for the record (depends on the record type).
-        :type  data: ``str``
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type  extra: ``dict``
-
-        :rtype: :class:`Record`
-        """
-        zone = record.zone
-        if extra is None:
-            extra = record.extra
-        else:
-            extra_fields = ['aux', 'ttl']
-            missing = set(extra_fields).difference(set(extra.keys()))
-            for field in missing:
-                extra[field] = record.extra.get(field)
-        extra['ddns_enabled'] = 'N'
-        schema_params = SCHEMA_BUILDER_MAP.get('update_record')
-        attributes = schema_params.get('attributes')
-        schema = api_schema_builder(schema_params.get('urn_nid'),
-                                    schema_params.get('method'),
-                                    attributes)
-        params = {'apiuser': self.key, 'apikey': self.secret,
-                  'zonename': zone.id, 'id': record.id, 'name': name,
-                  'data': data}
-        params.update(extra)
-        urn = schema.getchildren()[0]
-        for child in urn:
-            key = child.tag.split(':')[2]
-            if key in attributes:
-                if isinstance(params.get(key), int):
-                    child.text = "%d"
-                else:
-                    child.text = "%s"
-        # We can't insert values directly in child.text because API raises
-        # and exception for values that need to be integers. And tostring
-        # method from ElementTree can't handle int values.
-        skel = ensure_string(tostring(schema))  # Deal with PY3
-        req_data = skel % (self.key, self.secret, zone.id, record.id, name,
-                           extra.get('aux'), data, extra.get('ttl'),
-                           extra.get('ddns_enabled'))
-        action = '/services/dns/updateRecord.php?'
-        headers = {"SOAPAction": "urn:updateRecordwsdl#updateRecord"}
-        try:
-            self.connection.request(action=action,
-                                    data=req_data,
-                                    method="POST",
-                                    headers=headers)
-        except DurableDNSException:
-            e = sys.exc_info()[1]
-            if 'Zone does not exist' in e.message:
-                raise ZoneDoesNotExistError(zone_id=zone.id, driver=self,
-                                            value=e.message)
-            raise e
-
-        record_item = {}
-        record_item['id'] = record.id
-        record_item['name'] = name
-        record_item['type'] = type
-        record_item['data'] = data
-        record_item['ttl'] = extra.get('ttl')
-        record_item['aux'] = extra.get('aux')
-        record = self._to_record(record_item, zone)
-        return record
-
-    def delete_zone(self, zone):
-        """
-        Delete a zone.
-
-        Note: This will delete all the records belonging to this zone.
-
-        :param zone: Zone to delete.
-        :type  zone: :class:`Zone`
-
-        :rtype: ``bool``
-        """
-        schema_params = SCHEMA_BUILDER_MAP.get('delete_zone')
-        attributes = schema_params.get('attributes')
-        schema = api_schema_builder(schema_params.get('urn_nid'),
-                                    schema_params.get('method'),
-                                    attributes)
-        params = {'apiuser': self.key, 'apikey': self.secret,
-                  'zonename': zone.id}
-        urn = schema.getchildren()[0]
-        for child in urn:
-            key = child.tag.split(':')[2]
-            if key in attributes:
-                child.text = str(params.get(key))
-        req_data = tostring(schema)
-        action = '/services/dns/deleteZone.php?'
-        headers = {"SOAPAction": "urn:deleteZonewsdl#deleteZone"}
-        try:
-            response = self.connection.request(action=action,
-                                               data=req_data, method="POST",
-                                               headers=headers)
-        except DurableDNSException:
-            e = sys.exc_info()[1]
-            if 'Zone does not exist' in e.message:
-                raise ZoneDoesNotExistError(zone_id=zone.id, driver=self,
-                                            value=e.message)
-            raise e
-
-        return response.status in [httplib.OK]
-
-    def delete_record(self, record):
-        """
-        Delete a record.
-
-        :param record: Record to delete.
-        :type  record: :class:`Record`
-
-        :rtype: ``bool``
-        """
-        schema_params = SCHEMA_BUILDER_MAP.get('delete_record')
-        attributes = schema_params.get('attributes')
-        schema = api_schema_builder(schema_params.get('urn_nid'),
-                                    schema_params.get('method'),
-                                    attributes)
-        params = {'apiuser': self.key, 'apikey': self.secret,
-                  'zonename': record.zone.id, 'id': record.id}
-        urn = schema.getchildren()[0]
-        for child in urn:
-            key = child.tag.split(':')[2]
-            if key in attributes:
-                child.text = str(params.get(key))
-        req_data = tostring(schema)
-        action = '/services/dns/deleteRecord.php?'
-        headers = {"SOAPAction": "urn:deleteRecordwsdl#deleteRecord"}
-        try:
-            response = self.connection.request(action=action, data=req_data,
-                                               headers=headers, method="POST")
-        except DurableDNSException:
-            e = sys.exc_info()[1]
-            if 'Record does not exists' in e.message:
-                raise RecordDoesNotExistError(record_id=record.id, driver=self,
-                                              value=e.message)
-            if 'Zone does not exist' in e.message:
-                raise ZoneDoesNotExistError(zone_id=record.zone.id,
-                                            driver=self, value=e.message)
-            raise e
-
-        return response.status in [httplib.OK]
-
-    def _to_zone(self, item):
-        extra = item.get('extra')
-        # DurableDNS does not return information about zone type. This will be
-        # set as master by default.
-        zone = Zone(id=item.get('id'), type='master', domain=item.get('id'),
-                    ttl=item.get('ttl'), driver=self, extra=extra)
-
-        return zone
-
-    def _to_zones(self, items):
-        zones = []
-        for item in items:
-            zones.append(self._to_zone(item))
-
-        return zones
-
-    def _to_record(self, item, zone=None):
-        extra = {'aux': int(item.get('aux')), 'ttl': int(item.get('ttl'))}
-        record = Record(id=item.get('id'), type=item.get('type'), zone=zone,
-                        name=item.get('name'), data=item.get('data'),
-                        driver=self, ttl=item.get('ttl', None), extra=extra)
-
-        return record
-
-    def _to_records(self, items, zone=None):
-        records = []
-        for item in items:
-            records.append(self._to_record(item, zone))
-
-        return records

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/gandi.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/gandi.py b/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/gandi.py
deleted file mode 100644
index 2014034..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/gandi.py
+++ /dev/null
@@ -1,279 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from __future__ import with_statement
-
-__all__ = [
-    'GandiDNSDriver'
-]
-
-from libcloud.common.gandi import BaseGandiDriver, GandiConnection
-from libcloud.common.gandi import GandiResponse
-from libcloud.dns.types import Provider, RecordType
-from libcloud.dns.types import RecordError
-from libcloud.dns.types import ZoneDoesNotExistError, RecordDoesNotExistError
-from libcloud.dns.base import DNSDriver, Zone, Record
-
-
-TTL_MIN = 30
-TTL_MAX = 2592000  # 30 days
-
-
-class NewZoneVersion(object):
-    """
-    Changes to a zone in the Gandi DNS service need to be wrapped in a new
-    version object. The changes are made to the new version, then that
-    version is made active.
-
-    In effect, this is a transaction.
-
-    Any calls made inside this context manager will be applied to a new version
-    id. If your changes are successful (and only if they are successful) they
-    are activated.
-    """
-
-    def __init__(self, driver, zone):
-        self.driver = driver
-        self.connection = driver.connection
-        self.zone = zone
-
-    def __enter__(self):
-        zid = int(self.zone.id)
-        self.connection.set_context({'zone_id': self.zone.id})
-        vid = self.connection.request('domain.zone.version.new', zid).object
-        self.vid = vid
-        return vid
-
-    def __exit__(self, type, value, traceback):
-        if not traceback:
-            zid = int(self.zone.id)
-            con = self.connection
-            con.set_context({'zone_id': self.zone.id})
-            con.request('domain.zone.version.set', zid, self.vid).object
-
-
-class GandiDNSResponse(GandiResponse):
-    exceptions = {
-        581042: ZoneDoesNotExistError,
-    }
-
-
-class GandiDNSConnection(GandiConnection):
-    responseCls = GandiDNSResponse
-
-
-class GandiDNSDriver(BaseGandiDriver, DNSDriver):
-    """
-    API reference can be found at:
-
-    http://doc.rpc.gandi.net/domain/reference.html
-    """
-
-    type = Provider.GANDI
-    name = 'Gandi DNS'
-    website = 'http://www.gandi.net/domain'
-
-    connectionCls = GandiDNSConnection
-
-    RECORD_TYPE_MAP = {
-        RecordType.A: 'A',
-        RecordType.AAAA: 'AAAA',
-        RecordType.CNAME: 'CNAME',
-        RecordType.LOC: 'LOC',
-        RecordType.MX: 'MX',
-        RecordType.NS: 'NS',
-        RecordType.SPF: 'SPF',
-        RecordType.SRV: 'SRV',
-        RecordType.TXT: 'TXT',
-        RecordType.WKS: 'WKS',
-    }
-
-    def _to_zone(self, zone):
-        return Zone(
-            id=str(zone['id']),
-            domain=zone['name'],
-            type='master',
-            ttl=0,
-            driver=self,
-            extra={}
-        )
-
-    def _to_zones(self, zones):
-        ret = []
-        for z in zones:
-            ret.append(self._to_zone(z))
-        return ret
-
-    def list_zones(self):
-        zones = self.connection.request('domain.zone.list')
-        return self._to_zones(zones.object)
-
-    def get_zone(self, zone_id):
-        zid = int(zone_id)
-        self.connection.set_context({'zone_id': zone_id})
-        zone = self.connection.request('domain.zone.info', zid)
-        return self._to_zone(zone.object)
-
-    def create_zone(self, domain, type='master', ttl=None, extra=None):
-        params = {
-            'name': domain,
-        }
-        info = self.connection.request('domain.zone.create', params)
-        return self._to_zone(info.object)
-
-    def update_zone(self, zone, domain=None, type=None, ttl=None, extra=None):
-        zid = int(zone.id)
-        params = {'name': domain}
-        self.connection.set_context({'zone_id': zone.id})
-        zone = self.connection.request('domain.zone.update', zid, params)
-        return self._to_zone(zone.object)
-
-    def delete_zone(self, zone):
-        zid = int(zone.id)
-        self.connection.set_context({'zone_id': zone.id})
-        res = self.connection.request('domain.zone.delete', zid)
-        return res.object
-
-    def _to_record(self, record, zone):
-        extra = {'ttl': int(record['ttl'])}
-        value = record['value']
-        if record['type'] == 'MX':
-            # Record is in the following form:
-            # <priority> <value>
-            # e.g. 15 aspmx.l.google.com
-            split = record['value'].split(' ')
-            extra['priority'] = int(split[0])
-            value = split[1]
-        return Record(
-            id='%s:%s' % (record['type'], record['name']),
-            name=record['name'],
-            type=self._string_to_record_type(record['type']),
-            data=value,
-            zone=zone,
-            driver=self,
-            ttl=record['ttl'],
-            extra=extra)
-
-    def _to_records(self, records, zone):
-        retval = []
-        for r in records:
-            retval.append(self._to_record(r, zone))
-        return retval
-
-    def list_records(self, zone):
-        zid = int(zone.id)
-        self.connection.set_context({'zone_id': zone.id})
-        records = self.connection.request('domain.zone.record.list', zid, 0)
-        return self._to_records(records.object, zone)
-
-    def get_record(self, zone_id, record_id):
-        zid = int(zone_id)
-        record_type, name = record_id.split(':', 1)
-        filter_opts = {
-            'name': name,
-            'type': record_type
-        }
-        self.connection.set_context({'zone_id': zone_id})
-        records = self.connection.request('domain.zone.record.list',
-                                          zid, 0, filter_opts).object
-
-        if len(records) == 0:
-            raise RecordDoesNotExistError(value='', driver=self,
-                                          record_id=record_id)
-
-        return self._to_record(records[0], self.get_zone(zone_id))
-
-    def _validate_record(self, record_id, name, record_type, data, extra):
-        if len(data) > 1024:
-            raise RecordError('Record data must be <= 1024 characters',
-                              driver=self, record_id=record_id)
-        if extra and 'ttl' in extra:
-            if extra['ttl'] < TTL_MIN:
-                raise RecordError('TTL must be at least 30 seconds',
-                                  driver=self, record_id=record_id)
-            if extra['ttl'] > TTL_MAX:
-                raise RecordError('TTL must not excdeed 30 days',
-                                  driver=self, record_id=record_id)
-
-    def create_record(self, name, zone, type, data, extra=None):
-        self._validate_record(None, name, type, data, extra)
-
-        zid = int(zone.id)
-
-        create = {
-            'name': name,
-            'type': self.RECORD_TYPE_MAP[type],
-            'value': data
-        }
-
-        if 'ttl' in extra:
-            create['ttl'] = extra['ttl']
-
-        with NewZoneVersion(self, zone) as vid:
-            con = self.connection
-            con.set_context({'zone_id': zone.id})
-            rec = con.request('domain.zone.record.add',
-                              zid, vid, create).object
-
-        return self._to_record(rec, zone)
-
-    def update_record(self, record, name, type, data, extra):
-        self._validate_record(record.id, name, type, data, extra)
-
-        filter_opts = {
-            'name': record.name,
-            'type': self.RECORD_TYPE_MAP[record.type]
-        }
-
-        update = {
-            'name': name,
-            'type': self.RECORD_TYPE_MAP[type],
-            'value': data
-        }
-
-        if 'ttl' in extra:
-            update['ttl'] = extra['ttl']
-
-        zid = int(record.zone.id)
-
-        with NewZoneVersion(self, record.zone) as vid:
-            con = self.connection
-            con.set_context({'zone_id': record.zone.id})
-            con.request('domain.zone.record.delete',
-                        zid, vid, filter_opts)
-            res = con.request('domain.zone.record.add',
-                              zid, vid, update).object
-
-        return self._to_record(res, record.zone)
-
-    def delete_record(self, record):
-        zid = int(record.zone.id)
-
-        filter_opts = {
-            'name': record.name,
-            'type': self.RECORD_TYPE_MAP[record.type]
-        }
-
-        with NewZoneVersion(self, record.zone) as vid:
-            con = self.connection
-            con.set_context({'zone_id': record.zone.id})
-            count = con.request('domain.zone.record.delete',
-                                zid, vid, filter_opts).object
-
-        if count == 1:
-            return True
-
-        raise RecordDoesNotExistError(value='No such record', driver=self,
-                                      record_id=record.id)


[32/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/cloudstack.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/cloudstack.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/cloudstack.py
deleted file mode 100644
index 387e1c7..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/cloudstack.py
+++ /dev/null
@@ -1,4754 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from __future__ import with_statement
-
-import sys
-import base64
-import warnings
-
-from libcloud.utils.py3 import b
-from libcloud.utils.py3 import urlparse
-
-from libcloud.compute.providers import Provider
-from libcloud.common.cloudstack import CloudStackDriverMixIn
-from libcloud.compute.base import Node, NodeDriver, NodeImage, NodeLocation
-from libcloud.compute.base import NodeSize, StorageVolume, VolumeSnapshot
-from libcloud.compute.base import KeyPair
-from libcloud.compute.types import NodeState, LibcloudError
-from libcloud.compute.types import KeyPairDoesNotExistError, StorageVolumeState
-from libcloud.utils.networking import is_private_subnet
-
-
-# Utility functions
-def transform_int_or_unlimited(value):
-    try:
-        return int(value)
-    except ValueError:
-        e = sys.exc_info()[1]
-
-        if str(value).lower() == 'unlimited':
-            return -1
-
-        raise e
-
-
-"""
-Define the extra dictionary for specific resources
-"""
-RESOURCE_EXTRA_ATTRIBUTES_MAP = {
-    'network': {
-        'broadcast_domain_type': {
-            'key_name': 'broadcastdomaintype',
-            'transform_func': str
-        },
-        'traffic_type': {
-            'key_name': 'traffictype',
-            'transform_func': str
-        },
-        'zone_name': {
-            'key_name': 'zonename',
-            'transform_func': str
-        },
-        'network_offering_name': {
-            'key_name': 'networkofferingname',
-            'transform_func': str
-        },
-        'network_offeringdisplay_text': {
-            'key_name': 'networkofferingdisplaytext',
-            'transform_func': str
-        },
-        'network_offering_availability': {
-            'key_name': 'networkofferingavailability',
-            'transform_func': str
-        },
-        'is_system': {
-            'key_name': 'issystem',
-            'transform_func': str
-        },
-        'state': {
-            'key_name': 'state',
-            'transform_func': str
-        },
-        'dns1': {
-            'key_name': 'dns1',
-            'transform_func': str
-        },
-        'dns2': {
-            'key_name': 'dns2',
-            'transform_func': str
-        },
-        'type': {
-            'key_name': 'type',
-            'transform_func': str
-        },
-        'acl_type': {
-            'key_name': 'acltype',
-            'transform_func': str
-        },
-        'subdomain_access': {
-            'key_name': 'subdomainaccess',
-            'transform_func': str
-        },
-        'network_domain': {
-            'key_name': 'networkdomain',
-            'transform_func': str
-        },
-        'physical_network_id': {
-            'key_name': 'physicalnetworkid',
-            'transform_func': str
-        },
-        'can_use_for_deploy': {
-            'key_name': 'canusefordeploy',
-            'transform_func': str
-        },
-        'gateway': {
-            'key_name': 'gateway',
-            'transform_func': str
-        },
-        'netmask': {
-            'key_name': 'netmask',
-            'transform_func': str
-        },
-        'vpc_id': {
-            'key_name': 'vpcid',
-            'transform_func': str
-        },
-        'project_id': {
-            'key_name': 'projectid',
-            'transform_func': str
-        }
-    },
-    'node': {
-        'haenable': {
-            'key_name': 'haenable',
-            'transform_func': str
-        },
-        'zone_id': {
-            'key_name': 'zoneid',
-            'transform_func': str
-        },
-        'zone_name': {
-            'key_name': 'zonename',
-            'transform_func': str
-        },
-        'key_name': {
-            'key_name': 'keypair',
-            'transform_func': str
-        },
-        'password': {
-            'key_name': 'password',
-            'transform_func': str
-        },
-        'image_id': {
-            'key_name': 'templateid',
-            'transform_func': str
-        },
-        'image_name': {
-            'key_name': 'templatename',
-            'transform_func': str
-        },
-        'template_display_text': {
-            'key_name': 'templatdisplaytext',
-            'transform_func': str
-        },
-        'password_enabled': {
-            'key_name': 'passwordenabled',
-            'transform_func': str
-        },
-        'size_id': {
-            'key_name': 'serviceofferingid',
-            'transform_func': str
-        },
-        'size_name': {
-            'key_name': 'serviceofferingname',
-            'transform_func': str
-        },
-        'root_device_id': {
-            'key_name': 'rootdeviceid',
-            'transform_func': str
-        },
-        'root_device_type': {
-            'key_name': 'rootdevicetype',
-            'transform_func': str
-        },
-        'hypervisor': {
-            'key_name': 'hypervisor',
-            'transform_func': str
-        },
-        'project': {
-            'key_name': 'project',
-            'transform_func': str
-        },
-        'project_id': {
-            'key_name': 'projectid',
-            'transform_func': str
-        },
-        'nics:': {
-            'key_name': 'nic',
-            'transform_func': list
-        }
-    },
-    'volume': {
-        'created': {
-            'key_name': 'created',
-            'transform_func': str
-        },
-        'device_id': {
-            'key_name': 'deviceid',
-            'transform_func': transform_int_or_unlimited
-        },
-        'instance_id': {
-            'key_name': 'virtualmachineid',
-            'transform_func': str
-        },
-        'serviceoffering_id': {
-            'key_name': 'serviceofferingid',
-            'transform_func': str
-        },
-        'state': {
-            'key_name': 'state',
-            'transform_func': str
-        },
-        'volume_type': {
-            'key_name': 'type',
-            'transform_func': str
-        },
-        'zone_id': {
-            'key_name': 'zoneid',
-            'transform_func': str
-        },
-        'zone_name': {
-            'key_name': 'zonename',
-            'transform_func': str
-        }
-    },
-    'vpc': {
-        'created': {
-            'key_name': 'created',
-            'transform_func': str
-        },
-        'domain': {
-            'key_name': 'domain',
-            'transform_func': str
-        },
-        'domain_id': {
-            'key_name': 'domainid',
-            'transform_func': transform_int_or_unlimited
-        },
-        'network_domain': {
-            'key_name': 'networkdomain',
-            'transform_func': str
-        },
-        'state': {
-            'key_name': 'state',
-            'transform_func': str
-        },
-        'vpc_offering_id': {
-            'key_name': 'vpcofferingid',
-            'transform_func': str
-        },
-        'zone_name': {
-            'key_name': 'zonename',
-            'transform_func': str
-        },
-        'zone_id': {
-            'key_name': 'zoneid',
-            'transform_func': str
-        }
-    },
-    'project': {
-        'account': {'key_name': 'account', 'transform_func': str},
-        'cpuavailable': {'key_name': 'cpuavailable',
-                         'transform_func': transform_int_or_unlimited},
-        'cpulimit': {'key_name': 'cpulimit',
-                     'transform_func': transform_int_or_unlimited},
-        'cputotal': {'key_name': 'cputotal',
-                     'transform_func': transform_int_or_unlimited},
-        'domain': {'key_name': 'domain', 'transform_func': str},
-        'domainid': {'key_name': 'domainid', 'transform_func': str},
-        'ipavailable': {'key_name': 'ipavailable',
-                        'transform_func': transform_int_or_unlimited},
-        'iplimit': {'key_name': 'iplimit',
-                    'transform_func': transform_int_or_unlimited},
-        'iptotal': {'key_name': 'iptotal',
-                    'transform_func': transform_int_or_unlimited},
-        'memoryavailable': {'key_name': 'memoryavailable',
-                            'transform_func': transform_int_or_unlimited},
-        'memorylimit': {'key_name': 'memorylimit',
-                        'transform_func': transform_int_or_unlimited},
-        'memorytotal': {'key_name': 'memorytotal',
-                        'transform_func': transform_int_or_unlimited},
-        'networkavailable': {'key_name': 'networkavailable',
-                             'transform_func': transform_int_or_unlimited},
-        'networklimit': {'key_name': 'networklimit',
-                         'transform_func': transform_int_or_unlimited},
-        'networktotal': {'key_name': 'networktotal',
-                         'transform_func': transform_int_or_unlimited},
-        'primarystorageavailable': {
-            'key_name': 'primarystorageavailable',
-            'transform_func': transform_int_or_unlimited},
-        'primarystoragelimit': {'key_name': 'primarystoragelimit',
-                                'transform_func': transform_int_or_unlimited},
-        'primarystoragetotal': {'key_name': 'primarystoragetotal',
-                                'transform_func': transform_int_or_unlimited},
-        'secondarystorageavailable': {
-            'key_name': 'secondarystorageavailable',
-            'transform_func': transform_int_or_unlimited},
-        'secondarystoragelimit': {
-            'key_name': 'secondarystoragelimit',
-            'transform_func': transform_int_or_unlimited},
-        'secondarystoragetotal': {
-            'key_name': 'secondarystoragetotal',
-            'transform_func': transform_int_or_unlimited},
-        'snapshotavailable': {'key_name': 'snapshotavailable',
-                              'transform_func': transform_int_or_unlimited},
-        'snapshotlimit': {'key_name': 'snapshotlimit',
-                          'transform_func': transform_int_or_unlimited},
-        'snapshottotal': {'key_name': 'snapshottotal',
-                          'transform_func': transform_int_or_unlimited},
-        'state': {'key_name': 'state', 'transform_func': str},
-        'tags': {'key_name': 'tags', 'transform_func': str},
-        'templateavailable': {'key_name': 'templateavailable',
-                              'transform_func': transform_int_or_unlimited},
-        'templatelimit': {'key_name': 'templatelimit',
-                          'transform_func': transform_int_or_unlimited},
-        'templatetotal': {'key_name': 'templatetotal',
-                          'transform_func': transform_int_or_unlimited},
-        'vmavailable': {'key_name': 'vmavailable',
-                        'transform_func': transform_int_or_unlimited},
-        'vmlimit': {'key_name': 'vmlimit',
-                    'transform_func': transform_int_or_unlimited},
-        'vmrunning': {'key_name': 'vmrunning',
-                      'transform_func': transform_int_or_unlimited},
-        'vmtotal': {'key_name': 'vmtotal',
-                    'transform_func': transform_int_or_unlimited},
-        'volumeavailable': {'key_name': 'volumeavailable',
-                            'transform_func': transform_int_or_unlimited},
-        'volumelimit': {'key_name': 'volumelimit',
-                        'transform_func': transform_int_or_unlimited},
-        'volumetotal': {'key_name': 'volumetotal',
-                        'transform_func': transform_int_or_unlimited},
-        'vpcavailable': {'key_name': 'vpcavailable',
-                         'transform_func': transform_int_or_unlimited},
-        'vpclimit': {'key_name': 'vpclimit',
-                     'transform_func': transform_int_or_unlimited},
-        'vpctotal': {'key_name': 'vpctotal',
-                     'transform_func': transform_int_or_unlimited}
-    },
-    'nic': {
-        'secondary_ip': {
-            'key_name': 'secondaryip',
-            'transform_func': list
-        }
-    },
-    'vpngateway': {
-        'for_display': {
-            'key_name': 'fordisplay',
-            'transform_func': str
-        },
-        'project': {
-            'key_name': 'project',
-            'transform_func': str
-        },
-        'project_id': {
-            'key_name': 'projectid',
-            'transform_func': str
-        },
-        'removed': {
-            'key_name': 'removed',
-            'transform_func': str
-        }
-    },
-    'vpncustomergateway': {
-        'account': {
-            'key_name': 'account',
-            'transform_func': str
-        },
-        'domain': {
-            'key_name': 'domain',
-            'transform_func': str
-        },
-        'domain_id': {
-            'key_name': 'domainid',
-            'transform_func': str
-        },
-        'dpd': {
-            'key_name': 'dpd',
-            'transform_func': bool
-        },
-        'esp_lifetime': {
-            'key_name': 'esplifetime',
-            'transform_func': transform_int_or_unlimited
-        },
-        'ike_lifetime': {
-            'key_name': 'ikelifetime',
-            'transform_func': transform_int_or_unlimited
-        },
-        'name': {
-            'key_name': 'name',
-            'transform_func': str
-        }
-    },
-    'vpnconnection': {
-        'account': {
-            'key_name': 'account',
-            'transform_func': str
-        },
-        'domain': {
-            'key_name': 'domain',
-            'transform_func': str
-        },
-        'domain_id': {
-            'key_name': 'domainid',
-            'transform_func': str
-        },
-        'for_display': {
-            'key_name': 'fordisplay',
-            'transform_func': str
-        },
-        'project': {
-            'key_name': 'project',
-            'transform_func': str
-        },
-        'project_id': {
-            'key_name': 'projectid',
-            'transform_func': str
-        }
-    }
-}
-
-
-class CloudStackNode(Node):
-    """
-    Subclass of Node so we can expose our extension methods.
-    """
-
-    def ex_allocate_public_ip(self):
-        """
-        Allocate a public IP and bind it to this node.
-        """
-        return self.driver.ex_allocate_public_ip(self)
-
-    def ex_release_public_ip(self, address):
-        """
-        Release a public IP that this node holds.
-        """
-        return self.driver.ex_release_public_ip(self, address)
-
-    def ex_create_ip_forwarding_rule(self, address, protocol,
-                                     start_port, end_port=None):
-        """
-        Add a NAT/firewall forwarding rule for a port or ports.
-        """
-        return self.driver.ex_create_ip_forwarding_rule(node=self,
-                                                        address=address,
-                                                        protocol=protocol,
-                                                        start_port=start_port,
-                                                        end_port=end_port)
-
-    def ex_create_port_forwarding_rule(self, address,
-                                       private_port, public_port,
-                                       protocol,
-                                       public_end_port=None,
-                                       private_end_port=None,
-                                       openfirewall=True):
-        """
-        Add a port forwarding rule for port or ports.
-        """
-        return self.driver.ex_create_port_forwarding_rule(
-            node=self, address=address, private_port=private_port,
-            public_port=public_port, protocol=protocol,
-            public_end_port=public_end_port, private_end_port=private_end_port,
-            openfirewall=openfirewall)
-
-    def ex_delete_ip_forwarding_rule(self, rule):
-        """
-        Delete a port forwarding rule.
-        """
-        return self.driver.ex_delete_ip_forwarding_rule(node=self, rule=rule)
-
-    def ex_delete_port_forwarding_rule(self, rule):
-        """
-        Delete a NAT/firewall rule.
-        """
-        return self.driver.ex_delete_port_forwarding_rule(node=self, rule=rule)
-
-    def ex_start(self):
-        """
-        Starts a stopped virtual machine.
-        """
-        return self.driver.ex_start(node=self)
-
-    def ex_stop(self):
-        """
-        Stops a running virtual machine.
-        """
-        return self.driver.ex_stop(node=self)
-
-
-class CloudStackAddress(object):
-    """
-    A public IP address.
-
-    :param      id: UUID of the Public IP
-    :type       id: ``str``
-
-    :param      address: The public IP address
-    :type       address: ``str``
-
-    :param      associated_network_id: The ID of the network where this address
-                                        has been associated with
-    :type       associated_network_id: ``str``
-
-    :param      vpc_id: VPC the ip belongs to
-    :type       vpc_id: ``str``
-
-    :param      virtualmachine_id: The ID of virutal machine this address
-                                   is assigned to
-    :type       virtualmachine_id: ``str``
-    """
-
-    def __init__(self, id, address, driver, associated_network_id=None,
-                 vpc_id=None, virtualmachine_id=None):
-        self.id = id
-        self.address = address
-        self.driver = driver
-        self.associated_network_id = associated_network_id
-        self.vpc_id = vpc_id
-        self.virtualmachine_id = virtualmachine_id
-
-    def release(self):
-        self.driver.ex_release_public_ip(address=self)
-
-    def __str__(self):
-        return self.address
-
-    def __eq__(self, other):
-        return self.__class__ is other.__class__ and self.id == other.id
-
-
-class CloudStackFirewallRule(object):
-    """
-    A firewall rule.
-    """
-
-    def __init__(self, id, address, cidr_list, protocol,
-                 icmp_code=None, icmp_type=None,
-                 start_port=None, end_port=None):
-
-        """
-        A Firewall rule.
-
-        @note: This is a non-standard extension API, and only works for
-               CloudStack.
-
-        :param      id: Firewall Rule ID
-        :type       id: ``int``
-
-        :param      address: External IP address
-        :type       address: :class:`CloudStackAddress`
-
-        :param      cidr_list: cidr list
-        :type       cidr_list: ``str``
-
-        :param      protocol: TCP/IP Protocol (TCP, UDP)
-        :type       protocol: ``str``
-
-        :param      icmp_code: Error code for this icmp message
-        :type       icmp_code: ``int``
-
-        :param      icmp_type: Type of the icmp message being sent
-        :type       icmp_type: ``int``
-
-        :param      start_port: start of port range
-        :type       start_port: ``int``
-
-        :param      end_port: end of port range
-        :type       end_port: ``int``
-
-        :rtype: :class:`CloudStackFirewallRule`
-        """
-
-        self.id = id
-        self.address = address
-        self.cidr_list = cidr_list
-        self.protocol = protocol
-        self.icmp_code = icmp_code
-        self.icmp_type = icmp_type
-        self.start_port = start_port
-        self.end_port = end_port
-
-    def __eq__(self, other):
-        return self.__class__ is other.__class__ and self.id == other.id
-
-
-class CloudStackEgressFirewallRule(object):
-    """
-    A egress firewall rule.
-    """
-
-    def __init__(self, id, network_id, cidr_list, protocol,
-                 icmp_code=None, icmp_type=None,
-                 start_port=None, end_port=None):
-
-        """
-        A egress firewall rule.
-
-        @note: This is a non-standard extension API, and only works for
-               CloudStack.
-
-        :param      id: Firewall Rule ID
-        :type       id: ``int``
-
-        :param      network_id: the id network network for the egress firwall
-                    services
-        :type       network_id: ``str``
-
-        :param      protocol: TCP/IP Protocol (TCP, UDP)
-        :type       protocol: ``str``
-
-        :param      cidr_list: cidr list
-        :type       cidr_list: ``str``
-
-        :param      icmp_code: Error code for this icmp message
-        :type       icmp_code: ``int``
-
-        :param      icmp_type: Type of the icmp message being sent
-        :type       icmp_type: ``int``
-
-        :param      start_port: start of port range
-        :type       start_port: ``int``
-
-        :param      end_port: end of port range
-        :type       end_port: ``int``
-
-        :rtype: :class:`CloudStackEgressFirewallRule`
-        """
-
-        self.id = id
-        self.network_id = network_id
-        self.cidr_list = cidr_list
-        self.protocol = protocol
-        self.icmp_code = icmp_code
-        self.icmp_type = icmp_type
-        self.start_port = start_port
-        self.end_port = end_port
-
-    def __eq__(self, other):
-        return self.__class__ is other.__class__ and self.id == other.id
-
-
-class CloudStackIPForwardingRule(object):
-    """
-    A NAT/firewall forwarding rule.
-    """
-
-    def __init__(self, node, id, address, protocol, start_port, end_port=None):
-        """
-        A NAT/firewall forwarding rule.
-
-        @note: This is a non-standard extension API, and only works for
-               CloudStack.
-
-        :param      node: Node for rule
-        :type       node: :class:`Node`
-
-        :param      id: Rule ID
-        :type       id: ``int``
-
-        :param      address: External IP address
-        :type       address: :class:`CloudStackAddress`
-
-        :param      protocol: TCP/IP Protocol (TCP, UDP)
-        :type       protocol: ``str``
-
-        :param      start_port: Start port for the rule
-        :type       start_port: ``int``
-
-        :param      end_port: End port for the rule
-        :type       end_port: ``int``
-
-        :rtype: :class:`CloudStackIPForwardingRule`
-        """
-        self.node = node
-        self.id = id
-        self.address = address
-        self.protocol = protocol
-        self.start_port = start_port
-        self.end_port = end_port
-
-    def delete(self):
-        self.node.ex_delete_ip_forwarding_rule(rule=self)
-
-    def __eq__(self, other):
-        return self.__class__ is other.__class__ and self.id == other.id
-
-
-class CloudStackPortForwardingRule(object):
-    """
-    A Port forwarding rule for Source NAT.
-    """
-
-    def __init__(self, node, rule_id, address, protocol, public_port,
-                 private_port, public_end_port=None, private_end_port=None,
-                 network_id=None):
-        """
-        A Port forwarding rule for Source NAT.
-
-        @note: This is a non-standard extension API, and only works for EC2.
-
-        :param      node: Node for rule
-        :type       node: :class:`Node`
-
-        :param      rule_id: Rule ID
-        :type       rule_id: ``int``
-
-        :param      address: External IP address
-        :type       address: :class:`CloudStackAddress`
-
-        :param      protocol: TCP/IP Protocol (TCP, UDP)
-        :type       protocol: ``str``
-
-        :param      public_port: External port for rule (or start port if
-                                 public_end_port is also provided)
-        :type       public_port: ``int``
-
-        :param      private_port: Internal node port for rule (or start port if
-                                  public_end_port is also provided)
-        :type       private_port: ``int``
-
-        :param      public_end_port: End of external port range
-        :type       public_end_port: ``int``
-
-        :param      private_end_port: End of internal port range
-        :type       private_end_port: ``int``
-
-        :param      network_id: The network of the vm the Port Forwarding rule
-                                will be created for. Required when public Ip
-                                address is not associated with any Guest
-                                network yet (VPC case)
-        :type       network_id: ``str``
-
-        :rtype: :class:`CloudStackPortForwardingRule`
-        """
-        self.node = node
-        self.id = rule_id
-        self.address = address
-        self.protocol = protocol
-        self.public_port = public_port
-        self.public_end_port = public_end_port
-        self.private_port = private_port
-        self.private_end_port = private_end_port
-
-    def delete(self):
-        self.node.ex_delete_port_forwarding_rule(rule=self)
-
-    def __eq__(self, other):
-        return self.__class__ is other.__class__ and self.id == other.id
-
-
-class CloudStackNetworkACLList(object):
-    """
-    a Network ACL for the given VPC
-    """
-
-    def __init__(self, acl_id, name, vpc_id, driver, description=None):
-        """
-        a Network ACL for the given VPC
-
-        @note: This is a non-standard extension API, and only works for
-               Cloudstack.
-
-        :param      acl_id: ACL ID
-        :type       acl_id: ``int``
-
-        :param      name: Name of the network ACL List
-        :type       name: ``str``
-
-        :param      vpc_id: Id of the VPC associated with this network ACL List
-        :type       vpc_id: ``string``
-
-        :param      description: Description of the network ACL List
-        :type       description: ``str``
-
-        :rtype: :class:`CloudStackNetworkACLList`
-        """
-
-        self.id = acl_id
-        self.name = name
-        self.vpc_id = vpc_id
-        self.driver = driver
-        self.description = description
-
-    def __repr__(self):
-        return (('<CloudStackNetworkACLList: id=%s, name=%s, vpc_id=%s, '
-                 'driver=%s, description=%s>')
-                % (self.id, self.name, self.vpc_id,
-                   self.driver.name, self.description))
-
-
-class CloudStackNetworkACL(object):
-    """
-    a ACL rule in the given network (the network has to belong to VPC)
-    """
-
-    def __init__(self, id, protocol, acl_id, action, cidr_list,
-                 start_port, end_port, traffic_type=None):
-        """
-        a ACL rule in the given network (the network has to belong to
-        VPC)
-
-        @note: This is a non-standard extension API, and only works for
-               Cloudstack.
-
-        :param      id: the ID of the ACL Item
-        :type       id ``int``
-
-        :param      protocol: the protocol for the ACL rule. Valid values are
-                               TCP/UDP/ICMP/ALL or valid protocol number
-        :type       protocol: ``string``
-
-        :param      acl_id: Name of the network ACL List
-        :type       acl_id: ``str``
-
-        :param      action: scl entry action, allow or deny
-        :type       action: ``string``
-
-        :param      cidr_list: the cidr list to allow traffic from/to
-        :type       cidr_list: ``str``
-
-        :param      start_port: the starting port of ACL
-        :type       start_port: ``str``
-
-        :param      end_port: the ending port of ACL
-        :type       end_port: ``str``
-
-        :param      traffic_type: the traffic type for the ACL,can be Ingress
-                                  or Egress, defaulted to Ingress if not
-                                  specified
-        :type       traffic_type: ``str``
-
-        :rtype: :class:`CloudStackNetworkACL`
-        """
-
-        self.id = id
-        self.protocol = protocol
-        self.acl_id = acl_id
-        self.action = action
-        self.cidr_list = cidr_list
-        self.start_port = start_port
-        self.end_port = end_port
-        self.traffic_type = traffic_type
-
-    def __eq__(self, other):
-        return self.__class__ is other.__class__ and self.id == other.id
-
-
-class CloudStackDiskOffering(object):
-    """
-    A disk offering within CloudStack.
-    """
-
-    def __init__(self, id, name, size, customizable):
-        self.id = id
-        self.name = name
-        self.size = size
-        self.customizable = customizable
-
-    def __eq__(self, other):
-        return self.__class__ is other.__class__ and self.id == other.id
-
-
-class CloudStackNetwork(object):
-    """
-    Class representing a CloudStack Network.
-    """
-
-    def __init__(self, displaytext, name, networkofferingid, id, zoneid,
-                 driver, extra=None):
-        self.displaytext = displaytext
-        self.name = name
-        self.networkofferingid = networkofferingid
-        self.id = id
-        self.zoneid = zoneid
-        self.driver = driver
-        self.extra = extra or {}
-
-    def __repr__(self):
-        return (('<CloudStackNetwork: displaytext=%s, name=%s, '
-                 'networkofferingid=%s, '
-                 'id=%s, zoneid=%s, driver=%s>')
-                % (self.displaytext, self.name, self.networkofferingid,
-                   self.id, self.zoneid, self.driver.name))
-
-
-class CloudStackNetworkOffering(object):
-    """
-    Class representing a CloudStack Network Offering.
-    """
-
-    def __init__(self, name, display_text, guest_ip_type, id,
-                 service_offering_id, for_vpc, driver, extra=None):
-        self.display_text = display_text
-        self.name = name
-        self.guest_ip_type = guest_ip_type
-        self.id = id
-        self.service_offering_id = service_offering_id
-        self.for_vpc = for_vpc
-        self.driver = driver
-        self.extra = extra or {}
-
-    def __repr__(self):
-        return (('<CloudStackNetworkOffering: id=%s, name=%s, '
-                 'display_text=%s, guest_ip_type=%s, service_offering_id=%s, '
-                 'for_vpc=%s, driver=%s>')
-                % (self.id, self.name, self.display_text,
-                   self.guest_ip_type, self.service_offering_id, self.for_vpc,
-                   self.driver.name))
-
-
-class CloudStackNic(object):
-    """
-    Class representing a CloudStack Network Interface.
-    """
-
-    def __init__(self, id, network_id, net_mask, gateway, ip_address,
-                 is_default, mac_address, driver, extra=None):
-        self.id = id
-        self.network_id = network_id
-        self.net_mask = net_mask
-        self.gateway = gateway
-        self.ip_address = ip_address
-        self.is_default = is_default
-        self.mac_address = mac_address
-        self.driver = driver
-        self.extra = extra or {}
-
-    def __repr__(self):
-        return (('<CloudStackNic: id=%s, network_id=%s, '
-                 'net_mask=%s, gateway=%s, ip_address=%s, '
-                 'is_default=%s, mac_address=%s, driver%s>')
-                % (self.id, self.network_id, self.net_mask,
-                   self.gateway, self.ip_address, self.is_default,
-                   self.mac_address, self.driver.name))
-
-    def __eq__(self, other):
-        return self.__class__ is other.__class__ and self.id == other.id
-
-
-class CloudStackVPC(object):
-    """
-    Class representing a CloudStack VPC.
-    """
-
-    def __init__(self, name, vpc_offering_id, id, cidr, driver,
-                 zone_id=None, display_text=None, extra=None):
-        self.display_text = display_text
-        self.name = name
-        self.vpc_offering_id = vpc_offering_id
-        self.id = id
-        self.zone_id = zone_id
-        self.cidr = cidr
-        self.driver = driver
-        self.extra = extra or {}
-
-    def __repr__(self):
-        return (('<CloudStackVPC: name=%s, vpc_offering_id=%s, id=%s, '
-                 'cidr=%s, driver=%s, zone_id=%s, display_text=%s>')
-                % (self.name, self.vpc_offering_id, self.id,
-                   self.cidr, self.driver.name, self.zone_id,
-                   self.display_text))
-
-
-class CloudStackVPCOffering(object):
-    """
-    Class representing a CloudStack VPC Offering.
-    """
-
-    def __init__(self, name, display_text, id,
-                 driver, extra=None):
-        self.name = name
-        self.display_text = display_text
-        self.id = id
-        self.driver = driver
-        self.extra = extra or {}
-
-    def __repr__(self):
-        return (('<CloudStackVPCOffering: name=%s, display_text=%s, '
-                 'id=%s, '
-                 'driver=%s>')
-                % (self.name, self.display_text, self.id,
-                   self.driver.name))
-
-
-class CloudStackVpnGateway(object):
-    """
-    Class representing a CloudStack VPN Gateway.
-    """
-    def __init__(self, id, account, domain, domain_id,
-                 public_ip, vpc_id, driver, extra=None):
-        self.id = id
-        self.account = account
-        self.domain = domain
-        self.domain_id = domain_id
-        self.public_ip = public_ip
-        self.vpc_id = vpc_id
-        self.driver = driver
-        self.extra = extra or {}
-
-    @property
-    def vpc(self):
-        for vpc in self.driver.ex_list_vpcs():
-            if self.vpc_id == vpc.id:
-                return vpc
-
-        raise LibcloudError('VPC with id=%s not found' % self.vpc_id)
-
-    def delete(self):
-        return self.driver.ex_delete_vpn_gateway(vpn_gateway=self)
-
-    def __repr__(self):
-        return (('<CloudStackVpnGateway: account=%s, domain=%s, '
-                 'domain_id=%s, id=%s, public_ip=%s, vpc_id=%s, '
-                 'driver=%s>')
-                % (self.account, self.domain, self.domain_id,
-                   self.id, self.public_ip, self.vpc_id, self.driver.name))
-
-
-class CloudStackVpnCustomerGateway(object):
-    """
-    Class representing a CloudStack VPN Customer Gateway.
-    """
-    def __init__(self, id, cidr_list, esp_policy, gateway,
-                 ike_policy, ipsec_psk, driver, extra=None):
-        self.id = id
-        self.cidr_list = cidr_list
-        self.esp_policy = esp_policy
-        self.gateway = gateway
-        self.ike_policy = ike_policy
-        self.ipsec_psk = ipsec_psk
-        self.driver = driver
-        self.extra = extra or {}
-
-    def delete(self):
-        return self.driver.ex_delete_vpn_customer_gateway(
-            vpn_customer_gateway=self)
-
-    def __repr__(self):
-        return (('<CloudStackVpnCustomerGateway: id=%s, cidr_list=%s, '
-                 'esp_policy=%s, gateway=%s, ike_policy=%s, ipsec_psk=%s, '
-                 'driver=%s>')
-                % (self.id, self.cidr_list, self.esp_policy, self.gateway,
-                   self.ike_policy, self.ipsec_psk, self.driver.name))
-
-
-class CloudStackVpnConnection(object):
-    """
-    Class representing a CloudStack VPN Connection.
-    """
-    def __init__(self, id, passive, vpn_customer_gateway_id,
-                 vpn_gateway_id, state, driver, extra=None):
-        self.id = id
-        self.passive = passive
-        self.vpn_customer_gateway_id = vpn_customer_gateway_id
-        self.vpn_gateway_id = vpn_gateway_id
-        self.state = state
-        self.driver = driver
-        self.extra = extra or {}
-
-    @property
-    def vpn_customer_gateway(self):
-        try:
-            return self.driver.ex_list_vpn_customer_gateways(
-                id=self.vpn_customer_gateway_id)[0]
-        except IndexError:
-            raise LibcloudError('VPN Customer Gateway with id=%s not found' %
-                                self.vpn_customer_gateway_id)
-
-    @property
-    def vpn_gateway(self):
-        try:
-            return self.driver.ex_list_vpn_gateways(id=self.vpn_gateway_id)[0]
-        except IndexError:
-            raise LibcloudError('VPN Gateway with id=%s not found' %
-                                self.vpn_gateway_id)
-
-    def delete(self):
-        return self.driver.ex_delete_vpn_connection(vpn_connection=self)
-
-    def __repr__(self):
-        return (('<CloudStackVpnConnection: id=%s, passive=%s, '
-                 'vpn_customer_gateway_id=%s, vpn_gateway_id=%s, state=%s, '
-                 'driver=%s>')
-                % (self.id, self.passive, self.vpn_customer_gateway_id,
-                   self.vpn_gateway_id, self.state, self.driver.name))
-
-
-class CloudStackRouter(object):
-    """
-    Class representing a CloudStack Router.
-    """
-
-    def __init__(self, id, name, state, public_ip, vpc_id, driver):
-        self.id = id
-        self.name = name
-        self.state = state
-        self.public_ip = public_ip
-        self.vpc_id = vpc_id
-        self.driver = driver
-
-    def __repr__(self):
-        return (('<CloudStackRouter: id=%s, name=%s, state=%s, '
-                 'public_ip=%s, vpc_id=%s, driver=%s>')
-                % (self.id, self.name, self.state,
-                   self.public_ip, self.vpc_id, self.driver.name))
-
-
-class CloudStackProject(object):
-    """
-    Class representing a CloudStack Project.
-    """
-
-    def __init__(self, id, name, display_text, driver, extra=None):
-        self.id = id
-        self.name = name
-        self.display_text = display_text
-        self.driver = driver
-        self.extra = extra or {}
-
-    def __repr__(self):
-        return (('<CloudStackProject: id=%s, name=%s, display_text=%s,'
-                 'driver=%s>')
-                % (self.id, self.display_text, self.name,
-                   self.driver.name))
-
-
-class CloudStackAffinityGroup(object):
-    """
-    Class representing a CloudStack AffinityGroup.
-    """
-
-    def __init__(self, id, account, description, domain, domainid, name,
-                 group_type, virtualmachine_ids):
-        """
-        A CloudStack Affinity Group.
-
-        @note: This is a non-standard extension API, and only works for
-               CloudStack.
-
-        :param      id: CloudStack Affinity Group ID
-        :type       id: ``str``
-
-        :param      account: An account for the affinity group. Must be used
-                             with domainId.
-        :type       account: ``str``
-
-        :param      description: optional description of the affinity group
-        :type       description: ``str``
-
-        :param      domain: the domain name of the affinity group
-        :type       domain: ``str``
-
-        :param      domainid: domain ID of the account owning the affinity
-                              group
-        :type       domainid: ``str``
-
-        :param      name: name of the affinity group
-        :type       name: ``str``
-
-        :param      group_type: the type of the affinity group
-        :type       group_type: :class:`CloudStackAffinityGroupType`
-
-        :param      virtualmachine_ids: virtual machine Ids associated with
-                                        this affinity group
-        :type       virtualmachine_ids: ``str``
-
-        :rtype:     :class:`CloudStackAffinityGroup`
-        """
-        self.id = id
-        self.account = account
-        self.description = description
-        self.domain = domain
-        self.domainid = domainid
-        self.name = name
-        self.type = group_type
-        self.virtualmachine_ids = virtualmachine_ids
-
-    def __repr__(self):
-        return (('<CloudStackAffinityGroup: id=%s, name=%s, type=%s>')
-                % (self.id, self.name, self.type))
-
-
-class CloudStackAffinityGroupType(object):
-    """
-    Class representing a CloudStack AffinityGroupType.
-    """
-
-    def __init__(self, type_name):
-        """
-        A CloudStack Affinity Group Type.
-
-        @note: This is a non-standard extension API, and only works for
-               CloudStack.
-
-        :param      type_name: the type of the affinity group
-        :type       type_name: ``str``
-
-        :rtype: :class:`CloudStackAffinityGroupType`
-        """
-        self.type = type_name
-
-    def __repr__(self):
-        return (('<CloudStackAffinityGroupType: type=%s>') % self.type)
-
-
-class CloudStackNodeDriver(CloudStackDriverMixIn, NodeDriver):
-    """
-    Driver for the CloudStack API.
-
-    :cvar host: The host where the API can be reached.
-    :cvar path: The path where the API can be reached.
-    :cvar async_poll_frequency: How often (in seconds) to poll for async
-                                job completion.
-    :type async_poll_frequency: ``int``"""
-
-    name = 'CloudStack'
-    api_name = 'cloudstack'
-    website = 'http://cloudstack.org/'
-    type = Provider.CLOUDSTACK
-
-    features = {'create_node': ['generates_password']}
-
-    NODE_STATE_MAP = {
-        'Running': NodeState.RUNNING,
-        'Starting': NodeState.REBOOTING,
-        'Stopped': NodeState.STOPPED,
-        'Stopping': NodeState.PENDING,
-        'Destroyed': NodeState.TERMINATED,
-        'Expunging': NodeState.PENDING,
-        'Error': NodeState.TERMINATED
-    }
-
-    VOLUME_STATE_MAP = {
-        'Creating': StorageVolumeState.CREATING,
-        'Destroying': StorageVolumeState.DELETING,
-        'Expunging': StorageVolumeState.DELETING,
-        'Destroy': StorageVolumeState.DELETED,
-        'Expunged': StorageVolumeState.DELETED,
-        'Allocated': StorageVolumeState.AVAILABLE,
-        'Ready': StorageVolumeState.AVAILABLE,
-        'Snapshotting': StorageVolumeState.BACKUP,
-        'UploadError': StorageVolumeState.ERROR
-    }
-
-    def __init__(self, key, secret=None, secure=True, host=None,
-                 path=None, port=None, url=None, *args, **kwargs):
-        """
-        :inherits: :class:`NodeDriver.__init__`
-
-        :param    host: The host where the API can be reached. (required)
-        :type     host: ``str``
-
-        :param    path: The path where the API can be reached. (required)
-        :type     path: ``str``
-
-        :param url: Full URL to the API endpoint. Mutually exclusive with host
-                    and path argument.
-        :type url: ``str``
-        """
-        if url:
-            parsed = urlparse.urlparse(url)
-
-            path = parsed.path
-
-            scheme = parsed.scheme
-            split = parsed.netloc.split(':')
-
-            if len(split) == 1:
-                # No port provided, use the default one
-                host = parsed.netloc
-                port = 443 if scheme == 'https' else 80
-            else:
-                host = split[0]
-                port = int(split[1])
-        else:
-            host = host if host else self.host
-            path = path if path else self.path
-
-        if path is not None:
-            self.path = path
-
-        if host is not None:
-            self.host = host
-
-        if (self.type == Provider.CLOUDSTACK) and (not host or not path):
-            raise Exception('When instantiating CloudStack driver directly '
-                            'you also need to provide url or host and path '
-                            'argument')
-
-        super(CloudStackNodeDriver, self).__init__(key=key,
-                                                   secret=secret,
-                                                   secure=secure,
-                                                   host=host,
-                                                   port=port)
-
-    def list_images(self, location=None):
-        args = {
-            'templatefilter': 'executable'
-        }
-        if location is not None:
-            args['zoneid'] = location.id
-
-        imgs = self._sync_request(command='listTemplates',
-                                  params=args,
-                                  method='GET')
-        images = []
-        for img in imgs.get('template', []):
-
-            extra = {'hypervisor': img['hypervisor'],
-                     'format': img['format'],
-                     'os': img['ostypename'],
-                     'displaytext': img['displaytext']}
-
-            size = img.get('size', None)
-            if size is not None:
-                extra.update({'size': img['size']})
-
-            images.append(NodeImage(
-                id=img['id'],
-                name=img['name'],
-                driver=self.connection.driver,
-                extra=extra))
-        return images
-
-    def list_locations(self):
-        """
-        :rtype ``list`` of :class:`NodeLocation`
-        """
-        locs = self._sync_request('listZones')
-
-        locations = []
-        for loc in locs['zone']:
-            location = NodeLocation(str(loc['id']), loc['name'], 'Unknown',
-                                    self)
-            locations.append(location)
-
-        return locations
-
-    def list_nodes(self, project=None, location=None):
-        """
-        @inherits: :class:`NodeDriver.list_nodes`
-
-        :keyword    project: Limit nodes returned to those configured under
-                             the defined project.
-        :type       project: :class:`.CloudStackProject`
-
-        :keyword    location: Limit nodes returned to those in the defined
-                              location.
-        :type       location: :class:`.NodeLocation`
-
-        :rtype: ``list`` of :class:`CloudStackNode`
-        """
-
-        args = {}
-
-        if project:
-            args['projectid'] = project.id
-
-        if location is not None:
-            args['zoneid'] = location.id
-
-        vms = self._sync_request('listVirtualMachines', params=args)
-        addrs = self._sync_request('listPublicIpAddresses', params=args)
-        port_forwarding_rules = self._sync_request('listPortForwardingRules')
-        ip_forwarding_rules = self._sync_request('listIpForwardingRules')
-
-        public_ips_map = {}
-        for addr in addrs.get('publicipaddress', []):
-            if 'virtualmachineid' not in addr:
-                continue
-            vm_id = str(addr['virtualmachineid'])
-            if vm_id not in public_ips_map:
-                public_ips_map[vm_id] = {}
-            public_ips_map[vm_id][addr['ipaddress']] = addr['id']
-
-        nodes = []
-
-        for vm in vms.get('virtualmachine', []):
-            public_ips = public_ips_map.get(str(vm['id']), {}).keys()
-            public_ips = list(public_ips)
-            node = self._to_node(data=vm, public_ips=public_ips)
-
-            addresses = public_ips_map.get(str(vm['id']), {}).items()
-            addresses = [CloudStackAddress(id=address_id, address=address,
-                                           driver=node.driver) for
-                         address, address_id in addresses]
-            node.extra['ip_addresses'] = addresses
-
-            rules = []
-            for addr in addresses:
-                for r in ip_forwarding_rules.get('ipforwardingrule', []):
-                    if str(r['virtualmachineid']) == node.id:
-                        rule = CloudStackIPForwardingRule(node, r['id'],
-                                                          addr,
-                                                          r['protocol']
-                                                          .upper(),
-                                                          r['startport'],
-                                                          r['endport'])
-                        rules.append(rule)
-            node.extra['ip_forwarding_rules'] = rules
-
-            rules = []
-            for r in port_forwarding_rules.get('portforwardingrule', []):
-                if str(r['virtualmachineid']) == node.id:
-                    addr = [CloudStackAddress(id=a['id'],
-                                              address=a['ipaddress'],
-                                              driver=node.driver)
-                            for a in addrs.get('publicipaddress', [])
-                            if a['ipaddress'] == r['ipaddress']]
-                    rule = CloudStackPortForwardingRule(node, r['id'],
-                                                        addr[0],
-                                                        r['protocol'].upper(),
-                                                        r['publicport'],
-                                                        r['privateport'],
-                                                        r['publicendport'],
-                                                        r['privateendport'])
-                    if not addr[0].address in node.public_ips:
-                        node.public_ips.append(addr[0].address)
-                    rules.append(rule)
-            node.extra['port_forwarding_rules'] = rules
-
-            nodes.append(node)
-
-        return nodes
-
-    def ex_get_node(self, node_id, project=None):
-        """
-        Return a Node object based on its ID.
-
-        :param  node_id: The id of the node
-        :type   node_id: ``str``
-
-        :keyword    project: Limit node returned to those configured under
-                             the defined project.
-        :type       project: :class:`.CloudStackProject`
-
-        :rtype: :class:`CloudStackNode`
-        """
-        list_nodes_args = {'id': node_id}
-        list_ips_args = {}
-        if project:
-            list_nodes_args['projectid'] = project.id
-            list_ips_args['projectid'] = project.id
-        vms = self._sync_request('listVirtualMachines', params=list_nodes_args)
-        if not vms:
-            raise Exception("Node '%s' not found" % node_id)
-        vm = vms['virtualmachine'][0]
-        addrs = self._sync_request('listPublicIpAddresses',
-                                   params=list_ips_args)
-
-        public_ips = {}
-        for addr in addrs.get('publicipaddress', []):
-            if 'virtualmachineid' not in addr:
-                continue
-            public_ips[addr['ipaddress']] = addr['id']
-
-        node = self._to_node(data=vm, public_ips=list(public_ips.keys()))
-
-        addresses = [CloudStackAddress(id=address_id, address=address,
-                                       driver=node.driver) for
-                     address, address_id in public_ips.items()]
-        node.extra['ip_addresses'] = addresses
-
-        rules = []
-        list_fw_rules = {'virtualmachineid': node_id}
-        for addr in addresses:
-            result = self._sync_request('listIpForwardingRules',
-                                        params=list_fw_rules)
-            for r in result.get('ipforwardingrule', []):
-                if str(r['virtualmachineid']) == node.id:
-                    rule = CloudStackIPForwardingRule(node, r['id'],
-                                                      addr,
-                                                      r['protocol']
-                                                      .upper(),
-                                                      r['startport'],
-                                                      r['endport'])
-                    rules.append(rule)
-        node.extra['ip_forwarding_rules'] = rules
-
-        rules = []
-        public_ips = self.ex_list_public_ips()
-        result = self._sync_request('listPortForwardingRules',
-                                    params=list_fw_rules)
-        for r in result.get('portforwardingrule', []):
-            if str(r['virtualmachineid']) == node.id:
-                addr = [a for a in public_ips if
-                        a.address == r['ipaddress']]
-                rule = CloudStackPortForwardingRule(node, r['id'],
-                                                    addr[0],
-                                                    r['protocol'].upper(),
-                                                    r['publicport'],
-                                                    r['privateport'],
-                                                    r['publicendport'],
-                                                    r['privateendport'])
-                if not addr[0].address in node.public_ips:
-                    node.public_ips.append(addr[0].address)
-                rules.append(rule)
-        node.extra['port_forwarding_rules'] = rules
-        return node
-
-    def list_sizes(self, location=None):
-        """
-        :rtype ``list`` of :class:`NodeSize`
-        """
-        szs = self._sync_request(command='listServiceOfferings',
-                                 method='GET')
-        sizes = []
-        for sz in szs['serviceoffering']:
-            extra = {'cpu': sz['cpunumber']}
-            sizes.append(NodeSize(sz['id'], sz['name'], sz['memory'], 0, 0,
-                                  0, self, extra=extra))
-        return sizes
-
-    def create_node(self, **kwargs):
-        """
-        Create a new node
-
-        @inherits: :class:`NodeDriver.create_node`
-
-        :keyword    networks: Optional list of networks to launch the server
-                              into.
-        :type       networks: ``list`` of :class:`.CloudStackNetwork`
-
-        :keyword    project: Optional project to create the new node under.
-        :type       project: :class:`.CloudStackProject`
-
-        :keyword    diskoffering:  Optional disk offering to add to the new
-                                   node.
-        :type       diskoffering:  :class:`.CloudStackDiskOffering`
-
-        :keyword    ex_keyname:  Name of existing keypair
-        :type       ex_keyname:  ``str``
-
-        :keyword    ex_userdata: String containing user data
-        :type       ex_userdata: ``str``
-
-        :keyword    ex_security_groups: List of security groups to assign to
-                                        the node
-        :type       ex_security_groups: ``list`` of ``str``
-
-        :keyword    ex_displayname: String containing instance display name
-        :type       ex_displayname: ``str``
-
-        :keyword    ex_ip_address: String with ipaddress for the default nic
-        :type       ex_ip_address: ``str``
-
-        :keyword    ex_start_vm: Boolean to specify to start VM after creation
-                                 Default Cloudstack behaviour is to start a VM,
-                                 if not specified.
-
-        :type       ex_start_vm: ``bool``
-
-        :keyword    ex_rootdisksize: String with rootdisksize for the template
-        :type       ex_rootdisksize: ``str``
-
-        :keyword    ex_affinity_groups: List of affinity groups to assign to
-                                        the node
-        :type       ex_affinity_groups: ``list`` of
-                                        :class:`.CloudStackAffinityGroup`
-
-        :rtype:     :class:`.CloudStackNode`
-        """
-
-        server_params = self._create_args_to_params(None, **kwargs)
-
-        data = self._async_request(command='deployVirtualMachine',
-                                   params=server_params,
-                                   method='GET')['virtualmachine']
-        node = self._to_node(data=data)
-        return node
-
-    def _create_args_to_params(self, node, **kwargs):
-        server_params = {}
-
-        # TODO: Refactor and use "kwarg_to_server_params" map
-        name = kwargs.get('name', None)
-        size = kwargs.get('size', None)
-        image = kwargs.get('image', None)
-        location = kwargs.get('location', None)
-        networks = kwargs.get('networks', None)
-        project = kwargs.get('project', None)
-        diskoffering = kwargs.get('diskoffering', None)
-        ex_key_name = kwargs.get('ex_keyname', None)
-        ex_user_data = kwargs.get('ex_userdata', None)
-        ex_security_groups = kwargs.get('ex_security_groups', None)
-        ex_displayname = kwargs.get('ex_displayname', None)
-        ex_ip_address = kwargs.get('ex_ip_address', None)
-        ex_start_vm = kwargs.get('ex_start_vm', None)
-        ex_rootdisksize = kwargs.get('ex_rootdisksize', None)
-        ex_affinity_groups = kwargs.get('ex_affinity_groups', None)
-
-        if name:
-            server_params['name'] = name
-
-        if ex_displayname:
-            server_params['displayname'] = ex_displayname
-
-        if size:
-            server_params['serviceofferingid'] = size.id
-
-        if image:
-            server_params['templateid'] = image.id
-
-        if location:
-            server_params['zoneid'] = location.id
-        else:
-            # Use a default location
-            server_params['zoneid'] = self.list_locations()[0].id
-
-        if networks:
-            networks = ','.join([str(network.id) for network in networks])
-            server_params['networkids'] = networks
-
-        if project:
-            server_params['projectid'] = project.id
-
-        if diskoffering:
-            server_params['diskofferingid'] = diskoffering.id
-
-        if ex_key_name:
-            server_params['keypair'] = ex_key_name
-
-        if ex_user_data:
-            ex_user_data = base64.b64encode(b(ex_user_data).decode('ascii'))
-            server_params['userdata'] = ex_user_data
-
-        if ex_security_groups:
-            ex_security_groups = ','.join(ex_security_groups)
-            server_params['securitygroupnames'] = ex_security_groups
-
-        if ex_ip_address:
-            server_params['ipaddress'] = ex_ip_address
-
-        if ex_rootdisksize:
-            server_params['rootdisksize'] = ex_rootdisksize
-
-        if ex_start_vm is not None:
-            server_params['startvm'] = ex_start_vm
-
-        if ex_affinity_groups:
-            affinity_group_ids = ','.join(ag.id for ag in ex_affinity_groups)
-            server_params['affinitygroupids'] = affinity_group_ids
-
-        return server_params
-
-    def destroy_node(self, node, ex_expunge=False):
-        """
-        @inherits: :class:`NodeDriver.reboot_node`
-        :type node: :class:`CloudStackNode`
-
-        :keyword    ex_expunge: If true is passed, the vm is expunged
-                                immediately. False by default.
-        :type       ex_expunge: ``bool``
-
-        :rtype: ``bool``
-        """
-
-        args = {
-            'id': node.id,
-        }
-
-        if ex_expunge:
-            args['expunge'] = ex_expunge
-
-        self._async_request(command='destroyVirtualMachine',
-                            params=args,
-                            method='GET')
-        return True
-
-    def reboot_node(self, node):
-        """
-        @inherits: :class:`NodeDriver.reboot_node`
-        :type node: :class:`CloudStackNode`
-
-        :rtype: ``bool``
-        """
-        self._async_request(command='rebootVirtualMachine',
-                            params={'id': node.id},
-                            method='GET')
-        return True
-
-    def ex_start(self, node):
-        """
-        Starts/Resumes a stopped virtual machine
-
-        :type node: :class:`CloudStackNode`
-
-        :param id: The ID of the virtual machine (required)
-        :type  id: ``str``
-
-        :param hostid: destination Host ID to deploy the VM to
-                       parameter available for root admin only
-        :type  hostid: ``str``
-
-        :rtype ``str``
-        """
-        res = self._async_request(command='startVirtualMachine',
-                                  params={'id': node.id},
-                                  method='GET')
-        return res['virtualmachine']['state']
-
-    def ex_stop(self, node):
-        """
-        Stops/Suspends a running virtual machine
-
-        :param node: Node to stop.
-        :type node: :class:`CloudStackNode`
-
-        :rtype: ``str``
-        """
-        res = self._async_request(command='stopVirtualMachine',
-                                  params={'id': node.id},
-                                  method='GET')
-        return res['virtualmachine']['state']
-
-    def ex_list_disk_offerings(self):
-        """
-        Fetch a list of all available disk offerings.
-
-        :rtype: ``list`` of :class:`CloudStackDiskOffering`
-        """
-
-        diskOfferings = []
-
-        diskOfferResponse = self._sync_request(command='listDiskOfferings',
-                                               method='GET')
-        for diskOfferDict in diskOfferResponse.get('diskoffering', ()):
-            diskOfferings.append(
-                CloudStackDiskOffering(
-                    id=diskOfferDict['id'],
-                    name=diskOfferDict['name'],
-                    size=diskOfferDict['disksize'],
-                    customizable=diskOfferDict['iscustomized']))
-
-        return diskOfferings
-
-    def ex_list_networks(self, project=None):
-        """
-        List the available networks
-
-        :param  project: Optional project the networks belongs to.
-        :type   project: :class:`.CloudStackProject`
-
-        :rtype ``list`` of :class:`CloudStackNetwork`
-        """
-
-        args = {}
-
-        if project is not None:
-            args['projectid'] = project.id
-
-        res = self._sync_request(command='listNetworks',
-                                 params=args,
-                                 method='GET')
-        nets = res.get('network', [])
-
-        networks = []
-        extra_map = RESOURCE_EXTRA_ATTRIBUTES_MAP['network']
-        for net in nets:
-            extra = self._get_extra_dict(net, extra_map)
-
-            if 'tags' in net:
-                extra['tags'] = self._get_resource_tags(net['tags'])
-
-            networks.append(CloudStackNetwork(
-                            net['displaytext'],
-                            net['name'],
-                            net['networkofferingid'],
-                            net['id'],
-                            net['zoneid'],
-                            self,
-                            extra=extra))
-
-        return networks
-
-    def ex_list_network_offerings(self):
-        """
-        List the available network offerings
-
-        :rtype ``list`` of :class:`CloudStackNetworkOffering`
-        """
-        res = self._sync_request(command='listNetworkOfferings',
-                                 method='GET')
-        netoffers = res.get('networkoffering', [])
-
-        networkofferings = []
-
-        for netoffer in netoffers:
-            networkofferings.append(CloudStackNetworkOffering(
-                                    netoffer['name'],
-                                    netoffer['displaytext'],
-                                    netoffer['guestiptype'],
-                                    netoffer['id'],
-                                    netoffer['serviceofferingid'],
-                                    netoffer['forvpc'],
-                                    self))
-
-        return networkofferings
-
-    def ex_create_network(self, display_text, name, network_offering,
-                          location, gateway=None, netmask=None,
-                          network_domain=None, vpc_id=None, project_id=None):
-        """
-
-        Creates a Network, only available in advanced zones.
-
-        :param  display_text: the display text of the network
-        :type   display_text: ``str``
-
-        :param  name: the name of the network
-        :type   name: ``str``
-
-        :param  network_offering: NetworkOffering object
-        :type   network_offering: :class:'CloudStackNetworkOffering`
-
-        :param location: Zone object
-        :type  location: :class:`NodeLocation`
-
-        :param  gateway: Optional, the Gateway of this network
-        :type   gateway: ``str``
-
-        :param  netmask: Optional, the netmask of this network
-        :type   netmask: ``str``
-
-        :param  network_domain: Optional, the DNS domain of the network
-        :type   network_domain: ``str``
-
-        :param  vpc_id: Optional, the VPC id the network belongs to
-        :type   vpc_id: ``str``
-
-        :param  project_id: Optional, the project id the networks belongs to
-        :type   project_id: ``str``
-
-        :rtype: :class:`CloudStackNetwork`
-
-        """
-
-        extra_map = RESOURCE_EXTRA_ATTRIBUTES_MAP['network']
-
-        args = {
-            'displaytext': display_text,
-            'name': name,
-            'networkofferingid': network_offering.id,
-            'zoneid': location.id,
-        }
-
-        if gateway is not None:
-            args['gateway'] = gateway
-
-        if netmask is not None:
-            args['netmask'] = netmask
-
-        if network_domain is not None:
-            args['networkdomain'] = network_domain
-
-        if vpc_id is not None:
-            args['vpcid'] = vpc_id
-
-        if project_id is not None:
-            args['projectid'] = project_id
-
-        """ Cloudstack allows for duplicate network names,
-        this should be handled in the code leveraging libcloud
-        As there could be use cases for duplicate names.
-        e.g. management from ROOT level"""
-
-        # for net in self.ex_list_networks():
-        #    if name == net.name:
-        #        raise LibcloudError('This network name already exists')
-
-        result = self._sync_request(command='createNetwork',
-                                    params=args,
-                                    method='GET')
-
-        result = result['network']
-        extra = self._get_extra_dict(result, extra_map)
-
-        network = CloudStackNetwork(display_text,
-                                    name,
-                                    network_offering.id,
-                                    result['id'],
-                                    location.id,
-                                    self,
-                                    extra=extra)
-
-        return network
-
-    def ex_delete_network(self, network, force=None):
-        """
-
-        Deletes a Network, only available in advanced zones.
-
-        :param  network: The network
-        :type   network: :class: 'CloudStackNetwork'
-
-        :param  force: Force deletion of the network?
-        :type   force: ``bool``
-
-        :rtype: ``bool``
-
-        """
-
-        args = {'id': network.id, 'forced': force}
-
-        self._async_request(command='deleteNetwork',
-                            params=args,
-                            method='GET')
-        return True
-
-    def ex_list_vpc_offerings(self):
-        """
-        List the available vpc offerings
-
-        :rtype ``list`` of :class:`CloudStackVPCOffering`
-        """
-        res = self._sync_request(command='listVPCOfferings',
-                                 method='GET')
-        vpcoffers = res.get('vpcoffering', [])
-
-        vpcofferings = []
-
-        for vpcoffer in vpcoffers:
-            vpcofferings.append(CloudStackVPCOffering(
-                                vpcoffer['name'],
-                                vpcoffer['displaytext'],
-                                vpcoffer['id'],
-                                self))
-
-        return vpcofferings
-
-    def ex_list_vpcs(self, project=None):
-        """
-        List the available VPCs
-
-        :keyword    project: Optional project under which VPCs are present.
-        :type       project: :class:`.CloudStackProject`
-
-        :rtype ``list`` of :class:`CloudStackVPC`
-        """
-
-        args = {}
-
-        if project is not None:
-            args['projectid'] = project.id
-
-        res = self._sync_request(command='listVPCs',
-                                 params=args,
-                                 method='GET')
-        vpcs = res.get('vpc', [])
-
-        networks = []
-        for vpc in vpcs:
-
-            networks.append(CloudStackVPC(
-                            vpc['name'],
-                            vpc['vpcofferingid'],
-                            vpc['id'],
-                            vpc['cidr'],
-                            self,
-                            vpc['zoneid'],
-                            vpc['displaytext']))
-
-        return networks
-
-    def ex_list_routers(self, vpc_id=None):
-        """
-        List routers
-
-        :rtype ``list`` of :class:`CloudStackRouter`
-        """
-
-        args = {}
-
-        if vpc_id is not None:
-            args['vpcid'] = vpc_id
-
-        res = self._sync_request(command='listRouters',
-                                 params=args,
-                                 method='GET')
-        rts = res.get('router', [])
-
-        routers = []
-        for router in rts:
-
-            routers.append(CloudStackRouter(
-                router['id'],
-                router['name'],
-                router['state'],
-                router['publicip'],
-                router['vpcid'],
-                self))
-
-        return routers
-
-    def ex_create_vpc(self, cidr, display_text, name, vpc_offering,
-                      zone_id, network_domain=None):
-        """
-
-        Creates a VPC, only available in advanced zones.
-
-        :param  cidr: the cidr of the VPC. All VPC guest networks' cidrs
-                should be within this CIDR
-
-        :type   display_text: ``str``
-
-        :param  display_text: the display text of the VPC
-        :type   display_text: ``str``
-
-        :param  name: the name of the VPC
-        :type   name: ``str``
-
-        :param  vpc_offering: the ID of the VPC offering
-        :type   vpc_offering: :class:'CloudStackVPCOffering`
-
-        :param  zone_id: the ID of the availability zone
-        :type   zone_id: ``str``
-
-        :param  network_domain: Optional, the DNS domain of the network
-        :type   network_domain: ``str``
-
-        :rtype: :class:`CloudStackVPC`
-
-        """
-
-        extra_map = RESOURCE_EXTRA_ATTRIBUTES_MAP['vpc']
-
-        args = {
-            'cidr': cidr,
-            'displaytext': display_text,
-            'name': name,
-            'vpcofferingid': vpc_offering.id,
-            'zoneid': zone_id,
-        }
-
-        if network_domain is not None:
-            args['networkdomain'] = network_domain
-
-        result = self._sync_request(command='createVPC',
-                                    params=args,
-                                    method='GET')
-
-        extra = self._get_extra_dict(result, extra_map)
-
-        vpc = CloudStackVPC(name,
-                            vpc_offering.id,
-                            result['id'],
-                            cidr,
-                            self,
-                            zone_id,
-                            display_text,
-                            extra=extra)
-
-        return vpc
-
-    def ex_delete_vpc(self, vpc):
-        """
-
-        Deletes a VPC, only available in advanced zones.
-
-        :param  vpc: The VPC
-        :type   vpc: :class: 'CloudStackVPC'
-
-        :rtype: ``bool``
-
-        """
-
-        args = {'id': vpc.id}
-
-        self._async_request(command='deleteVPC',
-                            params=args,
-                            method='GET')
-        return True
-
-    def ex_list_projects(self):
-        """
-        List the available projects
-
-        :rtype ``list`` of :class:`CloudStackProject`
-        """
-
-        res = self._sync_request(command='listProjects',
-                                 method='GET')
-        projs = res.get('project', [])
-
-        projects = []
-        extra_map = RESOURCE_EXTRA_ATTRIBUTES_MAP['project']
-        for proj in projs:
-            extra = self._get_extra_dict(proj, extra_map)
-
-            if 'tags' in proj:
-                extra['tags'] = self._get_resource_tags(proj['tags'])
-
-            projects.append(CloudStackProject(
-                            id=proj['id'],
-                            name=proj['name'],
-                            display_text=proj['displaytext'],
-                            driver=self,
-                            extra=extra))
-
-        return projects
-
-    def create_volume(self, size, name, location=None, snapshot=None):
-        """
-        Creates a data volume
-        Defaults to the first location
-        """
-        for diskOffering in self.ex_list_disk_offerings():
-            if diskOffering.size == size or diskOffering.customizable:
-                break
-        else:
-            raise LibcloudError(
-                'Disk offering with size=%s not found' % size)
-
-        if location is None:
-            location = self.list_locations()[0]
-
-        params = {'name': name,
-                  'diskOfferingId': diskOffering.id,
-                  'zoneId': location.id}
-
-        if diskOffering.customizable:
-            params['size'] = size
-
-        requestResult = self._async_request(command='createVolume',
-                                            params=params,
-                                            method='GET')
-
-        volumeResponse = requestResult['volume']
-
-        state = self._to_volume_state(volumeResponse)
-
-        return StorageVolume(id=volumeResponse['id'],
-                             name=name,
-                             size=size,
-                             state=state,
-                             driver=self,
-                             extra=dict(name=volumeResponse['name']))
-
-    def destroy_volume(self, volume):
-        """
-        :rtype: ``bool``
-        """
-        self._sync_request(command='deleteVolume',
-                           params={'id': volume.id},
-                           method='GET')
-        return True
-
-    def attach_volume(self, node, volume, device=None):
-        """
-        @inherits: :class:`NodeDriver.attach_volume`
-        :type node: :class:`CloudStackNode`
-
-        :rtype: ``bool``
-        """
-        # TODO Add handling for device name
-        self._async_request(command='attachVolume',
-                            params={'id': volume.id,
-                                    'virtualMachineId': node.id},
-                            method='GET')
-        return True
-
-    def detach_volume(self, volume):
-        """
-        :rtype: ``bool``
-        """
-        self._async_request(command='detachVolume',
-                            params={'id': volume.id},
-                            method='GET')
-        return True
-
-    def list_volumes(self, node=None):
-        """
-        List all volumes
-
-        :param node: Only return volumes for the provided node.
-        :type node: :class:`CloudStackNode`
-
-        :rtype: ``list`` of :class:`StorageVolume`
-        """
-        if node:
-            volumes = self._sync_request(command='listVolumes',
-                                         params={'virtualmachineid': node.id},
-                                         method='GET')
-        else:
-            volumes = self._sync_request(command='listVolumes',
-                                         method='GET')
-
-        list_volumes = []
-
-        extra_map = RESOURCE_EXTRA_ATTRIBUTES_MAP['volume']
-        for vol in volumes.get('volume', []):
-            extra = self._get_extra_dict(vol, extra_map)
-
-            if 'tags' in vol:
-                extra['tags'] = self._get_resource_tags(vol['tags'])
-
-            state = self._to_volume_state(vol)
-
-            list_volumes.append(StorageVolume(id=vol['id'],
-                                              name=vol['name'],
-                                              size=vol['size'],
-                                              state=state,
-                                              driver=self,
-                                              extra=extra))
-        return list_volumes
-
-    def ex_get_volume(self, volume_id, project=None):
-        """
-        Return a StorageVolume object based on its ID.
-
-        :param  volume_id: The id of the volume
-        :type   volume_id: ``str``
-
-        :keyword    project: Limit volume returned to those configured under
-                             the defined project.
-        :type       project: :class:`.CloudStackProject`
-
-        :rtype: :class:`CloudStackNode`
-        """
-        args = {'id': volume_id}
-        if project:
-            args['projectid'] = project.id
-        volumes = self._sync_request(command='listVolumes', params=args)
-        if not volumes:
-            raise Exception("Volume '%s' not found" % volume_id)
-        vol = volumes['volume'][0]
-
-        extra_map = RESOURCE_EXTRA_ATTRIBUTES_MAP['volume']
-        extra = self._get_extra_dict(vol, extra_map)
-
-        if 'tags' in vol:
-            extra['tags'] = self._get_resource_tags(vol['tags'])
-
-        state = self._to_volume_state(vol)
-
-        volume = StorageVolume(id=vol['id'], name=vol['name'], state=state,
-                               size=vol['size'], driver=self, extra=extra)
-        return volume
-
-    def list_key_pairs(self, **kwargs):
-        """
-        List registered key pairs.
-
-        :param     projectid: list objects by project
-        :type      projectid: ``str``
-
-        :param     page: The page to list the keypairs from
-        :type      page: ``int``
-
-        :param     keyword: List by keyword
-        :type      keyword: ``str``
-
-        :param     listall: If set to false, list only resources
-                            belonging to the command's caller;
-                            if set to true - list resources that
-                            the caller is authorized to see.
-                            Default value is false
-
-        :type      listall: ``bool``
-
-        :param     pagesize: The number of results per page
-        :type      pagesize: ``int``
-
-        :param     account: List resources by account.
-                            Must be used with the domainId parameter
-        :type      account: ``str``
-
-        :param     isrecursive: Defaults to false, but if true,
-                                lists all resources from
-                                the parent specified by the
-                                domainId till leaves.
-        :type      isrecursive: ``bool``
-
-        :param     fingerprint: A public key fingerprint to look for
-        :type      fingerprint: ``str``
-
-        :param     name: A key pair name to look for
-        :type      name: ``str``
-
-        :param     domainid: List only resources belonging to
-                                     the domain specified
-        :type      domainid: ``str``
-
-        :return:   A list of key par objects.
-        :rtype:   ``list`` of :class:`libcloud.compute.base.KeyPair`
-        """
-        extra_args = kwargs.copy()
-        res = self._sync_request(command='listSSHKeyPairs',
-                                 params=extra_args,
-                                 method='GET')
-        key_pairs = res.get('sshkeypair', [])
-        key_pairs = self._to_key_pairs(data=key_pairs)
-        return key_pairs
-
-    def get_key_pair(self, name):
-        """
-        Retrieve a single key pair.
-
-        :param name: Name of the key pair to retrieve.
-        :type name: ``str``
-
-        :rtype: :class:`.KeyPair`
-        """
-        params = {'name': name}
-        res = self._sync_request(command='listSSHKeyPairs',
-                                 params=params,
-                                 method='GET')
-        key_pairs = res.get('sshkeypair', [])
-
-        if len(key_pairs) == 0:
-            raise KeyPairDoesNotExistError(name=name, driver=self)
-
-        key_pair = self._to_key_pair(data=key_pairs[0])
-        return key_pair
-
-    def create_key_pair(self, name, **kwargs):
-        """
-        Create a new key pair object.
-
-        :param name: Key pair name.
-        :type name: ``str``
-
-        :param     name: Name of the keypair (required)
-        :type      name: ``str``
-
-        :param     projectid: An optional project for the ssh key
-        :type      projectid: ``str``
-
-        :param     domainid: An optional domainId for the ssh key.
-                             If the account parameter is used,
-                             domainId must also be used.
-        :type      domainid: ``str``
-
-        :param     account: An optional account for the ssh key.
-                            Must be used with domainId.
-        :type      account: ``str``
-
-        :return:   Created key pair object.
-        :rtype:    :class:`libcloud.compute.base.KeyPair`
-        """
-        extra_args = kwargs.copy()
-
-        params = {'name': name}
-        params.update(extra_args)
-
-        res = self._sync_request(command='createSSHKeyPair',
-                                 params=params,
-                                 method='GET')
-        key_pair = self._to_key_pair(data=res['keypair'])
-        return key_pair
-
-    def import_key_pair_from_string(self, name, key_material):
-        """
-        Import a new public key from string.
-
-        :param name: Key pair name.
-        :type name: ``str``
-
-        :param key_material: Public key material.
-        :type key_material: ``str``
-
-        :return: Imported key pair object.
-        :rtype: :class:`libcloud.compute.base.KeyPair`
-        """
-        res = self._sync_request(command='registerSSHKeyPair',
-                                 params={'name': name,
-                                         'publickey': key_material},
-                                 method='GET')
-        key_pair = self._to_key_pair(data=res['keypair'])
-        return key_pair
-
-    def delete_key_pair(self, key_pair, **kwargs):
-        """
-        Delete an existing key pair.
-
-        :param key_pair: Key pair object.
-        :type key_pair: :class:`libcloud.compute.base.KeyPair`
-
-        :param     projectid: The project associated with keypair
-        :type      projectid: ``str``
-
-        :param     domainid: The domain ID associated with the keypair
-        :type      domainid: ``str``
-
-        :param     account: The account associated with the keypair.
-                            Must be used with the domainId parameter.
-        :type      account: ``str``
-
-        :return:   True of False based on success of Keypair deletion
-        :rtype:    ``bool``
-        """
-
-        extra_args = kwargs.copy()
-        params = {'name': key_pair.name}
-        params.update(extra_args)
-
-        res = self._sync_request(command='deleteSSHKeyPair',
-                                 params=params,
-                                 method='GET')
-        return res['success'] == 'true'
-
-    def ex_list_public_ips(self):
-        """
-        Lists all Public IP Addresses.
-
-        :rtype: ``list`` of :class:`CloudStackAddress`
-        """
-        ips = []
-
-        res = self._sync_request(command='listPublicIpAddresses',
-                                 method='GET')
-
-        # Workaround for basic zones
-        if not res:
-            return ips
-
-        for ip in res['publicipaddress']:
-            ips.append(CloudStackAddress(ip['id'],
-                                         ip['ipaddress'],
-                                         self,
-                                         ip.get('associatednetworkid', []),
-                                         ip.get('vpcid'),
-                                         ip.get('virtualmachineid')))
-
-        return ips
-
-    def ex_allocate_public_ip(self, vpc_id=None, network_id=None,
-                              location=None):
-        """
-        Allocate a public IP.
-
-        :param vpc_id: VPC the ip belongs to
-        :type vpc_id: ``str``
-
-        :param network_id: Network where this IP is connected to.
-        :type network_id: ''str''
-
-        :param location: Zone
-        :type  location: :class:`NodeLocation`
-
-        :rtype: :class:`CloudStackAddress`
-        """
-
-        args = {}
-
-        if location is not None:
-            args['zoneid'] = location.id
-        else:
-            args['zoneid'] = self.list_locations()[0].id
-
-        if vpc_id is not None:
-            args['vpcid'] = vpc_id
-
-        if network_id is not None:
-            args['networkid'] = network_id
-
-        addr = self._async_request(command='associateIpAddress',
-                                   params=args,
-                                   method='GET')
-        addr = addr['ipaddress']
-        addr = CloudStackAddress(addr['id'], addr['ipaddress'], self)
-        return addr
-
-    def ex_release_public_ip(self, address):
-        """
-        Release a public IP.
-
-        :param address: CloudStackAddress which should be used
-        :type  address: :class:`CloudStackAddress`
-
-        :rtype: ``bool``
-        """
-        res = self._async_request(command='disassociateIpAddress',
-                                  params={'id': address.id},
-                                  method='GET')
-        return res['success']
-
-    def ex_list_firewall_rules(self):
-        """
-        Lists all Firewall Rules
-
-        :rtype: ``list`` of :class:`CloudStackFirewallRule`
-        """
-        rules = []
-        result = self._sync_request(command='listFirewallRules',
-                                    method='GET')
-        if result != {}:
-            public_ips = self.ex_list_public_ips()
-            for rule in result['firewallrule']:
-                addr = [a for a in public_ips if
-                        a.address == rule['ipaddress']]
-
-                rules.append(CloudStackFirewallRule(rule['id'],
-                                                    addr[0],
-                                                    rule['cidrlist'],
-                                                    rule['protocol'],
-                                                    rule.get('icmpcode'),
-                                                    rule.get('icmptype'),
-                                                    rule.get('startport'),
-                                                    rule.get('endport')))
-
-        return rules
-
-    def ex_create_firewall_rule(self, address, cidr_list, protocol,
-                                icmp_code=None, icmp_type=None,
-                                start_port=None, end_port=None):
-        """
-        Creates a Firewall Rule
-
-        :param      address: External IP address
-        :type       address: :class:`CloudStackAddress`
-
-        :param      cidr_list: cidr list
-        :type       cidr_list: ``str``
-
-        :param      protocol: TCP/IP Protocol (TCP, UDP)
-        :type       protocol: ``str``
-
-        :param      icmp_code: Error code for this icmp message
-        :type       icmp_code: ``int``
-
-        :param      icmp_type: Type of the icmp message being sent
-        :type       icmp_type: ``int``
-
-        :param      start_port: start of port range
-        :type       start_port: ``int``
-
-        :param      end_port: end of port range
-        :type       end_port: ``int``
-
-        :rtype: :class:`CloudStackFirewallRule`
-        """
-        args = {
-            'ipaddressid': address.id,
-            'cidrlist': cidr_list,
-            'protocol': protocol
-        }
-        if icmp_code is not None:
-            args['icmpcode'] = int(icmp_code)
-        if icmp_type is not None:
-            args['icmptype'] = int(icmp_type)
-        if start_port is not None:
-            args['startport'] = int(start_port)
-        if end_port is not None:
-            args['endport'] = int(end_port)
-        result = self._async_request(command='createFirewallRule',
-                                     params=args,
-                                     method='GET')
-        rule = CloudStackFirewallRule(result['firewallrule']['id'],
-                                      address,
-                                      cidr_list,
-                                      protocol,
-                                      icmp_code,
-                                      icmp_type,
-                                      start_port,
-                                      end_port)
-        return rule
-
-    def ex_delete_firewall_rule(self, firewall_rule):
-        """
-        Remove a Firewall Rule.
-
-        :param firewall_rule: Firewall rule which should be used
-        :type  firewall_rule: :class:`CloudStackFirewallRule`
-
-        :rtype: ``bool``
-        """
-        res = self._async_request(command='deleteFirewallRule',
-                      

<TRUNCATED>

[26/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/elasticstack.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/elasticstack.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/elasticstack.py
deleted file mode 100644
index 18b581b..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/elasticstack.py
+++ /dev/null
@@ -1,495 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-Base driver for the providers based on the ElasticStack platform -
-http://www.elasticstack.com.
-"""
-
-import re
-import time
-import base64
-
-from libcloud.utils.py3 import httplib
-from libcloud.utils.py3 import b
-
-try:
-    import simplejson as json
-except ImportError:
-    import json
-
-from libcloud.common.base import ConnectionUserAndKey, JsonResponse
-from libcloud.common.types import InvalidCredsError
-from libcloud.compute.types import NodeState
-from libcloud.compute.base import NodeDriver, NodeSize, Node
-from libcloud.compute.base import NodeImage
-from libcloud.compute.deployment import ScriptDeployment, SSHKeyDeployment
-from libcloud.compute.deployment import MultiStepDeployment
-
-
-NODE_STATE_MAP = {
-    'active': NodeState.RUNNING,
-    'dead': NodeState.TERMINATED,
-    'dumped': NodeState.TERMINATED,
-}
-
-# Default timeout (in seconds) for the drive imaging process
-IMAGING_TIMEOUT = 10 * 60
-
-# ElasticStack doesn't specify special instance types, so I just specified
-# some plans based on the other provider offerings.
-#
-# Basically for CPU any value between 500Mhz and 20000Mhz should work,
-# 256MB to 8192MB for ram and 1GB to 2TB for disk.
-INSTANCE_TYPES = {
-    'small': {
-        'id': 'small',
-        'name': 'Small instance',
-        'cpu': 2000,
-        'memory': 1700,
-        'disk': 160,
-        'bandwidth': None,
-    },
-    'medium': {
-        'id': 'medium',
-        'name': 'Medium instance',
-        'cpu': 3000,
-        'memory': 4096,
-        'disk': 500,
-        'bandwidth': None,
-    },
-    'large': {
-        'id': 'large',
-        'name': 'Large instance',
-        'cpu': 4000,
-        'memory': 7680,
-        'disk': 850,
-        'bandwidth': None,
-    },
-    'extra-large': {
-        'id': 'extra-large',
-        'name': 'Extra Large instance',
-        'cpu': 8000,
-        'memory': 8192,
-        'disk': 1690,
-        'bandwidth': None,
-    },
-    'high-cpu-medium': {
-        'id': 'high-cpu-medium',
-        'name': 'High-CPU Medium instance',
-        'cpu': 5000,
-        'memory': 1700,
-        'disk': 350,
-        'bandwidth': None,
-    },
-    'high-cpu-extra-large': {
-        'id': 'high-cpu-extra-large',
-        'name': 'High-CPU Extra Large instance',
-        'cpu': 20000,
-        'memory': 7168,
-        'disk': 1690,
-        'bandwidth': None,
-    },
-}
-
-
-class ElasticStackException(Exception):
-    def __str__(self):
-        return self.args[0]
-
-    def __repr__(self):
-        return "<ElasticStackException '%s'>" % (self.args[0])
-
-
-class ElasticStackResponse(JsonResponse):
-    def success(self):
-        if self.status == 401:
-            raise InvalidCredsError()
-
-        return self.status >= 200 and self.status <= 299
-
-    def parse_error(self):
-        error_header = self.headers.get('x-elastic-error', '')
-        return 'X-Elastic-Error: %s (%s)' % (error_header, self.body.strip())
-
-
-class ElasticStackNodeSize(NodeSize):
-    def __init__(self, id, name, cpu, ram, disk, bandwidth, price, driver):
-        self.id = id
-        self.name = name
-        self.cpu = cpu
-        self.ram = ram
-        self.disk = disk
-        self.bandwidth = bandwidth
-        self.price = price
-        self.driver = driver
-
-    def __repr__(self):
-        return (('<NodeSize: id=%s, name=%s, cpu=%s, ram=%s '
-                 'disk=%s bandwidth=%s price=%s driver=%s ...>')
-                % (self.id, self.name, self.cpu, self.ram,
-                   self.disk, self.bandwidth, self.price, self.driver.name))
-
-
-class ElasticStackBaseConnection(ConnectionUserAndKey):
-    """
-    Base connection class for the ElasticStack driver
-    """
-
-    host = None
-    responseCls = ElasticStackResponse
-
-    def add_default_headers(self, headers):
-        headers['Accept'] = 'application/json'
-        headers['Content-Type'] = 'application/json'
-        headers['Authorization'] = \
-            ('Basic %s' % (base64.b64encode(b('%s:%s' % (self.user_id,
-                                                         self.key))))
-                .decode('utf-8'))
-        return headers
-
-
-class ElasticStackBaseNodeDriver(NodeDriver):
-    website = 'http://www.elasticstack.com'
-    connectionCls = ElasticStackBaseConnection
-    features = {"create_node": ["generates_password"]}
-
-    def reboot_node(self, node):
-        # Reboots the node
-        response = self.connection.request(
-            action='/servers/%s/reset' % (node.id),
-            method='POST'
-        )
-        return response.status == 204
-
-    def destroy_node(self, node):
-        # Kills the server immediately
-        response = self.connection.request(
-            action='/servers/%s/destroy' % (node.id),
-            method='POST'
-        )
-        return response.status == 204
-
-    def list_images(self, location=None):
-        # Returns a list of available pre-installed system drive images
-        images = []
-        for key, value in self._standard_drives.items():
-            image = NodeImage(
-                id=value['uuid'],
-                name=value['description'],
-                driver=self.connection.driver,
-                extra={
-                    'size_gunzipped': value['size_gunzipped']
-                }
-            )
-            images.append(image)
-
-        return images
-
-    def list_sizes(self, location=None):
-        sizes = []
-        for key, value in INSTANCE_TYPES.items():
-            size = ElasticStackNodeSize(
-                id=value['id'],
-                name=value['name'], cpu=value['cpu'], ram=value['memory'],
-                disk=value['disk'], bandwidth=value['bandwidth'],
-                price=self._get_size_price(size_id=value['id']),
-                driver=self.connection.driver
-            )
-            sizes.append(size)
-
-        return sizes
-
-    def list_nodes(self):
-        # Returns a list of active (running) nodes
-        response = self.connection.request(action='/servers/info').object
-
-        nodes = []
-        for data in response:
-            node = self._to_node(data)
-            nodes.append(node)
-
-        return nodes
-
-    def create_node(self, **kwargs):
-        """Creates an ElasticStack instance
-
-        @inherits: :class:`NodeDriver.create_node`
-
-        :keyword    name: String with a name for this new node (required)
-        :type       name: ``str``
-
-        :keyword    smp: Number of virtual processors or None to calculate
-                         based on the cpu speed
-        :type       smp: ``int``
-
-        :keyword    nic_model: e1000, rtl8139 or virtio
-                               (if not specified, e1000 is used)
-        :type       nic_model: ``str``
-
-        :keyword    vnc_password: If set, the same password is also used for
-                                  SSH access with user toor,
-                                  otherwise VNC access is disabled and
-                                  no SSH login is possible.
-        :type       vnc_password: ``str``
-        """
-        size = kwargs['size']
-        image = kwargs['image']
-        smp = kwargs.get('smp', 'auto')
-        nic_model = kwargs.get('nic_model', 'e1000')
-        vnc_password = ssh_password = kwargs.get('vnc_password', None)
-
-        if nic_model not in ('e1000', 'rtl8139', 'virtio'):
-            raise ElasticStackException('Invalid NIC model specified')
-
-        # check that drive size is not smaller than pre installed image size
-
-        # First we create a drive with the specified size
-        drive_data = {}
-        drive_data.update({'name': kwargs['name'],
-                           'size': '%sG' % (kwargs['size'].disk)})
-
-        response = self.connection.request(action='/drives/create',
-                                           data=json.dumps(drive_data),
-                                           method='POST').object
-
-        if not response:
-            raise ElasticStackException('Drive creation failed')
-
-        drive_uuid = response['drive']
-
-        # Then we image the selected pre-installed system drive onto it
-        response = self.connection.request(
-            action='/drives/%s/image/%s/gunzip' % (drive_uuid, image.id),
-            method='POST'
-        )
-
-        if response.status not in (200, 204):
-            raise ElasticStackException('Drive imaging failed')
-
-        # We wait until the drive is imaged and then boot up the node
-        # (in most cases, the imaging process shouldn't take longer
-        # than a few minutes)
-        response = self.connection.request(
-            action='/drives/%s/info' % (drive_uuid)
-        ).object
-
-        imaging_start = time.time()
-        while 'imaging' in response:
-            response = self.connection.request(
-                action='/drives/%s/info' % (drive_uuid)
-            ).object
-
-            elapsed_time = time.time() - imaging_start
-            if ('imaging' in response and elapsed_time >= IMAGING_TIMEOUT):
-                raise ElasticStackException('Drive imaging timed out')
-
-            time.sleep(1)
-
-        node_data = {}
-        node_data.update({'name': kwargs['name'],
-                          'cpu': size.cpu,
-                          'mem': size.ram,
-                          'ide:0:0': drive_uuid,
-                          'boot': 'ide:0:0',
-                          'smp': smp})
-        node_data.update({'nic:0:model': nic_model, 'nic:0:dhcp': 'auto'})
-
-        if vnc_password:
-            node_data.update({'vnc': 'auto', 'vnc:password': vnc_password})
-
-        response = self.connection.request(
-            action='/servers/create', data=json.dumps(node_data),
-            method='POST'
-        ).object
-
-        if isinstance(response, list):
-            nodes = [self._to_node(node, ssh_password) for node in response]
-        else:
-            nodes = self._to_node(response, ssh_password)
-
-        return nodes
-
-    # Extension methods
-    def ex_set_node_configuration(self, node, **kwargs):
-        """
-        Changes the configuration of the running server
-
-        :param      node: Node which should be used
-        :type       node: :class:`Node`
-
-        :param      kwargs: keyword arguments
-        :type       kwargs: ``dict``
-
-        :rtype: ``bool``
-        """
-        valid_keys = ('^name$', '^parent$', '^cpu$', '^smp$', '^mem$',
-                      '^boot$', '^nic:0:model$', '^nic:0:dhcp',
-                      '^nic:1:model$', '^nic:1:vlan$', '^nic:1:mac$',
-                      '^vnc:ip$', '^vnc:password$', '^vnc:tls',
-                      '^ide:[0-1]:[0-1](:media)?$',
-                      '^scsi:0:[0-7](:media)?$', '^block:[0-7](:media)?$')
-
-        invalid_keys = []
-        keys = list(kwargs.keys())
-        for key in keys:
-            matches = False
-            for regex in valid_keys:
-                if re.match(regex, key):
-                    matches = True
-                    break
-            if not matches:
-                invalid_keys.append(key)
-
-        if invalid_keys:
-            raise ElasticStackException(
-                'Invalid configuration key specified: %s'
-                % (',' .join(invalid_keys))
-            )
-
-        response = self.connection.request(
-            action='/servers/%s/set' % (node.id), data=json.dumps(kwargs),
-            method='POST'
-        )
-
-        return (response.status == httplib.OK and response.body != '')
-
-    def deploy_node(self, **kwargs):
-        """
-        Create a new node, and start deployment.
-
-        @inherits: :class:`NodeDriver.deploy_node`
-
-        :keyword    enable_root: If true, root password will be set to
-                                 vnc_password (this will enable SSH access)
-                                 and default 'toor' account will be deleted.
-        :type       enable_root: ``bool``
-        """
-        image = kwargs['image']
-        vnc_password = kwargs.get('vnc_password', None)
-        enable_root = kwargs.get('enable_root', False)
-
-        if not vnc_password:
-            raise ValueError('You need to provide vnc_password argument '
-                             'if you want to use deployment')
-
-        if (image in self._standard_drives and
-                not self._standard_drives[image]['supports_deployment']):
-            raise ValueError('Image %s does not support deployment'
-                             % (image.id))
-
-        if enable_root:
-            script = ("unset HISTFILE;"
-                      "echo root:%s | chpasswd;"
-                      "sed -i '/^toor.*$/d' /etc/passwd /etc/shadow;"
-                      "history -c") % vnc_password
-            root_enable_script = ScriptDeployment(script=script,
-                                                  delete=True)
-            deploy = kwargs.get('deploy', None)
-            if deploy:
-                if (isinstance(deploy, ScriptDeployment) or
-                        isinstance(deploy, SSHKeyDeployment)):
-                    deployment = MultiStepDeployment([deploy,
-                                                      root_enable_script])
-                elif isinstance(deploy, MultiStepDeployment):
-                    deployment = deploy
-                    deployment.add(root_enable_script)
-            else:
-                deployment = root_enable_script
-
-            kwargs['deploy'] = deployment
-
-        if not kwargs.get('ssh_username', None):
-            kwargs['ssh_username'] = 'toor'
-
-        return super(ElasticStackBaseNodeDriver, self).deploy_node(**kwargs)
-
-    def ex_shutdown_node(self, node):
-        """
-        Sends the ACPI power-down event
-
-        :param      node: Node which should be used
-        :type       node: :class:`Node`
-
-        :rtype: ``bool``
-        """
-        response = self.connection.request(
-            action='/servers/%s/shutdown' % (node.id),
-            method='POST'
-        )
-        return response.status == 204
-
-    def ex_destroy_drive(self, drive_uuid):
-        """
-        Deletes a drive
-
-        :param      drive_uuid: Drive uuid which should be used
-        :type       drive_uuid: ``str``
-
-        :rtype: ``bool``
-        """
-        response = self.connection.request(
-            action='/drives/%s/destroy' % (drive_uuid),
-            method='POST'
-        )
-        return response.status == 204
-
-    # Helper methods
-    def _to_node(self, data, ssh_password=None):
-        try:
-            state = NODE_STATE_MAP[data['status']]
-        except KeyError:
-            state = NodeState.UNKNOWN
-
-        if 'nic:0:dhcp:ip' in data:
-            if isinstance(data['nic:0:dhcp:ip'], list):
-                public_ip = data['nic:0:dhcp:ip']
-            else:
-                public_ip = [data['nic:0:dhcp:ip']]
-        else:
-            public_ip = []
-
-        extra = {'cpu': data['cpu'],
-                 'mem': data['mem']}
-
-        if 'started' in data:
-            extra['started'] = data['started']
-
-        if 'smp' in data:
-            extra['smp'] = data['smp']
-
-        if 'vnc:ip' in data:
-            extra['vnc:ip'] = data['vnc:ip']
-
-        if 'vnc:password' in data:
-            extra['vnc:password'] = data['vnc:password']
-
-        boot_device = data['boot']
-
-        if isinstance(boot_device, list):
-            for device in boot_device:
-                extra[device] = data[device]
-        else:
-            extra[boot_device] = data[boot_device]
-
-        if ssh_password:
-            extra.update({'password': ssh_password})
-
-        node = Node(id=data['server'], name=data['name'], state=state,
-                    public_ips=public_ip, private_ips=None,
-                    driver=self.connection.driver,
-                    extra=extra)
-
-        return node

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/exoscale.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/exoscale.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/exoscale.py
deleted file mode 100644
index 9f883e0..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/exoscale.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from libcloud.compute.providers import Provider
-from libcloud.compute.drivers.cloudstack import CloudStackNodeDriver
-
-__all__ = [
-    'ExoscaleNodeDriver'
-]
-
-
-class ExoscaleNodeDriver(CloudStackNodeDriver):
-    type = Provider.EXOSCALE
-    name = 'Exoscale'
-    website = 'https://www.exoscale.ch/'
-
-    # API endpoint info
-    host = 'api.exoscale.ch'
-    path = '/compute'

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/gandi.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/gandi.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/gandi.py
deleted file mode 100644
index 844850a..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/gandi.py
+++ /dev/null
@@ -1,825 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-Gandi driver for compute
-"""
-import sys
-from datetime import datetime
-
-from libcloud.common.gandi import BaseGandiDriver, GandiException,\
-    NetworkInterface, IPAddress, Disk
-from libcloud.compute.base import KeyPair
-from libcloud.compute.base import StorageVolume
-from libcloud.compute.types import NodeState, Provider
-from libcloud.compute.base import Node, NodeDriver
-from libcloud.compute.base import NodeSize, NodeImage, NodeLocation
-
-
-NODE_STATE_MAP = {
-    'running': NodeState.RUNNING,
-    'halted': NodeState.TERMINATED,
-    'paused': NodeState.TERMINATED,
-    'locked': NodeState.TERMINATED,
-    'being_created': NodeState.PENDING,
-    'invalid': NodeState.UNKNOWN,
-    'legally_locked': NodeState.PENDING,
-    'deleted': NodeState.TERMINATED
-}
-
-NODE_PRICE_HOURLY_USD = 0.02
-
-INSTANCE_TYPES = {
-    'small': {
-        'id': 'small',
-        'name': 'Small instance',
-        'cpu': 1,
-        'memory': 256,
-        'disk': 3,
-        'bandwidth': 10240,
-    },
-    'medium': {
-        'id': 'medium',
-        'name': 'Medium instance',
-        'cpu': 1,
-        'memory': 1024,
-        'disk': 20,
-        'bandwidth': 10240,
-    },
-    'large': {
-        'id': 'large',
-        'name': 'Large instance',
-        'cpu': 2,
-        'memory': 2048,
-        'disk': 50,
-        'bandwidth': 10240,
-    },
-    'x-large': {
-        'id': 'x-large',
-        'name': 'Extra Large instance',
-        'cpu': 4,
-        'memory': 4096,
-        'disk': 100,
-        'bandwidth': 10240,
-    },
-}
-
-
-class GandiNodeDriver(BaseGandiDriver, NodeDriver):
-    """
-    Gandi node driver
-
-    """
-    api_name = 'gandi'
-    friendly_name = 'Gandi.net'
-    website = 'http://www.gandi.net/'
-    country = 'FR'
-    type = Provider.GANDI
-    # TODO : which features to enable ?
-    features = {}
-
-    def __init__(self, *args, **kwargs):
-        """
-        @inherits: :class:`NodeDriver.__init__`
-        """
-        super(BaseGandiDriver, self).__init__(*args, **kwargs)
-
-    def _resource_info(self, type, id):
-        try:
-            obj = self.connection.request('hosting.%s.info' % type, int(id))
-            return obj.object
-        except Exception:
-            e = sys.exc_info()[1]
-            raise GandiException(1003, e)
-        return None
-
-    def _node_info(self, id):
-        return self._resource_info('vm', id)
-
-    def _volume_info(self, id):
-        return self._resource_info('disk', id)
-
-    # Generic methods for driver
-    def _to_node(self, vm):
-        return Node(
-            id=vm['id'],
-            name=vm['hostname'],
-            state=NODE_STATE_MAP.get(
-                vm['state'],
-                NodeState.UNKNOWN
-            ),
-            public_ips=vm.get('ips', []),
-            private_ips=[],
-            driver=self,
-            extra={
-                'ai_active': vm.get('ai_active'),
-                'datacenter_id': vm.get('datacenter_id'),
-                'description': vm.get('description')
-            }
-        )
-
-    def _to_nodes(self, vms):
-        return [self._to_node(v) for v in vms]
-
-    def _to_volume(self, disk):
-        extra = {'can_snapshot': disk['can_snapshot']}
-        return StorageVolume(
-            id=disk['id'],
-            name=disk['name'],
-            size=int(disk['size']),
-            driver=self,
-            extra=extra)
-
-    def _to_volumes(self, disks):
-        return [self._to_volume(d) for d in disks]
-
-    def list_nodes(self):
-        """
-        Return a list of nodes in the current zone or all zones.
-
-        :return:  List of Node objects
-        :rtype:   ``list`` of :class:`Node`
-        """
-        vms = self.connection.request('hosting.vm.list').object
-        ips = self.connection.request('hosting.ip.list').object
-        for vm in vms:
-            vm['ips'] = []
-            for ip in ips:
-                if vm['ifaces_id'][0] == ip['iface_id']:
-                    ip = ip.get('ip', None)
-                    if ip:
-                        vm['ips'].append(ip)
-
-        nodes = self._to_nodes(vms)
-        return nodes
-
-    def ex_get_node(self, node_id):
-        """
-        Return a Node object based on a node id.
-
-        :param  name: The ID of the node
-        :type   name: ``int``
-
-        :return:  A Node object for the node
-        :rtype:   :class:`Node`
-        """
-        vm = self.connection.request('hosting.vm.info', int(node_id)).object
-        ips = self.connection.request('hosting.ip.list').object
-        vm['ips'] = []
-        for ip in ips:
-            if vm['ifaces_id'][0] == ip['iface_id']:
-                ip = ip.get('ip', None)
-                if ip:
-                    vm['ips'].append(ip)
-        node = self._to_node(vm)
-        return node
-
-    def reboot_node(self, node):
-        """
-        Reboot a node.
-
-        :param  node: Node to be rebooted
-        :type   node: :class:`Node`
-
-        :return:  True if successful, False if not
-        :rtype:   ``bool``
-        """
-        op = self.connection.request('hosting.vm.reboot', int(node.id))
-        self._wait_operation(op.object['id'])
-        vm = self._node_info(int(node.id))
-        if vm['state'] == 'running':
-            return True
-        return False
-
-    def destroy_node(self, node):
-        """
-        Destroy a node.
-
-        :param  node: Node object to destroy
-        :type   node: :class:`Node`
-
-        :return:  True if successful
-        :rtype:   ``bool``
-        """
-        vm = self._node_info(node.id)
-        if vm['state'] == 'running':
-            # Send vm_stop and wait for accomplish
-            op_stop = self.connection.request('hosting.vm.stop', int(node.id))
-            if not self._wait_operation(op_stop.object['id']):
-                raise GandiException(1010, 'vm.stop failed')
-            # Delete
-        op = self.connection.request('hosting.vm.delete', int(node.id))
-        if self._wait_operation(op.object['id']):
-            return True
-        return False
-
-    def deploy_node(self, **kwargs):
-        """
-        deploy_node is not implemented for gandi driver
-
-        :rtype: ``bool``
-        """
-        raise NotImplementedError(
-            'deploy_node not implemented for gandi driver')
-
-    def create_node(self, **kwargs):
-        """
-        Create a new Gandi node
-
-        :keyword    name:   String with a name for this new node (required)
-        :type       name:   ``str``
-
-        :keyword    image:  OS Image to boot on node. (required)
-        :type       image:  :class:`NodeImage`
-
-        :keyword    location: Which data center to create a node in. If empty,
-                              undefined behavior will be selected. (optional)
-        :type       location: :class:`NodeLocation`
-
-        :keyword    size:   The size of resources allocated to this node.
-                            (required)
-        :type       size:   :class:`NodeSize`
-
-        :keyword    login: user name to create for login on machine (required)
-        :type       login: ``str``
-
-        :keyword    password: password for user that'll be created (required)
-        :type       password: ``str``
-
-        :keyword    inet_family: version of ip to use, default 4 (optional)
-        :type       inet_family: ``int``
-
-        :keyword    keypairs: IDs of keypairs or Keypairs object
-        :type       keypairs: list of ``int`` or :class:`.KeyPair`
-
-        :rtype: :class:`Node`
-        """
-
-        if not kwargs.get('login') and not kwargs.get('keypairs'):
-            raise GandiException(1020, "Login and password or ssh keypair "
-                                 "must be defined for node creation")
-
-        location = kwargs.get('location')
-        if location and isinstance(location, NodeLocation):
-            dc_id = int(location.id)
-        else:
-            raise GandiException(
-                1021, 'location must be a subclass of NodeLocation')
-
-        size = kwargs.get('size')
-        if not size and not isinstance(size, NodeSize):
-            raise GandiException(
-                1022, 'size must be a subclass of NodeSize')
-
-        keypairs = kwargs.get('keypairs', [])
-        keypair_ids = [
-            k if isinstance(k, int) else k.extra['id']
-            for k in keypairs
-        ]
-
-        # If size name is in INSTANCE_TYPE we use new rating model
-        instance = INSTANCE_TYPES.get(size.id)
-        cores = instance['cpu'] if instance else int(size.id)
-
-        src_disk_id = int(kwargs['image'].id)
-
-        disk_spec = {
-            'datacenter_id': dc_id,
-            'name': 'disk_%s' % kwargs['name']
-        }
-
-        vm_spec = {
-            'datacenter_id': dc_id,
-            'hostname': kwargs['name'],
-            'memory': int(size.ram),
-            'cores': cores,
-            'bandwidth': int(size.bandwidth),
-            'ip_version': kwargs.get('inet_family', 4),
-        }
-
-        if kwargs.get('login') and kwargs.get('password'):
-            vm_spec.update({
-                'login': kwargs['login'],
-                'password': kwargs['password'],  # TODO : use NodeAuthPassword
-            })
-        if keypair_ids:
-            vm_spec['keys'] = keypair_ids
-
-        # Call create_from helper api. Return 3 operations : disk_create,
-        # iface_create,vm_create
-        (op_disk, op_iface, op_vm) = self.connection.request(
-            'hosting.vm.create_from',
-            vm_spec, disk_spec, src_disk_id
-        ).object
-
-        # We wait for vm_create to finish
-        if self._wait_operation(op_vm['id']):
-            # after successful operation, get ip information
-            # thru first interface
-            node = self._node_info(op_vm['vm_id'])
-            ifaces = node.get('ifaces')
-            if len(ifaces) > 0:
-                ips = ifaces[0].get('ips')
-                if len(ips) > 0:
-                    node['ip'] = ips[0]['ip']
-            return self._to_node(node)
-
-        return None
-
-    def _to_image(self, img):
-        return NodeImage(
-            id=img['disk_id'],
-            name=img['label'],
-            driver=self.connection.driver
-        )
-
-    def list_images(self, location=None):
-        """
-        Return a list of image objects.
-
-        :keyword    location: Which data center to filter a images in.
-        :type       location: :class:`NodeLocation`
-
-        :return:  List of GCENodeImage objects
-        :rtype:   ``list`` of :class:`GCENodeImage`
-        """
-        try:
-            if location:
-                filtering = {'datacenter_id': int(location.id)}
-            else:
-                filtering = {}
-            images = self.connection.request('hosting.image.list', filtering)
-            return [self._to_image(i) for i in images.object]
-        except Exception:
-            e = sys.exc_info()[1]
-            raise GandiException(1011, e)
-
-    def _to_size(self, id, size):
-        return NodeSize(
-            id=id,
-            name='%s cores' % id,
-            ram=size['memory'],
-            disk=size['disk'],
-            bandwidth=size['bandwidth'],
-            price=(self._get_size_price(size_id='1') * id),
-            driver=self.connection.driver,
-        )
-
-    def _instance_type_to_size(self, instance):
-        return NodeSize(
-            id=instance['id'],
-            name=instance['name'],
-            ram=instance['memory'],
-            disk=instance['disk'],
-            bandwidth=instance['bandwidth'],
-            price=self._get_size_price(size_id=instance['id']),
-            driver=self.connection.driver,
-        )
-
-    def list_instance_type(self, location=None):
-        return [self._instance_type_to_size(instance)
-                for name, instance in INSTANCE_TYPES.items()]
-
-    def list_sizes(self, location=None):
-        """
-        Return a list of sizes (machineTypes) in a zone.
-
-        :keyword  location: Which data center to filter a sizes in.
-        :type     location: :class:`NodeLocation` or ``None``
-
-        :return:  List of NodeSize objects
-        :rtype:   ``list`` of :class:`NodeSize`
-        """
-        account = self.connection.request('hosting.account.info').object
-        if account.get('rating_enabled'):
-            # This account use new rating model
-            return self.list_instance_type(location)
-        # Look for available shares, and return a list of share_definition
-        available_res = account['resources']['available']
-
-        if available_res['shares'] == 0:
-            return None
-        else:
-            share_def = account['share_definition']
-            available_cores = available_res['cores']
-            # 0.75 core given when creating a server
-            max_core = int(available_cores + 0.75)
-            shares = []
-            if available_res['servers'] < 1:
-                # No server quota, no way
-                return shares
-            for i in range(1, max_core + 1):
-                share = {id: i}
-                share_is_available = True
-                for k in ['memory', 'disk', 'bandwidth']:
-                    if share_def[k] * i > available_res[k]:
-                        # We run out for at least one resource inside
-                        share_is_available = False
-                    else:
-                        share[k] = share_def[k] * i
-                if share_is_available:
-                    nb_core = i
-                    shares.append(self._to_size(nb_core, share))
-            return shares
-
-    def _to_loc(self, loc):
-        return NodeLocation(
-            id=loc['id'],
-            name=loc['name'],
-            country=loc['country'],
-            driver=self
-        )
-
-    def list_locations(self):
-        """
-        Return a list of locations (datacenters).
-
-        :return: List of NodeLocation objects
-        :rtype: ``list`` of :class:`NodeLocation`
-        """
-        res = self.connection.request('hosting.datacenter.list')
-        return [self._to_loc(l) for l in res.object]
-
-    def list_volumes(self):
-        """
-        Return a list of volumes.
-
-        :return: A list of volume objects.
-        :rtype: ``list`` of :class:`StorageVolume`
-        """
-        res = self.connection.request('hosting.disk.list', {})
-        return self._to_volumes(res.object)
-
-    def ex_get_volume(self, volume_id):
-        """
-        Return a Volume object based on a volume ID.
-
-        :param  volume_id: The ID of the volume
-        :type   volume_id: ``int``
-
-        :return:  A StorageVolume object for the volume
-        :rtype:   :class:`StorageVolume`
-        """
-        res = self.connection.request('hosting.disk.info', volume_id)
-        return self._to_volume(res.object)
-
-    def create_volume(self, size, name, location=None, snapshot=None):
-        """
-        Create a volume (disk).
-
-        :param  size: Size of volume to create (in GB).
-        :type   size: ``int``
-
-        :param  name: Name of volume to create
-        :type   name: ``str``
-
-        :keyword  location: Location (zone) to create the volume in
-        :type     location: :class:`NodeLocation` or ``None``
-
-        :keyword  snapshot: Snapshot to create image from
-        :type     snapshot: :class:`Snapshot`
-
-        :return:  Storage Volume object
-        :rtype:   :class:`StorageVolume`
-        """
-        disk_param = {
-            'name': name,
-            'size': int(size),
-            'datacenter_id': int(location.id)
-        }
-        if snapshot:
-            op = self.connection.request('hosting.disk.create_from',
-                                         disk_param, int(snapshot.id))
-        else:
-            op = self.connection.request('hosting.disk.create', disk_param)
-        if self._wait_operation(op.object['id']):
-            disk = self._volume_info(op.object['disk_id'])
-            return self._to_volume(disk)
-        return None
-
-    def attach_volume(self, node, volume, device=None):
-        """
-        Attach a volume to a node.
-
-        :param  node: The node to attach the volume to
-        :type   node: :class:`Node`
-
-        :param  volume: The volume to attach.
-        :type   volume: :class:`StorageVolume`
-
-        :keyword  device: Not used in this cloud.
-        :type     device: ``None``
-
-        :return:  True if successful
-        :rtype:   ``bool``
-        """
-        op = self.connection.request('hosting.vm.disk_attach',
-                                     int(node.id), int(volume.id))
-        if self._wait_operation(op.object['id']):
-            return True
-        return False
-
-    def detach_volume(self, node, volume):
-        """
-        Detaches a volume from a node.
-
-        :param      node: Node which should be used
-        :type       node: :class:`Node`
-
-        :param      volume: Volume to be detached
-        :type       volume: :class:`StorageVolume`
-
-        :rtype: ``bool``
-        """
-        op = self.connection.request('hosting.vm.disk_detach',
-                                     int(node.id), int(volume.id))
-        if self._wait_operation(op.object['id']):
-            return True
-        return False
-
-    def destroy_volume(self, volume):
-        """
-        Destroy a volume.
-
-        :param  volume: Volume object to destroy
-        :type   volume: :class:`StorageVolume`
-
-        :return:  True if successful
-        :rtype:   ``bool``
-        """
-        op = self.connection.request('hosting.disk.delete', int(volume.id))
-        if self._wait_operation(op.object['id']):
-            return True
-        return False
-
-    def _to_iface(self, iface):
-        ips = []
-        for ip in iface.get('ips', []):
-            new_ip = IPAddress(
-                ip['id'],
-                NODE_STATE_MAP.get(
-                    ip['state'],
-                    NodeState.UNKNOWN
-                ),
-                ip['ip'],
-                self.connection.driver,
-                version=ip.get('version'),
-                extra={'reverse': ip['reverse']}
-            )
-            ips.append(new_ip)
-        return NetworkInterface(
-            iface['id'],
-            NODE_STATE_MAP.get(
-                iface['state'],
-                NodeState.UNKNOWN
-            ),
-            mac_address=None,
-            driver=self.connection.driver,
-            ips=ips,
-            node_id=iface.get('vm_id'),
-            extra={'bandwidth': iface['bandwidth']},
-        )
-
-    def _to_ifaces(self, ifaces):
-        return [self._to_iface(i) for i in ifaces]
-
-    def ex_list_interfaces(self):
-        """
-        Specific method to list network interfaces
-
-        :rtype: ``list`` of :class:`GandiNetworkInterface`
-        """
-        ifaces = self.connection.request('hosting.iface.list').object
-        ips = self.connection.request('hosting.ip.list').object
-        for iface in ifaces:
-            iface['ips'] = list(
-                filter(lambda i: i['iface_id'] == iface['id'], ips))
-        return self._to_ifaces(ifaces)
-
-    def _to_disk(self, element):
-        disk = Disk(
-            id=element['id'],
-            state=NODE_STATE_MAP.get(
-                element['state'],
-                NodeState.UNKNOWN
-            ),
-            name=element['name'],
-            driver=self.connection.driver,
-            size=element['size'],
-            extra={'can_snapshot': element['can_snapshot']}
-        )
-        return disk
-
-    def _to_disks(self, elements):
-        return [self._to_disk(el) for el in elements]
-
-    def ex_list_disks(self):
-        """
-        Specific method to list all disk
-
-        :rtype: ``list`` of :class:`GandiDisk`
-        """
-        res = self.connection.request('hosting.disk.list', {})
-        return self._to_disks(res.object)
-
-    def ex_node_attach_disk(self, node, disk):
-        """
-        Specific method to attach a disk to a node
-
-        :param      node: Node which should be used
-        :type       node: :class:`Node`
-
-        :param      disk: Disk which should be used
-        :type       disk: :class:`GandiDisk`
-
-        :rtype: ``bool``
-        """
-        op = self.connection.request('hosting.vm.disk_attach',
-                                     int(node.id), int(disk.id))
-        if self._wait_operation(op.object['id']):
-            return True
-        return False
-
-    def ex_node_detach_disk(self, node, disk):
-        """
-        Specific method to detach a disk from a node
-
-        :param      node: Node which should be used
-        :type       node: :class:`Node`
-
-        :param      disk: Disk which should be used
-        :type       disk: :class:`GandiDisk`
-
-        :rtype: ``bool``
-        """
-        op = self.connection.request('hosting.vm.disk_detach',
-                                     int(node.id), int(disk.id))
-        if self._wait_operation(op.object['id']):
-            return True
-        return False
-
-    def ex_node_attach_interface(self, node, iface):
-        """
-        Specific method to attach an interface to a node
-
-        :param      node: Node which should be used
-        :type       node: :class:`Node`
-
-        :param      iface: Network interface which should be used
-        :type       iface: :class:`GandiNetworkInterface`
-
-        :rtype: ``bool``
-        """
-        op = self.connection.request('hosting.vm.iface_attach',
-                                     int(node.id), int(iface.id))
-        if self._wait_operation(op.object['id']):
-            return True
-        return False
-
-    def ex_node_detach_interface(self, node, iface):
-        """
-        Specific method to detach an interface from a node
-
-        :param      node: Node which should be used
-        :type       node: :class:`Node`
-
-        :param      iface: Network interface which should be used
-        :type       iface: :class:`GandiNetworkInterface`
-
-        :rtype: ``bool``
-        """
-        op = self.connection.request('hosting.vm.iface_detach',
-                                     int(node.id), int(iface.id))
-        if self._wait_operation(op.object['id']):
-            return True
-        return False
-
-    def ex_snapshot_disk(self, disk, name=None):
-        """
-        Specific method to make a snapshot of a disk
-
-        :param      disk: Disk which should be used
-        :type       disk: :class:`GandiDisk`
-
-        :param      name: Name which should be used
-        :type       name: ``str``
-
-        :rtype: ``bool``
-        """
-        if not disk.extra.get('can_snapshot'):
-            raise GandiException(1021, 'Disk %s can\'t snapshot' % disk.id)
-        if not name:
-            suffix = datetime.today().strftime('%Y%m%d')
-            name = 'snap_%s' % (suffix)
-        op = self.connection.request(
-            'hosting.disk.create_from',
-            {'name': name, 'type': 'snapshot', },
-            int(disk.id),
-        )
-        if self._wait_operation(op.object['id']):
-            return True
-        return False
-
-    def ex_update_disk(self, disk, new_size=None, new_name=None):
-        """Specific method to update size or name of a disk
-        WARNING: if a server is attached it'll be rebooted
-
-        :param      disk: Disk which should be used
-        :type       disk: :class:`GandiDisk`
-
-        :param      new_size: New size
-        :type       new_size: ``int``
-
-        :param      new_name: New name
-        :type       new_name: ``str``
-
-        :rtype: ``bool``
-        """
-        params = {}
-        if new_size:
-            params.update({'size': new_size})
-        if new_name:
-            params.update({'name': new_name})
-        op = self.connection.request('hosting.disk.update',
-                                     int(disk.id),
-                                     params)
-        if self._wait_operation(op.object['id']):
-            return True
-        return False
-
-    def _to_key_pair(self, data):
-        key_pair = KeyPair(name=data['name'],
-                           fingerprint=data['fingerprint'],
-                           public_key=data.get('value', None),
-                           private_key=data.get('privatekey', None),
-                           driver=self, extra={'id': data['id']})
-        return key_pair
-
-    def _to_key_pairs(self, data):
-        return [self._to_key_pair(k) for k in data]
-
-    def list_key_pairs(self):
-        """
-        List registered key pairs.
-
-        :return:   A list of key par objects.
-        :rtype:   ``list`` of :class:`libcloud.compute.base.KeyPair`
-        """
-        kps = self.connection.request('hosting.ssh.list').object
-        return self._to_key_pairs(kps)
-
-    def get_key_pair(self, name):
-        """
-        Retrieve a single key pair.
-
-        :param name: Name of the key pair to retrieve.
-        :type name: ``str``
-
-        :rtype: :class:`.KeyPair`
-        """
-        filter_params = {'name': name}
-        kps = self.connection.request('hosting.ssh.list', filter_params).object
-        return self._to_key_pair(kps[0])
-
-    def import_key_pair_from_string(self, name, key_material):
-        """
-        Create a new key pair object.
-
-        :param name: Key pair name.
-        :type name: ``str``
-
-        :param key_material: Public key material.
-        :type key_material: ``str``
-
-        :return: Imported key pair object.
-        :rtype: :class:`.KeyPair`
-        """
-        params = {'name': name, 'value': key_material}
-        kp = self.connection.request('hosting.ssh.create', params).object
-        return self._to_key_pair(kp)
-
-    def delete_key_pair(self, key_pair):
-        """
-        Delete an existing key pair.
-
-        :param key_pair: Key pair object or ID.
-        :type key_pair: :class.KeyPair` or ``int``
-
-        :return:   True of False based on success of Keypair deletion
-        :rtype:    ``bool``
-        """
-        key_id = key_pair if isinstance(key_pair, int) \
-            else key_pair.extra['id']
-        success = self.connection.request('hosting.ssh.delete', key_id).object
-        return success


[08/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/rackspace.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/rackspace.py b/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/rackspace.py
deleted file mode 100644
index db30f85..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/rackspace.py
+++ /dev/null
@@ -1,1531 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from datetime import datetime
-
-try:
-    import simplejson as json
-except ImportError:
-    import json
-
-from libcloud.utils.py3 import httplib
-from libcloud.utils.misc import reverse_dict
-from libcloud.loadbalancer.base import LoadBalancer, Member, Driver, Algorithm
-from libcloud.loadbalancer.base import DEFAULT_ALGORITHM
-from libcloud.compute.drivers.rackspace import RackspaceConnection
-from libcloud.common.types import LibcloudError
-from libcloud.common.base import JsonResponse, PollingConnection
-from libcloud.loadbalancer.types import State, MemberCondition
-from libcloud.common.openstack import OpenStackDriverMixin
-from libcloud.common.rackspace import AUTH_URL
-
-ENDPOINT_ARGS_MAP = {
-    'dfw': {'service_type': 'rax:load-balancer',
-            'name': 'cloudLoadBalancers',
-            'region': 'DFW'},
-    'ord': {'service_type': 'rax:load-balancer',
-            'name': 'cloudLoadBalancers',
-            'region': 'ORD'},
-    'iad': {'service_type': 'rax:load-balancer',
-            'name': 'cloudLoadBalancers',
-            'region': 'IAD'},
-    'lon': {'service_type': 'rax:load-balancer',
-            'name': 'cloudLoadBalancers',
-            'region': 'LON'},
-    'syd': {'service_type': 'rax:load-balancer',
-            'name': 'cloudLoadBalancers',
-            'region': 'SYD'},
-    'hkg': {'service_type': 'rax:load-balancer',
-            'name': 'cloudLoadBalancers',
-            'region': 'HKG'},
-
-}
-
-
-class RackspaceResponse(JsonResponse):
-    def parse_body(self):
-        if not self.body:
-            return None
-        return super(RackspaceResponse, self).parse_body()
-
-    def success(self):
-        return 200 <= int(self.status) <= 299
-
-
-class RackspaceHealthMonitor(object):
-    """
-    :param type: type of load balancer.  currently CONNECT (connection
-                 monitoring), HTTP, HTTPS (connection and HTTP
-                 monitoring) are supported.
-    :type type: ``str``
-
-    :param delay: minimum seconds to wait before executing the health
-                      monitor.  (Must be between 1 and 3600)
-    :type delay: ``int``
-
-    :param timeout: maximum seconds to wait when establishing a
-                    connection before timing out.  (Must be between 1
-                    and 3600)
-    :type timeout: ``int``
-
-    :param attempts_before_deactivation: Number of monitor failures
-                                         before removing a node from
-                                         rotation. (Must be between 1
-                                         and 10)
-    :type attempts_before_deactivation: ``int``
-    """
-
-    def __init__(self, type, delay, timeout, attempts_before_deactivation):
-        self.type = type
-        self.delay = delay
-        self.timeout = timeout
-        self.attempts_before_deactivation = attempts_before_deactivation
-
-    def __repr__(self):
-        return ('<RackspaceHealthMonitor: type=%s, delay=%d, timeout=%d, '
-                'attempts_before_deactivation=%d>' %
-                (self.type, self.delay, self.timeout,
-                 self.attempts_before_deactivation))
-
-    def _to_dict(self):
-        return {
-            'type': self.type,
-            'delay': self.delay,
-            'timeout': self.timeout,
-            'attemptsBeforeDeactivation': self.attempts_before_deactivation
-        }
-
-
-class RackspaceHTTPHealthMonitor(RackspaceHealthMonitor):
-    """
-    A HTTP health monitor adds extra features to a Rackspace health monitor.
-
-    :param path: the HTTP path to monitor.
-    :type path: ``str``
-
-    :param body_regex: Regular expression used to evaluate the body of
-                       the HTTP response.
-    :type body_regex: ``str``
-
-    :param status_regex: Regular expression used to evaluate the HTTP
-                         status code of the response.
-    :type status_regex: ``str``
-    """
-
-    def __init__(self, type, delay, timeout, attempts_before_deactivation,
-                 path, body_regex, status_regex):
-        super(RackspaceHTTPHealthMonitor, self).__init__(
-            type, delay, timeout, attempts_before_deactivation)
-        self.path = path
-        self.body_regex = body_regex
-        self.status_regex = status_regex
-
-    def __repr__(self):
-        return ('<RackspaceHTTPHealthMonitor: type=%s, delay=%d, timeout=%d, '
-                'attempts_before_deactivation=%d, path=%s, body_regex=%s, '
-                'status_regex=%s>' %
-                (self.type, self.delay, self.timeout,
-                 self.attempts_before_deactivation, self.path, self.body_regex,
-                 self.status_regex))
-
-    def _to_dict(self):
-        super_dict = super(RackspaceHTTPHealthMonitor, self)._to_dict()
-        super_dict['path'] = self.path
-        super_dict['statusRegex'] = self.status_regex
-
-        if self.body_regex:
-            super_dict['bodyRegex'] = self.body_regex
-
-        return super_dict
-
-
-class RackspaceConnectionThrottle(object):
-    """
-    :param min_connections: Minimum number of connections per IP address
-                            before applying throttling.
-    :type min_connections: ``int``
-
-    :param max_connections: Maximum number of connections per IP address.
-                            (Must be between 0 and 100000, 0 allows an
-                            unlimited number of connections.)
-    :type max_connections: ``int``
-
-    :param max_connection_rate: Maximum number of connections allowed
-                                from a single IP address within the
-                                given rate_interval_seconds.  (Must be
-                                between 0 and 100000, 0 allows an
-                                unlimited number of connections.)
-    :type max_connection_rate: ``int``
-
-    :param rate_interval_seconds: Interval at which the
-                                  max_connection_rate is enforced.
-                                  (Must be between 1 and 3600.)
-    :type rate_interval_seconds: ``int``
-    """
-
-    def __init__(self, min_connections, max_connections,
-                 max_connection_rate, rate_interval_seconds):
-        self.min_connections = min_connections
-        self.max_connections = max_connections
-        self.max_connection_rate = max_connection_rate
-        self.rate_interval_seconds = rate_interval_seconds
-
-    def __repr__(self):
-        return ('<RackspaceConnectionThrottle: min_connections=%d, '
-                'max_connections=%d, max_connection_rate=%d, '
-                'rate_interval_seconds=%d>' %
-                (self.min_connections, self.max_connections,
-                 self.max_connection_rate, self.rate_interval_seconds))
-
-    def _to_dict(self):
-        return {
-            'maxConnections': self.max_connections,
-            'minConnections': self.min_connections,
-            'maxConnectionRate': self.max_connection_rate,
-            'rateInterval': self.rate_interval_seconds
-        }
-
-
-class RackspaceAccessRuleType(object):
-    ALLOW = 0
-    DENY = 1
-
-    _RULE_TYPE_STRING_MAP = {
-        ALLOW: 'ALLOW',
-        DENY: 'DENY'
-    }
-
-
-class RackspaceAccessRule(object):
-    """
-    An access rule allows or denies traffic to a Load Balancer based on the
-    incoming IPs.
-
-    :param id: Unique identifier to refer to this rule by.
-    :type id: ``str``
-
-    :param rule_type: RackspaceAccessRuleType.ALLOW or
-                      RackspaceAccessRuleType.DENY.
-    :type id: ``int``
-
-    :param address: IP address or cidr (can be IPv4 or IPv6).
-    :type address: ``str``
-    """
-
-    def __init__(self, id=None, rule_type=None, address=None):
-        self.id = id
-        self.rule_type = rule_type
-        self.address = address
-
-    def _to_dict(self):
-        type_string =\
-            RackspaceAccessRuleType._RULE_TYPE_STRING_MAP[self.rule_type]
-
-        as_dict = {
-            'type': type_string,
-            'address': self.address
-        }
-
-        if self.id is not None:
-            as_dict['id'] = self.id
-
-        return as_dict
-
-
-class RackspaceConnection(RackspaceConnection, PollingConnection):
-    responseCls = RackspaceResponse
-    auth_url = AUTH_URL
-    poll_interval = 2
-    timeout = 80
-    cache_busting = True
-
-    def request(self, action, params=None, data='', headers=None,
-                method='GET'):
-        if not headers:
-            headers = {}
-        if not params:
-            params = {}
-
-        if method in ('POST', 'PUT'):
-            headers['Content-Type'] = 'application/json'
-
-        return super(RackspaceConnection, self).request(
-            action=action, params=params,
-            data=data, method=method, headers=headers)
-
-    def get_poll_request_kwargs(self, response, context, request_kwargs):
-        return {'action': request_kwargs['action'],
-                'method': 'GET'}
-
-    def has_completed(self, response):
-        state = response.object['loadBalancer']['status']
-        if state == 'ERROR':
-            raise LibcloudError("Load balancer entered an ERROR state.",
-                                driver=self.driver)
-
-        return state == 'ACTIVE'
-
-    def encode_data(self, data):
-        return data
-
-
-class RackspaceLBDriver(Driver, OpenStackDriverMixin):
-    connectionCls = RackspaceConnection
-    api_name = 'rackspace_lb'
-    name = 'Rackspace LB'
-    website = 'http://www.rackspace.com/'
-
-    LB_STATE_MAP = {
-        'ACTIVE': State.RUNNING,
-        'BUILD': State.PENDING,
-        'ERROR': State.ERROR,
-        'DELETED': State.DELETED,
-        'PENDING_UPDATE': State.PENDING,
-        'PENDING_DELETE': State.PENDING
-    }
-
-    LB_MEMBER_CONDITION_MAP = {
-        'ENABLED': MemberCondition.ENABLED,
-        'DISABLED': MemberCondition.DISABLED,
-        'DRAINING': MemberCondition.DRAINING
-    }
-
-    CONDITION_LB_MEMBER_MAP = reverse_dict(LB_MEMBER_CONDITION_MAP)
-
-    _VALUE_TO_ALGORITHM_MAP = {
-        'RANDOM': Algorithm.RANDOM,
-        'ROUND_ROBIN': Algorithm.ROUND_ROBIN,
-        'LEAST_CONNECTIONS': Algorithm.LEAST_CONNECTIONS,
-        'WEIGHTED_ROUND_ROBIN': Algorithm.WEIGHTED_ROUND_ROBIN,
-        'WEIGHTED_LEAST_CONNECTIONS': Algorithm.WEIGHTED_LEAST_CONNECTIONS
-    }
-
-    _ALGORITHM_TO_VALUE_MAP = reverse_dict(_VALUE_TO_ALGORITHM_MAP)
-
-    def __init__(self, key, secret=None, secure=True, host=None, port=None,
-                 region='ord', **kwargs):
-        ex_force_region = kwargs.pop('ex_force_region', None)
-        if ex_force_region:
-            # For backward compatibility
-            region = ex_force_region
-        OpenStackDriverMixin.__init__(self, **kwargs)
-        super(RackspaceLBDriver, self).__init__(key=key, secret=secret,
-                                                secure=secure, host=host,
-                                                port=port, region=region)
-
-    @classmethod
-    def list_regions(cls):
-        return ENDPOINT_ARGS_MAP.keys()
-
-    def _ex_connection_class_kwargs(self):
-        endpoint_args = ENDPOINT_ARGS_MAP[self.region]
-        kwargs = self.openstack_connection_kwargs()
-        kwargs['get_endpoint_args'] = endpoint_args
-        return kwargs
-
-    def list_protocols(self):
-        return self._to_protocols(
-            self.connection.request('/loadbalancers/protocols').object)
-
-    def ex_list_protocols_with_default_ports(self):
-        """
-        List protocols with default ports.
-
-        :rtype: ``list`` of ``tuple``
-        :return: A list of protocols with default ports included.
-        """
-        return self._to_protocols_with_default_ports(
-            self.connection.request('/loadbalancers/protocols').object)
-
-    def list_balancers(self, ex_member_address=None):
-        """
-        @inherits: :class:`Driver.list_balancers`
-
-        :param ex_member_address: Optional IP address of the attachment member.
-                                  If provided, only the load balancers which
-                                  have this member attached will be returned.
-        :type ex_member_address: ``str``
-        """
-        params = {}
-
-        if ex_member_address:
-            params['nodeaddress'] = ex_member_address
-
-        return self._to_balancers(
-            self.connection.request('/loadbalancers', params=params).object)
-
-    def create_balancer(self, name, members, protocol='http',
-                        port=80, algorithm=DEFAULT_ALGORITHM):
-        return self.ex_create_balancer(name, members, protocol, port,
-                                       algorithm)
-
-    def ex_create_balancer(self, name, members, protocol='http',
-                           port=80, algorithm=DEFAULT_ALGORITHM, vip='PUBLIC'):
-        """
-        Creates a new load balancer instance
-
-        :param name: Name of the new load balancer (required)
-        :type  name: ``str``
-
-        :param members: ``list`` of:class:`Member`s to attach to balancer
-        :type  members: ``list`` of :class:`Member`
-
-        :param protocol: Loadbalancer protocol, defaults to http.
-        :type  protocol: ``str``
-
-        :param port: Port the load balancer should listen on, defaults to 80
-        :type  port: ``str``
-
-        :param algorithm: Load balancing algorithm, defaults to
-                            LBAlgorithm.ROUND_ROBIN
-        :type  algorithm: :class:`Algorithm`
-
-        :param vip: Virtual ip type of PUBLIC, SERVICENET, or ID of a virtual
-                      ip
-        :type  vip: ``str``
-
-        :rtype: :class:`LoadBalancer`
-        """
-        balancer_attrs = self._kwargs_to_mutable_attrs(
-            name=name,
-            protocol=protocol,
-            port=port,
-            algorithm=algorithm,
-            vip=vip)
-
-        balancer_attrs.update({
-            'nodes': [self._member_attributes(member) for member in members],
-        })
-        # balancer_attrs['nodes'] = ['fu']
-        balancer_object = {"loadBalancer": balancer_attrs}
-
-        resp = self.connection.request('/loadbalancers',
-                                       method='POST',
-                                       data=json.dumps(balancer_object))
-        return self._to_balancer(resp.object['loadBalancer'])
-
-    def _member_attributes(self, member):
-        member_attributes = {'address': member.ip,
-                             'port': member.port}
-
-        member_attributes.update(self._kwargs_to_mutable_member_attrs(
-            **member.extra))
-
-        # If the condition is not specified on the member, then it should be
-        # set to ENABLED by default
-        if 'condition' not in member_attributes:
-            member_attributes['condition'] =\
-                self.CONDITION_LB_MEMBER_MAP[MemberCondition.ENABLED]
-
-        return member_attributes
-
-    def destroy_balancer(self, balancer):
-        uri = '/loadbalancers/%s' % (balancer.id)
-        resp = self.connection.request(uri, method='DELETE')
-
-        return resp.status == httplib.ACCEPTED
-
-    def ex_destroy_balancers(self, balancers):
-        """
-        Destroys a list of Balancers (the API supports up to 10).
-
-        :param balancers: A list of Balancers to destroy.
-        :type balancers: ``list`` of :class:`LoadBalancer`
-
-        :return: Returns whether the destroy request was accepted.
-        :rtype: ``bool``
-        """
-        ids = [('id', balancer.id) for balancer in balancers]
-        resp = self.connection.request('/loadbalancers',
-                                       method='DELETE',
-                                       params=ids)
-
-        return resp.status == httplib.ACCEPTED
-
-    def get_balancer(self, balancer_id):
-        uri = '/loadbalancers/%s' % (balancer_id)
-        resp = self.connection.request(uri)
-
-        return self._to_balancer(resp.object["loadBalancer"])
-
-    def balancer_attach_member(self, balancer, member):
-        member_object = {"nodes": [self._member_attributes(member)]}
-
-        uri = '/loadbalancers/%s/nodes' % (balancer.id)
-        resp = self.connection.request(uri, method='POST',
-                                       data=json.dumps(member_object))
-        return self._to_members(resp.object, balancer)[0]
-
-    def ex_balancer_attach_members(self, balancer, members):
-        """
-        Attaches a list of members to a load balancer.
-
-        :param balancer: The Balancer to which members will be attached.
-        :type  balancer: :class:`LoadBalancer`
-
-        :param members: A list of Members to attach.
-        :type  members: ``list`` of :class:`Member`
-
-        :rtype: ``list`` of :class:`Member`
-        """
-        member_objects = {"nodes": [self._member_attributes(member) for member
-                                    in members]}
-
-        uri = '/loadbalancers/%s/nodes' % (balancer.id)
-        resp = self.connection.request(uri, method='POST',
-                                       data=json.dumps(member_objects))
-        return self._to_members(resp.object, balancer)
-
-    def balancer_detach_member(self, balancer, member):
-        # Loadbalancer always needs to have at least 1 member.
-        # Last member cannot be detached. You can only disable it or destroy
-        # the balancer.
-        uri = '/loadbalancers/%s/nodes/%s' % (balancer.id, member.id)
-        resp = self.connection.request(uri, method='DELETE')
-
-        return resp.status == httplib.ACCEPTED
-
-    def ex_balancer_detach_members(self, balancer, members):
-        """
-        Detaches a list of members from a balancer (the API supports up to 10).
-        This method blocks until the detach request has been processed and the
-        balancer is in a RUNNING state again.
-
-        :param balancer: The Balancer to detach members from.
-        :type  balancer: :class:`LoadBalancer`
-
-        :param members: A list of Members to detach.
-        :type  members: ``list`` of :class:`Member`
-
-        :return: Updated Balancer.
-        :rtype: :class:`LoadBalancer`
-        """
-        accepted = self.ex_balancer_detach_members_no_poll(balancer, members)
-
-        if not accepted:
-            msg = 'Detach members request was not accepted'
-            raise LibcloudError(msg, driver=self)
-
-        return self._get_updated_balancer(balancer)
-
-    def ex_balancer_detach_members_no_poll(self, balancer, members):
-        """
-        Detaches a list of members from a balancer (the API supports up to 10).
-        This method returns immediately.
-
-        :param balancer: The Balancer to detach members from.
-        :type  balancer: :class:`LoadBalancer`
-
-        :param members: A list of Members to detach.
-        :type  members: ``list`` of :class:`Member`
-
-        :return: Returns whether the detach request was accepted.
-        :rtype: ``bool``
-        """
-        uri = '/loadbalancers/%s/nodes' % (balancer.id)
-        ids = [('id', member.id) for member in members]
-        resp = self.connection.request(uri, method='DELETE', params=ids)
-
-        return resp.status == httplib.ACCEPTED
-
-    def balancer_list_members(self, balancer):
-        uri = '/loadbalancers/%s/nodes' % (balancer.id)
-        data = self.connection.request(uri).object
-        return self._to_members(data, balancer)
-
-    def update_balancer(self, balancer, **kwargs):
-        attrs = self._kwargs_to_mutable_attrs(**kwargs)
-        resp = self.connection.async_request(
-            action='/loadbalancers/%s' % balancer.id,
-            method='PUT',
-            data=json.dumps(attrs))
-        return self._to_balancer(resp.object["loadBalancer"])
-
-    def ex_update_balancer_no_poll(self, balancer, **kwargs):
-        """
-        Update balancer no poll.
-
-        @inherits: :class:`Driver.update_balancer`
-        """
-        attrs = self._kwargs_to_mutable_attrs(**kwargs)
-        resp = self.connection.request(
-            action='/loadbalancers/%s' % balancer.id,
-            method='PUT',
-            data=json.dumps(attrs))
-        return resp.status == httplib.ACCEPTED
-
-    def ex_balancer_update_member(self, balancer, member, **kwargs):
-        """
-        Updates a Member's extra attributes for a Balancer.  The attributes can
-        include 'weight' or 'condition'.  This method blocks until the update
-        request has been processed and the balancer is in a RUNNING state
-        again.
-
-        :param balancer: Balancer to update the member on.
-        :type  balancer: :class:`LoadBalancer`
-
-        :param member: Member which should be used
-        :type member: :class:`Member`
-
-        :keyword **kwargs: New attributes.  Should contain either 'weight'
-        or 'condition'.  'condition' can be set to 'ENABLED', 'DISABLED'.
-        or 'DRAINING'.  'weight' can be set to a positive integer between
-        1 and 100, with a higher weight indicating that the node will receive
-        more traffic (assuming the Balancer is using a weighted algorithm).
-        :type **kwargs: ``dict``
-
-        :return: Updated Member.
-        :rtype: :class:`Member`
-        """
-        accepted = self.ex_balancer_update_member_no_poll(
-            balancer, member, **kwargs)
-
-        if not accepted:
-            msg = 'Update member attributes was not accepted'
-            raise LibcloudError(msg, driver=self)
-
-        balancer = self._get_updated_balancer(balancer)
-        members = balancer.extra['members']
-
-        updated_members = [m for m in members if m.id == member.id]
-
-        if not updated_members:
-            raise LibcloudError('Could not find updated member')
-
-        return updated_members[0]
-
-    def ex_balancer_update_member_no_poll(self, balancer, member, **kwargs):
-        """
-        Updates a Member's extra attributes for a Balancer.  The attribute can
-        include 'weight' or 'condition'.  This method returns immediately.
-
-        :param balancer: Balancer to update the member on.
-        :type balancer: :class:`LoadBalancer`
-
-        :param member: Member which should be used
-        :type member: :class:`Member`
-
-        :keyword **kwargs: New attributes.  Should contain either 'weight'
-        or 'condition'.  'condition' can be set to 'ENABLED', 'DISABLED'.
-        or 'DRAINING'.  'weight' can be set to a positive integer between
-        1 and 100, with a higher weight indicating that the node will receive
-        more traffic (assuming the Balancer is using a weighted algorithm).
-        :type **kwargs: ``dict``
-
-        :return: Returns whether the update request was accepted.
-        :rtype: ``bool``
-        """
-        resp = self.connection.request(
-            action='/loadbalancers/%s/nodes/%s' % (balancer.id, member.id),
-            method='PUT',
-            data=json.dumps(self._kwargs_to_mutable_member_attrs(**kwargs))
-        )
-
-        return resp.status == httplib.ACCEPTED
-
-    def ex_list_algorithm_names(self):
-        """
-        Lists algorithms supported by the API.  Returned as strings because
-        this list may change in the future.
-
-        :rtype: ``list`` of ``str``
-        """
-        response = self.connection.request('/loadbalancers/algorithms')
-        return [a["name"].upper() for a in response.object["algorithms"]]
-
-    def ex_get_balancer_error_page(self, balancer):
-        """
-        List error page configured for the specified load balancer.
-
-        :param balancer: Balancer which should be used
-        :type balancer: :class:`LoadBalancer`
-
-        :rtype: ``str``
-        """
-        uri = '/loadbalancers/%s/errorpage' % (balancer.id)
-        resp = self.connection.request(uri)
-
-        return resp.object["errorpage"]["content"]
-
-    def ex_balancer_access_list(self, balancer):
-        """
-        List the access list.
-
-        :param balancer: Balancer which should be used
-        :type balancer: :class:`LoadBalancer`
-
-        :rtype: ``list`` of :class:`RackspaceAccessRule`
-        """
-        uri = '/loadbalancers/%s/accesslist' % (balancer.id)
-        resp = self.connection.request(uri)
-
-        return [self._to_access_rule(el) for el in resp.object["accessList"]]
-
-    def _get_updated_balancer(self, balancer):
-        """
-        Updating a balancer's attributes puts a balancer into
-        'PENDING_UPDATE' status.  Wait until the balancer is
-        back in 'ACTIVE' status and then return the individual
-        balancer details call.
-        """
-        resp = self.connection.async_request(
-            action='/loadbalancers/%s' % balancer.id,
-            method='GET')
-
-        return self._to_balancer(resp.object['loadBalancer'])
-
-    def ex_update_balancer_health_monitor(self, balancer, health_monitor):
-        """
-        Sets a Balancer's health monitor.  This method blocks until the update
-        request has been processed and the balancer is in a RUNNING state
-        again.
-
-        :param balancer: Balancer to update.
-        :type  balancer: :class:`LoadBalancer`
-
-        :param health_monitor: Health Monitor for the balancer.
-        :type  health_monitor: :class:`RackspaceHealthMonitor`
-
-        :return: Updated Balancer.
-        :rtype: :class:`LoadBalancer`
-        """
-        accepted = self.ex_update_balancer_health_monitor_no_poll(
-            balancer, health_monitor)
-        if not accepted:
-            msg = 'Update health monitor request not accepted'
-            raise LibcloudError(msg, driver=self)
-
-        return self._get_updated_balancer(balancer)
-
-    def ex_update_balancer_health_monitor_no_poll(self, balancer,
-                                                  health_monitor):
-        """
-        Sets a Balancer's health monitor.  This method returns immediately.
-
-        :param balancer: Balancer to update health monitor on.
-        :type  balancer: :class:`LoadBalancer`
-
-        :param health_monitor: Health Monitor for the balancer.
-        :type  health_monitor: :class:`RackspaceHealthMonitor`
-
-        :return: Returns whether the update request was accepted.
-        :rtype: ``bool``
-        """
-        uri = '/loadbalancers/%s/healthmonitor' % (balancer.id)
-
-        resp = self.connection.request(
-            uri, method='PUT', data=json.dumps(health_monitor._to_dict()))
-
-        return resp.status == httplib.ACCEPTED
-
-    def ex_disable_balancer_health_monitor(self, balancer):
-        """
-        Disables a Balancer's health monitor.  This method blocks until the
-        disable request has been processed and the balancer is in a RUNNING
-        state again.
-
-        :param balancer: Balancer to disable health monitor on.
-        :type  balancer: :class:`LoadBalancer`
-
-        :return: Updated Balancer.
-        :rtype: :class:`LoadBalancer`
-        """
-        if not self.ex_disable_balancer_health_monitor_no_poll(balancer):
-            msg = 'Disable health monitor request not accepted'
-            raise LibcloudError(msg, driver=self)
-
-        return self._get_updated_balancer(balancer)
-
-    def ex_disable_balancer_health_monitor_no_poll(self, balancer):
-        """
-        Disables a Balancer's health monitor.  This method returns
-        immediately.
-
-        :param balancer: Balancer to disable health monitor on.
-        :type  balancer: :class:`LoadBalancer`
-
-        :return: Returns whether the disable request was accepted.
-        :rtype: ``bool``
-        """
-        uri = '/loadbalancers/%s/healthmonitor' % (balancer.id)
-
-        resp = self.connection.request(uri,
-                                       method='DELETE')
-
-        return resp.status == httplib.ACCEPTED
-
-    def ex_update_balancer_connection_throttle(self, balancer,
-                                               connection_throttle):
-        """
-        Updates a Balancer's connection throttle.  This method blocks until
-        the update request has been processed and the balancer is in a
-        RUNNING state again.
-
-        :param balancer: Balancer to update connection throttle on.
-        :type  balancer: :class:`LoadBalancer`
-
-        :param connection_throttle: Connection Throttle for the balancer.
-        :type  connection_throttle: :class:`RackspaceConnectionThrottle`
-
-        :return: Updated Balancer.
-        :rtype: :class:`LoadBalancer`
-        """
-        accepted = self.ex_update_balancer_connection_throttle_no_poll(
-            balancer, connection_throttle)
-
-        if not accepted:
-            msg = 'Update connection throttle request not accepted'
-            raise LibcloudError(msg, driver=self)
-
-        return self._get_updated_balancer(balancer)
-
-    def ex_update_balancer_connection_throttle_no_poll(self, balancer,
-                                                       connection_throttle):
-        """
-        Sets a Balancer's connection throttle.  This method returns
-        immediately.
-
-        :param balancer: Balancer to update connection throttle on.
-        :type  balancer: :class:`LoadBalancer`
-
-        :param connection_throttle: Connection Throttle for the balancer.
-        :type  connection_throttle: :class:`RackspaceConnectionThrottle`
-
-        :return: Returns whether the update request was accepted.
-        :rtype: ``bool``
-        """
-        uri = '/loadbalancers/%s/connectionthrottle' % (balancer.id)
-        resp = self.connection.request(
-            uri, method='PUT',
-            data=json.dumps(connection_throttle._to_dict()))
-
-        return resp.status == httplib.ACCEPTED
-
-    def ex_disable_balancer_connection_throttle(self, balancer):
-        """
-        Disables a Balancer's connection throttle.  This method blocks until
-        the disable request has been processed and the balancer is in a RUNNING
-        state again.
-
-        :param balancer: Balancer to disable connection throttle on.
-        :type  balancer: :class:`LoadBalancer`
-
-        :return: Updated Balancer.
-        :rtype: :class:`LoadBalancer`
-        """
-        if not self.ex_disable_balancer_connection_throttle_no_poll(balancer):
-            msg = 'Disable connection throttle request not accepted'
-            raise LibcloudError(msg, driver=self)
-
-        return self._get_updated_balancer(balancer)
-
-    def ex_disable_balancer_connection_throttle_no_poll(self, balancer):
-        """
-        Disables a Balancer's connection throttle.  This method returns
-        immediately.
-
-        :param balancer: Balancer to disable connection throttle on.
-        :type  balancer: :class:`LoadBalancer`
-
-        :return: Returns whether the disable request was accepted.
-        :rtype: ``bool``
-        """
-        uri = '/loadbalancers/%s/connectionthrottle' % (balancer.id)
-        resp = self.connection.request(uri, method='DELETE')
-
-        return resp.status == httplib.ACCEPTED
-
-    def ex_enable_balancer_connection_logging(self, balancer):
-        """
-        Enables connection logging for a Balancer.  This method blocks until
-        the enable request has been processed and the balancer is in a RUNNING
-        state again.
-
-        :param balancer: Balancer to enable connection logging on.
-        :type  balancer: :class:`LoadBalancer`
-
-        :return: Updated Balancer.
-        :rtype: :class:`LoadBalancer`
-        """
-        if not self.ex_enable_balancer_connection_logging_no_poll(balancer):
-            msg = 'Enable connection logging request not accepted'
-            raise LibcloudError(msg, driver=self)
-
-        return self._get_updated_balancer(balancer)
-
-    def ex_enable_balancer_connection_logging_no_poll(self, balancer):
-        """
-        Enables connection logging for a Balancer.  This method returns
-        immediately.
-
-        :param balancer: Balancer to enable connection logging on.
-        :type  balancer: :class:`LoadBalancer`
-
-        :return: Returns whether the enable request was accepted.
-        :rtype: ``bool``
-        """
-        uri = '/loadbalancers/%s/connectionlogging' % (balancer.id)
-
-        resp = self.connection.request(
-            uri, method='PUT',
-            data=json.dumps({'connectionLogging': {'enabled': True}})
-        )
-
-        return resp.status == httplib.ACCEPTED
-
-    def ex_disable_balancer_connection_logging(self, balancer):
-        """
-        Disables connection logging for a Balancer.  This method blocks until
-        the enable request has been processed and the balancer is in a RUNNING
-        state again.
-
-        :param balancer: Balancer to disable connection logging on.
-        :type  balancer: :class:`LoadBalancer`
-
-        :return: Updated Balancer.
-        :rtype: :class:`LoadBalancer`
-        """
-        if not self.ex_disable_balancer_connection_logging_no_poll(balancer):
-            msg = 'Disable connection logging request not accepted'
-            raise LibcloudError(msg, driver=self)
-
-        return self._get_updated_balancer(balancer)
-
-    def ex_disable_balancer_connection_logging_no_poll(self, balancer):
-        """
-        Disables connection logging for a Balancer.  This method returns
-        immediately.
-
-        :param balancer: Balancer to disable connection logging on.
-        :type  balancer: :class:`LoadBalancer`
-
-        :return: Returns whether the disable request was accepted.
-        :rtype: ``bool``
-        """
-        uri = '/loadbalancers/%s/connectionlogging' % (balancer.id)
-        resp = self.connection.request(
-            uri, method='PUT',
-            data=json.dumps({'connectionLogging': {'enabled': False}})
-        )
-
-        return resp.status == httplib.ACCEPTED
-
-    def ex_enable_balancer_session_persistence(self, balancer):
-        """
-        Enables session persistence for a Balancer by setting the persistence
-        type to 'HTTP_COOKIE'.  This method blocks until the enable request
-        has been processed and the balancer is in a RUNNING state again.
-
-        :param balancer: Balancer to enable session persistence on.
-        :type  balancer: :class:`LoadBalancer`
-
-        :return: Updated Balancer.
-        :rtype: :class:`LoadBalancer`
-        """
-        if not self.ex_enable_balancer_session_persistence_no_poll(balancer):
-            msg = 'Enable session persistence request not accepted'
-            raise LibcloudError(msg, driver=self)
-
-        return self._get_updated_balancer(balancer)
-
-    def ex_enable_balancer_session_persistence_no_poll(self, balancer):
-        """
-        Enables session persistence for a Balancer by setting the persistence
-        type to 'HTTP_COOKIE'.  This method returns immediately.
-
-        :param balancer: Balancer to enable session persistence on.
-        :type  balancer: :class:`LoadBalancer`
-
-        :return: Returns whether the enable request was accepted.
-        :rtype: ``bool``
-        """
-        uri = '/loadbalancers/%s/sessionpersistence' % (balancer.id)
-        resp = self.connection.request(
-            uri, method='PUT',
-            data=json.dumps(
-                {'sessionPersistence': {'persistenceType': 'HTTP_COOKIE'}})
-        )
-
-        return resp.status == httplib.ACCEPTED
-
-    def ex_disable_balancer_session_persistence(self, balancer):
-        """
-        Disables session persistence for a Balancer.  This method blocks until
-        the disable request has been processed and the balancer is in a RUNNING
-        state again.
-
-        :param balancer: Balancer to disable session persistence on.
-        :type balancer:  :class:`LoadBalancer`
-
-        :return: Updated Balancer.
-        :rtype: :class:`LoadBalancer`
-        """
-        if not self.ex_disable_balancer_session_persistence_no_poll(balancer):
-            msg = 'Disable session persistence request not accepted'
-            raise LibcloudError(msg, driver=self)
-
-        return self._get_updated_balancer(balancer)
-
-    def ex_disable_balancer_session_persistence_no_poll(self, balancer):
-        """
-        Disables session persistence for a Balancer.  This method returns
-        immediately.
-
-        :param balancer: Balancer to disable session persistence for.
-        :type  balancer: :class:`LoadBalancer`
-
-        :return: Returns whether the disable request was accepted.
-        :rtype: ``bool``
-        """
-        uri = '/loadbalancers/%s/sessionpersistence' % (balancer.id)
-        resp = self.connection.request(uri, method='DELETE')
-
-        return resp.status == httplib.ACCEPTED
-
-    def ex_update_balancer_error_page(self, balancer, page_content):
-        """
-        Updates a Balancer's custom error page.  This method blocks until
-        the update request has been processed and the balancer is in a
-        RUNNING state again.
-
-        :param balancer: Balancer to update the custom error page for.
-        :type  balancer: :class:`LoadBalancer`
-
-        :param page_content: HTML content for the custom error page.
-        :type  page_content: ``str``
-
-        :return: Updated Balancer.
-        :rtype:  :class:`LoadBalancer`
-        """
-        accepted = self.ex_update_balancer_error_page_no_poll(balancer,
-                                                              page_content)
-        if not accepted:
-            msg = 'Update error page request not accepted'
-            raise LibcloudError(msg, driver=self)
-
-        return self._get_updated_balancer(balancer)
-
-    def ex_update_balancer_error_page_no_poll(self, balancer, page_content):
-        """
-        Updates a Balancer's custom error page.  This method returns
-        immediately.
-
-        :param balancer: Balancer to update the custom error page for.
-        :type  balancer: :class:`LoadBalancer`
-
-        :param page_content: HTML content for the custom error page.
-        :type  page_content: ``str``
-
-        :return: Returns whether the update request was accepted.
-        :rtype: ``bool``
-        """
-        uri = '/loadbalancers/%s/errorpage' % (balancer.id)
-        resp = self.connection.request(
-            uri, method='PUT',
-            data=json.dumps({'errorpage': {'content': page_content}})
-        )
-
-        return resp.status == httplib.ACCEPTED
-
-    def ex_disable_balancer_custom_error_page(self, balancer):
-        """
-        Disables a Balancer's custom error page, returning its error page to
-        the Rackspace-provided default.  This method blocks until the disable
-        request has been processed and the balancer is in a RUNNING state
-        again.
-
-        :param balancer: Balancer to disable the custom error page for.
-        :type  balancer: :class:`LoadBalancer`
-
-        :return: Updated Balancer.
-        :rtype: :class:`LoadBalancer`
-        """
-        if not self.ex_disable_balancer_custom_error_page_no_poll(balancer):
-            msg = 'Disable custom error page request not accepted'
-            raise LibcloudError(msg, driver=self)
-
-        return self._get_updated_balancer(balancer)
-
-    def ex_disable_balancer_custom_error_page_no_poll(self, balancer):
-        """
-        Disables a Balancer's custom error page, returning its error page to
-        the Rackspace-provided default.  This method returns immediately.
-
-        :param balancer: Balancer to disable the custom error page for.
-        :type  balancer: :class:`LoadBalancer`
-
-        :return: Returns whether the disable request was accepted.
-        :rtype: ``bool``
-        """
-        uri = '/loadbalancers/%s/errorpage' % (balancer.id)
-        resp = self.connection.request(uri, method='DELETE')
-
-        # Load Balancer API currently returns 200 OK on custom error page
-        # delete.
-        return resp.status == httplib.OK or resp.status == httplib.ACCEPTED
-
-    def ex_create_balancer_access_rule(self, balancer, rule):
-        """
-        Adds an access rule to a Balancer's access list.  This method blocks
-        until the update request has been processed and the balancer is in a
-        RUNNING state again.
-
-        :param balancer: Balancer to create the access rule for.
-        :type balancer: :class:`LoadBalancer`
-
-        :param rule: Access Rule to add to the balancer.
-        :type rule: :class:`RackspaceAccessRule`
-
-        :return: The created access rule.
-        :rtype: :class:`RackspaceAccessRule`
-        """
-        accepted = self.ex_create_balancer_access_rule_no_poll(balancer, rule)
-        if not accepted:
-            msg = 'Create access rule not accepted'
-            raise LibcloudError(msg, driver=self)
-
-        balancer = self._get_updated_balancer(balancer)
-        access_list = balancer.extra['accessList']
-
-        created_rule = self._find_matching_rule(rule, access_list)
-
-        if not created_rule:
-            raise LibcloudError('Could not find created rule')
-
-        return created_rule
-
-    def ex_create_balancer_access_rule_no_poll(self, balancer, rule):
-        """
-        Adds an access rule to a Balancer's access list.  This method returns
-        immediately.
-
-        :param balancer: Balancer to create the access rule for.
-        :type balancer: :class:`LoadBalancer`
-
-        :param rule: Access Rule to add to the balancer.
-        :type rule: :class:`RackspaceAccessRule`
-
-        :return: Returns whether the create request was accepted.
-        :rtype: ``bool``
-        """
-        uri = '/loadbalancers/%s/accesslist' % (balancer.id)
-        resp = self.connection.request(
-            uri, method='POST',
-            data=json.dumps({'networkItem': rule._to_dict()})
-        )
-
-        return resp.status == httplib.ACCEPTED
-
-    def ex_create_balancer_access_rules(self, balancer, rules):
-        """
-        Adds a list of access rules to a Balancer's access list.  This method
-        blocks until the update request has been processed and the balancer is
-        in a RUNNING state again.
-
-        :param balancer: Balancer to create the access rule for.
-        :type  balancer: :class:`LoadBalancer`
-
-        :param rules: List of :class:`RackspaceAccessRule` to add to the
-                      balancer.
-        :type  rules: ``list`` of :class:`RackspaceAccessRule`
-
-        :return: The created access rules.
-        :rtype: :class:`RackspaceAccessRule`
-        """
-        accepted = self.ex_create_balancer_access_rules_no_poll(balancer,
-                                                                rules)
-        if not accepted:
-            msg = 'Create access rules not accepted'
-            raise LibcloudError(msg, driver=self)
-
-        balancer = self._get_updated_balancer(balancer)
-        access_list = balancer.extra['accessList']
-
-        created_rules = []
-        for r in rules:
-            matched_rule = self._find_matching_rule(r, access_list)
-            if matched_rule:
-                created_rules.append(matched_rule)
-
-        if len(created_rules) != len(rules):
-            raise LibcloudError('Could not find all created rules')
-
-        return created_rules
-
-    def _find_matching_rule(self, rule_to_find, access_list):
-        """
-        LB API does not return the ID for the newly created rules, so we have
-        to search the list to find the rule with a matching rule type and
-        address to return an object with the right identifier.it.  The API
-        enforces rule type and address uniqueness.
-        """
-        for r in access_list:
-            if rule_to_find.rule_type == r.rule_type and\
-                    rule_to_find.address == r.address:
-                return r
-
-        return None
-
-    def ex_create_balancer_access_rules_no_poll(self, balancer, rules):
-        """
-        Adds a list of access rules to a Balancer's access list.  This method
-        returns immediately.
-
-        :param balancer: Balancer to create the access rule for.
-        :type balancer: :class:`LoadBalancer`
-
-        :param rules: List of :class:`RackspaceAccessRule` to add to
-                      the balancer.
-        :type  rules: ``list`` of :class:`RackspaceAccessRule`
-
-        :return: Returns whether the create request was accepted.
-        :rtype: ``bool``
-        """
-        uri = '/loadbalancers/%s/accesslist' % (balancer.id)
-        resp = self.connection.request(
-            uri, method='POST',
-            data=json.dumps({'accessList':
-                             [rule._to_dict() for rule in rules]})
-        )
-
-        return resp.status == httplib.ACCEPTED
-
-    def ex_destroy_balancer_access_rule(self, balancer, rule):
-        """
-        Removes an access rule from a Balancer's access list.  This method
-        blocks until the update request has been processed and the balancer
-        is in a RUNNING state again.
-
-        :param balancer: Balancer to remove the access rule from.
-        :type  balancer: :class:`LoadBalancer`
-
-        :param rule: Access Rule to remove from the balancer.
-        :type  rule: :class:`RackspaceAccessRule`
-
-        :return: Updated Balancer.
-        :rtype: :class:`LoadBalancer`
-        """
-        accepted = self.ex_destroy_balancer_access_rule_no_poll(balancer, rule)
-        if not accepted:
-            msg = 'Delete access rule not accepted'
-            raise LibcloudError(msg, driver=self)
-
-        return self._get_updated_balancer(balancer)
-
-    def ex_destroy_balancer_access_rule_no_poll(self, balancer, rule):
-        """
-        Removes an access rule from a Balancer's access list.  This method
-        returns immediately.
-
-        :param balancer: Balancer to remove the access rule from.
-        :type  balancer: :class:`LoadBalancer`
-
-        :param rule: Access Rule to remove from the balancer.
-        :type  rule: :class:`RackspaceAccessRule`
-
-        :return: Returns whether the destroy request was accepted.
-        :rtype: ``bool``
-        """
-        uri = '/loadbalancers/%s/accesslist/%s' % (balancer.id, rule.id)
-        resp = self.connection.request(uri, method='DELETE')
-
-        return resp.status == httplib.ACCEPTED
-
-    def ex_destroy_balancer_access_rules(self, balancer, rules):
-        """
-        Removes a list of access rules from a Balancer's access list.  This
-        method blocks until the update request has been processed and the
-        balancer is in a RUNNING state again.
-
-        :param balancer: Balancer to remove the access rules from.
-        :type  balancer: :class:`LoadBalancer`
-
-        :param rules: List of :class:`RackspaceAccessRule` objects to remove
-                      from the balancer.
-        :type  rules: ``list`` of :class:`RackspaceAccessRule`
-
-        :return: Updated Balancer.
-        :rtype: :class:`LoadBalancer`
-        """
-        accepted = self.ex_destroy_balancer_access_rules_no_poll(
-            balancer, rules)
-
-        if not accepted:
-            msg = 'Destroy access rules request not accepted'
-            raise LibcloudError(msg, driver=self)
-
-        return self._get_updated_balancer(balancer)
-
-    def ex_destroy_balancer_access_rules_no_poll(self, balancer, rules):
-        """
-        Removes a list of access rules from a Balancer's access list.  This
-        method returns immediately.
-
-        :param balancer: Balancer to remove the access rules from.
-        :type  balancer: :class:`LoadBalancer`
-
-        :param rules: List of :class:`RackspaceAccessRule` objects to remove
-                      from the balancer.
-        :type  rules: ``list`` of :class:`RackspaceAccessRule`
-
-        :return: Returns whether the destroy request was accepted.
-        :rtype: ``bool``
-        """
-        ids = [('id', rule.id) for rule in rules]
-        uri = '/loadbalancers/%s/accesslist' % balancer.id
-
-        resp = self.connection.request(uri,
-                                       method='DELETE',
-                                       params=ids)
-
-        return resp.status == httplib.ACCEPTED
-
-    def ex_list_current_usage(self, balancer):
-        """
-        Return current load balancer usage report.
-
-        :param balancer: Balancer to remove the access rules from.
-        :type  balancer: :class:`LoadBalancer`
-
-        :return: Raw load balancer usage object.
-        :rtype: ``dict``
-        """
-        uri = '/loadbalancers/%s/usage/current' % (balancer.id)
-        resp = self.connection.request(uri, method='GET')
-
-        return resp.object
-
-    def _to_protocols(self, object):
-        protocols = []
-        for item in object["protocols"]:
-            protocols.append(item['name'].lower())
-        return protocols
-
-    def _to_protocols_with_default_ports(self, object):
-        protocols = []
-        for item in object["protocols"]:
-            name = item['name'].lower()
-            port = int(item['port'])
-            protocols.append((name, port))
-
-        return protocols
-
-    def _to_balancers(self, object):
-        return [self._to_balancer(el) for el in object["loadBalancers"]]
-
-    def _to_balancer(self, el):
-        ip = None
-        port = None
-        sourceAddresses = {}
-
-        if 'port' in el:
-            port = el["port"]
-
-        if 'sourceAddresses' in el:
-            sourceAddresses = el['sourceAddresses']
-
-        extra = {
-            "ipv6PublicSource": sourceAddresses.get("ipv6Public"),
-            "ipv4PublicSource": sourceAddresses.get("ipv4Public"),
-            "ipv4PrivateSource": sourceAddresses.get("ipv4Servicenet"),
-            "service_name": self.connection.get_service_name(),
-            "uri": "https://%s%s/loadbalancers/%s" % (
-                self.connection.host, self.connection.request_path, el["id"]),
-        }
-
-        if 'virtualIps' in el:
-            ip = el['virtualIps'][0]['address']
-            extra['virtualIps'] = el['virtualIps']
-
-        if 'protocol' in el:
-            extra['protocol'] = el['protocol']
-
-        if 'algorithm' in el and \
-           el["algorithm"] in self._VALUE_TO_ALGORITHM_MAP:
-            extra["algorithm"] = self._value_to_algorithm(el["algorithm"])
-
-        if 'healthMonitor' in el:
-            health_monitor = self._to_health_monitor(el)
-            if health_monitor:
-                extra["healthMonitor"] = health_monitor
-
-        if 'connectionThrottle' in el:
-            extra["connectionThrottle"] = self._to_connection_throttle(el)
-
-        if 'sessionPersistence' in el:
-            persistence = el["sessionPersistence"]
-            extra["sessionPersistenceType"] =\
-                persistence.get("persistenceType")
-
-        if 'connectionLogging' in el:
-            logging = el["connectionLogging"]
-            extra["connectionLoggingEnabled"] = logging.get("enabled")
-
-        if 'nodes' in el:
-            extra['members'] = self._to_members(el)
-
-        if 'created' in el:
-            extra['created'] = self._iso_to_datetime(el['created']['time'])
-
-        if 'updated' in el:
-            extra['updated'] = self._iso_to_datetime(el['updated']['time'])
-
-        if 'accessList' in el:
-            extra['accessList'] = [self._to_access_rule(rule)
-                                   for rule in el['accessList']]
-
-        return LoadBalancer(id=el["id"],
-                            name=el["name"],
-                            state=self.LB_STATE_MAP.get(
-                                el["status"], State.UNKNOWN),
-                            ip=ip,
-                            port=port,
-                            driver=self.connection.driver,
-                            extra=extra)
-
-    def _to_members(self, object, balancer=None):
-        return [self._to_member(el, balancer) for el in object["nodes"]]
-
-    def _to_member(self, el, balancer=None):
-        extra = {}
-        if 'weight' in el:
-            extra['weight'] = el["weight"]
-
-        if 'condition' in el and\
-           el['condition'] in self.LB_MEMBER_CONDITION_MAP:
-            extra['condition'] =\
-                self.LB_MEMBER_CONDITION_MAP.get(el["condition"])
-
-        if 'status' in el:
-            extra['status'] = el["status"]
-
-        lbmember = Member(id=el["id"],
-                          ip=el["address"],
-                          port=el["port"],
-                          balancer=balancer,
-                          extra=extra)
-        return lbmember
-
-    def _protocol_to_value(self, protocol):
-        non_standard_protocols = {'imapv2': 'IMAPv2', 'imapv3': 'IMAPv3',
-                                  'imapv4': 'IMAPv4'}
-        protocol_name = protocol.lower()
-
-        if protocol_name in non_standard_protocols:
-            protocol_value = non_standard_protocols[protocol_name]
-        else:
-            protocol_value = protocol.upper()
-
-        return protocol_value
-
-    def _kwargs_to_mutable_attrs(self, **attrs):
-        update_attrs = {}
-        if "name" in attrs:
-            update_attrs['name'] = attrs['name']
-
-        if "algorithm" in attrs:
-            algorithm_value = self._algorithm_to_value(attrs['algorithm'])
-            update_attrs['algorithm'] = algorithm_value
-
-        if "protocol" in attrs:
-            update_attrs['protocol'] =\
-                self._protocol_to_value(attrs['protocol'])
-
-        if "port" in attrs:
-            update_attrs['port'] = int(attrs['port'])
-
-        if "vip" in attrs:
-            if attrs['vip'] == 'PUBLIC' or attrs['vip'] == 'SERVICENET':
-                update_attrs['virtualIps'] = [{'type': attrs['vip']}]
-            else:
-                update_attrs['virtualIps'] = [{'id': attrs['vip']}]
-
-        return update_attrs
-
-    def _kwargs_to_mutable_member_attrs(self, **attrs):
-        update_attrs = {}
-        if 'condition' in attrs:
-            update_attrs['condition'] =\
-                self.CONDITION_LB_MEMBER_MAP.get(attrs['condition'])
-
-        if 'weight' in attrs:
-            update_attrs['weight'] = attrs['weight']
-
-        return update_attrs
-
-    def _to_health_monitor(self, el):
-        health_monitor_data = el["healthMonitor"]
-
-        type = health_monitor_data.get("type")
-        delay = health_monitor_data.get("delay")
-        timeout = health_monitor_data.get("timeout")
-        attempts_before_deactivation =\
-            health_monitor_data.get("attemptsBeforeDeactivation")
-
-        if type == "CONNECT":
-            return RackspaceHealthMonitor(
-                type=type, delay=delay, timeout=timeout,
-                attempts_before_deactivation=attempts_before_deactivation)
-
-        if type == "HTTP" or type == "HTTPS":
-            return RackspaceHTTPHealthMonitor(
-                type=type, delay=delay, timeout=timeout,
-                attempts_before_deactivation=attempts_before_deactivation,
-                path=health_monitor_data.get("path"),
-                status_regex=health_monitor_data.get("statusRegex"),
-                body_regex=health_monitor_data.get("bodyRegex", ''))
-
-        return None
-
-    def _to_connection_throttle(self, el):
-        connection_throttle_data = el["connectionThrottle"]
-
-        min_connections = connection_throttle_data.get("minConnections")
-        max_connections = connection_throttle_data.get("maxConnections")
-        max_connection_rate = connection_throttle_data.get("maxConnectionRate")
-        rate_interval = connection_throttle_data.get("rateInterval")
-
-        return RackspaceConnectionThrottle(
-            min_connections=min_connections,
-            max_connections=max_connections,
-            max_connection_rate=max_connection_rate,
-            rate_interval_seconds=rate_interval)
-
-    def _to_access_rule(self, el):
-        return RackspaceAccessRule(
-            id=el.get("id"),
-            rule_type=self._to_access_rule_type(el.get("type")),
-            address=el.get("address"))
-
-    def _to_access_rule_type(self, type):
-        if type == "ALLOW":
-            return RackspaceAccessRuleType.ALLOW
-        elif type == "DENY":
-            return RackspaceAccessRuleType.DENY
-
-    def _iso_to_datetime(self, isodate):
-        date_formats = ('%Y-%m-%dT%H:%M:%SZ', '%Y-%m-%dT%H:%M:%S%z')
-        date = None
-
-        for date_format in date_formats:
-            try:
-                date = datetime.strptime(isodate, date_format)
-            except ValueError:
-                pass
-
-            if date:
-                break
-
-        return date


[15/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/container/utils/docker.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/container/utils/docker.py b/apache-libcloud-1.0.0rc2/libcloud/container/utils/docker.py
deleted file mode 100644
index da67516..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/container/utils/docker.py
+++ /dev/null
@@ -1,177 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from __future__ import with_statement
-
-from base64 import b64encode
-
-from libcloud.common.base import Connection, JsonResponse
-from libcloud.container.base import ContainerImage
-
-__all__ = [
-    'RegistryClient',
-    'HubClient'
-]
-
-
-class DockerHubConnection(Connection):
-    responseCls = JsonResponse
-
-    def __init__(self, host, username=None, password=None,
-                 secure=True,
-                 port=None, url=None, timeout=None,
-                 proxy_url=None, backoff=None, retry_delay=None):
-        super(DockerHubConnection, self).__init__(secure=secure, host=host,
-                                                  port=port, url=url,
-                                                  timeout=timeout,
-                                                  proxy_url=proxy_url,
-                                                  backoff=backoff,
-                                                  retry_delay=retry_delay)
-        self.username = username
-        self.password = password
-
-    def add_default_headers(self, headers):
-        headers['Content-Type'] = 'application/json'
-        if self.username is not None:
-            authstr = 'Basic ' + str(
-                b64encode(
-                    ('%s:%s' % (self.username,
-                                self.password))
-                    .encode('latin1'))
-                .strip()
-            )
-            headers['Authorization'] = authstr
-        return headers
-
-
-class RegistryClient(object):
-    """
-    A client for the Docker v2 registry API
-    """
-    connectionCls = DockerHubConnection
-
-    def __init__(self, host, username=None, password=None, **kwargs):
-        """
-        Construct a Docker hub client
-
-        :param username: (optional) Your Hub account username
-        :type  username: ``str``
-
-        :param password: (optional) Your hub account password
-        :type  password: ``str``
-        """
-        self.connection = self.connectionCls(host,
-                                             username,
-                                             password,
-                                             **kwargs)
-
-    def list_images(self, repository_name, namespace='library', max_count=100):
-        """
-        List the tags (versions) in a repository
-
-        :param  repository_name: The name of the repository e.g. 'ubuntu'
-        :type   repository_name: ``str``
-
-        :param  namespace: (optional) The docker namespace
-        :type   namespace: ``str``
-
-        :param  max_count: The maximum number of records to return
-        :type   max_count: ``int``
-
-        :return: A list of images
-        :rtype: ``list`` of :class:`libcloud.container.base.ContainerImage`
-        """
-        path = '/v2/repositories/%s/%s/tags/?page=1&page_size=%s' \
-               % (namespace, repository_name, max_count)
-        response = self.connection.request(path)
-        images = []
-        for image in response.object['results']:
-            images.append(self._to_image(repository_name, image))
-        return images
-
-    def get_repository(self, repository_name, namespace='library'):
-        """
-        Get the information about a specific repository
-
-        :param  repository_name: The name of the repository e.g. 'ubuntu'
-        :type   repository_name: ``str``
-
-        :param  namespace: (optional) The docker namespace
-        :type   namespace: ``str``
-
-        :return: The details of the repository
-        :rtype: ``object``
-        """
-        path = '/v2/repositories/%s/%s' % (namespace, repository_name)
-        response = self.connection.request(path)
-        return response.object
-
-    def get_image(self, repository_name, tag='latest', namespace='library'):
-        """
-        Get an image from a repository with a specific tag
-
-        :param repository_name: The name of the repository, e.g. ubuntu
-        :type  repository_name: ``str``
-
-        :param  tag: (optional) The image tag (defaults to latest)
-        :type   tag: ``str``
-
-        :param  namespace: (optional) The docker namespace
-        :type   namespace: ``str``
-
-        :return: A container image
-        :rtype: :class:`libcloud.container.base.ContainerImage`
-        """
-        path = '/v2/repositories/%s/%s/tags/%s' \
-               % (namespace, repository_name, tag)
-        response = self.connection.request(path)
-        return self._to_image(repository_name, response.object)
-
-    def _to_image(self, repository_name, obj):
-        path = '%s/%s:%s' % (self.connection.host,
-                             repository_name,
-                             obj['name'])
-        return ContainerImage(
-            id=obj['id'],
-            path=path,
-            name=path,
-            version=obj['name'],
-            extra={
-                'full_size': obj['full_size']
-            },
-            driver=None
-        )
-
-
-class HubClient(RegistryClient):
-    """
-    A client for the Docker Hub API
-
-    The hub is based on the v2 registry API
-    """
-    host = 'registry.hub.docker.com'
-
-    def __init__(self, username=None, password=None, **kwargs):
-        """
-        Construct a Docker hub client
-
-        :param username: (optional) Your Hub account username
-        :type  username: ``str``
-
-        :param password: (optional) Your hub account password
-        :type  password: ``str``
-        """
-        super(HubClient, self).__init__(self.host, username,
-                                        password, **kwargs)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/data/pricing.json
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/data/pricing.json b/apache-libcloud-1.0.0rc2/libcloud/data/pricing.json
deleted file mode 100644
index bb0dac4..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/data/pricing.json
+++ /dev/null
@@ -1,1038 +0,0 @@
-{
-    "compute": {
-        "bluebox": {
-            "1gb": 0.15,
-            "2gb": 0.25,
-            "4gb": 0.35,
-            "8gb": 0.45
-        },
-        "cloudsigma_lvs": {
-            "high-cpu-extra-large": 0.0,
-            "high-cpu-medium": 0.0,
-            "high-memory-double-extra-large": 0.0,
-            "high-memory-extra-large": 0.0,
-            "micro-high-cpu": 0.0,
-            "micro-regular": 0.0,
-            "standard-extra-large": 0.0,
-            "standard-large": 0.0,
-            "standard-small": 0.0
-        },
-        "cloudsigma_zrh": {
-            "high-cpu-extra-large": 0.78,
-            "high-cpu-medium": 0.211,
-            "high-memory-double-extra-large": 1.383,
-            "high-memory-extra-large": 0.642,
-            "micro-high-cpu": 0.381,
-            "micro-regular": 0.0548,
-            "standard-extra-large": 0.762,
-            "standard-large": 0.381,
-            "standard-small": 0.0796
-        },
-        "ec2_ap_northeast": {
-            "c1.medium": "0.158",
-            "c1.xlarge": "0.632",
-            "c3.large": "0.128",
-            "c3.xlarge": "0.255",
-            "c3.2xlarge": "0.511",
-            "c3.4xlarge": "1.021",
-            "c3.8xlarge": "2.043",
-            "c4.large": "0.120",
-            "c4.xlarge": "0.239",
-            "c4.2xlarge": "0.478",
-            "c4.4xlarge": "0.955",
-            "c4.8xlarge": "1.910",
-            "cc2.8xlarge": "2.349",
-            "cg1.4xlarge": "N/A",
-            "cr1.8xlarge": "4.105",
-            "d2.xlarge": "0.844",
-            "d2.2xlarge": "1.688",
-            "d2.4xlarge": "3.376",
-            "d2.8xlarge": "6.752",
-            "g2.2xlarge": "0.898",
-            "g2.8xlarge": "3.592",
-            "hi1.4xlarge": "3.276",
-            "hs1.8xlarge": "5.4",
-            "i2.xlarge": "1.001",
-            "i2.2xlarge": "2.001",
-            "i2.4xlarge": "4.002",
-            "i2.8xlarge": "8.004",
-            "m1.small": "0.061",
-            "m1.medium": "0.122",
-            "m1.large": "0.243",
-            "m1.xlarge": "0.486",
-            "m2.xlarge": "0.287",
-            "m2.2xlarge": "0.575",
-            "m2.4xlarge": "1.15",
-            "m3.medium": "0.096",
-            "m3.large": "0.193",
-            "m3.xlarge": "0.385",
-            "m3.2xlarge": "0.77",
-            "m4.large": "0.165",
-            "m4.xlarge": "0.331",
-            "m4.2xlarge": "0.660",
-            "m4.4xlarge": "1.321",
-            "m4.10xlarge": "3.303",
-            "r3.large": "0.200",
-            "r3.xlarge": "0.399",
-            "r3.2xlarge": "0.798",
-            "r3.4xlarge": "1.596",
-            "r3.8xlarge": "3.192",
-            "t1.micro": "0.026",
-            "t2.micro": "0.020",
-            "t2.small": "0.040",
-            "t2.medium": "0.080",
-            "t2.large": "0.160",
-            "t2.nano": "0.010"
-        },
-        "ec2_ap_southeast": {
-            "c1.medium": "0.164",
-            "c1.xlarge": "0.655",
-            "c3.large": "0.132",
-            "c3.xlarge": "0.265",
-            "c3.2xlarge": "0.529",
-            "c3.4xlarge": "1.058",
-            "c3.8xlarge": "2.117",
-            "c4.large": "0.144",
-            "c4.xlarge": "0.289",
-            "c4.2xlarge": "0.578",
-            "c4.4xlarge": "1.155",
-            "c4.8xlarge": "2.31",
-            "cc2.8xlarge": "N/A",
-            "cg1.4xlarge": "N/A",
-            "cr1.8xlarge": "N/A",
-            "d2.xlarge": "0.87",
-            "d2.2xlarge": "1.74",
-            "d2.4xlarge": "3.48",
-            "d2.8xlarge": "6.96",
-            "g2.2xlarge": "1",
-            "g2.8xlarge": "4",
-            "hi1.4xlarge": "N/A",
-            "hs1.8xlarge": "5.57",
-            "i2.xlarge": "1.018",
-            "i2.2xlarge": "2.035",
-            "i2.4xlarge": "4.07",
-            "i2.8xlarge": "8.14",
-            "m1.small": "0.058",
-            "m1.medium": "0.117",
-            "m1.large": "0.233",
-            "m1.xlarge": "0.467",
-            "m2.xlarge": "0.296",
-            "m2.2xlarge": "0.592",
-            "m2.4xlarge": "1.183",
-            "m3.medium": "0.098",
-            "m3.large": "0.196",
-            "m3.xlarge": "0.392",
-            "m3.2xlarge": "0.784",
-            "m4.large": "0.178",
-            "m4.xlarge": "0.355",
-            "m4.2xlarge": "0.711",
-            "m4.4xlarge": "1.421",
-            "m4.10xlarge": "3.553",
-            "r3.large": "0.2",
-            "r3.xlarge": "0.399",
-            "r3.2xlarge": "0.798",
-            "r3.4xlarge": "1.596",
-            "r3.8xlarge": "3.192",
-            "t1.micro": "0.02",
-            "t2.micro": "0.02",
-            "t2.small": "0.04",
-            "t2.medium": "0.08",
-            "t2.large": "0.16",
-            "t2.nano": "0.01"
-        },
-        "ec2_ap_southeast_2": {
-            "c1.medium": "0.164",
-            "c1.xlarge": "0.655",
-            "c3.large": "0.132",
-            "c3.xlarge": "0.265",
-            "c3.2xlarge": "0.529",
-            "c3.4xlarge": "1.058",
-            "c3.8xlarge": "2.117",
-            "c4.large": "0.137",
-            "c4.xlarge": "0.275",
-            "c4.2xlarge": "0.549",
-            "c4.4xlarge": "1.097",
-            "c4.8xlarge": "2.195",
-            "cc2.8xlarge": "N/A",
-            "cg1.4xlarge": "N/A",
-            "cr1.8xlarge": "N/A",
-            "d2.xlarge": "0.87",
-            "d2.2xlarge": "1.74",
-            "d2.4xlarge": "3.48",
-            "d2.8xlarge": "6.96",
-            "g2.2xlarge": "0.898",
-            "g2.8xlarge": "3.592",
-            "hi1.4xlarge": "N/A",
-            "hs1.8xlarge": "5.57",
-            "i2.xlarge": "1.018",
-            "i2.2xlarge": "2.035",
-            "i2.4xlarge": "4.07",
-            "i2.8xlarge": "8.14",
-            "m1.small": "0.058",
-            "m1.medium": "0.117",
-            "m1.large": "0.233",
-            "m1.xlarge": "0.467",
-            "m2.xlarge": "0.296",
-            "m2.2xlarge": "0.592",
-            "m2.4xlarge": "1.183",
-            "m3.medium": "0.093",
-            "m3.large": "0.186",
-            "m3.xlarge": "0.372",
-            "m3.2xlarge": "0.745",
-            "m4.large": "0.168",
-            "m4.xlarge": "0.336",
-            "m4.2xlarge": "0.673",
-            "m4.4xlarge": "1.345",
-            "m4.10xlarge": "3.363",
-            "r3.large": "0.2",
-            "r3.xlarge": "0.399",
-            "r3.2xlarge": "0.798",
-            "r3.4xlarge": "1.596",
-            "r3.8xlarge": "3.192",
-            "t1.micro": "0.02",
-            "t2.micro": "0.02",
-            "t2.small": "0.04",
-            "t2.medium": "0.08",
-            "t2.large": "0.16"
-        },
-        "ec2_eu_central": {
-            "c1.medium": "N/A",
-            "c1.xlarge": "N/A",
-            "c3.large": "0.129",
-            "c3.xlarge": "0.258",
-            "c3.2xlarge": "0.516",
-            "c3.4xlarge": "1.032",
-            "c3.8xlarge": "2.064",
-            "c4.large": "0.134",
-            "c4.xlarge": "0.267",
-            "c4.2xlarge": "0.534",
-            "c4.4xlarge": "1.069",
-            "c4.8xlarge": "2.138",
-            "cc2.8xlarge": "N/A",
-            "cg1.4xlarge": "N/A",
-            "cr1.8xlarge": "N/A",
-            "d2.xlarge": "0.794",
-            "d2.2xlarge": "1.588",
-            "d2.4xlarge": "3.176",
-            "d2.8xlarge": "6.352",
-            "g2.2xlarge": "0.772",
-            "g2.8xlarge": "3.088",
-            "hi1.4xlarge": "N/A",
-            "hs1.8xlarge": "N/A",
-            "i2.xlarge": "1.013",
-            "i2.2xlarge": "2.026",
-            "i2.4xlarge": "4.051",
-            "i2.8xlarge": "8.102",
-            "m1.small": "N/A",
-            "m1.medium": "N/A",
-            "m1.large": "N/A",
-            "m1.xlarge": "N/A",
-            "m2.xlarge": "N/A",
-            "m2.2xlarge": "N/A",
-            "m2.4xlarge": "N/A",
-            "m3.medium": "0.079",
-            "m3.large": "0.158",
-            "m3.xlarge": "0.315",
-            "m3.2xlarge": "0.632",
-            "m4.large": "0.143",
-            "m4.xlarge": "0.285",
-            "m4.2xlarge": "0.57",
-            "m4.4xlarge": "1.14",
-            "m4.10xlarge": "2.85",
-            "r3.large": "0.2",
-            "r3.xlarge": "0.4",
-            "r3.2xlarge": "0.8",
-            "r3.4xlarge": "1.6",
-            "r3.8xlarge": "3.201",
-            "t1.micro": "N/A",
-            "t2.micro": "0.015",
-            "t2.small": "0.03",
-            "t2.medium": "0.06",
-            "t2.large": "0.12"
-        },
-        "ec2_eu_west": {
-            "c1.medium": "0.148",
-            "c1.xlarge": "0.592",
-            "c3.large": "0.12",
-            "c3.xlarge": "0.239",
-            "c3.2xlarge": "0.478",
-            "c3.4xlarge": "0.956",
-            "c3.8xlarge": "1.912",
-            "c4.large": "0.119",
-            "c4.xlarge": "0.238",
-            "c4.2xlarge": "0.477",
-            "c4.4xlarge": "0.953",
-            "c4.8xlarge": "1.906",
-            "cc2.8xlarge": "2.25",
-            "cg1.4xlarge": "2.36",
-            "cr1.8xlarge": "3.75",
-            "d2.xlarge": "0.735",
-            "d2.2xlarge": "1.47",
-            "d2.4xlarge": "2.94",
-            "d2.8xlarge": "5.88",
-            "g2.2xlarge": "0.702",
-            "g2.8xlarge": "2.808",
-            "hi1.4xlarge": "3.1",
-            "hs1.8xlarge": "4.9",
-            "i2.xlarge": "0.938",
-            "i2.2xlarge": "1.876",
-            "i2.4xlarge": "3.751",
-            "i2.8xlarge": "7.502",
-            "m1.small": "0.047",
-            "m1.medium": "0.095",
-            "m1.large": "0.19",
-            "m1.xlarge": "0.379",
-            "m2.xlarge": "0.275",
-            "m2.2xlarge": "0.55",
-            "m2.4xlarge": "1.1",
-            "m3.medium": "0.073",
-            "m3.large": "0.146",
-            "m3.xlarge": "0.293",
-            "m3.2xlarge": "0.585",
-            "m4.large": "0.132",
-            "m4.xlarge": "0.264",
-            "m4.2xlarge": "0.528",
-            "m4.4xlarge": "1.056",
-            "m4.10xlarge": "2.641",
-            "r3.large": "0.185",
-            "r3.xlarge": "0.371",
-            "r3.2xlarge": "0.741",
-            "r3.4xlarge": "1.482",
-            "r3.8xlarge": "2.964",
-            "t1.micro": "0.02",
-            "t2.micro": "0.014",
-            "t2.small": "0.028",
-            "t2.medium": "0.056",
-            "t2.large": "0.112",
-            "t2.nano": "0.007"
-        },
-        "ec2_sa_east": {
-            "c1.medium": "0.179",
-            "c1.xlarge": "0.718",
-            "c3.large": "0.163",
-            "c3.xlarge": "0.325",
-            "c3.2xlarge": "0.65",
-            "c3.4xlarge": "1.3",
-            "c3.8xlarge": "2.6",
-            "cc2.8xlarge": "N/A",
-            "cg1.4xlarge": "N/A",
-            "cr1.8xlarge": "N/A",
-            "hi1.4xlarge": "N/A",
-            "hs1.8xlarge": "N/A",
-            "m1.small": "0.058",
-            "m1.medium": "0.117",
-            "m1.large": "0.233",
-            "m1.xlarge": "0.467",
-            "m2.xlarge": "0.323",
-            "m2.2xlarge": "0.645",
-            "m2.4xlarge": "1.291",
-            "m3.medium": "0.095",
-            "m3.large": "0.19",
-            "m3.xlarge": "0.381",
-            "m3.2xlarge": "0.761",
-            "r3.4xlarge": "2.799",
-            "r3.8xlarge": "5.597",
-            "t1.micro": "0.027",
-            "t2.micro": "0.027",
-            "t2.small": "0.054",
-            "t2.medium": "0.108",
-            "t2.large": "0.216",
-            "t2.nano": "0.0135"
-        },
-        "ec2_us_east": {
-            "c1.medium": "0.13",
-            "c1.xlarge": "0.52",
-            "c3.large": "0.105",
-            "c3.xlarge": "0.21",
-            "c3.2xlarge": "0.42",
-            "c3.4xlarge": "0.84",
-            "c3.8xlarge": "1.68",
-            "c4.large": "0.105",
-            "c4.xlarge": "0.209",
-            "c4.2xlarge": "0.419",
-            "c4.4xlarge": "0.838",
-            "c4.8xlarge": "1.675",
-            "cc2.8xlarge": "2",
-            "cg1.4xlarge": "2.1",
-            "cr1.8xlarge": "3.5",
-            "d2.xlarge": "0.69",
-            "d2.2xlarge": "1.38",
-            "d2.4xlarge": "2.76",
-            "d2.8xlarge": "5.52",
-            "g2.2xlarge": "0.65",
-            "g2.8xlarge": "2.6",
-            "hi1.4xlarge": "3.1",
-            "hs1.8xlarge": "4.6",
-            "i2.xlarge": "0.853",
-            "i2.2xlarge": "1.705",
-            "i2.4xlarge": "3.41",
-            "i2.8xlarge": "6.82",
-            "m1.small": "0.044",
-            "m1.medium": "0.087",
-            "m1.large": "0.175",
-            "m1.xlarge": "0.35",
-            "m2.xlarge": "0.245",
-            "m2.2xlarge": "0.49",
-            "m2.4xlarge": "0.98",
-            "m3.medium": "0.067",
-            "m3.large": "0.133",
-            "m3.xlarge": "0.266",
-            "m3.2xlarge": "0.532",
-            "m4.large": "0.12",
-            "m4.xlarge": "0.239",
-            "m4.2xlarge": "0.479",
-            "m4.4xlarge": "0.958",
-            "m4.10xlarge": "2.394",
-            "r3.large": "0.166",
-            "r3.xlarge": "0.333",
-            "r3.2xlarge": "0.665",
-            "r3.4xlarge": "1.33",
-            "r3.8xlarge": "2.66",
-            "t1.micro": "0.02",
-            "t2.micro": "0.013",
-            "t2.small": "0.026",
-            "t2.medium": "0.052",
-            "t2.large": "0.104",
-            "t2.nano": "0.0065"
-        },
-        "ec2_us_govwest": {
-            "c1.medium": "0.157",
-            "c1.xlarge": "0.628",
-            "c3.large": "0.126",
-            "c3.xlarge": "0.252",
-            "c3.2xlarge": "0.504",
-            "c3.4xlarge": "1.008",
-            "c3.8xlarge": "2.016",
-            "cc2.8xlarge": "2.25",
-            "cg1.4xlarge": "N/A",
-            "cr1.8xlarge": "N/A",
-            "d2.xlarge": "0.828",
-            "d2.2xlarge": "1.656",
-            "d2.4xlarge": "3.312",
-            "d2.8xlarge": "6.624",
-            "hi1.4xlarge": "N/A",
-            "hs1.8xlarge": "5.52",
-            "i2.xlarge": "1.023",
-            "i2.2xlarge": "2.046",
-            "i2.4xlarge": "4.092",
-            "i2.8xlarge": "8.184",
-            "m1.small": "0.053",
-            "m1.medium": "0.106",
-            "m1.large": "0.211",
-            "m1.xlarge": "0.423",
-            "m2.xlarge": "0.293",
-            "m2.2xlarge": "0.586",
-            "m2.4xlarge": "1.171",
-            "m3.medium": "0.084",
-            "m3.large": "0.168",
-            "m3.xlarge": "0.336",
-            "m3.2xlarge": "0.672",
-            "r3.large": "0.2",
-            "r3.xlarge": "0.399",
-            "r3.2xlarge": "0.798",
-            "r3.4xlarge": "1.596",
-            "r3.8xlarge": "3.192",
-            "t1.micro": "0.024",
-            "t2.micro": "0.015",
-            "t2.small": "0.031",
-            "t2.medium": "0.062",
-            "t2.large": "0.124",
-            "t2.nano": "0.0075"
-        },
-        "ec2_us_west": {
-            "c1.medium": "0.148",
-            "c1.xlarge": "0.592",
-            "c3.large": "0.12",
-            "c3.xlarge": "0.239",
-            "c3.2xlarge": "0.478",
-            "c3.4xlarge": "0.956",
-            "c3.8xlarge": "1.912",
-            "c4.large": "0.131",
-            "c4.xlarge": "0.262",
-            "c4.2xlarge": "0.524",
-            "c4.4xlarge": "1.049",
-            "c4.8xlarge": "2.098",
-            "cc2.8xlarge": "N/A",
-            "cg1.4xlarge": "N/A",
-            "cr1.8xlarge": "N/A",
-            "g2.2xlarge": "0.702",
-            "g2.8xlarge": "2.808",
-            "hi1.4xlarge": "N/A",
-            "hs1.8xlarge": "N/A",
-            "i2.xlarge": "0.938",
-            "i2.2xlarge": "1.876",
-            "i2.4xlarge": "3.751",
-            "i2.8xlarge": "7.502",
-            "m1.small": "0.047",
-            "m1.medium": "0.095",
-            "m1.large": "0.19",
-            "m1.xlarge": "0.379",
-            "m2.xlarge": "0.275",
-            "m2.2xlarge": "0.55",
-            "m2.4xlarge": "1.1",
-            "m3.medium": "0.077",
-            "m3.large": "0.154",
-            "m3.xlarge": "0.308",
-            "m3.2xlarge": "0.616",
-            "m4.large": "0.14",
-            "m4.xlarge": "0.279",
-            "m4.2xlarge": "0.559",
-            "m4.4xlarge": "1.117",
-            "m4.10xlarge": "2.793",
-            "r3.large": "0.185",
-            "r3.xlarge": "0.371",
-            "r3.2xlarge": "0.741",
-            "r3.4xlarge": "1.482",
-            "r3.8xlarge": "2.964",
-            "t1.micro": "0.025",
-            "t2.micro": "0.017",
-            "t2.small": "0.034",
-            "t2.medium": "0.068",
-            "t2.large": "0.136",
-            "t2.nano": "0.0085"
-        },
-        "ec2_us_west_oregon": {
-            "c1.medium": "0.13",
-            "c1.xlarge": "0.52",
-            "c3.large": "0.105",
-            "c3.xlarge": "0.21",
-            "c3.2xlarge": "0.42",
-            "c3.4xlarge": "0.84",
-            "c3.8xlarge": "1.68",
-            "c4.large": "0.105",
-            "c4.xlarge": "0.209",
-            "c4.2xlarge": "0.419",
-            "c4.4xlarge": "0.838",
-            "c4.8xlarge": "1.675",
-            "cc2.8xlarge": "2",
-            "cg1.4xlarge": "N/A",
-            "cr1.8xlarge": "3.5",
-            "d2.xlarge": "0.69",
-            "d2.2xlarge": "1.38",
-            "d2.4xlarge": "2.76",
-            "d2.8xlarge": "5.52",
-            "g2.2xlarge": "0.65",
-            "g2.8xlarge": "2.6",
-            "hi1.4xlarge": "3.1",
-            "hs1.8xlarge": "4.6",
-            "i2.xlarge": "0.853",
-            "i2.2xlarge": "1.705",
-            "i2.4xlarge": "3.41",
-            "i2.8xlarge": "6.82",
-            "m1.small": "0.044",
-            "m1.medium": "0.087",
-            "m1.large": "0.175",
-            "m1.xlarge": "0.35",
-            "m2.xlarge": "0.245",
-            "m2.2xlarge": "0.49",
-            "m2.4xlarge": "0.98",
-            "m3.medium": "0.067",
-            "m3.large": "0.133",
-            "m3.xlarge": "0.266",
-            "m3.2xlarge": "0.532",
-            "m4.large": "0.12",
-            "m4.xlarge": "0.239",
-            "m4.2xlarge": "0.479",
-            "m4.4xlarge": "0.958",
-            "m4.10xlarge": "2.394",
-            "r3.large": "0.166",
-            "r3.xlarge": "0.333",
-            "r3.2xlarge": "0.665",
-            "r3.4xlarge": "1.33",
-            "r3.8xlarge": "2.66",
-            "t1.micro": "0.02",
-            "t2.micro": "0.013",
-            "t2.small": "0.026",
-            "t2.medium": "0.052",
-            "t2.large": "0.104",
-            "t2.nano": "0.0065"
-        },
-        "elastichosts": {
-            "small": 0.1,
-            "medium": 0.223,
-            "large": 0.378,
-            "extra-large": 0.579,
-            "high-cpu-extra-large": 0.77,
-            "high-cpu-medium": 0.18
-        },
-        "gandi": {
-            "small": 0.02,
-            "medium": 0.03,
-            "large": 0.06,
-            "x-large": 0.12,
-            "1": 0.02
-        },
-        "gogrid": {
-            "1GB": 0.19,
-            "2GB": 0.38,
-            "4GB": 0.76,
-            "8GB": 1.52,
-            "16GB": 3.04,
-            "24GB": 4.56,
-            "512MB": 0.095
-        },
-        "google_asia": {
-            "f1-micro": 0.009,
-            "f1-micro-preemptible": 0.005,
-            "g1-small": 0.03,
-            "g1-small-preemptible": 0.01,
-            "n1-highcpu-2": 0.084,
-            "n1-highcpu-2-preemptible": 0.022,
-            "n1-highcpu-4": 0.168,
-            "n1-highcpu-4-preemptible": 0.044,
-            "n1-highcpu-8": 0.336,
-            "n1-highcpu-8-preemptible": 0.088,
-            "n1-highcpu-16": 0.672,
-            "n1-highcpu-16-preemptible": 0.176,
-            "n1-highcpu-32": 1.344,
-            "n1-highcpu-32-preemptible": 0.352,
-            "n1-highmem-2": 0.139,
-            "n1-highmem-2-preemptible": 0.0385,
-            "n1-highmem-4": 0.278,
-            "n1-highmem-4-preemptible": 0.077,
-            "n1-highmem-8": 0.556,
-            "n1-highmem-8-preemptible": 0.154,
-            "n1-highmem-16": 1.112,
-            "n1-highmem-16-preemptible": 0.308,
-            "n1-highmem-32": 2.224,
-            "n1-highmem-32-preemptible": 0.616,
-            "n1-standard-1": 0.055,
-            "n1-standard-1-preemptible": 0.0165,
-            "n1-standard-2": 0.11,
-            "n1-standard-2-preemptible": 0.033,
-            "n1-standard-4": 0.22,
-            "n1-standard-4-preemptible": 0.066,
-            "n1-standard-8": 0.44,
-            "n1-standard-8-preemptible": 0.132,
-            "n1-standard-16": 0.88,
-            "n1-standard-16-preemptible": 0.264,
-            "n1-standard-32": 1.76,
-            "n1-standard-32-preemptible": 0.528
-        },
-        "google_europe": {
-            "f1-micro": 0.009,
-            "f1-micro-preemptible": 0.005,
-            "g1-small": 0.03,
-            "g1-small-preemptible": 0.01,
-            "n1-highcpu-2": 0.084,
-            "n1-highcpu-2-preemptible": 0.022,
-            "n1-highcpu-4": 0.168,
-            "n1-highcpu-4-preemptible": 0.044,
-            "n1-highcpu-8": 0.336,
-            "n1-highcpu-8-preemptible": 0.088,
-            "n1-highcpu-16": 0.672,
-            "n1-highcpu-16-preemptible": 0.176,
-            "n1-highcpu-32": 1.344,
-            "n1-highcpu-32-preemptible": 0.352,
-            "n1-highmem-2": 0.139,
-            "n1-highmem-2-preemptible": 0.0385,
-            "n1-highmem-4": 0.278,
-            "n1-highmem-4-preemptible": 0.077,
-            "n1-highmem-8": 0.556,
-            "n1-highmem-8-preemptible": 0.154,
-            "n1-highmem-16": 1.112,
-            "n1-highmem-16-preemptible": 0.308,
-            "n1-highmem-32": 2.224,
-            "n1-highmem-32-preemptible": 0.616,
-            "n1-standard-1": 0.055,
-            "n1-standard-1-preemptible": 0.0165,
-            "n1-standard-2": 0.11,
-            "n1-standard-2-preemptible": 0.033,
-            "n1-standard-4": 0.22,
-            "n1-standard-4-preemptible": 0.066,
-            "n1-standard-8": 0.44,
-            "n1-standard-8-preemptible": 0.132,
-            "n1-standard-16": 0.88,
-            "n1-standard-16-preemptible": 0.264,
-            "n1-standard-32": 1.76,
-            "n1-standard-32-preemptible": 0.528
-        },
-        "google_us": {
-            "f1-micro": 0.008,
-            "f1-micro-preemptible": 0.005,
-            "g1-small": 0.027,
-            "g1-small-preemptible": 0.01,
-            "n1-highcpu-2": 0.076,
-            "n1-highcpu-2-preemptible": 0.02,
-            "n1-highcpu-4": 0.152,
-            "n1-highcpu-4-preemptible": 0.04,
-            "n1-highcpu-8": 0.304,
-            "n1-highcpu-8-preemptible": 0.08,
-            "n1-highcpu-16": 0.608,
-            "n1-highcpu-16-preemptible": 0.16,
-            "n1-highcpu-32": 1.216,
-            "n1-highcpu-32-preemptible": 0.32,
-            "n1-highmem-2": 0.126,
-            "n1-highmem-2-preemptible": 0.035,
-            "n1-highmem-4": 0.252,
-            "n1-highmem-4-preemptible": 0.07,
-            "n1-highmem-8": 0.504,
-            "n1-highmem-8-preemptible": 0.14,
-            "n1-highmem-16": 1.008,
-            "n1-highmem-16-preemptible": 0.28,
-            "n1-highmem-32": 2.016,
-            "n1-highmem-32-preemptible": 0.56,
-            "n1-standard-1": 0.05,
-            "n1-standard-1-preemptible": 0.015,
-            "n1-standard-2": 0.1,
-            "n1-standard-2-preemptible": 0.03,
-            "n1-standard-4": 0.2,
-            "n1-standard-4-preemptible": 0.06,
-            "n1-standard-8": 0.4,
-            "n1-standard-8-preemptible": 0.12,
-            "n1-standard-16": 0.8,
-            "n1-standard-16-preemptible": 0.24,
-            "n1-standard-32": 1.6,
-            "n1-standard-32-preemptible": 0.48
-        },
-        "nephoscale": {
-            "1": 0.6,
-            "3": 0.063,
-            "5": 0.031,
-            "7": 0.125,
-            "9": 0.188,
-            "11": 0.35,
-            "27": 0.0,
-            "46": 0.1,
-            "48": 0.15,
-            "50": 0.28,
-            "52": 0.48,
-            "54": 0.938,
-            "56": 0.75
-        },
-        "nimbus": {
-            "m1.small": 0.0,
-            "m1.large": 0.0,
-            "m1.xlarge": 0.0
-        },
-        "osc_inc_eu_west_1": {
-            "c1.medium": "0.230",
-            "c1.xlarge": "0.900",
-            "cc1.4xlarge": "1.300",
-            "cc2.8xlarge": "2.400",
-            "cr1.8xlarge": "3.500",
-            "m1.small": "0.090",
-            "m1.medium": "0.120",
-            "m1.large": "0.360",
-            "m1.xlarge": "0.730",
-            "m2.xlarge": "0.410",
-            "m2.2xlarge": "0.820",
-            "m2.4xlarge": "1.640",
-            "m3.xlarge": "0.780",
-            "m3.2xlarge": "1.560",
-            "nv1.small": "5.220",
-            "nv1.medium": "5.250",
-            "nv1.large": "5.490",
-            "nv1.xlarge": "5.610",
-            "os1.8xlarge": "4.310",
-            "t1.micro": "0.040"
-        },
-        "osc_inc_eu_west_2": {
-            "c1.medium": "0.230",
-            "c1.xlarge": "0.900",
-            "cc1.4xlarge": "1.300",
-            "cc2.8xlarge": "2.400",
-            "cr1.8xlarge": "3.500",
-            "m1.small": "0.090",
-            "m1.medium": "0.120",
-            "m1.large": "0.360",
-            "m1.xlarge": "0.730",
-            "m2.xlarge": "0.410",
-            "m2.2xlarge": "0.820",
-            "m2.4xlarge": "1.640",
-            "m3.xlarge": "0.780",
-            "m3.2xlarge": "1.560",
-            "nv1.small": "5.220",
-            "nv1.medium": "5.250",
-            "nv1.large": "5.490",
-            "nv1.xlarge": "5.610",
-            "os1.8xlarge": "4.310",
-            "t1.micro": "0.040"
-        },
-        "osc_inc_eu_west_3": {
-            "c1.medium": "0.230",
-            "c1.xlarge": "0.900",
-            "cc1.4xlarge": "1.300",
-            "cc2.8xlarge": "2.400",
-            "cr1.8xlarge": "3.500",
-            "m1.small": "0.090",
-            "m1.medium": "0.120",
-            "m1.large": "0.360",
-            "m1.xlarge": "0.730",
-            "m2.xlarge": "0.410",
-            "m2.2xlarge": "0.820",
-            "m2.4xlarge": "1.640",
-            "m3.xlarge": "0.780",
-            "m3.2xlarge": "1.560",
-            "nv1.small": "5.220",
-            "nv1.medium": "5.250",
-            "nv1.large": "5.490",
-            "nv1.xlarge": "5.610",
-            "os1.8xlarge": "4.310",
-            "t1.micro": "0.040"
-        },
-        "osc_inc_us_east_1": {
-            "c1.medium": "0.150",
-            "c1.xlarge": "0.580",
-            "cc1.4xlarge": "1.610",
-            "cc2.8xlarge": "2.400",
-            "cr1.8xlarge": "3.500",
-            "m1.small": "0.060",
-            "m1.medium": "0.180",
-            "m1.large": "0.240",
-            "m1.xlarge": "0.730",
-            "m2.xlarge": "0.410",
-            "m2.2xlarge": "1.020",
-            "m2.4xlarge": "2.040",
-            "m3.xlarge": "0.500",
-            "m3.2xlarge": "1.560",
-            "nv1.small": "5.190",
-            "nv1.medium": "5.250",
-            "nv1.large": "5.490",
-            "nv1.xlarge": "5.610",
-            "os1.8xlarge": "6.400",
-            "t1.micro": "0.020"
-        },
-        "osc_inc_us_east_2": {
-            "c1.medium": "0.150",
-            "c1.xlarge": "0.580",
-            "cc1.4xlarge": "1.610",
-            "cc2.8xlarge": "2.400",
-            "cr1.8xlarge": "3.500",
-            "m1.small": "0.060",
-            "m1.medium": "0.180",
-            "m1.large": "0.240",
-            "m1.xlarge": "0.730",
-            "m2.xlarge": "0.410",
-            "m2.2xlarge": "1.020",
-            "m2.4xlarge": "2.040",
-            "m3.xlarge": "0.500",
-            "m3.2xlarge": "1.560",
-            "nv1.small": "5.190",
-            "nv1.medium": "5.250",
-            "nv1.large": "5.490",
-            "nv1.xlarge": "5.610",
-            "os1.8xlarge": "6.400",
-            "t1.micro": "0.020"
-        },
-        "osc_sas_eu_west_1": {
-            "c1.medium": "0.230",
-            "c1.xlarge": "0.900",
-            "cc1.4xlarge": "1.460",
-            "cc2.8xlarge": "2.700",
-            "cr1.8xlarge": "3.750",
-            "m1.small": "0.090",
-            "m1.medium": "0.130",
-            "m1.large": "0.360",
-            "m1.xlarge": "0.730",
-            "m2.xlarge": "0.460",
-            "m2.2xlarge": "0.920",
-            "m2.4xlarge": "1.840",
-            "m3.xlarge": "0.780",
-            "m3.2xlarge": "1.560",
-            "nv1.small": "5.220",
-            "nv1.medium": "5.310",
-            "nv1.large": "5.490",
-            "nv1.xlarge": "5.860",
-            "os1.8xlarge": "6.400",
-            "t1.micro": "0.040"
-        },
-        "osc_sas_eu_west_2": {
-            "c1.medium": "0.230",
-            "c1.xlarge": "0.900",
-            "cc1.4xlarge": "1.460",
-            "cc2.8xlarge": "2.700",
-            "cr1.8xlarge": "3.750",
-            "m1.small": "0.090",
-            "m1.medium": "0.130",
-            "m1.large": "0.360",
-            "m1.xlarge": "0.730",
-            "m2.xlarge": "0.460",
-            "m2.2xlarge": "0.920",
-            "m2.4xlarge": "1.840",
-            "m3.xlarge": "0.780",
-            "m3.2xlarge": "1.560",
-            "nv1.small": "5.220",
-            "nv1.medium": "5.310",
-            "nv1.large": "5.490",
-            "nv1.xlarge": "5.860",
-            "os1.8xlarge": "6.400",
-            "t1.micro": "0.040"
-        },
-        "osc_sas_eu_west_3": {
-            "c1.medium": "0.230",
-            "c1.xlarge": "0.900",
-            "cc1.4xlarge": "1.460",
-            "cc2.8xlarge": "2.700",
-            "cr1.8xlarge": "3.750",
-            "m1.small": "0.090",
-            "m1.medium": "0.130",
-            "m1.large": "0.360",
-            "m1.xlarge": "0.730",
-            "m2.xlarge": "0.460",
-            "m2.2xlarge": "0.920",
-            "m2.4xlarge": "1.840",
-            "m3.xlarge": "0.780",
-            "m3.2xlarge": "1.560",
-            "nv1.small": "5.220",
-            "nv1.medium": "5.310",
-            "nv1.large": "5.490",
-            "nv1.xlarge": "5.860",
-            "os1.8xlarge": "6.400",
-            "t1.micro": "0.040"
-        },
-        "osc_sas_us_east_1": {
-            "c1.medium": "0.170",
-            "c1.xlarge": "0.660",
-            "cc1.4xlarge": "1.610",
-            "cc2.8xlarge": "2.700",
-            "cr1.8xlarge": "3.750",
-            "m1.small": "0.070",
-            "m1.medium": "0.180",
-            "m1.large": "0.260",
-            "m1.xlarge": "0.730",
-            "m2.xlarge": "0.460",
-            "m2.2xlarge": "1.020",
-            "m2.4xlarge": "2.040",
-            "m3.xlarge": "0.550",
-            "m3.2xlarge": "1.560",
-            "nv1.small": "5.220",
-            "nv1.medium": "5.310",
-            "nv1.large": "5.490",
-            "nv1.xlarge": "5.860",
-            "os1.8xlarge": "6.400",
-            "t1.micro": "0.020"
-        },
-        "osc_sas_us_east_2": {
-            "c1.medium": "0.170",
-            "c1.xlarge": "0.660",
-            "cc1.4xlarge": "1.610",
-            "cc2.8xlarge": "2.700",
-            "cr1.8xlarge": "3.750",
-            "m1.small": "0.070",
-            "m1.medium": "0.180",
-            "m1.large": "0.260",
-            "m1.xlarge": "0.730",
-            "m2.xlarge": "0.460",
-            "m2.2xlarge": "1.020",
-            "m2.4xlarge": "2.040",
-            "m3.xlarge": "0.550",
-            "m3.2xlarge": "1.560",
-            "nv1.small": "5.220",
-            "nv1.medium": "5.310",
-            "nv1.large": "5.490",
-            "nv1.xlarge": "5.860",
-            "os1.8xlarge": "6.400",
-            "t1.micro": "0.020"
-        },
-        "rackspace": {
-            "performance1-1": 0.04,
-            "performance1-2": 0.08,
-            "performance1-4": 0.16,
-            "performance1-8": 0.32,
-            "performance2-15": 0.68,
-            "performance2-30": 1.36,
-            "performance2-60": 2.72,
-            "performance2-90": 4.08,
-            "performance2-120": 5.44,
-            "1": 0.015,
-            "2": 0.03,
-            "3": 0.06,
-            "4": 0.12,
-            "5": 0.24,
-            "6": 0.48,
-            "7": 0.96,
-            "8": 1.8
-        },
-        "rackspacenovalon": {
-            "performance1-1": 0.04,
-            "performance1-2": 0.08,
-            "performance1-4": 0.16,
-            "performance1-8": 0.32,
-            "performance2-15": 0.68,
-            "performance2-30": 1.36,
-            "performance2-60": 2.72,
-            "performance2-90": 4.08,
-            "performance2-120": 5.44,
-            "2": 0.032,
-            "3": 0.064,
-            "4": 0.129,
-            "5": 0.258,
-            "6": 0.516,
-            "7": 0.967,
-            "8": 1.612
-        },
-        "rackspacenovasyd": {
-            "performance1-1": 0.04,
-            "performance1-2": 0.08,
-            "performance1-4": 0.16,
-            "performance1-8": 0.32,
-            "performance2-15": 0.68,
-            "performance2-30": 1.36,
-            "performance2-60": 2.72,
-            "performance2-90": 4.08,
-            "performance2-120": 5.44,
-            "2": 0.026,
-            "3": 0.072,
-            "4": 0.144,
-            "5": 0.288,
-            "6": 0.576,
-            "7": 1.08,
-            "8": 1.44
-        },
-        "rackspacenovaus": {
-            "performance1-1": 0.04,
-            "performance1-2": 0.08,
-            "performance1-4": 0.16,
-            "performance1-8": 0.32,
-            "performance2-15": 0.68,
-            "performance2-30": 1.36,
-            "performance2-60": 2.72,
-            "performance2-90": 4.08,
-            "performance2-120": 5.44,
-            "2": 0.022,
-            "3": 0.06,
-            "4": 0.12,
-            "5": 0.24,
-            "6": 0.48,
-            "7": 0.96,
-            "8": 1.2
-        },
-        "serverlove": {
-            "small": 0.161,
-            "medium": 0.404,
-            "large": 0.534,
-            "extra-large": 0.615,
-            "high-cpu-extra-large": 0.776,
-            "high-cpu-medium": 0.291
-        },
-        "skalicloud": {
-            "small": 0.136,
-            "medium": 0.301,
-            "large": 0.505,
-            "extra-large": 0.654,
-            "high-cpu-extra-large": 0.936,
-            "high-cpu-medium": 0.249
-        },
-        "softlayer": {
-            "0": 0.023,
-            "1": 0.024,
-            "2": 0.024,
-            "3": 0.026,
-            "4": 0.045,
-            "5": 0.045,
-            "6": 0.045,
-            "7": 0.09,
-            "8": 0.09,
-            "9": 0.09,
-            "10": 0.09,
-            "11": 0.205,
-            "12": 0.205
-        },
-        "vps_net": {
-            "1": 0.416
-        }
-    },
-    "storage": {},
-    "updated": 1452645090
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/__init__.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/__init__.py b/apache-libcloud-1.0.0rc2/libcloud/dns/__init__.py
deleted file mode 100644
index e69de29..0000000

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/base.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/base.py b/apache-libcloud-1.0.0rc2/libcloud/dns/base.py
deleted file mode 100644
index 6f7cb14..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/dns/base.py
+++ /dev/null
@@ -1,495 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from __future__ import with_statement
-
-import datetime
-
-from libcloud import __version__
-from libcloud.common.base import ConnectionUserAndKey, BaseDriver
-from libcloud.dns.types import RecordType
-
-__all__ = [
-    'Zone',
-    'Record',
-    'DNSDriver'
-]
-
-
-class Zone(object):
-    """
-    DNS zone.
-    """
-
-    def __init__(self, id, domain, type, ttl, driver, extra=None):
-        """
-        :param id: Zone id.
-        :type id: ``str``
-
-        :param domain: The name of the domain.
-        :type domain: ``str``
-
-        :param type: Zone type (master, slave).
-        :type type: ``str``
-
-        :param ttl: Default TTL for records in this zone (in seconds).
-        :type ttl: ``int``
-
-        :param driver: DNSDriver instance.
-        :type driver: :class:`DNSDriver`
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type extra: ``dict``
-        """
-        self.id = str(id) if id else None
-        self.domain = domain
-        self.type = type
-        self.ttl = ttl or None
-        self.driver = driver
-        self.extra = extra or {}
-
-    def list_records(self):
-        return self.driver.list_records(zone=self)
-
-    def create_record(self, name, type, data, extra=None):
-        return self.driver.create_record(name=name, zone=self, type=type,
-                                         data=data, extra=extra)
-
-    def update(self, domain=None, type=None, ttl=None, extra=None):
-        return self.driver.update_zone(zone=self, domain=domain, type=type,
-                                       ttl=ttl, extra=extra)
-
-    def delete(self):
-        return self.driver.delete_zone(zone=self)
-
-    def export_to_bind_format(self):
-        return self.driver.export_zone_to_bind_format(zone=self)
-
-    def export_to_bind_zone_file(self, file_path):
-        self.driver.export_zone_to_bind_zone_file(zone=self,
-                                                  file_path=file_path)
-
-    def __repr__(self):
-        return ('<Zone: domain=%s, ttl=%s, provider=%s ...>' %
-                (self.domain, self.ttl, self.driver.name))
-
-
-class Record(object):
-    """
-    Zone record / resource.
-    """
-
-    def __init__(self, id, name, type, data, zone, driver, ttl=None,
-                 extra=None):
-        """
-        :param id: Record id
-        :type id: ``str``
-
-        :param name: Hostname or FQDN.
-        :type name: ``str``
-
-        :param type: DNS record type (A, AAAA, ...).
-        :type type: :class:`RecordType`
-
-        :param data: Data for the record (depends on the record type).
-        :type data: ``str``
-
-        :param zone: Zone instance.
-        :type zone: :class:`Zone`
-
-        :param driver: DNSDriver instance.
-        :type driver: :class:`DNSDriver`
-
-        :param ttl: Record TTL.
-        :type ttl: ``int``
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type extra: ``dict``
-        """
-        self.id = str(id) if id else None
-        self.name = name
-        self.type = type
-        self.data = data
-        self.zone = zone
-        self.driver = driver
-        self.ttl = ttl
-        self.extra = extra or {}
-
-    def update(self, name=None, type=None, data=None, extra=None):
-        return self.driver.update_record(record=self, name=name, type=type,
-                                         data=data, extra=extra)
-
-    def delete(self):
-        return self.driver.delete_record(record=self)
-
-    def _get_numeric_id(self):
-        record_id = self.id
-
-        if record_id.isdigit():
-            record_id = int(record_id)
-
-        return record_id
-
-    def __repr__(self):
-        zone = self.zone.domain if self.zone.domain else self.zone.id
-        return ('<Record: zone=%s, name=%s, type=%s, data=%s, provider=%s, '
-                'ttl=%s ...>' %
-                (zone, self.name, self.type, self.data,
-                 self.driver.name, self.ttl))
-
-
-class DNSDriver(BaseDriver):
-    """
-    A base DNSDriver class to derive from
-
-    This class is always subclassed by a specific driver.
-    """
-    connectionCls = ConnectionUserAndKey
-    name = None
-    website = None
-
-    # Map libcloud record type enum to provider record type name
-    RECORD_TYPE_MAP = {}
-
-    def __init__(self, key, secret=None, secure=True, host=None, port=None,
-                 **kwargs):
-        """
-        :param    key: API key or username to used (required)
-        :type     key: ``str``
-
-        :param    secret: Secret password to be used (required)
-        :type     secret: ``str``
-
-        :param    secure: Whether to use HTTPS or HTTP. Note: Some providers
-                only support HTTPS, and it is on by default.
-        :type     secure: ``bool``
-
-        :param    host: Override hostname used for connections.
-        :type     host: ``str``
-
-        :param    port: Override port used for connections.
-        :type     port: ``int``
-
-        :return: ``None``
-        """
-        super(DNSDriver, self).__init__(key=key, secret=secret, secure=secure,
-                                        host=host, port=port, **kwargs)
-
-    def list_record_types(self):
-        """
-        Return a list of RecordType objects supported by the provider.
-
-        :return: ``list`` of :class:`RecordType`
-        """
-        return list(self.RECORD_TYPE_MAP.keys())
-
-    def iterate_zones(self):
-        """
-        Return a generator to iterate over available zones.
-
-        :rtype: ``generator`` of :class:`Zone`
-        """
-        raise NotImplementedError(
-            'iterate_zones not implemented for this driver')
-
-    def list_zones(self):
-        """
-        Return a list of zones.
-
-        :return: ``list`` of :class:`Zone`
-        """
-        return list(self.iterate_zones())
-
-    def iterate_records(self, zone):
-        """
-        Return a generator to iterate over records for the provided zone.
-
-        :param zone: Zone to list records for.
-        :type zone: :class:`Zone`
-
-        :rtype: ``generator`` of :class:`Record`
-        """
-        raise NotImplementedError(
-            'iterate_records not implemented for this driver')
-
-    def list_records(self, zone):
-        """
-        Return a list of records for the provided zone.
-
-        :param zone: Zone to list records for.
-        :type zone: :class:`Zone`
-
-        :return: ``list`` of :class:`Record`
-        """
-        return list(self.iterate_records(zone))
-
-    def get_zone(self, zone_id):
-        """
-        Return a Zone instance.
-
-        :param zone_id: ID of the required zone
-        :type  zone_id: ``str``
-
-        :rtype: :class:`Zone`
-        """
-        raise NotImplementedError(
-            'get_zone not implemented for this driver')
-
-    def get_record(self, zone_id, record_id):
-        """
-        Return a Record instance.
-
-        :param zone_id: ID of the required zone
-        :type  zone_id: ``str``
-
-        :param record_id: ID of the required record
-        :type  record_id: ``str``
-
-        :rtype: :class:`Record`
-        """
-        raise NotImplementedError(
-            'get_record not implemented for this driver')
-
-    def create_zone(self, domain, type='master', ttl=None, extra=None):
-        """
-        Create a new zone.
-
-        :param domain: Zone domain name (e.g. example.com)
-        :type domain: ``str``
-
-        :param type: Zone type (master / slave).
-        :type  type: ``str``
-
-        :param ttl: TTL for new records. (optional)
-        :type  ttl: ``int``
-
-        :param extra: Extra attributes (driver specific). (optional)
-        :type extra: ``dict``
-
-        :rtype: :class:`Zone`
-        """
-        raise NotImplementedError(
-            'create_zone not implemented for this driver')
-
-    def update_zone(self, zone, domain, type='master', ttl=None, extra=None):
-        """
-        Update en existing zone.
-
-        :param zone: Zone to update.
-        :type  zone: :class:`Zone`
-
-        :param domain: Zone domain name (e.g. example.com)
-        :type  domain: ``str``
-
-        :param type: Zone type (master / slave).
-        :type  type: ``str``
-
-        :param ttl: TTL for new records. (optional)
-        :type  ttl: ``int``
-
-        :param extra: Extra attributes (driver specific). (optional)
-        :type  extra: ``dict``
-
-        :rtype: :class:`Zone`
-        """
-        raise NotImplementedError(
-            'update_zone not implemented for this driver')
-
-    def create_record(self, name, zone, type, data, extra=None):
-        """
-        Create a new record.
-
-        :param name: Record name without the domain name (e.g. www).
-                     Note: If you want to create a record for a base domain
-                     name, you should specify empty string ('') for this
-                     argument.
-        :type  name: ``str``
-
-        :param zone: Zone where the requested record is created.
-        :type  zone: :class:`Zone`
-
-        :param type: DNS record type (A, AAAA, ...).
-        :type  type: :class:`RecordType`
-
-        :param data: Data for the record (depends on the record type).
-        :type  data: ``str``
-
-        :param extra: Extra attributes (driver specific). (optional)
-        :type extra: ``dict``
-
-        :rtype: :class:`Record`
-        """
-        raise NotImplementedError(
-            'create_record not implemented for this driver')
-
-    def update_record(self, record, name, type, data, extra=None):
-        """
-        Update an existing record.
-
-        :param record: Record to update.
-        :type  record: :class:`Record`
-
-        :param name: Record name without the domain name (e.g. www).
-                     Note: If you want to create a record for a base domain
-                     name, you should specify empty string ('') for this
-                     argument.
-        :type  name: ``str``
-
-        :param type: DNS record type (A, AAAA, ...).
-        :type  type: :class:`RecordType`
-
-        :param data: Data for the record (depends on the record type).
-        :type  data: ``str``
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type  extra: ``dict``
-
-        :rtype: :class:`Record`
-        """
-        raise NotImplementedError(
-            'update_record not implemented for this driver')
-
-    def delete_zone(self, zone):
-        """
-        Delete a zone.
-
-        Note: This will delete all the records belonging to this zone.
-
-        :param zone: Zone to delete.
-        :type  zone: :class:`Zone`
-
-        :rtype: ``bool``
-        """
-        raise NotImplementedError(
-            'delete_zone not implemented for this driver')
-
-    def delete_record(self, record):
-        """
-        Delete a record.
-
-        :param record: Record to delete.
-        :type  record: :class:`Record`
-
-        :rtype: ``bool``
-        """
-        raise NotImplementedError(
-            'delete_record not implemented for this driver')
-
-    def export_zone_to_bind_format(self, zone):
-        """
-        Export Zone object to the BIND compatible format.
-
-        :param zone: Zone to export.
-        :type  zone: :class:`Zone`
-
-        :return: Zone data in BIND compatible format.
-        :rtype: ``str``
-        """
-        if zone.type != 'master':
-            raise ValueError('You can only generate BIND out for master zones')
-
-        lines = []
-
-        # For consistent output, records are sorted based on the id
-        records = zone.list_records()
-        records = sorted(records, key=Record._get_numeric_id)
-
-        date = datetime.datetime.now().strftime('%Y-%m-%d %H:%m:%S')
-        values = {'version': __version__, 'date': date}
-
-        lines.append('; Generated by Libcloud v%(version)s on %(date)s' %
-                     values)
-        lines.append('$ORIGIN %(domain)s.' % {'domain': zone.domain})
-        lines.append('$TTL %(domain_ttl)s\n' % {'domain_ttl': zone.ttl})
-
-        for record in records:
-            line = self._get_bind_record_line(record=record)
-            lines.append(line)
-
-        output = '\n'.join(lines)
-        return output
-
-    def export_zone_to_bind_zone_file(self, zone, file_path):
-        """
-        Export Zone object to the BIND compatible format and write result to a
-        file.
-
-        :param zone: Zone to export.
-        :type  zone: :class:`Zone`
-
-        :param file_path: File path where the output will be saved.
-        :type  file_path: ``str``
-        """
-        result = self.export_zone_to_bind_format(zone=zone)
-
-        with open(file_path, 'w') as fp:
-            fp.write(result)
-
-    def _get_bind_record_line(self, record):
-        """
-        Generate BIND record line for the provided record.
-
-        :param record: Record to generate the line for.
-        :type  record: :class:`Record`
-
-        :return: Bind compatible record line.
-        :rtype: ``str``
-        """
-        parts = []
-
-        if record.name:
-            name = '%(name)s.%(domain)s' % {'name': record.name,
-                                            'domain': record.zone.domain}
-        else:
-            name = record.zone.domain
-
-        name += '.'
-
-        ttl = record.extra['ttl'] if 'ttl' in record.extra else record.zone.ttl
-        ttl = str(ttl)
-        data = record.data
-
-        if record.type in [RecordType.CNAME, RecordType.DNAME, RecordType.MX,
-                           RecordType.PTR, RecordType.SRV]:
-            # Make sure trailing dot is present
-            if data[len(data) - 1] != '.':
-                data += '.'
-
-        if record.type in [RecordType.TXT, RecordType.SPF] and ' ' in data:
-            # Escape the quotes
-            data = data.replace('"', '\\"')
-
-            # Quote the string
-            data = '"%s"' % (data)
-
-        if record.type in [RecordType.MX, RecordType.SRV]:
-            priority = str(record.extra['priority'])
-            parts = [name, ttl, 'IN', record.type, priority, data]
-        else:
-            parts = [name, ttl, 'IN', record.type, data]
-
-        line = '\t'.join(parts)
-        return line
-
-    def _string_to_record_type(self, string):
-        """
-        Return a string representation of a DNS record type to a
-        libcloud RecordType ENUM.
-
-        :rtype: ``str``
-        """
-        string = string.upper()
-        record_type = getattr(RecordType, string)
-        return record_type

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/__init__.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/__init__.py b/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/__init__.py
deleted file mode 100644
index e69de29..0000000

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/auroradns.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/auroradns.py b/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/auroradns.py
deleted file mode 100644
index 658f99c..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/auroradns.py
+++ /dev/null
@@ -1,609 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-AuroraDNS DNS Driver
-"""
-
-import base64
-import json
-import hmac
-import datetime
-
-from hashlib import sha256
-
-from libcloud.utils.py3 import httplib
-from libcloud.utils.py3 import b
-
-from libcloud.common.base import ConnectionUserAndKey, JsonResponse
-
-from libcloud.common.types import InvalidCredsError, ProviderError
-from libcloud.common.types import LibcloudError
-
-from libcloud.dns.base import DNSDriver, Zone, Record
-from libcloud.dns.types import RecordType, ZoneDoesNotExistError
-from libcloud.dns.types import ZoneAlreadyExistsError, RecordDoesNotExistError
-
-
-API_HOST = 'api.auroradns.eu'
-
-# Default TTL required by libcloud, but doesn't do anything in AuroraDNS
-DEFAULT_ZONE_TTL = 3600
-DEFAULT_ZONE_TYPE = 'master'
-
-VALID_RECORD_PARAMS_EXTRA = ['ttl', 'prio', 'health_check_id', 'disabled']
-
-
-class AuroraDNSHealthCheckType(object):
-    """
-    Healthcheck type.
-    """
-    HTTP = 'HTTP'
-    HTTPS = 'HTTPS'
-    TCP = 'TCP'
-
-
-class HealthCheckError(LibcloudError):
-    error_type = 'HealthCheckError'
-
-    def __init__(self, value, driver, health_check_id):
-        self.health_check_id = health_check_id
-        super(HealthCheckError, self).__init__(value=value, driver=driver)
-
-    def __str__(self):
-        return self.__repr__()
-
-    def __repr__(self):
-        return ('<%s in %s, health_check_id=%s, value=%s>' %
-                (self.error_type, repr(self.driver),
-                 self.health_check_id, self.value))
-
-
-class HealthCheckDoesNotExistError(HealthCheckError):
-    error_type = 'HealthCheckDoesNotExistError'
-
-
-class AuroraDNSHealthCheck(object):
-    """
-    AuroraDNS Healthcheck resource.
-    """
-
-    def __init__(self, id, type, hostname, ipaddress, port, interval, path,
-                 threshold, health, enabled, zone, driver, extra=None):
-        """
-        :param id: Healthcheck id
-        :type id: ``str``
-
-        :param hostname: Hostname or FQDN of the target
-        :type hostname: ``str``
-
-        :param ipaddress: IPv4 or IPv6 address of the target
-        :type ipaddress: ``str``
-
-        :param port: The port on the target to monitor
-        :type port: ``int``
-
-        :param interval: The interval of the health check
-        :type interval: ``int``
-
-        :param path: The path to monitor on the target
-        :type path: ``str``
-
-        :param threshold: The threshold of before marking a check as failed
-        :type threshold: ``int``
-
-        :param health: The current health of the health check
-        :type health: ``bool``
-
-        :param enabled: If the health check is currently enabled
-        :type enabled: ``bool``
-
-        :param zone: Zone instance.
-        :type zone: :class:`Zone`
-
-        :param driver: DNSDriver instance.
-        :type driver: :class:`DNSDriver`
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type extra: ``dict``
-        """
-        self.id = str(id) if id else None
-        self.type = type
-        self.hostname = hostname
-        self.ipaddress = ipaddress
-        self.port = int(port) if port else None
-        self.interval = int(interval)
-        self.path = path
-        self.threshold = int(threshold)
-        self.health = bool(health)
-        self.enabled = bool(enabled)
-        self.zone = zone
-        self.driver = driver
-        self.extra = extra or {}
-
-    def update(self, type=None, hostname=None, ipaddress=None, port=None,
-               interval=None, path=None, threshold=None, enabled=None,
-               extra=None):
-        return self.driver.ex_update_healthcheck(healthcheck=self, type=type,
-                                                 hostname=hostname,
-                                                 ipaddress=ipaddress,
-                                                 port=port, path=path,
-                                                 interval=interval,
-                                                 threshold=threshold,
-                                                 enabled=enabled, extra=extra)
-
-    def delete(self):
-        return self.driver.ex_delete_healthcheck(healthcheck=self)
-
-    def __repr__(self):
-        return ('<AuroraDNSHealthCheck: zone=%s, id=%s, type=%s, hostname=%s, '
-                'ipaddress=%s, port=%d, interval=%d, health=%s, provider=%s'
-                '...>' %
-                (self.zone.id, self.id, self.type, self.hostname,
-                 self.ipaddress, self.port, self.interval, self.health,
-                 self.driver.name))
-
-
-class AuroraDNSResponse(JsonResponse):
-    def success(self):
-        return self.status in [httplib.OK, httplib.CREATED, httplib.ACCEPTED]
-
-    def parse_error(self):
-        status = int(self.status)
-        error = {'driver': self, 'value': ''}
-
-        if status == httplib.UNAUTHORIZED:
-            error['value'] = 'Authentication failed'
-            raise InvalidCredsError(**error)
-        elif status == httplib.FORBIDDEN:
-            error['value'] = 'Authorization failed'
-            error['http_status'] = status
-            raise ProviderError(**error)
-        elif status == httplib.NOT_FOUND:
-            context = self.connection.context
-            if context['resource'] == 'zone':
-                error['zone_id'] = context['id']
-                raise ZoneDoesNotExistError(**error)
-            elif context['resource'] == 'record':
-                error['record_id'] = context['id']
-                raise RecordDoesNotExistError(**error)
-            elif context['resource'] == 'healthcheck':
-                error['health_check_id'] = context['id']
-                raise HealthCheckDoesNotExistError(**error)
-        elif status == httplib.CONFLICT:
-            context = self.connection.context
-            if context['resource'] == 'zone':
-                error['zone_id'] = context['id']
-                raise ZoneAlreadyExistsError(**error)
-        elif status == httplib.BAD_REQUEST:
-            context = self.connection.context
-            body = self.parse_body()
-            raise ProviderError(value=body['errormsg'],
-                                http_code=status, driver=self)
-
-
-class AuroraDNSConnection(ConnectionUserAndKey):
-    host = API_HOST
-    responseCls = AuroraDNSResponse
-
-    def calculate_auth_signature(self, secret_key, method, url, timestamp):
-        b64_hmac = base64.b64encode(
-            hmac.new(b(secret_key),
-                     b(method) + b(url) + b(timestamp),
-                     digestmod=sha256).digest()
-        )
-
-        return b64_hmac.decode('utf-8')
-
-    def gen_auth_header(self, api_key, secret_key, method, url, timestamp):
-        signature = self.calculate_auth_signature(secret_key, method, url,
-                                                  timestamp)
-
-        auth_b64 = base64.b64encode(b('%s:%s' % (api_key, signature)))
-        return 'AuroraDNSv1 %s' % (auth_b64.decode('utf-8'))
-
-    def request(self, action, params=None, data='', headers=None,
-                method='GET'):
-        if not headers:
-            headers = {}
-        if not params:
-            params = {}
-
-        if method in ("POST", "PUT"):
-            headers = {'Content-Type': 'application/json; charset=UTF-8'}
-
-        t = datetime.datetime.utcnow()
-        timestamp = t.strftime('%Y%m%dT%H%M%SZ')
-
-        headers['X-AuroraDNS-Date'] = timestamp
-        headers['Authorization'] = self.gen_auth_header(self.user_id, self.key,
-                                                        method, action,
-                                                        timestamp)
-
-        return super(AuroraDNSConnection, self).request(action=action,
-                                                        params=params,
-                                                        data=data,
-                                                        method=method,
-                                                        headers=headers)
-
-
-class AuroraDNSDriver(DNSDriver):
-    name = 'AuroraDNS'
-    website = 'https://www.pcextreme.nl/en/aurora/dns'
-    connectionCls = AuroraDNSConnection
-
-    RECORD_TYPE_MAP = {
-        RecordType.A: 'A',
-        RecordType.AAAA: 'AAAA',
-        RecordType.CNAME: 'CNAME',
-        RecordType.MX: 'MX',
-        RecordType.NS: 'NS',
-        RecordType.SOA: 'SOA',
-        RecordType.SPF: 'SPF',
-        RecordType.SRV: 'SRV',
-        RecordType.TXT: 'TXT',
-    }
-
-    HEALTHCHECK_TYPE_MAP = {
-        AuroraDNSHealthCheckType.HTTP: 'HTTP',
-        AuroraDNSHealthCheckType.HTTPS: 'HTTPS',
-        AuroraDNSHealthCheckType.TCP: 'TCP'
-    }
-
-    def list_zones(self):
-        zones = []
-
-        res = self.connection.request('/zones')
-        for zone in res.parse_body():
-            zones.append(self.__res_to_zone(zone))
-
-        return zones
-
-    def list_records(self, zone):
-        self.connection.set_context({'resource': 'zone', 'id': zone.id})
-        records = []
-        res = self.connection.request('/zones/%s/records' % zone.id)
-
-        for record in res.parse_body():
-            records.append(self.__res_to_record(zone, record))
-
-        return records
-
-    def get_zone(self, zone_id):
-        self.connection.set_context({'resource': 'zone', 'id': zone_id})
-        res = self.connection.request('/zones/%s' % zone_id)
-        zone = res.parse_body()
-        return self.__res_to_zone(zone)
-
-    def get_record(self, zone_id, record_id):
-        self.connection.set_context({'resource': 'record', 'id': record_id})
-        res = self.connection.request('/zones/%s/records/%s' % (zone_id,
-                                                                record_id))
-        record = res.parse_body()
-
-        zone = self.get_zone(zone_id)
-
-        return self.__res_to_record(zone, record)
-
-    def create_zone(self, domain, type='master', ttl=None, extra=None):
-        self.connection.set_context({'resource': 'zone', 'id': domain})
-        res = self.connection.request('/zones', method='POST',
-                                      data=json.dumps({'name': domain}))
-        zone = res.parse_body()
-        return self.__res_to_zone(zone)
-
-    def create_record(self, name, zone, type, data, extra=None):
-        if name is None:
-            name = ""
-
-        rdata = {
-            'name': name,
-            'type': self.RECORD_TYPE_MAP[type],
-            'content': data
-        }
-
-        rdata = self.__merge_extra_data(rdata, extra)
-
-        if 'ttl' not in rdata:
-            rdata['ttl'] = DEFAULT_ZONE_TTL
-
-        self.connection.set_context({'resource': 'zone', 'id': zone.id})
-        res = self.connection.request('/zones/%s/records' % zone.id,
-                                      method='POST',
-                                      data=json.dumps(rdata))
-
-        record = res.parse_body()
-        return self.__res_to_record(zone, record)
-
-    def delete_zone(self, zone):
-        self.connection.set_context({'resource': 'zone', 'id': zone.id})
-        self.connection.request('/zones/%s' % zone.id, method='DELETE')
-        return True
-
-    def delete_record(self, record):
-        self.connection.set_context({'resource': 'record', 'id': record.id})
-        self.connection.request('/zones/%s/records/%s' % (record.zone.id,
-                                                          record.id),
-                                method='DELETE')
-        return True
-
-    def update_record(self, record, name, type, data, extra):
-        rdata = {}
-
-        if name is not None:
-            rdata['name'] = name
-
-        if type is not None:
-            rdata['type'] = self.RECORD_TYPE_MAP[type]
-
-        if data is not None:
-            rdata['content'] = data
-
-        rdata = self.__merge_extra_data(rdata, extra)
-
-        self.connection.set_context({'resource': 'record', 'id': record.id})
-        self.connection.request('/zones/%s/records/%s' % (record.zone.id,
-                                                          record.id),
-                                method='PUT',
-                                data=json.dumps(rdata))
-
-        return self.get_record(record.zone.id, record.id)
-
-    def ex_list_healthchecks(self, zone):
-        """
-        List all Health Checks in a zone.
-
-        :param zone: Zone to list health checks for.
-        :type zone: :class:`Zone`
-
-        :return: ``list`` of :class:`AuroraDNSHealthCheck`
-        """
-        healthchecks = []
-        self.connection.set_context({'resource': 'zone', 'id': zone.id})
-        res = self.connection.request('/zones/%s/health_checks' % zone.id)
-
-        for healthcheck in res.parse_body():
-            healthchecks.append(self.__res_to_healthcheck(zone, healthcheck))
-
-        return healthchecks
-
-    def ex_get_healthcheck(self, zone, health_check_id):
-        """
-        Get a single Health Check from a zone
-
-        :param zone: Zone in which the health check is
-        :type zone: :class:`Zone`
-
-        :param health_check_id: ID of the required health check
-        :type  health_check_id: ``str``
-
-        :return: :class:`AuroraDNSHealthCheck`
-        """
-        self.connection.set_context({'resource': 'healthcheck',
-                                     'id': health_check_id})
-        res = self.connection.request('/zones/%s/health_checks/%s'
-                                      % (zone.id, health_check_id))
-        check = res.parse_body()
-
-        return self.__res_to_healthcheck(zone, check)
-
-    def ex_create_healthcheck(self, zone, type, hostname, port, path,
-                              interval, threshold, ipaddress=None,
-                              enabled=True, extra=None):
-        """
-        Create a new Health Check in a zone
-
-        :param zone: Zone in which the health check should be created
-        :type zone: :class:`Zone`
-
-        :param type: The type of health check to be created
-        :type  type: :class:`AuroraDNSHealthCheckType`
-
-        :param hostname: The hostname of the target to monitor
-        :type  hostname: ``str``
-
-        :param port: The port of the target to monitor. E.g. 80 for HTTP
-        :type  port: ``int``
-
-        :param path: The path of the target to monitor. Only used by HTTP
-                     at this moment. Usually this is simple /.
-        :type  path: ``str``
-
-        :param interval: The interval of checks. 10, 30 or 60 seconds.
-        :type  interval: ``int``
-
-        :param threshold: The threshold of failures before the healthcheck is
-                          marked as failed.
-        :type  threshold: ``int``
-
-        :param ipaddress: (optional) The IP Address of the target to monitor.
-                          You can pass a empty string if this is not required.
-        :type  ipaddress: ``str``
-
-        :param enabled: (optional) If this healthcheck is enabled to run
-        :type  enabled: ``bool``
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type  extra: ``dict``
-
-        :return: :class:`AuroraDNSHealthCheck`
-        """
-        cdata = {
-            'type': self.HEALTHCHECK_TYPE_MAP[type],
-            'hostname': hostname,
-            'ipaddress': ipaddress,
-            'port': int(port),
-            'interval': int(interval),
-            'path': path,
-            'threshold': int(threshold),
-            'enabled': enabled
-        }
-
-        self.connection.set_context({'resource': 'zone', 'id': zone.id})
-        res = self.connection.request('/zones/%s/health_checks' % zone.id,
-                                      method='POST',
-                                      data=json.dumps(cdata))
-
-        healthcheck = res.parse_body()
-        return self.__res_to_healthcheck(zone, healthcheck)
-
-    def ex_update_healthcheck(self, healthcheck, type=None,
-                              hostname=None, ipaddress=None, port=None,
-                              path=None, interval=None, threshold=None,
-                              enabled=None, extra=None):
-        """
-        Update an existing Health Check
-
-        :param zone: The healthcheck which has to be updated
-        :type zone: :class:`AuroraDNSHealthCheck`
-
-        :param type: (optional) The type of health check to be created
-        :type  type: :class:`AuroraDNSHealthCheckType`
-
-        :param hostname: (optional) The hostname of the target to monitor
-        :type  hostname: ``str``
-
-        :param ipaddress: (optional) The IP Address of the target to monitor.
-                          You can pass a empty string if this is not required.
-        :type  ipaddress: ``str``
-
-        :param port: (optional) The port of the target to monitor. E.g. 80
-                     for HTTP
-        :type  port: ``int``
-
-        :param path: (optional) The path of the target to monitor.
-                     Only used by HTTP at this moment. Usually just '/'.
-        :type  path: ``str``
-
-        :param interval: (optional) The interval of checks.
-                         10, 30 or 60 seconds.
-        :type  interval: ``int``
-
-        :param threshold: (optional) The threshold of failures before the
-                          healthcheck is marked as failed.
-        :type  threshold: ``int``
-
-        :param enabled: (optional) If this healthcheck is enabled to run
-        :type  enabled: ``bool``
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type  extra: ``dict``
-
-        :return: :class:`AuroraDNSHealthCheck`
-        """
-        cdata = {}
-
-        if type is not None:
-            cdata['type'] = self.HEALTHCHECK_TYPE_MAP[type]
-
-        if hostname is not None:
-            cdata['hostname'] = hostname
-
-        if ipaddress is not None:
-            if len(ipaddress) == 0:
-                cdata['ipaddress'] = None
-            else:
-                cdata['ipaddress'] = ipaddress
-
-        if port is not None:
-            cdata['port'] = int(port)
-
-        if path is not None:
-            cdata['path'] = path
-
-        if interval is not None:
-            cdata['interval'] = int(interval)
-
-        if threshold is not None:
-            cdata['threshold'] = threshold
-
-        if enabled is not None:
-            cdata['enabled'] = bool(enabled)
-
-        self.connection.set_context({'resource': 'healthcheck',
-                                     'id': healthcheck.id})
-
-        self.connection.request('/zones/%s/health_checks/%s'
-                                % (healthcheck.zone.id,
-                                   healthcheck.id),
-                                method='PUT',
-                                data=json.dumps(cdata))
-
-        return self.ex_get_healthcheck(healthcheck.zone,
-                                       healthcheck.id)
-
-    def ex_delete_healthcheck(self, healthcheck):
-        """
-        Remove an existing Health Check
-
-        :param zone: The healthcheck which has to be removed
-        :type zone: :class:`AuroraDNSHealthCheck`
-        """
-        self.connection.set_context({'resource': 'healthcheck',
-                                     'id': healthcheck.id})
-
-        self.connection.request('/zones/%s/health_checks/%s'
-                                % (healthcheck.zone.id,
-                                   healthcheck.id),
-                                method='DELETE')
-        return True
-
-    def __res_to_record(self, zone, record):
-        if len(record['name']) == 0:
-            name = None
-        else:
-            name = record['name']
-
-        extra = {}
-        extra['created'] = record['created']
-        extra['modified'] = record['modified']
-        extra['disabled'] = record['disabled']
-        extra['ttl'] = record['ttl']
-        extra['prio'] = record['prio']
-
-        return Record(id=record['id'], name=name,
-                      type=record['type'],
-                      data=record['content'], zone=zone,
-                      driver=self.connection.driver, ttl=record['ttl'],
-                      extra=extra)
-
-    def __res_to_zone(self, zone):
-        return Zone(id=zone['id'], domain=zone['name'],
-                    type=DEFAULT_ZONE_TYPE,
-                    ttl=DEFAULT_ZONE_TTL, driver=self.connection.driver,
-                    extra={'created': zone['created'],
-                           'servers': zone['servers'],
-                           'account_id': zone['account_id'],
-                           'cluster_id': zone['cluster_id']})
-
-    def __res_to_healthcheck(self, zone, healthcheck):
-        return AuroraDNSHealthCheck(id=healthcheck['id'],
-                                    type=healthcheck['type'],
-                                    hostname=healthcheck['hostname'],
-                                    ipaddress=healthcheck['ipaddress'],
-                                    health=healthcheck['health'],
-                                    threshold=healthcheck['threshold'],
-                                    path=healthcheck['path'],
-                                    interval=healthcheck['interval'],
-                                    port=healthcheck['port'],
-                                    enabled=healthcheck['enabled'],
-                                    zone=zone, driver=self.connection.driver)
-
-    def __merge_extra_data(self, rdata, extra):
-        if extra is not None:
-            for param in VALID_RECORD_PARAMS_EXTRA:
-                if param in extra:
-                    rdata[param] = extra[param]
-
-        return rdata

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/buddyns.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/buddyns.py b/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/buddyns.py
deleted file mode 100644
index 02af34d..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/buddyns.py
+++ /dev/null
@@ -1,153 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-BuddyNS DNS Driver
-"""
-
-import sys
-
-try:
-    import simplejson as json
-except ImportError:
-    import json
-
-from libcloud.dns.types import Provider, ZoneDoesNotExistError,\
-    ZoneAlreadyExistsError
-from libcloud.dns.base import DNSDriver, Zone
-from libcloud.common.buddyns import BuddyNSConnection, BuddyNSResponse,\
-    BuddyNSException
-
-__all__ = [
-    'BuddyNSDNSDriver'
-]
-
-
-class BuddyNSDNSResponse(BuddyNSResponse):
-    pass
-
-
-class BuddyNSDNSConnection(BuddyNSConnection):
-    responseCls = BuddyNSDNSResponse
-
-
-class BuddyNSDNSDriver(DNSDriver):
-    name = 'BuddyNS DNS'
-    website = 'https://www.buddyns.com'
-    type = Provider.BUDDYNS
-    connectionCls = BuddyNSDNSConnection
-
-    def list_zones(self):
-        action = '/api/v2/zone/'
-        response = self.connection.request(action=action, method='GET')
-        zones = self._to_zones(items=response.parse_body())
-
-        return zones
-
-    def get_zone(self, zone_id):
-        """
-        :param zone_id: Zone domain name (e.g. example.com)
-        :return: :class:`Zone`
-        """
-        action = '/api/v2/zone/%s' % zone_id
-        try:
-            response = self.connection.request(action=action, method='GET')
-        except BuddyNSException:
-            e = sys.exc_info()[1]
-            if e.message == 'Not found':
-                raise ZoneDoesNotExistError(value=e.message, driver=self,
-                                            zone_id=zone_id)
-            else:
-                raise e
-        zone = self._to_zone(response.parse_body())
-
-        return zone
-
-    def create_zone(self, domain, type='master', ttl=None, extra=None):
-        """
-        :param domain: Zone domain name (e.g. example.com)
-        :type domain: ``str``
-
-        :param type: Zone type (This is not really used. See API docs for extra
-          parameters)
-        :type type: ``str``
-
-        :param ttl: TTL for new records (This is used through the extra param)
-        :type ttl: ``int``
-
-        :param extra: Extra attributes that are specific to the driver
-        such as ttl.
-        :type extra: ``dict``
-
-        :rtype: :class:`Zone`
-        Do not forget to pass the master in extra,
-        extra = {'master':'65.55.37.62'} for example.
-        """
-        action = '/api/v2/zone/'
-        data = {'name': domain}
-        if extra is not None:
-            data.update(extra)
-        post_data = json.dumps(data)
-        try:
-            response = self.connection.request(action=action, method='POST',
-                                               data=post_data)
-        except BuddyNSException:
-            e = sys.exc_info()[1]
-            if e.message == 'Invalid zone submitted for addition.':
-                raise ZoneAlreadyExistsError(value=e.message, driver=self,
-                                             zone_id=domain)
-            else:
-                raise e
-
-        zone = self._to_zone(response.parse_body())
-
-        return zone
-
-    def delete_zone(self, zone):
-        """
-        :param zone: Zone to be deleted.
-        :type zone: :class:`Zone`
-
-        :return: Boolean
-        """
-        action = '/api/v2/zone/%s' % zone.domain
-        try:
-            self.connection.request(action=action, method='DELETE')
-        except BuddyNSException:
-            e = sys.exc_info()[1]
-            if e.message == 'Not found':
-                raise ZoneDoesNotExistError(value=e.message, driver=self,
-                                            zone_id=zone.id)
-            else:
-                raise e
-
-        return True
-
-    def _to_zone(self, item):
-        common_keys = ['name', ]
-        extra = {}
-        for key in item:
-            if key not in common_keys:
-                extra[key] = item.get(key)
-        zone = Zone(domain=item['name'], id=item['name'], type=None,
-                    extra=extra, ttl=None, driver=self)
-
-        return zone
-
-    def _to_zones(self, items):
-        zones = []
-        for item in items:
-            zones.append(self._to_zone(item))
-
-        return zones


[16/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/container/base.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/container/base.py b/apache-libcloud-1.0.0rc2/libcloud/container/base.py
deleted file mode 100644
index 0980041..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/container/base.py
+++ /dev/null
@@ -1,416 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from __future__ import with_statement
-
-from libcloud.common.base import ConnectionUserAndKey, BaseDriver
-
-
-__all__ = [
-    'Container',
-    'ContainerImage',
-    'ContainerCluster',
-    'ClusterLocation',
-    'ContainerDriver'
-]
-
-
-class Container(object):
-    """
-    Container.
-    """
-
-    def __init__(self, id, name, image, state,
-                 ip_addresses, driver, extra=None):
-        """
-        :param id: Container id.
-        :type id: ``str``
-
-        :param name: The name of the container.
-        :type  name: ``str``
-
-        :param image: The image this container was deployed using.
-        :type  image: :class:`.ContainerImage`
-
-        :param state: The state of the container, e.g. running
-        :type  state: :class:`libcloud.container.types.ContainerState`
-
-        :param ip_addresses: A list of IP addresses for this container
-        :type  ip_addresses: ``list`` of ``str``
-
-        :param driver: ContainerDriver instance.
-        :type driver: :class:`.ContainerDriver`
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type extra: ``dict``
-        """
-        self.id = str(id) if id else None
-        self.name = name
-        self.image = image
-        self.state = state
-        self.ip_addresses = ip_addresses
-        self.driver = driver
-        self.extra = extra or {}
-
-    def start(self):
-        return self.driver.start_container(container=self)
-
-    def stop(self):
-        return self.driver.stop_container(container=self)
-
-    def restart(self):
-        return self.driver.restart_container(container=self)
-
-    def destroy(self):
-        return self.driver.destroy_container(container=self)
-
-    def __repr__(self):
-        return ('<Container: id=%s, name=%s,'
-                'state=%s, provider=%s ...>' %
-                (self.id, self.name, self.state,
-                 self.driver.name))
-
-
-class ContainerImage(object):
-    """
-    Container Image.
-    """
-
-    def __init__(self, id, name, path, version, driver, extra=None):
-        """
-        :param id: Container Image id.
-        :type id: ``str``
-
-        :param name: The name of the image.
-        :type  name: ``str``
-
-        :param path: The path to the image
-        :type  path: ``str``
-
-        :param version: The version of the image
-        :type  version: ``str``
-
-        :param driver: ContainerDriver instance.
-        :type driver: :class:`.ContainerDriver`
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type extra: ``dict``
-        """
-        self.id = str(id) if id else None
-        self.name = name
-        self.path = path
-        self.version = version
-        self.driver = driver
-        self.extra = extra or {}
-
-    def deploy(self, name, parameters, *args, **kwargs):
-        return self.driver.deploy_container(name=name,
-                                            image=self,
-                                            parameters=parameters,
-                                            *args,
-                                            **kwargs)
-
-    def __repr__(self):
-        return ('<ContainerImage: id=%s, name=%s, path=%s ...>' %
-                (self.id, self.name, self.path))
-
-
-class ContainerCluster(object):
-    """
-    A cluster group for containers
-    """
-
-    def __init__(self, id, name, driver, extra=None):
-        """
-        :param id: Container Image id.
-        :type id: ``str``
-
-        :param name: The name of the image.
-        :type  name: ``str``
-
-        :param driver: ContainerDriver instance.
-        :type driver: :class:`.ContainerDriver`
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type extra: ``dict``
-        """
-        self.id = str(id) if id else None
-        self.name = name
-        self.driver = driver
-        self.extra = extra or {}
-
-    def list_containers(self):
-        return self.driver.list_containers(cluster=self)
-
-    def destroy(self):
-        return self.driver.destroy_cluster(cluster=self)
-
-    def __repr__(self):
-        return ('<ContainerCluster: id=%s, name=%s, provider=%s ...>' %
-                (self.id, self.name, self.driver.name))
-
-
-class ClusterLocation(object):
-    """
-    A physical location where clusters can be.
-
-    >>> from libcloud.container.drivers.dummy import DummyContainerDriver
-    >>> driver = DummyContainerDriver(0)
-    >>> location = driver.list_locations()[0]
-    >>> location.country
-    'US'
-    """
-
-    def __init__(self, id, name, country, driver):
-        """
-        :param id: Location ID.
-        :type id: ``str``
-
-        :param name: Location name.
-        :type name: ``str``
-
-        :param country: Location country.
-        :type country: ``str``
-
-        :param driver: Driver this location belongs to.
-        :type driver: :class:`.ContainerDriver`
-        """
-        self.id = str(id)
-        self.name = name
-        self.country = country
-        self.driver = driver
-
-    def __repr__(self):
-        return (('<ClusterLocation: id=%s, name=%s, country=%s, driver=%s>')
-                % (self.id, self.name, self.country, self.driver.name))
-
-
-class ContainerDriver(BaseDriver):
-    """
-    A base ContainerDriver class to derive from
-
-    This class is always subclassed by a specific driver.
-    """
-    connectionCls = ConnectionUserAndKey
-    name = None
-    website = None
-    supports_clusters = False
-    """
-    Whether the driver supports containers being deployed into clusters
-    """
-
-    def __init__(self, key, secret=None, secure=True, host=None, port=None,
-                 **kwargs):
-        """
-        :param    key: API key or username to used (required)
-        :type     key: ``str``
-
-        :param    secret: Secret password to be used (required)
-        :type     secret: ``str``
-
-        :param    secure: Whether to use HTTPS or HTTP. Note: Some providers
-                only support HTTPS, and it is on by default.
-        :type     secure: ``bool``
-
-        :param    host: Override hostname used for connections.
-        :type     host: ``str``
-
-        :param    port: Override port used for connections.
-        :type     port: ``int``
-
-        :return: ``None``
-        """
-        super(ContainerDriver, self).__init__(
-            key=key, secret=secret, secure=secure,
-            host=host, port=port, **kwargs)
-
-    def install_image(self, path):
-        """
-        Install a container image from a remote path.
-
-        :param path: Path to the container image
-        :type  path: ``str``
-
-        :rtype: :class:`.ContainerImage`
-        """
-        raise NotImplementedError(
-            'install_image not implemented for this driver')
-
-    def list_images(self):
-        """
-        List the installed container images
-
-        :rtype: ``list`` of :class:`.ContainerImage`
-        """
-        raise NotImplementedError(
-            'list_images not implemented for this driver')
-
-    def list_containers(self, image=None, cluster=None):
-        """
-        List the deployed container images
-
-        :param image: Filter to containers with a certain image
-        :type  image: :class:`.ContainerImage`
-
-        :param cluster: Filter to containers in a cluster
-        :type  cluster: :class:`.ContainerCluster`
-
-        :rtype: ``list`` of :class:`.Container`
-        """
-        raise NotImplementedError(
-            'list_containers not implemented for this driver')
-
-    def deploy_container(self, name, image, cluster=None,
-                         parameters=None, start=True):
-        """
-        Deploy an installed container image
-
-        :param name: The name of the new container
-        :type  name: ``str``
-
-        :param image: The container image to deploy
-        :type  image: :class:`.ContainerImage`
-
-        :param cluster: The cluster to deploy to, None is default
-        :type  cluster: :class:`.ContainerCluster`
-
-        :param parameters: Container Image parameters
-        :type  parameters: ``str``
-
-        :param start: Start the container on deployment
-        :type  start: ``bool``
-
-        :rtype: :class:`.Container`
-        """
-        raise NotImplementedError(
-            'deploy_container not implemented for this driver')
-
-    def get_container(self, id):
-        """
-        Get a container by ID
-
-        :param id: The ID of the container to get
-        :type  id: ``str``
-
-        :rtype: :class:`.Container`
-        """
-        raise NotImplementedError(
-            'get_container not implemented for this driver')
-
-    def start_container(self, container):
-        """
-        Start a deployed container
-
-        :param container: The container to start
-        :type  container: :class:`.Container`
-
-        :rtype: :class:`.Container`
-        """
-        raise NotImplementedError(
-            'start_container not implemented for this driver')
-
-    def stop_container(self, container):
-        """
-        Stop a deployed container
-
-        :param container: The container to stop
-        :type  container: :class:`.Container`
-
-        :rtype: :class:`.Container`
-        """
-        raise NotImplementedError(
-            'stop_container not implemented for this driver')
-
-    def restart_container(self, container):
-        """
-        Restart a deployed container
-
-        :param container: The container to restart
-        :type  container: :class:`.Container`
-
-        :rtype: :class:`.Container`
-        """
-        raise NotImplementedError(
-            'restart_container not implemented for this driver')
-
-    def destroy_container(self, container):
-        """
-        Destroy a deployed container
-
-        :param container: The container to destroy
-        :type  container: :class:`.Container`
-
-        :rtype: :class:`.Container`
-        """
-        raise NotImplementedError(
-            'destroy_container not implemented for this driver')
-
-    def list_locations(self):
-        """
-        Get a list of potential locations to deploy clusters into
-
-        :rtype: ``list`` of :class:`.ClusterLocation`
-        """
-        raise NotImplementedError(
-            'list_locations not implemented for this driver')
-
-    def create_cluster(self, name, location=None):
-        """
-        Create a container cluster
-
-        :param  name: The name of the cluster
-        :type   name: ``str``
-
-        :param  location: The location to create the cluster in
-        :type   location: :class:`.ClusterLocation`
-
-        :rtype: :class:`.ContainerCluster`
-        """
-        raise NotImplementedError(
-            'create_cluster not implemented for this driver')
-
-    def destroy_cluster(self, cluster):
-        """
-        Delete a cluster
-
-        :return: ``True`` if the destroy was successful, otherwise ``False``.
-        :rtype: ``bool``
-        """
-        raise NotImplementedError(
-            'destroy_cluster not implemented for this driver')
-
-    def list_clusters(self, location=None):
-        """
-        Get a list of potential locations to deploy clusters into
-
-        :param  location: The location to search in
-        :type   location: :class:`.ClusterLocation`
-
-        :rtype: ``list`` of :class:`.ContainerCluster`
-        """
-        raise NotImplementedError(
-            'list_clusters not implemented for this driver')
-
-    def get_cluster(self, id):
-        """
-        Get a cluster by ID
-
-        :param id: The ID of the cluster to get
-        :type  id: ``str``
-
-        :rtype: :class:`.ContainerCluster`
-        """
-        raise NotImplementedError(
-            'list_clusters not implemented for this driver')

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/container/drivers/__init__.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/container/drivers/__init__.py b/apache-libcloud-1.0.0rc2/libcloud/container/drivers/__init__.py
deleted file mode 100644
index e69de29..0000000

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/container/drivers/docker.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/container/drivers/docker.py b/apache-libcloud-1.0.0rc2/libcloud/container/drivers/docker.py
deleted file mode 100644
index d7c8419..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/container/drivers/docker.py
+++ /dev/null
@@ -1,656 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 base64
-import datetime
-import shlex
-import re
-
-try:
-    import simplejson as json
-except:
-    import json
-
-from libcloud.utils.py3 import httplib
-from libcloud.utils.py3 import b
-
-from libcloud.common.base import JsonResponse, ConnectionUserAndKey
-from libcloud.common.types import InvalidCredsError
-
-from libcloud.container.base import (Container, ContainerDriver,
-                                     ContainerImage)
-
-from libcloud.container.providers import Provider
-from libcloud.container.types import ContainerState
-
-
-VALID_RESPONSE_CODES = [httplib.OK, httplib.ACCEPTED, httplib.CREATED,
-                        httplib.NO_CONTENT]
-
-
-class DockerResponse(JsonResponse):
-
-    valid_response_codes = [httplib.OK, httplib.ACCEPTED, httplib.CREATED,
-                            httplib.NO_CONTENT]
-
-    def parse_body(self):
-        if len(self.body) == 0 and not self.parse_zero_length_body:
-            return self.body
-
-        try:
-            # error responses are tricky in Docker. Eg response could be
-            # an error, but response status could still be 200
-            content_type = self.headers.get('content-type', 'application/json')
-            if content_type == 'application/json' or content_type == '':
-                body = json.loads(self.body)
-            else:
-                body = self.body
-        except ValueError:
-            m = re.search('Error: (.+?)"', self.body)
-            if m:
-                error_msg = m.group(1)
-                raise Exception(error_msg)
-            else:
-                raise Exception(
-                    'ConnectionError: Failed to parse JSON response')
-        return body
-
-    def parse_error(self):
-        if self.status == 401:
-            raise InvalidCredsError('Invalid credentials')
-        return self.body
-
-    def success(self):
-        return self.status in self.valid_response_codes
-
-
-class DockerException(Exception):
-
-    def __init__(self, code, message):
-        self.code = code
-        self.message = message
-        self.args = (code, message)
-
-    def __str__(self):
-        return "%s %s" % (self.code, self.message)
-
-    def __repr__(self):
-        return "DockerException %s %s" % (self.code, self.message)
-
-
-class DockerConnection(ConnectionUserAndKey):
-
-    responseCls = DockerResponse
-    timeout = 60
-
-    def add_default_headers(self, headers):
-        """
-        Add parameters that are necessary for every request
-        If user and password are specified, include a base http auth
-        header
-        """
-        headers['Content-Type'] = 'application/json'
-        if self.user_id and self.key:
-            user_b64 = base64.b64encode(b('%s:%s' % (self.user_id, self.key)))
-            headers['Authorization'] = 'Basic %s' % (user_b64.decode('utf-8'))
-        return headers
-
-
-class DockerContainerDriver(ContainerDriver):
-    """
-    Docker container driver class.
-
-    >>> from libcloud.container.providers import get_driver
-    >>> driver = get_driver('docker')
-    >>> conn = driver(host='198.61.239.128', port=4243)
-    >>> conn.list_containers()
-    or connecting to http basic auth protected https host:
-    >>> conn = driver('user', 'pass', host='https://198.61.239.128', port=443)
-
-    connect with tls authentication, by providing a hostname, port, a private
-    key file (.pem) and certificate (.pem) file
-    >>> conn = driver(host='https://198.61.239.128',
-    >>> port=4243, key_file='key.pem', cert_file='cert.pem')
-    """
-
-    type = Provider.DOCKER
-    name = 'Docker'
-    website = 'http://docker.io'
-    connectionCls = DockerConnection
-    supports_clusters = False
-
-    def __init__(self, key=None, secret=None, secure=False, host='localhost',
-                 port=4243, key_file=None, cert_file=None):
-        """
-        :param    key: API key or username to used (required)
-        :type     key: ``str``
-
-        :param    secret: Secret password to be used (required)
-        :type     secret: ``str``
-
-        :param    secure: Whether to use HTTPS or HTTP. Note: Some providers
-                only support HTTPS, and it is on by default.
-        :type     secure: ``bool``
-
-        :param    host: Override hostname used for connections.
-        :type     host: ``str``
-
-        :param    port: Override port used for connections.
-        :type     port: ``int``
-
-        :param    key_file: Path to private key for TLS connection (optional)
-        :type     key_file: ``str``
-
-        :param    cert_file: Path to public key for TLS connection (optional)
-        :type     cert_file: ``str``
-
-        :return: ``None``
-        """
-        super(DockerContainerDriver, self).__init__(key=key, secret=secret,
-                                                    secure=secure, host=host,
-                                                    port=port,
-                                                    key_file=key_file,
-                                                    cert_file=cert_file)
-        if host.startswith('https://'):
-            secure = True
-
-        # strip the prefix
-        prefixes = ['http://', 'https://']
-        for prefix in prefixes:
-            if host.startswith(prefix):
-                host = host.strip(prefix)
-
-        if key_file or cert_file:
-            # docker tls authentication-
-            # https://docs.docker.com/articles/https/
-            # We pass two files, a key_file with the
-            # private key and cert_file with the certificate
-            # libcloud will handle them through LibcloudHTTPSConnection
-            if not (key_file and cert_file):
-                raise Exception(
-                    'Needs both private key file and '
-                    'certificate file for tls authentication')
-            self.connection.key_file = key_file
-            self.connection.cert_file = cert_file
-            self.connection.secure = True
-        else:
-            self.connection.secure = secure
-
-        self.connection.host = host
-        self.connection.port = port
-
-    def install_image(self, path):
-        """
-        Install a container image from a remote path.
-
-        :param path: Path to the container image
-        :type  path: ``str``
-
-        :rtype: :class:`libcloud.container.base.ContainerImage`
-        """
-        payload = {
-        }
-        data = json.dumps(payload)
-
-        result = self.connection.request('/images/create?fromImage=%s' %
-                                         (path), data=data, method='POST')
-        if "errorDetail" in result.body:
-            raise DockerException(None, result.body)
-        try:
-            # get image id
-            image_id = re.findall(
-                r'{"status":"Download complete"'
-                r',"progressDetail":{},"id":"\w+"}',
-                result.body)[-1]
-            image_id = json.loads(image_id).get('id')
-        except:
-            raise DockerException(None, 'failed to install image')
-
-        image = ContainerImage(
-            id=image_id,
-            name=path,
-            path=path,
-            version=None,
-            driver=self.connection.driver,
-            extra={})
-        return image
-
-    def list_images(self):
-        """
-        List the installed container images
-
-        :rtype: ``list`` of :class:`libcloud.container.base.ContainerImage`
-        """
-        result = self.connection.request('/images/json').object
-        images = []
-        for image in result:
-            try:
-                name = image.get('RepoTags')[0]
-            except:
-                name = image.get('Id')
-            images.append(ContainerImage(
-                id=image.get('Id'),
-                name=name,
-                path=name,
-                version=None,
-                driver=self.connection.driver,
-                extra={
-                    "created": image.get('Created'),
-                    "size": image.get('Size'),
-                    "virtual_size": image.get('VirtualSize'),
-                },
-            ))
-
-        return images
-
-    def list_containers(self, image=None, all=True):
-        """
-        List the deployed container images
-
-        :param image: Filter to containers with a certain image
-        :type  image: :class:`libcloud.container.base.ContainerImage`
-
-        :param all: Show all container (including stopped ones)
-        :type  all: ``bool``
-
-        :rtype: ``list`` of :class:`libcloud.container.base.Container`
-        """
-        if all:
-            ex = '?all=1'
-        else:
-            ex = ''
-        try:
-            result = self.connection.request(
-                "/containers/json%s" % (ex)).object
-        except Exception as exc:
-            if hasattr(exc, 'errno') and exc.errno == 111:
-                raise DockerException(
-                    exc.errno,
-                    'Make sure docker host is accessible'
-                    'and the API port is correct')
-            raise
-
-        containers = [self._to_container(value) for value in result]
-        return containers
-
-    def deploy_container(self, name, image, parameters=None, start=True,
-                         command=None, hostname=None, user='',
-                         stdin_open=True, tty=True,
-                         mem_limit=0, ports=None, environment=None, dns=None,
-                         volumes=None, volumes_from=None,
-                         network_disabled=False, entrypoint=None,
-                         cpu_shares=None, working_dir='', domainname=None,
-                         memswap_limit=0, port_bindings=None):
-        """
-        Deploy an installed container image
-
-        For details on the additional parameters see : http://bit.ly/1PjMVKV
-
-        :param name: The name of the new container
-        :type  name: ``str``
-
-        :param image: The container image to deploy
-        :type  image: :class:`libcloud.container.base.ContainerImage`
-
-        :param parameters: Container Image parameters
-        :type  parameters: ``str``
-
-        :param start: Start the container on deployment
-        :type  start: ``bool``
-
-        :rtype: :class:`Container`
-        """
-        command = shlex.split(str(command))
-        if port_bindings is None:
-            port_bindings = {}
-        params = {
-            'name': name
-        }
-
-        payload = {
-            'Hostname': hostname,
-            'Domainname': domainname,
-            'ExposedPorts': ports,
-            'User': user,
-            'Tty': tty,
-            'OpenStdin': stdin_open,
-            'StdinOnce': False,
-            'Memory': mem_limit,
-            'AttachStdin': True,
-            'AttachStdout': True,
-            'AttachStderr': True,
-            'Env': environment,
-            'Cmd': command,
-            'Dns': dns,
-            'Image': image.name,
-            'Volumes': volumes,
-            'VolumesFrom': volumes_from,
-            'NetworkDisabled': network_disabled,
-            'Entrypoint': entrypoint,
-            'CpuShares': cpu_shares,
-            'WorkingDir': working_dir,
-            'MemorySwap': memswap_limit,
-            'PublishAllPorts': True,
-            'PortBindings': port_bindings,
-        }
-
-        data = json.dumps(payload)
-        try:
-            result = self.connection.request('/containers/create', data=data,
-                                             params=params, method='POST')
-        except Exception as e:
-            if e.message.startswith('No such image:'):
-                raise DockerException(None, 'No such image: %s' % image.name)
-            else:
-                raise DockerException(None, e)
-
-        id_ = result.object['Id']
-
-        payload = {
-            'Binds': [],
-            'PublishAllPorts': True,
-            'PortBindings': port_bindings,
-        }
-
-        data = json.dumps(payload)
-        if start:
-            result = self.connection.request(
-                '/containers/%s/start' % id_, data=data,
-                method='POST')
-
-        return self.get_container(id_)
-
-    def get_container(self, id):
-        """
-        Get a container by ID
-
-        :param id: The ID of the container to get
-        :type  id: ``str``
-
-        :rtype: :class:`libcloud.container.base.Container`
-        """
-        result = self.connection.request("/containers/%s/json" %
-                                         id).object
-
-        return self._to_container(result)
-
-    def start_container(self, container):
-        """
-        Start a container
-
-        :param container: The container to be started
-        :type  container: :class:`libcloud.container.base.Container`
-
-        :return: The container refreshed with current data
-        :rtype: :class:`libcloud.container.base.Container`
-        """
-        payload = {
-            'Binds': [],
-            'PublishAllPorts': True,
-        }
-        data = json.dumps(payload)
-        result = self.connection.request(
-            '/containers/%s/start' %
-            (container.id),
-            method='POST', data=data)
-        if result.status in VALID_RESPONSE_CODES:
-            return self.get_container(container.id)
-        else:
-            raise DockerException(result.status,
-                                  'failed to start container')
-
-    def stop_container(self, container):
-        """
-        Stop a container
-
-        :param container: The container to be stopped
-        :type  container: :class:`libcloud.container.base.Container`
-
-        :return: The container refreshed with current data
-        :rtype: :class:`libcloud.container.base.Container`
-        """
-        result = self.connection.request('/containers/%s/stop' %
-                                         (container.id),
-                                         method='POST')
-        if result.status in VALID_RESPONSE_CODES:
-            return self.get_container(container.id)
-        else:
-            raise DockerException(result.status,
-                                  'failed to stop container')
-
-    def restart_container(self, container):
-        """
-        Restart a container
-
-        :param container: The container to be stopped
-        :type  container: :class:`libcloud.container.base.Container`
-
-        :return: The container refreshed with current data
-        :rtype: :class:`libcloud.container.base.Container`
-        """
-        data = json.dumps({'t': 10})
-        # number of seconds to wait before killing the container
-        result = self.connection.request('/containers/%s/restart' %
-                                         (container.id),
-                                         data=data, method='POST')
-        if result.status in VALID_RESPONSE_CODES:
-            return self.get_container(container.id)
-        else:
-            raise DockerException(result.status,
-                                  'failed to restart container')
-
-    def destroy_container(self, container):
-        """
-        Remove a container
-
-        :param container: The container to be destroyed
-        :type  container: :class:`libcloud.container.base.Container`
-
-        :return: True if the destroy was successful, False otherwise.
-        :rtype: ``bool``
-        """
-        result = self.connection.request('/containers/%s' % (container.id),
-                                         method='DELETE')
-        return result.status in VALID_RESPONSE_CODES
-
-    def ex_list_processes(self, container):
-        """
-        List processes running inside a container
-
-        :param container: The container to list processes for.
-        :type  container: :class:`libcloud.container.base.Container`
-
-        :rtype: ``str``
-        """
-        result = self.connection.request("/containers/%s/top" %
-                                         container.id).object
-
-        return result
-
-    def ex_rename_container(self, container, name):
-        """
-        Rename a container
-
-        :param container: The container to be renamed
-        :type  container: :class:`libcloud.container.base.Container`
-
-        :param name: The new name
-        :type  name: ``str``
-
-        :rtype: :class:`libcloud.container.base.Container`
-        """
-        result = self.connection.request('/containers/%s/rename?name=%s'
-                                         % (container.id, name),
-                                         method='POST')
-        if result.status in VALID_RESPONSE_CODES:
-            return self.get_container(container.id)
-
-    def ex_get_logs(self, container, stream=False):
-        """
-        Get container logs
-
-        If stream == True, logs will be yielded as a stream
-        From Api Version 1.11 and above we need a GET request to get the logs
-        Logs are in different format of those of Version 1.10 and below
-
-        :param container: The container to list logs for
-        :type  container: :class:`libcloud.container.base.Container`
-
-        :param stream: Stream the output
-        :type  stream: ``bool``
-
-        :rtype: ``bool``
-        """
-        payload = {}
-        data = json.dumps(payload)
-
-        if float(self._get_api_version()) > 1.10:
-            result = self.connection.request(
-                "/containers/%s/logs?follow=%s&stdout=1&stderr=1" %
-                (container.id, str(stream))).object
-            logs = result
-        else:
-            result = self.connection.request(
-                "/containers/%s/attach?logs=1&stream=%s&stdout=1&stderr=1" %
-                (container.id, str(stream)), method='POST', data=data)
-            logs = result.body
-
-        return logs
-
-    def ex_search_images(self, term):
-        """Search for an image on Docker.io.
-           Returns a list of ContainerImage objects
-
-           >>> images = conn.ex_search_images(term='mistio')
-           >>> images
-           [<ContainerImage: id=rolikeusch/docker-mistio...>,
-            <ContainerImage: id=mist/mistio, name=mist/mistio,
-                driver=Docker  ...>]
-
-            :param term: The search term
-            :type  term: ``str``
-
-            :rtype: ``list`` of :class:`libcloud.container.base.ContainerImage`
-        """
-
-        term = term.replace(' ', '+')
-        result = self.connection.request('/images/search?term=%s' %
-                                         term).object
-        images = []
-        for image in result:
-            name = image.get('name')
-            images.append(
-                ContainerImage(
-                    id=name,
-                    path=name,
-                    version=None,
-                    name=name,
-                    driver=self.connection.driver,
-                    extra={
-                        "description": image.get('description'),
-                        "is_official": image.get('is_official'),
-                        "is_trusted": image.get('is_trusted'),
-                        "star_count": image.get('star_count'),
-                    },
-                ))
-
-        return images
-
-    def ex_delete_image(self, image):
-        """
-        Remove image from the filesystem
-
-        :param  image: The image to remove
-        :type   image: :class:`libcloud.container.base.ContainerImage`
-
-        :rtype: ``bool``
-        """
-        result = self.connection.request('/images/%s' % (image.name),
-                                         method='DELETE')
-        return result.status in VALID_RESPONSE_CODES
-
-    def _to_container(self, data):
-        """
-        Convert container in Container instances
-        """
-        try:
-            name = data.get('Name').strip('/')
-        except:
-            try:
-                name = data.get('Names')[0].strip('/')
-            except:
-                name = data.get('Id')
-        state = data.get('State')
-        status = data.get('Status',
-                          state.get('Status')
-                          if state is not None else None)
-        if 'Exited' in status:
-            state = ContainerState.STOPPED
-        elif status.startswith('Up '):
-            state = ContainerState.RUNNING
-        else:
-            state = ContainerState.STOPPED
-        image = data.get('Image')
-        ports = data.get('Ports', [])
-        created = data.get('Created')
-        if isinstance(created, float):
-            created = ts_to_str(created)
-        extra = {
-            'id': data.get('Id'),
-            'status': data.get('Status'),
-            'created': created,
-            'image': image,
-            'ports': ports,
-            'command': data.get('Command'),
-            'sizerw': data.get('SizeRw'),
-            'sizerootfs': data.get('SizeRootFs'),
-        }
-        ips = []
-        if ports is not None:
-            for port in ports:
-                if port.get('IP') is not None:
-                    ips.append(port.get('IP'))
-        return Container(
-            id=data['Id'],
-            name=name,
-            image=ContainerImage(
-                id=data.get('ImageID', None),
-                path=image,
-                name=image,
-                version=None,
-                driver=self.connection.driver
-            ),
-            ip_addresses=ips,
-            state=state,
-            driver=self.connection.driver,
-            extra=extra)
-
-    def _get_api_version(self):
-        """
-        Get the docker API version information
-        """
-        result = self.connection.request('/version').object
-        api_version = result.get('ApiVersion')
-
-        return api_version
-
-
-def ts_to_str(timestamp):
-    """
-    Return a timestamp as a nicely formated datetime string.
-    """
-    date = datetime.datetime.fromtimestamp(timestamp)
-    date_string = date.strftime("%d/%m/%Y %H:%M %Z")
-    return date_string

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/container/drivers/dummy.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/container/drivers/dummy.py b/apache-libcloud-1.0.0rc2/libcloud/container/drivers/dummy.py
deleted file mode 100644
index 2c99259..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/container/drivers/dummy.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from libcloud.container.base import ContainerDriver
-
-
-class DummyContainerDriver(ContainerDriver):
-    """
-    Dummy Container driver.
-
-    >>> from libcloud.container.drivers.dummy import DummyContainerDriver
-    >>> driver = DummyContainerDriver('key', 'secret')
-    >>> driver.name
-    'Dummy Container Provider'
-    """
-
-    name = 'Dummy Container Provider'
-    website = 'http://example.com'
-    supports_clusters = False
-
-    def __init__(self, api_key, api_secret):
-        """
-        :param    api_key:    API key or username to used (required)
-        :type     api_key:    ``str``
-
-        :param    api_secret: Secret password to be used (required)
-        :type     api_secret: ``str``
-
-        :rtype: ``None``
-        """
-
-if __name__ == "__main__":
-    import doctest
-    doctest.testmod()

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/container/drivers/ecs.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/container/drivers/ecs.py b/apache-libcloud-1.0.0rc2/libcloud/container/drivers/ecs.py
deleted file mode 100644
index 36c5be3..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/container/drivers/ecs.py
+++ /dev/null
@@ -1,627 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-try:
-    import simplejson as json
-except ImportError:
-    import json
-
-from libcloud.container.base import (ContainerDriver, Container,
-                                     ContainerCluster, ContainerImage)
-from libcloud.container.types import ContainerState
-from libcloud.container.utils.docker import RegistryClient
-from libcloud.common.aws import SignedAWSConnection, AWSJsonResponse
-
-__all__ = [
-    'ElasticContainerDriver'
-]
-
-
-ECS_VERSION = '2014-11-13'
-ECR_VERSION = '2015-09-21'
-ECS_HOST = 'ecs.%s.amazonaws.com'
-ECR_HOST = 'ecr.%s.amazonaws.com'
-ROOT = '/'
-ECS_TARGET_BASE = 'AmazonEC2ContainerServiceV%s' % \
-                  (ECS_VERSION.replace('-', ''))
-ECR_TARGET_BASE = 'AmazonEC2ContainerRegistry_V%s' % \
-                  (ECR_VERSION.replace('-', ''))
-
-
-class ECSJsonConnection(SignedAWSConnection):
-    version = ECS_VERSION
-    host = ECS_HOST
-    responseCls = AWSJsonResponse
-    service_name = 'ecs'
-
-
-class ECRJsonConnection(SignedAWSConnection):
-    version = ECR_VERSION
-    host = ECR_HOST
-    responseCls = AWSJsonResponse
-    service_name = 'ecr'
-
-
-class ElasticContainerDriver(ContainerDriver):
-    name = 'Amazon Elastic Container Service'
-    website = 'https://aws.amazon.com/ecs/details/'
-    ecr_repository_host = '%s.dkr.ecr.%s.amazonaws.com'
-    connectionCls = ECSJsonConnection
-    ecrConnectionClass = ECRJsonConnection
-    supports_clusters = False
-    status_map = {
-        'RUNNING': ContainerState.RUNNING
-    }
-
-    def __init__(self, access_id, secret, region):
-        super(ElasticContainerDriver, self).__init__(access_id, secret)
-        self.region = region
-        self.region_name = region
-        self.connection.host = ECS_HOST % (region)
-
-        # Setup another connection class for ECR
-        conn_kwargs = self._ex_connection_class_kwargs()
-        self.ecr_connection = self.ecrConnectionClass(
-            access_id, secret, **conn_kwargs)
-        self.ecr_connection.host = ECR_HOST % (region)
-        self.ecr_connection.driver = self
-        self.ecr_connection.connect()
-
-    def _ex_connection_class_kwargs(self):
-        return {'signature_version': '4'}
-
-    def list_images(self, ex_repository_name):
-        """
-        List the images in an ECR repository
-
-        :param  ex_repository_name: The name of the repository to check
-            defaults to the default repository.
-        :type   ex_repository_name: ``str``
-
-        :return: a list of images
-        :rtype: ``list`` of :class:`libcloud.container.base.ContainerImage`
-        """
-        request = {}
-        request['repositoryName'] = ex_repository_name
-        list_response = self.ecr_connection.request(
-            ROOT,
-            method='POST',
-            data=json.dumps(request),
-            headers=self._get_ecr_headers('ListImages')
-        ).object
-        repository_id = self.ex_get_repository_id(ex_repository_name)
-        host = self._get_ecr_host(repository_id)
-        return self._to_images(list_response['imageIds'],
-                               host,
-                               ex_repository_name)
-
-    def list_clusters(self):
-        """
-        Get a list of potential locations to deploy clusters into
-
-        :param  location: The location to search in
-        :type   location: :class:`libcloud.container.base.ClusterLocation`
-
-        :rtype: ``list`` of :class:`libcloud.container.base.ContainerCluster`
-        """
-        listdata = self.connection.request(
-            ROOT,
-            method='POST',
-            data=json.dumps({}),
-            headers=self._get_headers('ListClusters')
-        ).object
-        request = {'clusters': listdata['clusterArns']}
-        data = self.connection.request(
-            ROOT,
-            method='POST',
-            data=json.dumps(request),
-            headers=self._get_headers('DescribeClusters')
-        ).object
-        return self._to_clusters(data)
-
-    def create_cluster(self, name, location=None):
-        """
-        Create a container cluster
-
-        :param  name: The name of the cluster
-        :type   name: ``str``
-
-        :param  location: The location to create the cluster in
-        :type   location: :class:`libcloud.container.base.ClusterLocation`
-
-        :rtype: :class:`libcloud.container.base.ContainerCluster`
-        """
-        request = {'clusterName': name}
-        response = self.connection.request(
-            ROOT,
-            method='POST',
-            data=json.dumps(request),
-            headers=self._get_headers('CreateCluster')
-        ).object
-        return self._to_cluster(response['cluster'])
-
-    def destroy_cluster(self, cluster):
-        """
-        Delete a cluster
-
-        :return: ``True`` if the destroy was successful, otherwise ``False``.
-        :rtype: ``bool``
-        """
-        request = {'cluster': cluster.id}
-        data = self.connection.request(
-            ROOT,
-            method='POST',
-            data=json.dumps(request),
-            headers=self._get_headers('DeleteCluster')
-        ).object
-        return data['cluster']['status'] == 'INACTIVE'
-
-    def list_containers(self, image=None, cluster=None):
-        """
-        List the deployed container images
-
-        :param image: Filter to containers with a certain image
-        :type  image: :class:`libcloud.container.base.ContainerImage`
-
-        :param cluster: Filter to containers in a cluster
-        :type  cluster: :class:`libcloud.container.base.ContainerCluster`
-
-        :rtype: ``list`` of :class:`libcloud.container.base.Container`
-        """
-        request = {'cluster': 'default'}
-        if cluster is not None:
-            request['cluster'] = cluster.id
-        if image is not None:
-            request['family'] = image.name
-        list_response = self.connection.request(
-            ROOT,
-            method='POST',
-            data=json.dumps(request),
-            headers=self._get_headers('ListTasks')
-        ).object
-        if len(list_response['taskArns']) == 0:
-            return []
-        containers = self.ex_list_containers_for_task(
-            list_response['taskArns'])
-        return containers
-
-    def deploy_container(self, name, image, cluster=None,
-                         parameters=None, start=True, ex_cpu=10, ex_memory=500,
-                         ex_container_port=None, ex_host_port=None):
-        """
-        Creates a task definition from a container image that can be run
-        in a cluster.
-
-        :param name: The name of the new container
-        :type  name: ``str``
-
-        :param image: The container image to deploy
-        :type  image: :class:`libcloud.container.base.ContainerImage`
-
-        :param cluster: The cluster to deploy to, None is default
-        :type  cluster: :class:`libcloud.container.base.ContainerCluster`
-
-        :param parameters: Container Image parameters
-        :type  parameters: ``str``
-
-        :param start: Start the container on deployment
-        :type  start: ``bool``
-
-        :rtype: :class:`libcloud.container.base.Container`
-        """
-        data = {}
-        if ex_container_port is None and ex_host_port is None:
-            port_maps = []
-        else:
-            port_maps = [
-                {
-                    "containerPort": ex_container_port,
-                    "hostPort": ex_host_port
-                }
-            ]
-        data['containerDefinitions'] = [
-            {
-                "mountPoints": [],
-                "name": name,
-                "image": image.name,
-                "cpu": ex_cpu,
-                "environment": [],
-                "memory": ex_memory,
-                "portMappings": port_maps,
-                "essential": True,
-                "volumesFrom": []
-            }
-        ]
-        data['family'] = name
-        response = self.connection.request(
-            ROOT,
-            method='POST',
-            data=json.dumps(data),
-            headers=self._get_headers('RegisterTaskDefinition')
-        ).object
-        if start:
-            return self.ex_start_task(
-                response['taskDefinition']['taskDefinitionArn'])[0]
-        else:
-            return Container(
-                id=None,
-                name=name,
-                image=image,
-                state=ContainerState.RUNNING,
-                ip_addresses=[],
-                extra={
-                    'taskDefinitionArn':
-                        response['taskDefinition']['taskDefinitionArn']
-                },
-                driver=self.connection.driver
-            )
-
-    def get_container(self, id):
-        """
-        Get a container by ID
-
-        :param id: The ID of the container to get
-        :type  id: ``str``
-
-        :rtype: :class:`libcloud.container.base.Container`
-        """
-        containers = self.ex_list_containers_for_task([id])
-        return containers[0]
-
-    def start_container(self, container, count=1):
-        """
-        Start a deployed task
-
-        :param container: The container to start
-        :type  container: :class:`libcloud.container.base.Container`
-
-        :param count: Number of containers to start
-        :type  count: ``int``
-
-        :rtype: :class:`libcloud.container.base.Container`
-        """
-        return self.ex_start_task(container.extra['taskDefinitionArn'], count)
-
-    def stop_container(self, container):
-        """
-        Stop a deployed container
-
-        :param container: The container to stop
-        :type  container: :class:`libcloud.container.base.Container`
-
-        :rtype: :class:`libcloud.container.base.Container`
-        """
-        request = {'task': container.extra['taskArn']}
-        response = self.connection.request(
-            ROOT,
-            method='POST',
-            data=json.dumps(request),
-            headers=self._get_headers('StopTask')
-        ).object
-        containers = []
-        containers.extend(self._to_containers(
-            response['task'],
-            container.extra['taskDefinitionArn']))
-        return containers
-
-    def restart_container(self, container):
-        """
-        Restart a deployed container
-
-        :param container: The container to restart
-        :type  container: :class:`libcloud.container.base.Container`
-
-        :rtype: :class:`libcloud.container.base.Container`
-        """
-        self.stop_container(container)
-        return self.start_container(container)
-
-    def destroy_container(self, container):
-        """
-        Destroy a deployed container
-
-        :param container: The container to destroy
-        :type  container: :class:`libcloud.container.base.Container`
-
-        :rtype: :class:`libcloud.container.base.Container`
-        """
-        return self.stop_container(container)
-
-    def ex_start_task(self, task_arn, count=1):
-        """
-        Run a task definition and get the containers
-
-        :param task_arn: The task ARN to Run
-        :type  task_arn: ``str``
-
-        :param count: The number of containers to start
-        :type  count: ``int``
-
-        :rtype: ``list`` of :class:`libcloud.container.base.Container`
-        """
-        request = None
-        request = {'count': count,
-                   'taskDefinition': task_arn}
-        response = self.connection.request(
-            ROOT,
-            method='POST',
-            data=json.dumps(request),
-            headers=self._get_headers('RunTask')
-        ).object
-        containers = []
-        for task in response['tasks']:
-            containers.extend(self._to_containers(task, task_arn))
-        return containers
-
-    def ex_list_containers_for_task(self, task_arns):
-        """
-        Get a list of containers by ID collection (ARN)
-
-        :param task_arns: The list of ARNs
-        :type  task_arns: ``list`` of ``str``
-
-        :rtype: ``list`` of :class:`libcloud.container.base.Container`
-        """
-        describe_request = {'tasks': task_arns}
-        descripe_response = self.connection.request(
-            ROOT,
-            method='POST',
-            data=json.dumps(describe_request),
-            headers=self._get_headers('DescribeTasks')
-        ).object
-        containers = []
-        for task in descripe_response['tasks']:
-            containers.extend(self._to_containers(
-                task, task['taskDefinitionArn']))
-        return containers
-
-    def ex_create_service(self, name, cluster,
-                          task_definition, desired_count=1):
-        """
-        Runs and maintains a desired number of tasks from a specified
-        task definition. If the number of tasks running in a service
-        drops below desired_count, Amazon ECS spawns another
-        instantiation of the task in the specified cluster.
-
-        :param  name: the name of the service
-        :type   name: ``str``
-
-        :param  cluster: The cluster to run the service on
-        :type   cluster: :class:`libcloud.container.base.ContainerCluster`
-
-        :param  task_definition: The task definition name or ARN for the
-            service
-        :type   task_definition: ``str``
-
-        :param  desired_count: The desired number of tasks to be running
-            at any one time
-        :type   desired_count: ``int``
-
-        :rtype: ``object`` The service object
-        """
-        request = {
-            'serviceName': name,
-            'taskDefinition': task_definition,
-            'desiredCount': desired_count,
-            'cluster': cluster.id}
-        response = self.connection.request(
-            ROOT,
-            method='POST',
-            data=json.dumps(request),
-            headers=self._get_headers('CreateService')
-        ).object
-        return response['service']
-
-    def ex_list_service_arns(self, cluster=None):
-        """
-        List the services
-
-        :param cluster: The cluster hosting the services
-        :type  cluster: :class:`libcloud.container.base.ContainerCluster`
-
-        :rtype: ``list`` of ``str``
-        """
-        request = {}
-        if cluster is not None:
-            request['cluster'] = cluster.id
-        response = self.connection.request(
-            ROOT,
-            method='POST',
-            data=json.dumps(request),
-            headers=self._get_headers('ListServices')
-        ).object
-        return response['serviceArns']
-
-    def ex_describe_service(self, service_arn):
-        """
-        Get the details of a service
-
-        :param  cluster: The hosting cluster
-        :type   cluster: :class:`libcloud.container.base.ContainerCluster`
-
-        :param  service_arn: The service ARN to describe
-        :type   service_arn: ``str``
-
-        :return: The service object
-        :rtype: ``object``
-        """
-        request = {'services': [service_arn]}
-        response = self.connection.request(
-            ROOT,
-            method='POST',
-            data=json.dumps(request),
-            headers=self._get_headers('DescribeServices')
-        ).object
-        return response['services'][0]
-
-    def ex_destroy_service(self, service_arn):
-        """
-        Deletes a service
-
-        :param  cluster: The target cluster
-        :type   cluster: :class:`libcloud.container.base.ContainerCluster`
-
-        :param  service_arn: The service ARN to destroy
-        :type   service_arn: ``str``
-        """
-        request = {
-            'service': service_arn}
-        response = self.connection.request(
-            ROOT,
-            method='POST',
-            data=json.dumps(request),
-            headers=self._get_headers('DeleteService')
-        ).object
-        return response['service']
-
-    def ex_get_registry_client(self, repository_name):
-        """
-        Get a client for an ECR repository
-
-        :param  repository_name: The unique name of the repository
-        :type   repository_name: ``str``
-
-        :return: a docker registry API client
-        :rtype: :class:`libcloud.container.utils.docker.RegistryClient`
-        """
-        repository_id = self.ex_get_repository_id(repository_name)
-        token = self.ex_get_repository_token(repository_id)
-        host = self._get_ecr_host(repository_id)
-        return RegistryClient(
-            host=host,
-            username='AWS',
-            password=token
-        )
-
-    def ex_get_repository_token(self, repository_id):
-        """
-        Get the authorization token (12 hour expiry) for a repository
-
-        :param  repository_id: The ID of the repository
-        :type   repository_id: ``str``
-
-        :return: A token for login
-        :rtype: ``str``
-        """
-        request = {'RegistryIds': [repository_id]}
-        response = self.ecr_connection.request(
-            ROOT,
-            method='POST',
-            data=json.dumps(request),
-            headers=self._get_ecr_headers('GetAuthorizationToken')
-        ).object
-        return response['authorizationData'][0]['authorizationToken']
-
-    def ex_get_repository_id(self, repository_name):
-        """
-        Get the ID of a repository
-
-        :param  repository_name: The unique name of the repository
-        :type   repository_name: ``str``
-
-        :return: The repository ID
-        :rtype: ``str``
-        """
-        request = {'repositoryNames': [repository_name]}
-        list_response = self.ecr_connection.request(
-            ROOT,
-            method='POST',
-            data=json.dumps(request),
-            headers=self._get_ecr_headers('DescribeRepositories')
-        ).object
-        repository_id = list_response['repositories'][0]['registryId']
-        return repository_id
-
-    def _get_ecr_host(self, repository_id):
-        return self.ecr_repository_host % (
-            repository_id,
-            self.region)
-
-    def _get_headers(self, action):
-        """
-        Get the default headers for a request to the ECS API
-        """
-        return {'x-amz-target': '%s.%s' %
-                (ECS_TARGET_BASE, action),
-                'Content-Type': 'application/x-amz-json-1.1'
-                }
-
-    def _get_ecr_headers(self, action):
-        """
-        Get the default headers for a request to the ECR API
-        """
-        return {'x-amz-target': '%s.%s' %
-                (ECR_TARGET_BASE, action),
-                'Content-Type': 'application/x-amz-json-1.1'
-                }
-
-    def _to_clusters(self, data):
-        clusters = []
-        for cluster in data['clusters']:
-            clusters.append(self._to_cluster(cluster))
-        return clusters
-
-    def _to_cluster(self, data):
-        return ContainerCluster(
-            id=data['clusterArn'],
-            name=data['clusterName'],
-            driver=self.connection.driver
-        )
-
-    def _to_containers(self, data, task_definition_arn):
-        clusters = []
-        for cluster in data['containers']:
-            clusters.append(self._to_container(cluster, task_definition_arn))
-        return clusters
-
-    def _to_container(self, data, task_definition_arn):
-        return Container(
-            id=data['containerArn'],
-            name=data['name'],
-            image=ContainerImage(
-                id=None,
-                name=data['name'],
-                path=None,
-                version=None,
-                driver=self.connection.driver
-            ),
-            ip_addresses=None,
-            state=self.status_map.get(data['lastStatus'], None),
-            extra={
-                'taskArn': data['taskArn'],
-                'taskDefinitionArn': task_definition_arn
-            },
-            driver=self.connection.driver
-        )
-
-    def _to_images(self, data, host, repository_name):
-        images = []
-        for image in data:
-            images.append(self._to_image(image, host, repository_name))
-        return images
-
-    def _to_image(self, data, host, repository_name):
-        path = '%s/%s:%s' % (
-            host,
-            repository_name,
-            data['imageTag']
-        )
-        return ContainerImage(
-            id=None,
-            name=path,
-            path=path,
-            version=data['imageTag'],
-            driver=self.connection.driver
-        )

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/container/drivers/joyent.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/container/drivers/joyent.py b/apache-libcloud-1.0.0rc2/libcloud/container/drivers/joyent.py
deleted file mode 100644
index 39df019..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/container/drivers/joyent.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-
-from libcloud.container.providers import Provider
-
-from libcloud.container.drivers.docker import (DockerContainerDriver,
-                                               DockerConnection)
-
-
-class JoyentContainerDriver(DockerContainerDriver):
-    """
-    Joyent Triton container driver class.
-
-    >>> from libcloud.container.providers import get_driver
-    >>> driver = get_driver('joyent')
-    >>> conn = driver(host='https://us-east-1.docker.joyent.com',
-        port=2376, key_file='key.pem', cert_file='cert.pem')
-    """
-
-    type = Provider.JOYENT
-    name = 'Joyent Triton'
-    website = 'http://joyent.com'
-    connectionCls = DockerConnection
-    supports_clusters = False
-
-    def __init__(self, key=None, secret=None, secure=False, host='localhost',
-                 port=2376, key_file=None, cert_file=None):
-
-        super(JoyentContainerDriver, self).__init__(key=key, secret=secret,
-                                                    secure=secure, host=host,
-                                                    port=port,
-                                                    key_file=key_file,
-                                                    cert_file=cert_file)
-        if host.startswith('https://'):
-            secure = True
-
-        # strip the prefix
-        prefixes = ['http://', 'https://']
-        for prefix in prefixes:
-            if host.startswith(prefix):
-                host = host.strip(prefix)
-
-        if key_file or cert_file:
-            # docker tls authentication-
-            # https://docs.docker.com/articles/https/
-            # We pass two files, a key_file with the
-            # private key and cert_file with the certificate
-            # libcloud will handle them through LibcloudHTTPSConnection
-            if not (key_file and cert_file):
-                raise Exception(
-                    'Needs both private key file and '
-                    'certificate file for tls authentication')
-            self.connection.key_file = key_file
-            self.connection.cert_file = cert_file
-            self.connection.secure = True
-        else:
-            self.connection.secure = secure
-
-        self.connection.host = host
-        self.connection.port = port

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/container/drivers/kubernetes.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/container/drivers/kubernetes.py b/apache-libcloud-1.0.0rc2/libcloud/container/drivers/kubernetes.py
deleted file mode 100644
index 426a5ef..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/container/drivers/kubernetes.py
+++ /dev/null
@@ -1,405 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 base64
-import datetime
-
-try:
-    import simplejson as json
-except:
-    import json
-
-from libcloud.utils.py3 import httplib
-from libcloud.utils.py3 import b
-
-from libcloud.common.base import JsonResponse, ConnectionUserAndKey
-from libcloud.common.types import InvalidCredsError
-
-from libcloud.container.base import (Container, ContainerDriver,
-                                     ContainerImage, ContainerCluster)
-
-from libcloud.container.providers import Provider
-from libcloud.container.types import ContainerState
-
-
-VALID_RESPONSE_CODES = [httplib.OK, httplib.ACCEPTED, httplib.CREATED,
-                        httplib.NO_CONTENT]
-
-ROOT_URL = '/api/'
-
-
-class KubernetesResponse(JsonResponse):
-
-    valid_response_codes = [httplib.OK, httplib.ACCEPTED, httplib.CREATED,
-                            httplib.NO_CONTENT]
-
-    def parse_error(self):
-        if self.status == 401:
-            raise InvalidCredsError('Invalid credentials')
-        return self.body
-
-    def success(self):
-        return self.status in self.valid_response_codes
-
-
-class KubernetesException(Exception):
-
-    def __init__(self, code, message):
-        self.code = code
-        self.message = message
-        self.args = (code, message)
-
-    def __str__(self):
-        return "%s %s" % (self.code, self.message)
-
-    def __repr__(self):
-        return "KubernetesException %s %s" % (self.code, self.message)
-
-
-class KubernetesConnection(ConnectionUserAndKey):
-    responseCls = KubernetesResponse
-    timeout = 60
-
-    def add_default_headers(self, headers):
-        """
-        Add parameters that are necessary for every request
-        If user and password are specified, include a base http auth
-        header
-        """
-        headers['Content-Type'] = 'application/json'
-        if self.key and self.secret:
-            user_b64 = base64.b64encode(b('%s:%s' % (self.key, self.secret)))
-            headers['Authorization'] = 'Basic %s' % (user_b64.decode('utf-8'))
-        return headers
-
-
-class KubernetesPod(object):
-    def __init__(self, name, containers, namespace):
-        """
-        A Kubernetes pod
-        """
-        self.name = name
-        self.containers = containers
-        self.namespace = namespace
-
-
-class KubernetesContainerDriver(ContainerDriver):
-    type = Provider.KUBERNETES
-    name = 'Kubernetes'
-    website = 'http://kubernetes.io'
-    connectionCls = KubernetesConnection
-    supports_clusters = True
-
-    def __init__(self, key=None, secret=None, secure=False, host='localhost',
-                 port=4243):
-        """
-        :param    key: API key or username to used (required)
-        :type     key: ``str``
-
-        :param    secret: Secret password to be used (required)
-        :type     secret: ``str``
-
-        :param    secure: Whether to use HTTPS or HTTP. Note: Some providers
-                only support HTTPS, and it is on by default.
-        :type     secure: ``bool``
-
-        :param    host: Override hostname used for connections.
-        :type     host: ``str``
-
-        :param    port: Override port used for connections.
-        :type     port: ``int``
-
-        :return: ``None``
-        """
-        super(KubernetesContainerDriver, self).__init__(key=key, secret=secret,
-                                                        secure=secure,
-                                                        host=host,
-                                                        port=port)
-        if host.startswith('https://'):
-            secure = True
-
-        # strip the prefix
-        prefixes = ['http://', 'https://']
-        for prefix in prefixes:
-            if host.startswith(prefix):
-                host = host.strip(prefix)
-
-        self.connection.secure = secure
-        self.connection.key = key
-        self.connection.secret = secret
-
-        self.connection.host = host
-        self.connection.port = port
-
-    def list_containers(self, image=None, all=True):
-        """
-        List the deployed container images
-
-        :param image: Filter to containers with a certain image
-        :type  image: :class:`libcloud.container.base.ContainerImage`
-
-        :param all: Show all container (including stopped ones)
-        :type  all: ``bool``
-
-        :rtype: ``list`` of :class:`libcloud.container.base.Container`
-        """
-        try:
-            result = self.connection.request(
-                ROOT_URL + "v1/pods").object
-        except Exception as exc:
-            if hasattr(exc, 'errno') and exc.errno == 111:
-                raise KubernetesException(
-                    exc.errno,
-                    'Make sure kube host is accessible'
-                    'and the API port is correct')
-            raise
-
-        pods = [self._to_pod(value) for value in result['items']]
-        containers = []
-        for pod in pods:
-            containers.extend(pod.containers)
-        return containers
-
-    def get_container(self, id):
-        """
-        Get a container by ID
-
-        :param id: The ID of the container to get
-        :type  id: ``str``
-
-        :rtype: :class:`libcloud.container.base.Container`
-        """
-        result = self.connection.request(ROOT_URL + "v1/nodes/%s" %
-                                         id).object
-
-        return self._to_container(result)
-
-    def list_clusters(self):
-        """
-        Get a list of namespaces that pods can be deployed into
-
-        :param  location: The location to search in
-        :type   location: :class:`libcloud.container.base.ClusterLocation`
-
-        :rtype: ``list`` of :class:`libcloud.container.base.ContainerCluster`
-        """
-        try:
-            result = self.connection.request(
-                ROOT_URL + "v1/namespaces/").object
-        except Exception as exc:
-            if hasattr(exc, 'errno') and exc.errno == 111:
-                raise KubernetesException(
-                    exc.errno,
-                    'Make sure kube host is accessible'
-                    'and the API port is correct')
-            raise
-
-        clusters = [self._to_cluster(value) for value in result['items']]
-        return clusters
-
-    def get_cluster(self, id):
-        """
-        Get a cluster by ID
-
-        :param id: The ID of the cluster to get
-        :type  id: ``str``
-
-        :rtype: :class:`libcloud.container.base.ContainerCluster`
-        """
-        result = self.connection.request(ROOT_URL + "v1/namespaces/%s" %
-                                         id).object
-
-        return self._to_cluster(result)
-
-    def destroy_cluster(self, cluster):
-        """
-        Delete a cluster (namespace)
-
-        :return: ``True`` if the destroy was successful, otherwise ``False``.
-        :rtype: ``bool``
-        """
-        self.connection.request(ROOT_URL + "v1/namespaces/%s" %
-                                cluster.id, method='DELETE').object
-        return True
-
-    def create_cluster(self, name, location=None):
-        """
-        Create a container cluster (a namespace)
-
-        :param  name: The name of the cluster
-        :type   name: ``str``
-
-        :param  location: The location to create the cluster in
-        :type   location: :class:`.ClusterLocation`
-
-        :rtype: :class:`.ContainerCluster`
-        """
-        request = {
-            'metadata': {
-                'name': name
-            }
-        }
-        result = self.connection.request(ROOT_URL + "v1/namespaces",
-                                         method='POST',
-                                         data=json.dumps(request)).object
-        return self._to_cluster(result)
-
-    def deploy_container(self, name, image, cluster=None,
-                         parameters=None, start=True):
-        """
-        Deploy an installed container image.
-        In kubernetes this deploys a single container Pod.
-        https://cloud.google.com/container-engine/docs/pods/single-container
-
-        :param name: The name of the new container
-        :type  name: ``str``
-
-        :param image: The container image to deploy
-        :type  image: :class:`.ContainerImage`
-
-        :param cluster: The cluster to deploy to, None is default
-        :type  cluster: :class:`.ContainerCluster`
-
-        :param parameters: Container Image parameters
-        :type  parameters: ``str``
-
-        :param start: Start the container on deployment
-        :type  start: ``bool``
-
-        :rtype: :class:`.Container`
-        """
-        if cluster is None:
-            namespace = 'default'
-        else:
-            namespace = cluster.id
-        request = {
-            "metadata": {
-                "name": name
-            },
-            "spec": {
-                "containers": [
-                    {
-                        "name": name,
-                        "image": image.name
-                    }
-                ]
-            }
-        }
-        result = self.connection.request(ROOT_URL + "v1/namespaces/%s/pods"
-                                         % namespace,
-                                         method='POST',
-                                         data=json.dumps(request)).object
-        return self._to_cluster(result)
-
-    def destroy_container(self, container):
-        """
-        Destroy a deployed container. Because the containers are single
-        container pods, this will delete the pod.
-
-        :param container: The container to destroy
-        :type  container: :class:`.Container`
-
-        :rtype: ``bool``
-        """
-        return self.ex_delete_pod(container.extra['namespace'],
-                                  container.extra['pod'])
-
-    def ex_list_pods(self):
-        """
-        List available Pods
-
-        :rtype: ``list`` of :class:`.KubernetesPod`
-        """
-        result = self.connection.request(ROOT_URL + "v1/pods").object
-        return [self._to_pod(value) for value in result['items']]
-
-    def ex_destroy_pod(self, namespace, pod_name):
-        """
-        Delete a pod and the containers within it.
-        """
-        self.connection.request(
-            ROOT_URL + "v1/namespaces/%s/pods/%s" % (
-                namespace, pod_name),
-            method='DELETE').object
-        return True
-
-    def _to_pod(self, data):
-        """
-        Convert an API response to a Pod object
-        """
-        container_statuses = data['status']['containerStatuses']
-        containers = []
-        # response contains the status of the containers in a separate field
-        for container in data['spec']['containers']:
-            spec = list(filter(lambda i: i['name'] == container['name'],
-                               container_statuses))[0]
-            containers.append(
-                self._to_container(container, spec, data)
-            )
-        return KubernetesPod(
-            name=data['metadata']['name'],
-            namespace=data['metadata']['namespace'],
-            containers=containers)
-
-    def _to_container(self, data, container_status, pod_data):
-        """
-        Convert container in Container instances
-        """
-        return Container(
-            id=container_status['containerID'],
-            name=data['name'],
-            image=ContainerImage(
-                id=container_status['imageID'],
-                name=data['image'],
-                path=None,
-                version=None,
-                driver=self.connection.driver),
-            ip_addresses=None,
-            state=ContainerState.RUNNING,
-            driver=self.connection.driver,
-            extra={
-                'pod': pod_data['metadata']['name'],
-                'namespace': pod_data['metadata']['namespace']
-            })
-
-    def _to_cluster(self, data):
-        """
-        Convert namespace to a cluster
-        """
-        metadata = data['metadata']
-        status = data['status']
-        return ContainerCluster(
-            id=metadata['name'],
-            name=metadata['name'],
-            driver=self.connection.driver,
-            extra={'phase': status['phase']})
-
-    def _get_api_version(self):
-        """
-        Get the docker API version information
-        """
-        result = self.connection.request('/version').object
-        api_version = result.get('ApiVersion')
-
-        return api_version
-
-
-def ts_to_str(timestamp):
-    """
-    Return a timestamp as a nicely formated datetime string.
-    """
-    date = datetime.datetime.fromtimestamp(timestamp)
-    date_string = date.strftime("%d/%m/%Y %H:%M %Z")
-    return date_string

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/container/providers.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/container/providers.py b/apache-libcloud-1.0.0rc2/libcloud/container/providers.py
deleted file mode 100644
index 16ab58c..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/container/providers.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from libcloud.container.types import Provider
-from libcloud.common.providers import get_driver as _get_provider_driver
-from libcloud.common.providers import set_driver as _set_provider_driver
-
-DRIVERS = {
-    Provider.DUMMY:
-    ('libcloud.container.drivers.dummy', 'DummyContainerDriver'),
-    Provider.DOCKER:
-    ('libcloud.container.drivers.docker', 'DockerContainerDriver'),
-    Provider.JOYENT:
-    ('libcloud.container.drivers.joyent', 'JoyentContainerDriver'),
-    Provider.ECS:
-    ('libcloud.container.drivers.ecs', 'ElasticContainerDriver'),
-    Provider.KUBERNETES:
-    ('libcloud.container.drivers.kubernetes', 'KubernetesContainerDriver'),
-}
-
-
-def get_driver(provider):
-    return _get_provider_driver(drivers=DRIVERS, provider=provider)
-
-
-def set_driver(provider, module, klass):
-    return _set_provider_driver(drivers=DRIVERS, provider=provider,
-                                module=module, klass=klass)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/container/types.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/container/types.py b/apache-libcloud-1.0.0rc2/libcloud/container/types.py
deleted file mode 100644
index 263d9d4..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/container/types.py
+++ /dev/null
@@ -1,76 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-__all__ = [
-    'Provider',
-    'ContainerState'
-]
-
-
-class Type(object):
-    @classmethod
-    def tostring(cls, value):
-        """Return the string representation of the state object attribute
-        :param str value: the state object to turn into string
-        :return: the uppercase string that represents the state object
-        :rtype: str
-        """
-        return value.upper()
-
-    @classmethod
-    def fromstring(cls, value):
-        """Return the state object attribute that matches the string
-        :param str value: the string to look up
-        :return: the state object attribute that matches the string
-        :rtype: str
-        """
-        return getattr(cls, value.upper(), None)
-
-
-class Provider(object):
-    DUMMY = 'dummy'
-    DOCKER = 'docker'
-    JOYENT = 'joyent'
-    ECS = 'ecs'
-    KUBERNETES = 'kubernetes'
-
-
-class ContainerState(Type):
-    """
-    Standard states for a container
-
-    :cvar RUNNING: Container is running.
-    :cvar REBOOTING: Container is rebooting.
-    :cvar TERMINATED: Container is terminated.
-                This container can't be started later on.
-    :cvar STOPPED: Container is stopped.
-                This container can be started later on.
-    :cvar PENDING: Container is pending.
-    :cvar SUSPENDED: Container is suspended.
-    :cvar ERROR: Container is an error state.
-                Usually no operations can be performed
-                on the container once it ends up in the error state.
-    :cvar PAUSED: Container is paused.
-    :cvar UNKNOWN: Container state is unknown.
-    """
-    RUNNING = 'running'
-    REBOOTING = 'rebooting'
-    TERMINATED = 'terminated'
-    PENDING = 'pending'
-    UNKNOWN = 'unknown'
-    STOPPED = 'stopped'
-    SUSPENDED = 'suspended'
-    ERROR = 'error'
-    PAUSED = 'paused'

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/container/utils/__init__.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/container/utils/__init__.py b/apache-libcloud-1.0.0rc2/libcloud/container/utils/__init__.py
deleted file mode 100644
index e69de29..0000000


[55/56] [abbrv] libcloud git commit: Merge branch 'trunk' of github.com:apache/libcloud into trunk

Posted by an...@apache.org.
Merge branch 'trunk' of github.com:apache/libcloud into trunk


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/04a09811
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/04a09811
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/04a09811

Branch: refs/heads/trunk
Commit: 04a09811e5e95041b9adfb877e89e1ed8e48ca18
Parents: c726d1f df93d65
Author: Anthony Shaw <an...@apache.org>
Authored: Tue Nov 15 10:25:01 2016 +1100
Committer: Anthony Shaw <an...@apache.org>
Committed: Tue Nov 15 10:25:01 2016 +1100

----------------------------------------------------------------------
 .pylintrc                                       |    2 +-
 CHANGES.rst                                     |  105 +-
 README.rst                                      |    2 +-
 demos/gce_demo.py                               |  237 +-
 doap_libcloud.rdf                               |    7 +
 .../_supported_methods_block_storage.rst        |   10 +-
 .../_supported_methods_image_management.rst     |    6 +-
 .../_supported_methods_key_pair_management.rst  |    8 +-
 docs/compute/_supported_methods_main.rst        |    6 +-
 docs/compute/_supported_providers.rst           |    6 +-
 docs/compute/index.rst                          |    2 +-
 docs/container/_supported_methods.rst           |    2 +
 docs/container/_supported_providers.rst         |    2 +
 docs/loadbalancer/_supported_methods.rst        |    2 +
 docs/loadbalancer/_supported_providers.rst      |    2 +
 docs/other/hacktoberfest.txt                    |   10 +
 docs/storage/_supported_methods_cdn.rst         |    6 +-
 docs/storage/_supported_methods_main.rst        |    6 +-
 docs/storage/_supported_providers.rst           |    6 +-
 libcloud/__init__.py                            |    3 +-
 libcloud/common/base.py                         |    2 +-
 libcloud/common/cloudsigma.py                   |    5 +
 libcloud/common/dimensiondata.py                |  246 +-
 libcloud/common/google.py                       |    4 +-
 libcloud/compute/drivers/ciscoccs.py            |   56 -
 libcloud/compute/drivers/digitalocean.py        |   66 +-
 libcloud/compute/drivers/dimensiondata.py       | 1535 ++++-
 libcloud/compute/drivers/ec2.py                 |    2 +-
 libcloud/compute/drivers/gce.py                 | 1967 ++++++-
 libcloud/compute/drivers/openstack.py           |    3 +
 libcloud/compute/drivers/ovh.py                 |  148 +-
 libcloud/compute/drivers/profitbricks.py        | 4101 ++++++++++---
 libcloud/compute/drivers/vultr.py               |  113 +-
 libcloud/compute/providers.py                   |    2 -
 libcloud/container/drivers/docker.py            |   36 +-
 libcloud/container/drivers/rancher.py           |   49 +-
 libcloud/loadbalancer/drivers/alb.py            |  321 ++
 libcloud/loadbalancer/providers.py              |    2 +
 libcloud/loadbalancer/types.py                  |    1 +
 libcloud/storage/drivers/google_storage.py      |   18 +
 libcloud/storage/drivers/s3.py                  |   12 +
 libcloud/storage/providers.py                   |    2 +
 libcloud/storage/types.py                       |    2 +
 libcloud/test/common/test_google.py             |   13 +-
 .../fixtures/digitalocean/ex_change_kernel.json |   12 +
 .../fixtures/digitalocean/ex_hard_reboot.json   |   12 +
 .../digitalocean_v2/create_volume_snapshot.json |   14 +
 .../digitalocean_v2/ex_change_kernel.json       |   12 +
 .../digitalocean_v2/ex_hard_reboot.json         |   12 +
 .../digitalocean_v2/list_volume_snapshots.json  |   44 +
 .../fixtures/dimensiondata/audit_log.csv        |   25 +
 .../dimensiondata/ip_address_list_create.xml    |    9 +
 .../dimensiondata/ip_address_list_delete.xml    |   10 +
 .../dimensiondata/ip_address_list_edit.xml      |   10 +
 .../fixtures/dimensiondata/ip_address_lists.xml |   46 +
 .../ip_address_lists_FILTERBYNAME.xml           |   14 +
 .../fixtures/dimensiondata/port_list_create.xml |    9 +
 .../fixtures/dimensiondata/port_list_delete.xml |   10 +
 .../fixtures/dimensiondata/port_list_edit.xml   |    8 +
 .../fixtures/dimensiondata/port_list_get.xml    |   15 +
 .../fixtures/dimensiondata/port_list_lists.xml  |   38 +
 .../fixtures/dimensiondata/server_GetServer.xml |   39 +
 .../gce/aggregated_instanceGroupManagers.json   |    8 +-
 .../gce/global_backendServices_web_service.json |    4 +-
 .../fixtures/gce/global_instanceTemplates.json  |   10 +-
 .../gce/global_instanceTemplates_insert.json    |   12 +
 .../fixtures/gce/global_sslcertificates.json    |   16 +
 .../gce/global_sslcertificates_example.json     |   10 +
 .../gce/global_sslcertificates_post.json        |   13 +
 ...eration_global_instanceTemplates_insert.json |   12 +
 ...s_operation_global_sslcertificates_post.json |   13 +
 ...nes_us_central1_a_instanceGroups_insert.json |   13 +
 ...l1_a_instanceGroups_myname_addInstances.json |   13 +
 ...central1_a_instanceGroups_myname_delete.json |   13 +
 ...a_instanceGroups_myname_removeInstances.json |   13 +
 ...1_a_instanceGroups_myname_setNamedPorts.json |   13 +
 ...s-east1_subnetworks_cf_972cf02e6ad49113.json |   11 +
 ...nes_us-central1-a_instanceGroupManagers.json |    4 +-
 ...a_instanceGroupManagers_myinstancegroup.json |    4 +-
 ...entral1-a_instanceGroup_myinstancegroup.json |    4 +-
 ...ntral1-a_instanceGroup_myinstancegroup2.json |   14 +
 ...b_instanceGroupManagers_myinstancegroup.json |    4 +-
 ...entral1-b_instanceGroup_myinstancegroup.json |    2 +-
 .../zones_us-east1-b_instanceGroupManagers.json |    4 +-
 ...s-east1-b_instanceGroup_myinstancegroup.json |    4 +-
 .../gce/zones_us_central1_a_instanceGroups.json |   29 +
 ...nes_us_central1_a_instanceGroups_insert.json |   13 +
 ...nes_us_central1_a_instanceGroups_myname.json |   12 +
 ...l1_a_instanceGroups_myname_addInstances.json |   13 +
 ...central1_a_instanceGroups_myname_delete.json |   13 +
 ...1_a_instanceGroups_myname_listInstances.json |   15 +
 ...a_instanceGroups_myname_removeInstances.json |   13 +
 ...1_a_instanceGroups_myname_setNamedPorts.json |   13 +
 .../fixtures/ovh/volume_snapshot_get.json       |   22 +
 .../ovh/volume_snapshot_get_details.json        |   10 +
 .../fixtures/profitbricks/attach_volume.json    |   34 +
 .../fixtures/profitbricks/attach_volume.xml     |   12 -
 .../fixtures/profitbricks/create_node.json      |   37 +
 .../fixtures/profitbricks/create_node.xml       |   13 -
 .../fixtures/profitbricks/create_volume.json    |   35 +
 .../fixtures/profitbricks/create_volume.xml     |   13 -
 .../profitbricks/create_volume_snapshot.json    |   30 +
 .../fixtures/profitbricks/destroy_node.xml      |   12 -
 .../fixtures/profitbricks/destroy_volume.xml    |   12 -
 .../fixtures/profitbricks/detach_volume.xml     |   12 -
 .../profitbricks/ex_clear_datacenter.xml        |   12 -
 .../profitbricks/ex_create_datacenter.json      |   20 +
 .../profitbricks/ex_create_datacenter.xml       |   13 -
 .../profitbricks/ex_create_firewall_rule.json   |   24 +
 .../profitbricks/ex_create_ip_block.json        |   22 +
 .../fixtures/profitbricks/ex_create_lan.json    |   17 +
 .../profitbricks/ex_create_load_balancer.json   |   18 +
 .../ex_create_network_interface.json            |   22 +
 .../ex_create_network_interface.xml             |   13 -
 .../profitbricks/ex_describe_datacenter.json    |  401 ++
 .../profitbricks/ex_describe_datacenter.xml     |   15 -
 .../profitbricks/ex_describe_firewall_rule.json |   24 +
 .../profitbricks/ex_describe_image.json         |   32 +
 .../profitbricks/ex_describe_ip_block.json      |   21 +
 .../fixtures/profitbricks/ex_describe_lan.json  |   24 +
 .../profitbricks/ex_describe_load_balancer.json |   25 +
 .../profitbricks/ex_describe_location.json      |   12 +
 .../ex_describe_network_interface.json          |   31 +
 .../ex_describe_network_interface.xml           |   26 -
 .../fixtures/profitbricks/ex_describe_node.json |  111 +
 .../fixtures/profitbricks/ex_describe_node.xml  |   77 -
 .../profitbricks/ex_describe_snapshot.json      |   30 +
 .../profitbricks/ex_describe_volume.json        |   35 +
 .../profitbricks/ex_describe_volume.xml         |   22 -
 .../profitbricks/ex_destroy_datacenter.xml      |   10 -
 .../ex_destroy_network_interface.xml            |   12 -
 .../profitbricks/ex_list_attached_volumes.json  |  112 +
 .../profitbricks/ex_list_datacenters.json       |   52 +
 .../profitbricks/ex_list_datacenters.xml        |   19 -
 .../profitbricks/ex_list_firewall_rules.json    |   79 +
 .../profitbricks/ex_list_ip_blocks.json         |   50 +
 .../fixtures/profitbricks/ex_list_lans.json     |  157 +
 .../ex_list_load_balanced_nics.json             |   69 +
 .../profitbricks/ex_list_load_balancers.json    |  216 +
 .../ex_list_network_interfaces.json             |   69 +
 .../profitbricks/ex_list_network_interfaces.xml |   75 -
 .../profitbricks/ex_rename_datacenter.json      |   46 +
 .../profitbricks/ex_set_inet_access.json        |   31 +
 .../fixtures/profitbricks/ex_start_node.xml     |   10 -
 .../fixtures/profitbricks/ex_stop_node.xml      |   10 -
 .../profitbricks/ex_update_datacenter.xml       |   12 -
 .../profitbricks/ex_update_firewall_rule.json   |   25 +
 .../fixtures/profitbricks/ex_update_image.json  |   32 +
 .../fixtures/profitbricks/ex_update_lan.json    |   24 +
 .../profitbricks/ex_update_load_balancer.json   |   18 +
 .../ex_update_network_interface.json            |   31 +
 .../ex_update_network_interface.xml             |   12 -
 .../fixtures/profitbricks/ex_update_node.json   |   45 +
 .../fixtures/profitbricks/ex_update_node.xml    |   12 -
 .../profitbricks/ex_update_snapshot.json        |   30 +
 .../fixtures/profitbricks/ex_update_volume.json |   35 +
 .../fixtures/profitbricks/ex_update_volume.xml  |   12 -
 .../fixtures/profitbricks/list_images.json      |  199 +
 .../fixtures/profitbricks/list_images.xml       |   43 -
 .../fixtures/profitbricks/list_locations.json   |   43 +
 .../fixtures/profitbricks/list_nodes.json       |  169 +
 .../fixtures/profitbricks/list_nodes.xml        |  172 -
 .../fixtures/profitbricks/list_snapshots.json   |   37 +
 .../fixtures/profitbricks/list_volumes.json     |  112 +
 .../fixtures/profitbricks/list_volumes.xml      |   66 -
 .../fixtures/profitbricks/reboot_node.xml       |   10 -
 .../compute/fixtures/vultr/create_key_pair.json |    3 +
 .../compute/fixtures/vultr/create_node.json     |    3 +
 .../compute/fixtures/vultr/list_key_pairs.json  |    8 +
 libcloud/test/compute/test_digitalocean_v2.py   |   63 +
 libcloud/test/compute/test_dimensiondata.py     | 1089 +++-
 libcloud/test/compute/test_gce.py               |  404 +-
 libcloud/test/compute/test_openstack.py         |    8 +
 libcloud/test/compute/test_ovh.py               |   38 +
 libcloud/test/compute/test_profitbricks.py      | 5377 ++++++++++++++++--
 libcloud/test/compute/test_vultr.py             |   40 +
 .../docker/linux_121/container_a68.json         |  163 -
 .../fixtures/docker/linux_121/containers.json   |  143 -
 .../docker/linux_121/create_container.json      |    4 -
 .../fixtures/docker/linux_121/create_image.json |    1 -
 .../fixtures/docker/linux_121/images.json       |   50 -
 .../fixtures/docker/linux_121/logs.txt          |    1 -
 .../fixtures/docker/linux_121/search.json       |  202 -
 .../fixtures/docker/linux_121/version.json      |   10 -
 .../docker/linux_124/container_a68.json         |  163 +
 .../fixtures/docker/linux_124/containers.json   |  143 +
 .../docker/linux_124/create_container.json      |    4 +
 .../fixtures/docker/linux_124/create_image.txt  |  238 +
 .../fixtures/docker/linux_124/images.json       |   50 +
 .../fixtures/docker/linux_124/logs.txt          |    1 +
 .../fixtures/docker/linux_124/search.json       |  202 +
 .../fixtures/docker/linux_124/version.json      |   10 +
 .../fixtures/docker/mac_124/create_image.json   |    1 -
 .../fixtures/docker/mac_124/create_image.txt    |  238 +
 .../fixtures/rancher/start_container.json       |  109 +
 libcloud/test/container/test_docker.py          |   52 +-
 libcloud/test/container/test_rancher.py         |   23 +-
 .../alb/describe_load_balancer_listeters.xml    |   27 +
 .../alb/describe_load_balancer_rules.xml        |   21 +
 .../describe_load_balancer_target_groups.xml    |   29 +
 .../fixtures/alb/describe_load_balancers.xml    |   31 +
 .../loadbalancer/fixtures/alb/describe_tags.xml |   18 +
 .../fixtures/alb/describe_target_health.xml     |   19 +
 libcloud/test/loadbalancer/test_alb.py          |  159 +
 libcloud/test/secrets.py-dist                   |    1 +
 205 files changed, 19372 insertions(+), 3029 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/04a09811/CHANGES.rst
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/libcloud/blob/04a09811/libcloud/common/base.py
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/libcloud/blob/04a09811/libcloud/compute/providers.py
----------------------------------------------------------------------


[49/56] [abbrv] libcloud git commit: Retrying the Fix for https://github.com/apache/libcloud/pull/845/

Posted by an...@apache.org.
Retrying the Fix for https://github.com/apache/libcloud/pull/845/


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/c674922a
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/c674922a
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/c674922a

Branch: refs/heads/trunk
Commit: c674922acd99a396f545a3c8b228db4c6489d5e1
Parents: 6f9e428
Author: Luke Morfitt <lu...@Lukes-MacBook-Pro.local>
Authored: Thu Sep 22 10:24:04 2016 +0100
Committer: Luke Morfitt <lu...@Lukes-MacBook-Pro.local>
Committed: Thu Sep 22 10:24:04 2016 +0100

----------------------------------------------------------------------
 libcloud/common/azure.py |  2 ++
 libcloud/common/base.py  | 17 ++++++++++++++---
 2 files changed, 16 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/c674922a/libcloud/common/azure.py
----------------------------------------------------------------------
diff --git a/libcloud/common/azure.py b/libcloud/common/azure.py
index b7f9ffc..cbba052 100644
--- a/libcloud/common/azure.py
+++ b/libcloud/common/azure.py
@@ -112,6 +112,8 @@ class AzureConnection(ConnectionUserAndKey):
 
     responseCls = AzureResponse
     rawResponseCls = AzureRawResponse
+    skip_host = False
+    skip_accept_encoding = False
 
     def add_default_params(self, params):
         return params

http://git-wip-us.apache.org/repos/asf/libcloud/blob/c674922a/libcloud/common/base.py
----------------------------------------------------------------------
diff --git a/libcloud/common/base.py b/libcloud/common/base.py
index 540244d..6a97564 100644
--- a/libcloud/common/base.py
+++ b/libcloud/common/base.py
@@ -118,6 +118,7 @@ class HTTPResponse(httplib.HTTPResponse):
     # In particular this happens on S3 when calls are made to get_object to
     # objects that don't exist.
     # This applies the behaviour from 2.7, fixing the hangs.
+
     def read(self, amt=None):
         if self.fp is None:
             return ''
@@ -354,6 +355,7 @@ class LoggingConnection():
 
         # this is evil. laugh with me. ha arharhrhahahaha
         class fakesock(object):
+
             def __init__(self, s):
                 self.s = s
 
@@ -532,6 +534,8 @@ class Connection(object):
     retry_delay = None
 
     allow_insecure = True
+    skip_host = True
+    skip_accept_encoding = True
 
     def __init__(self, secure=True, host=None, port=None, url=None,
                  timeout=None, proxy_url=None, retry_delay=None, backoff=None):
@@ -778,6 +782,9 @@ class Connection(object):
         else:
             headers.update({'Host': self.host})
 
+        skip_host = self.skip_host
+        skip_accept_encoding = self.skip_accept_encoding
+
         if data:
             data = self.encode_data(data)
             headers['Content-Length'] = str(len(data))
@@ -807,9 +814,11 @@ class Connection(object):
             # @TODO: Should we just pass File object as body to request method
             # instead of dealing with splitting and sending the file ourselves?
             if raw:
-                self.connection.putrequest(method, url,
-                                           skip_host=1,
-                                           skip_accept_encoding=1)
+                self.connection.putrequest(
+                    method,
+                    url,
+                    skip_host=skip_host,
+                    skip_accept_encoding=skip_accept_encoding)
 
                 for key, value in list(headers.items()):
                     self.connection.putheader(key, str(value))
@@ -1050,6 +1059,7 @@ class ConnectionKey(Connection):
     """
     Base connection class which accepts a single ``key`` argument.
     """
+
     def __init__(self, key, secure=True, host=None, port=None, url=None,
                  timeout=None, proxy_url=None, backoff=None, retry_delay=None):
         """
@@ -1069,6 +1079,7 @@ class CertificateConnection(Connection):
     """
     Base connection class which accepts a single ``cert_file`` argument.
     """
+
     def __init__(self, cert_file, secure=True, host=None, port=None, url=None,
                  proxy_url=None, timeout=None, backoff=None, retry_delay=None):
         """


[39/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/gogrid.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/gogrid.py b/apache-libcloud-1.0.0rc2/libcloud/common/gogrid.py
deleted file mode 100644
index e2448de..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/gogrid.py
+++ /dev/null
@@ -1,183 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 hashlib
-import time
-
-from libcloud.utils.py3 import b
-
-from libcloud.common.types import InvalidCredsError, LibcloudError
-from libcloud.common.types import MalformedResponseError
-from libcloud.common.base import ConnectionUserAndKey, JsonResponse
-from libcloud.compute.base import NodeLocation
-
-HOST = 'api.gogrid.com'
-PORTS_BY_SECURITY = {True: 443, False: 80}
-API_VERSION = '1.8'
-
-__all__ = [
-    "GoGridResponse",
-    "GoGridConnection",
-    "GoGridIpAddress",
-    "BaseGoGridDriver",
-]
-
-
-class GoGridResponse(JsonResponse):
-
-    def __init__(self, *args, **kwargs):
-        self.driver = BaseGoGridDriver
-        super(GoGridResponse, self).__init__(*args, **kwargs)
-
-    def success(self):
-        if self.status == 403:
-            raise InvalidCredsError('Invalid credentials', self.driver)
-        if self.status == 401:
-            raise InvalidCredsError('API Key has insufficient rights',
-                                    self.driver)
-        if not self.body:
-            return None
-        try:
-            return self.parse_body()['status'] == 'success'
-        except ValueError:
-            raise MalformedResponseError('Malformed reply',
-                                         body=self.body,
-                                         driver=self.driver)
-
-    def parse_error(self):
-        try:
-            return self.parse_body()["list"][0]["message"]
-        except (ValueError, KeyError):
-            return None
-
-
-class GoGridConnection(ConnectionUserAndKey):
-    """
-    Connection class for the GoGrid driver
-    """
-
-    host = HOST
-    responseCls = GoGridResponse
-
-    def add_default_params(self, params):
-        params["api_key"] = self.user_id
-        params["v"] = API_VERSION
-        params["format"] = 'json'
-        params["sig"] = self.get_signature(self.user_id, self.key)
-
-        return params
-
-    def get_signature(self, key, secret):
-        """ create sig from md5 of key + secret + time """
-        m = hashlib.md5(b(key + secret + str(int(time.time()))))
-        return m.hexdigest()
-
-    def request(self, action, params=None, data='', headers=None, method='GET',
-                raw=False):
-        return super(GoGridConnection, self).request(action, params, data,
-                                                     headers, method, raw)
-
-
-class GoGridIpAddress(object):
-    """
-    IP Address
-    """
-
-    def __init__(self, id, ip, public, state, subnet):
-        self.id = id
-        self.ip = ip
-        self.public = public
-        self.state = state
-        self.subnet = subnet
-
-
-class BaseGoGridDriver(object):
-    """GoGrid has common object model for services they
-    provide, like locations and IP, so keep handling of
-    these things in a single place."""
-
-    name = "GoGrid"
-
-    def _get_ip(self, element):
-        return element.get('ip').get('ip')
-
-    def _to_ip(self, element):
-        ip = GoGridIpAddress(id=element['id'],
-                             ip=element['ip'],
-                             public=element['public'],
-                             subnet=element['subnet'],
-                             state=element["state"]["name"])
-        ip.location = self._to_location(element['datacenter'])
-        return ip
-
-    def _to_ips(self, object):
-        return [self._to_ip(el)
-                for el in object['list']]
-
-    def _to_location(self, element):
-        location = NodeLocation(id=element['id'],
-                                name=element['name'],
-                                country="US",
-                                driver=self.connection.driver)
-        return location
-
-    def _to_locations(self, object):
-        return [self._to_location(el)
-                for el in object['list']]
-
-    def ex_list_ips(self, **kwargs):
-        """Return list of IP addresses assigned to
-        the account.
-
-        :keyword    public: set to True to list only
-                    public IPs or False to list only
-                    private IPs. Set to None or not specify
-                    at all not to filter by type
-        :type       public: ``bool``
-
-        :keyword    assigned: set to True to list only addresses
-                    assigned to servers, False to list unassigned
-                    addresses and set to None or don't set at all
-                    not no filter by state
-        :type       assigned: ``bool``
-
-        :keyword    location: filter IP addresses by location
-        :type       location: :class:`NodeLocation`
-
-        :rtype: ``list`` of :class:`GoGridIpAddress`
-        """
-
-        params = {}
-
-        if "public" in kwargs and kwargs["public"] is not None:
-            params["ip.type"] = {True: "Public",
-                                 False: "Private"}[kwargs["public"]]
-        if "assigned" in kwargs and kwargs["assigned"] is not None:
-            params["ip.state"] = {True: "Assigned",
-                                  False: "Unassigned"}[kwargs["assigned"]]
-        if "location" in kwargs and kwargs['location'] is not None:
-            params['datacenter'] = kwargs['location'].id
-
-        response = self.connection.request('/api/grid/ip/list', params=params)
-        ips = self._to_ips(response.object)
-        return ips
-
-    def _get_first_ip(self, location=None):
-        ips = self.ex_list_ips(public=True, assigned=False, location=location)
-        try:
-            return ips[0].ip
-        except IndexError:
-            raise LibcloudError('No public unassigned IPs left',
-                                self.driver)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/google.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/google.py b/apache-libcloud-1.0.0rc2/libcloud/common/google.py
deleted file mode 100644
index ca248d5..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/google.py
+++ /dev/null
@@ -1,828 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-Module for Google Connection and Authentication classes.
-
-Information about setting up your Google OAUTH2 credentials:
-
-For libcloud, there are two basic methods for authenticating to Google using
-OAUTH2: Service Accounts and Client IDs for Installed Applications.
-
-Both are initially set up from the Cloud Console Console -
-https://cloud.google.com/console
-
-Setting up Service Account authentication (note that you need the PyCrypto
-package installed to use this):
-
-- Go to the Console
-- Go to your project and then to "APIs & auth" on the left
-- Click on "Credentials"
-- Click on "Create New Client ID..."
-- Select "Service account" and click on "Create Client ID"
-- Download the Private Key (should happen automatically).  The key you download
-  is in JSON format.
-- Move the .json file to a safe location.
-- Optionally, you may choose to Generate a PKCS12 key from the Console.
-  It needs to be converted to the PEM format.  Please note, the PKCS12 format
-  is deprecated and may be removed in a future release.
-  - Convert the key using OpenSSL (the default password is 'notasecret').
-  - Move the .pem file to a safe location.
-- To Authenticate, you will need to pass the Service Account's "Email
-  address" in as the user_id and the path to the .pem file as the key.
-
-Setting up Installed Application authentication:
-
-- Go to the Console
-- Go to your project and then to "APIs & auth" on the left
-- Click on "Credentials"
-- Select "Installed application" and "Other" then click on
-  "Create Client ID"
-- To Authenticate, pass in the "Client ID" as the user_id and the "Client
-  secret" as the key
-- The first time that you do this, the libcloud will give you a URL to
-  visit.  Copy and paste the URL into a browser.
-- When you go to the URL it will ask you to log in (if you aren't already)
-  and ask you if you want to allow the project access to your account.
-- Click on Accept and you will be given a code.
-- Paste that code at the prompt given to you by the Google libcloud
-  connection.
-- At that point, a token & refresh token will be stored in your home
-  directory and will be used for authentication.
-
-Please remember to secure your keys and access tokens.
-"""
-
-from __future__ import with_statement
-
-try:
-    import simplejson as json
-except ImportError:
-    import json
-
-import base64
-import errno
-import time
-import datetime
-import os
-import socket
-import sys
-
-from libcloud.utils.connection import get_response_object
-from libcloud.utils.py3 import b, httplib, urlencode, urlparse, PY3
-from libcloud.common.base import (ConnectionUserAndKey, JsonResponse,
-                                  PollingConnection)
-from libcloud.common.types import (ProviderError,
-                                   LibcloudError)
-
-try:
-    from Crypto.Hash import SHA256
-    from Crypto.PublicKey import RSA
-    from Crypto.Signature import PKCS1_v1_5
-    import Crypto.Random
-    Crypto.Random.atfork()
-except ImportError:
-    # The pycrypto library is unavailable
-    SHA256 = None
-    RSA = None
-    PKCS1_v1_5 = None
-
-UTC_TIMESTAMP_FORMAT = '%Y-%m-%dT%H:%M:%SZ'
-
-
-def _utcnow():
-    """
-    Mocked in libcloud.test.common.google.GoogleTestCase.
-    """
-    return datetime.datetime.utcnow()
-
-
-def _utc_timestamp(datetime_obj):
-    return datetime_obj.strftime(UTC_TIMESTAMP_FORMAT)
-
-
-def _from_utc_timestamp(timestamp):
-    return datetime.datetime.strptime(timestamp, UTC_TIMESTAMP_FORMAT)
-
-
-def _get_gce_metadata(path=''):
-    try:
-        url = 'http://metadata/computeMetadata/v1/' + path.lstrip('/')
-        headers = {'Metadata-Flavor': 'Google'}
-        response = get_response_object(url, headers=headers)
-        return response.status, '', response.body
-    except Exception as e:
-        return -1, str(e), None
-
-
-class GoogleAuthError(LibcloudError):
-    """Generic Error class for various authentication errors."""
-    def __init__(self, value):
-        self.value = value
-
-    def __repr__(self):
-        return repr(self.value)
-
-
-class GoogleBaseError(ProviderError):
-    def __init__(self, value, http_code, code, driver=None):
-        self.code = code
-        super(GoogleBaseError, self).__init__(value, http_code, driver)
-
-
-class InvalidRequestError(GoogleBaseError):
-    pass
-
-
-class JsonParseError(GoogleBaseError):
-    pass
-
-
-class ResourceNotFoundError(GoogleBaseError):
-    def __init__(self, value, http_code, code, driver=None):
-        self.code = code
-        if isinstance(value, dict) and 'message' in value and \
-                value['message'].count('/') == 1 and \
-                value['message'].count('projects/') == 1:
-            value['message'] = value['message'] + ". A missing project " \
-                "error may be an authentication issue. " \
-                "Please  ensure your auth credentials match " \
-                "your project. "
-        super(GoogleBaseError, self).__init__(value, http_code, driver)
-
-
-class QuotaExceededError(GoogleBaseError):
-    pass
-
-
-class ResourceExistsError(GoogleBaseError):
-    pass
-
-
-class ResourceInUseError(GoogleBaseError):
-    pass
-
-
-class GoogleResponse(JsonResponse):
-    """
-    Google Base Response class.
-    """
-    def success(self):
-        """
-        Determine if the request was successful.
-
-        For the Google response class, tag all responses as successful and
-        raise appropriate Exceptions from parse_body.
-
-        :return: C{True}
-        """
-        return True
-
-    def _get_error(self, body):
-        """
-        Get the error code and message from a JSON response.
-
-        Return just the first error if there are multiple errors.
-
-        :param  body: The body of the JSON response dictionary
-        :type   body: ``dict``
-
-        :return:  Tuple containing error code and message
-        :rtype:   ``tuple`` of ``str`` or ``int``
-        """
-        if 'errors' in body['error']:
-            err = body['error']['errors'][0]
-        else:
-            err = body['error']
-
-        if 'code' in err:
-            code = err.get('code')
-            message = err.get('message')
-        else:
-            code = err.get('reason', None)
-            message = body.get('error_description', err)
-
-        return (code, message)
-
-    def parse_body(self):
-        """
-        Parse the JSON response body, or raise exceptions as appropriate.
-
-        :return:  JSON dictionary
-        :rtype:   ``dict``
-        """
-        if len(self.body) == 0 and not self.parse_zero_length_body:
-            return self.body
-
-        json_error = False
-        try:
-            body = json.loads(self.body)
-        except:
-            # If there is both a JSON parsing error and an unsuccessful http
-            # response (like a 404), we want to raise the http error and not
-            # the JSON one, so don't raise JsonParseError here.
-            body = self.body
-            json_error = True
-
-        valid_http_codes = [
-            httplib.OK,
-            httplib.CREATED,
-            httplib.ACCEPTED,
-            httplib.CONFLICT,
-        ]
-        if self.status in valid_http_codes:
-            if json_error:
-                raise JsonParseError(body, self.status, None)
-            elif 'error' in body:
-                (code, message) = self._get_error(body)
-                if code == 'QUOTA_EXCEEDED':
-                    raise QuotaExceededError(message, self.status, code)
-                elif code == 'RESOURCE_ALREADY_EXISTS':
-                    raise ResourceExistsError(message, self.status, code)
-                elif code == 'alreadyExists':
-                    raise ResourceExistsError(message, self.status, code)
-                elif code.startswith('RESOURCE_IN_USE'):
-                    raise ResourceInUseError(message, self.status, code)
-                else:
-                    raise GoogleBaseError(message, self.status, code)
-            else:
-                return body
-
-        elif self.status == httplib.NOT_FOUND:
-            if (not json_error) and ('error' in body):
-                (code, message) = self._get_error(body)
-            else:
-                message = body
-                code = None
-            raise ResourceNotFoundError(message, self.status, code)
-
-        elif self.status == httplib.BAD_REQUEST:
-            if (not json_error) and ('error' in body):
-                (code, message) = self._get_error(body)
-            else:
-                message = body
-                code = None
-            raise InvalidRequestError(message, self.status, code)
-
-        else:
-            if (not json_error) and ('error' in body):
-                (code, message) = self._get_error(body)
-            else:
-                message = body
-                code = None
-            raise GoogleBaseError(message, self.status, code)
-
-
-class GoogleBaseDriver(object):
-    name = "Google API"
-
-
-class GoogleBaseAuthConnection(ConnectionUserAndKey):
-    """
-    Base class for Google Authentication.  Should be subclassed for specific
-    types of authentication.
-    """
-    driver = GoogleBaseDriver
-    responseCls = GoogleResponse
-    name = 'Google Auth'
-    host = 'accounts.google.com'
-    auth_path = '/o/oauth2/auth'
-
-    def __init__(self, user_id, key=None, scopes=None,
-                 redirect_uri='urn:ietf:wg:oauth:2.0:oob',
-                 login_hint=None, **kwargs):
-        """
-        :param  user_id: The email address (for service accounts) or Client ID
-                         (for installed apps) to be used for authentication.
-        :type   user_id: ``str``
-
-        :param  key: The RSA Key (for service accounts) or file path containing
-                     key or Client Secret (for installed apps) to be used for
-                     authentication.
-        :type   key: ``str``
-
-        :param  scopes: A list of urls defining the scope of authentication
-                       to grant.
-        :type   scopes: ``list``
-
-        :keyword  redirect_uri: The Redirect URI for the authentication
-                                request.  See Google OAUTH2 documentation for
-                                more info.
-        :type     redirect_uri: ``str``
-
-        :keyword  login_hint: Login hint for authentication request.  Useful
-                              for Installed Application authentication.
-        :type     login_hint: ``str``
-        """
-        scopes = scopes or []
-
-        self.scopes = " ".join(scopes)
-        self.redirect_uri = redirect_uri
-        self.login_hint = login_hint
-
-        super(GoogleBaseAuthConnection, self).__init__(user_id, key, **kwargs)
-
-    def add_default_headers(self, headers):
-        headers['Content-Type'] = "application/x-www-form-urlencoded"
-        headers['Host'] = self.host
-        return headers
-
-    def _token_request(self, request_body):
-        """
-        Return an updated token from a token request body.
-
-        :param  request_body: A dictionary of values to send in the body of the
-                              token request.
-        :type   request_body: ``dict``
-
-        :return:  A dictionary with updated token information
-        :rtype:   ``dict``
-        """
-        data = urlencode(request_body)
-        try:
-            response = self.request('/o/oauth2/token', method='POST',
-                                    data=data)
-        except AttributeError:
-            raise GoogleAuthError('Invalid authorization response, please '
-                                  'check your credentials and time drift.')
-        token_info = response.object
-        if 'expires_in' in token_info:
-            expire_time = _utcnow() + datetime.timedelta(
-                seconds=token_info['expires_in'])
-            token_info['expire_time'] = _utc_timestamp(expire_time)
-        return token_info
-
-    def refresh_token(self, token_info):
-        """
-        Refresh the current token.
-
-        Fetch an updated refresh token from internal metadata service.
-
-        :param  token_info: Dictionary containing token information.
-                            (Not used, but here for compatibility)
-        :type   token_info: ``dict``
-
-        :return:  A dictionary containing updated token information.
-        :rtype:   ``dict``
-        """
-        return self.get_new_token()
-
-
-class GoogleInstalledAppAuthConnection(GoogleBaseAuthConnection):
-    """Authentication connection for "Installed Application" authentication."""
-    def get_code(self):
-        """
-        Give the user a URL that they can visit to authenticate and obtain a
-        code.  This method will ask for that code that the user can paste in.
-
-        Mocked in libcloud.test.common.google.GoogleTestCase.
-
-        :return:  Code supplied by the user after authenticating
-        :rtype:   ``str``
-        """
-        auth_params = {'response_type': 'code',
-                       'client_id': self.user_id,
-                       'redirect_uri': self.redirect_uri,
-                       'scope': self.scopes,
-                       'state': 'Libcloud Request'}
-        if self.login_hint:
-            auth_params['login_hint'] = self.login_hint
-
-        data = urlencode(auth_params)
-
-        url = 'https://%s%s?%s' % (self.host, self.auth_path, data)
-        print('\nPlease Go to the following URL and sign in:')
-        print(url)
-        if PY3:
-            code = input('Enter Code: ')
-        else:
-            code = raw_input('Enter Code: ')
-        return code
-
-    def get_new_token(self):
-        """
-        Get a new token. Generally used when no previous token exists or there
-        is no refresh token
-
-        :return:  Dictionary containing token information
-        :rtype:   ``dict``
-        """
-        # Ask the user for a code
-        code = self.get_code()
-
-        token_request = {'code': code,
-                         'client_id': self.user_id,
-                         'client_secret': self.key,
-                         'redirect_uri': self.redirect_uri,
-                         'grant_type': 'authorization_code'}
-
-        return self._token_request(token_request)
-
-    def refresh_token(self, token_info):
-        """
-        Use the refresh token supplied in the token info to get a new token.
-
-        :param  token_info: Dictionary containing current token information
-        :type   token_info: ``dict``
-
-        :return:  A dictionary containing updated token information.
-        :rtype:   ``dict``
-        """
-        if 'refresh_token' not in token_info:
-            return self.get_new_token()
-        refresh_request = {'refresh_token': token_info['refresh_token'],
-                           'client_id': self.user_id,
-                           'client_secret': self.key,
-                           'grant_type': 'refresh_token'}
-
-        new_token = self._token_request(refresh_request)
-        if 'refresh_token' not in new_token:
-            new_token['refresh_token'] = token_info['refresh_token']
-        return new_token
-
-
-class GoogleServiceAcctAuthConnection(GoogleBaseAuthConnection):
-    """Authentication class for "Service Account" authentication."""
-    def __init__(self, user_id, key, *args, **kwargs):
-        """
-        Check to see if PyCrypto is available, and convert key file path into a
-        key string if the key is in a file.
-
-        :param  user_id: Email address to be used for Service Account
-                authentication.
-        :type   user_id: ``str``
-
-        :param  key: The RSA Key or path to file containing the key.
-        :type   key: ``str``
-        """
-        if SHA256 is None:
-            raise GoogleAuthError('PyCrypto library required for '
-                                  'Service Account Authentication.')
-        # Check to see if 'key' is a file and read the file if it is.
-        if key.find("PRIVATE KEY---") == -1:
-            # key is a file
-            keypath = os.path.expanduser(key)
-            is_file_path = os.path.exists(keypath) and os.path.isfile(keypath)
-            if not is_file_path:
-                raise ValueError("Missing (or not readable) key "
-                                 "file: '%s'" % key)
-            with open(keypath, 'r') as f:
-                contents = f.read()
-            try:
-                key = json.loads(contents)
-                key = key['private_key']
-            except ValueError:
-                key = contents
-
-        super(GoogleServiceAcctAuthConnection, self).__init__(
-            user_id, key, *args, **kwargs)
-
-    def get_new_token(self):
-        """
-        Get a new token using the email address and RSA Key.
-
-        :return:  Dictionary containing token information
-        :rtype:   ``dict``
-        """
-        # The header is always the same
-        header = {'alg': 'RS256', 'typ': 'JWT'}
-        header_enc = base64.urlsafe_b64encode(b(json.dumps(header)))
-
-        # Construct a claim set
-        claim_set = {'iss': self.user_id,
-                     'scope': self.scopes,
-                     'aud': 'https://accounts.google.com/o/oauth2/token',
-                     'exp': int(time.time()) + 3600,
-                     'iat': int(time.time())}
-        claim_set_enc = base64.urlsafe_b64encode(b(json.dumps(claim_set)))
-
-        # The message contains both the header and claim set
-        message = b'.'.join((header_enc, claim_set_enc))
-        # Then the message is signed using the key supplied
-        key = RSA.importKey(self.key)
-        hash_func = SHA256.new(message)
-        signer = PKCS1_v1_5.new(key)
-        signature = base64.urlsafe_b64encode(signer.sign(hash_func))
-
-        # Finally the message and signature are sent to get a token
-        jwt = b'.'.join((message, signature))
-        request = {'grant_type': 'urn:ietf:params:oauth:grant-type:jwt-bearer',
-                   'assertion': jwt}
-
-        return self._token_request(request)
-
-
-class GoogleGCEServiceAcctAuthConnection(GoogleBaseAuthConnection):
-    """Authentication class for self-authentication when used with a GCE
-    instance that supports serviceAccounts.
-    """
-    def get_new_token(self):
-        """
-        Get a new token from the internal metadata service.
-
-        :return:  Dictionary containing token information
-        :rtype:   ``dict``
-        """
-        path = '/instance/service-accounts/default/token'
-        http_code, http_reason, token_info = _get_gce_metadata(path)
-        if http_code == httplib.NOT_FOUND:
-            raise ValueError("Service Accounts are not enabled for this "
-                             "GCE instance.")
-        if http_code != httplib.OK:
-            raise ValueError("Internal GCE Authorization failed: "
-                             "'%s'" % str(http_reason))
-        token_info = json.loads(token_info)
-        if 'expires_in' in token_info:
-            expire_time = _utcnow() + datetime.timedelta(
-                seconds=token_info['expires_in'])
-            token_info['expire_time'] = _utc_timestamp(expire_time)
-        return token_info
-
-
-class GoogleAuthType(object):
-    """
-    SA (Service Account),
-    IA (Installed Application),
-    GCE (Auth from a GCE instance with service account enabled)
-    GCS_S3 (Cloud Storage S3 interoperability authentication)
-    """
-    SA = 'SA'
-    IA = 'IA'
-    GCE = 'GCE'
-    GCS_S3 = 'GCS_S3'
-
-    ALL_TYPES = [SA, IA, GCE, GCS_S3]
-    OAUTH2_TYPES = [SA, IA, GCE]
-
-    @classmethod
-    def guess_type(cls, user_id):
-        if cls._is_sa(user_id):
-            return cls.SA
-        elif cls._is_gce():
-            return cls.GCE
-        elif cls._is_gcs_s3(user_id):
-            return cls.GCS_S3
-        else:
-            return cls.IA
-
-    @classmethod
-    def is_oauth2(cls, auth_type):
-        return auth_type in cls.OAUTH2_TYPES
-
-    @staticmethod
-    def _is_gce():
-        """
-        Checks if we can access the GCE metadata server.
-        Mocked in libcloud.test.common.google.GoogleTestCase.
-        """
-        http_code, http_reason, body = _get_gce_metadata()
-        if http_code == httplib.OK and body:
-            return True
-        return False
-
-    @staticmethod
-    def _is_gcs_s3(user_id):
-        """
-        Checks S3 key format: 20 alphanumeric chars starting with GOOG.
-        """
-        return len(user_id) == 20 and user_id.startswith('GOOG')
-
-    @staticmethod
-    def _is_sa(user_id):
-        return user_id.endswith('.gserviceaccount.com')
-
-
-class GoogleOAuth2Credential(object):
-    default_credential_file = '~/.google_libcloud_auth'
-
-    def __init__(self, user_id, key, auth_type=None, credential_file=None,
-                 scopes=None, **kwargs):
-        self.auth_type = auth_type or GoogleAuthType.guess_type(user_id)
-        if self.auth_type not in GoogleAuthType.ALL_TYPES:
-            raise GoogleAuthError('Invalid auth type: %s' % self.auth_type)
-        if not GoogleAuthType.is_oauth2(self.auth_type):
-            raise GoogleAuthError(('Auth type %s cannot be used with OAuth2' %
-                                   self.auth_type))
-        self.user_id = user_id
-        self.key = key
-
-        default_credential_file = '.'.join([self.default_credential_file,
-                                            user_id])
-        self.credential_file = credential_file or default_credential_file
-        # Default scopes to read/write for compute, storage, and dns.
-        self.scopes = scopes or [
-            'https://www.googleapis.com/auth/compute',
-            'https://www.googleapis.com/auth/devstorage.full_control',
-            'https://www.googleapis.com/auth/ndev.clouddns.readwrite',
-        ]
-
-        self.token = self._get_token_from_file()
-
-        if self.auth_type == GoogleAuthType.GCE:
-            self.oauth2_conn = GoogleGCEServiceAcctAuthConnection(
-                self.user_id, self.scopes, **kwargs)
-        elif self.auth_type == GoogleAuthType.SA:
-            self.oauth2_conn = GoogleServiceAcctAuthConnection(
-                self.user_id, self.key, self.scopes, **kwargs)
-        elif self.auth_type == GoogleAuthType.IA:
-            self.oauth2_conn = GoogleInstalledAppAuthConnection(
-                self.user_id, self.key, self.scopes, **kwargs)
-        else:
-            raise GoogleAuthError('Invalid auth_type: %s' %
-                                  str(self.auth_type))
-
-        if self.token is None:
-            self.token = self.oauth2_conn.get_new_token()
-            self._write_token_to_file()
-
-    @property
-    def access_token(self):
-        if self.token_expire_utc_datetime < _utcnow():
-            self._refresh_token()
-        return self.token['access_token']
-
-    @property
-    def token_expire_utc_datetime(self):
-        return _from_utc_timestamp(self.token['expire_time'])
-
-    def _refresh_token(self):
-        self.token = self.oauth2_conn.refresh_token(self.token)
-        self._write_token_to_file()
-
-    def _get_token_from_file(self):
-        """
-        Read credential file and return token information.
-        Mocked in libcloud.test.common.google.GoogleTestCase.
-
-        :return:  Token information dictionary, or None
-        :rtype:   ``dict`` or ``None``
-        """
-        token = None
-        filename = os.path.realpath(os.path.expanduser(self.credential_file))
-
-        try:
-            with open(filename, 'r') as f:
-                data = f.read()
-            token = json.loads(data)
-        except IOError:
-            pass
-        return token
-
-    def _write_token_to_file(self):
-        """
-        Write token to credential file.
-        Mocked in libcloud.test.common.google.GoogleTestCase.
-        """
-        filename = os.path.realpath(os.path.expanduser(self.credential_file))
-        data = json.dumps(self.token)
-        with os.fdopen(os.open(filename, os.O_CREAT | os.O_WRONLY,
-                               int('600', 8)), 'w') as f:
-            f.write(data)
-
-
-class GoogleBaseConnection(ConnectionUserAndKey, PollingConnection):
-    """Base connection class for interacting with Google APIs."""
-    driver = GoogleBaseDriver
-    responseCls = GoogleResponse
-    host = 'www.googleapis.com'
-    poll_interval = 2.0
-    timeout = 180
-
-    def __init__(self, user_id, key=None, auth_type=None,
-                 credential_file=None, scopes=None, **kwargs):
-        """
-        Determine authentication type, set up appropriate authentication
-        connection and get initial authentication information.
-
-        :param  user_id: The email address (for service accounts) or Client ID
-                         (for installed apps) to be used for authentication.
-        :type   user_id: ``str``
-
-        :param  key: The RSA Key (for service accounts) or file path containing
-                     key or Client Secret (for installed apps) to be used for
-                     authentication.
-        :type   key: ``str``
-
-        :keyword  auth_type: See GoogleAuthType class for list and description
-                             of accepted values.
-                             If not supplied, auth_type will be guessed based
-                             on value of user_id or if the code is running
-                             on a GCE instance.
-        :type     auth_type: ``str``
-
-        :keyword  credential_file: Path to file for caching authentication
-                                   information.
-        :type     credential_file: ``str``
-
-        :keyword  scopes: List of OAuth2 scope URLs. The empty default sets
-                          read/write access to Compute, Storage, and DNS.
-        :type     scopes: ``list``
-        """
-        super(GoogleBaseConnection, self).__init__(user_id, key, **kwargs)
-
-        self.oauth2_credential = GoogleOAuth2Credential(
-            user_id, key, auth_type, credential_file, scopes, **kwargs)
-
-        python_ver = '%s.%s.%s' % (sys.version_info[0], sys.version_info[1],
-                                   sys.version_info[2])
-        ver_platform = 'Python %s/%s' % (python_ver, sys.platform)
-        self.user_agent_append(ver_platform)
-
-    def add_default_headers(self, headers):
-        """
-        @inherits: :class:`Connection.add_default_headers`
-        """
-        headers['Content-Type'] = 'application/json'
-        headers['Host'] = self.host
-        return headers
-
-    def pre_connect_hook(self, params, headers):
-        """
-        Check to make sure that token hasn't expired.  If it has, get an
-        updated token.  Also, add the token to the headers.
-
-        @inherits: :class:`Connection.pre_connect_hook`
-        """
-        headers['Authorization'] = ('Bearer ' +
-                                    self.oauth2_credential.access_token)
-        return params, headers
-
-    def encode_data(self, data):
-        """Encode data to JSON"""
-        return json.dumps(data)
-
-    def request(self, *args, **kwargs):
-        """
-        @inherits: :class:`Connection.request`
-        """
-        # Adds some retry logic for the occasional
-        # "Connection Reset by peer" error.
-        retries = 4
-        tries = 0
-        while tries < (retries - 1):
-            try:
-                return super(GoogleBaseConnection, self).request(
-                    *args, **kwargs)
-            except socket.error:
-                e = sys.exc_info()[1]
-                if e.errno == errno.ECONNRESET:
-                    tries = tries + 1
-                else:
-                    raise e
-        # One more time, then give up.
-        return super(GoogleBaseConnection, self).request(*args, **kwargs)
-
-    def has_completed(self, response):
-        """
-        Determine if operation has completed based on response.
-
-        :param  response: JSON response
-        :type   response: I{responseCls}
-
-        :return:  True if complete, False otherwise
-        :rtype:   ``bool``
-        """
-        if response.object['status'] == 'DONE':
-            return True
-        else:
-            return False
-
-    def get_poll_request_kwargs(self, response, context, request_kwargs):
-        """
-        @inherits: :class:`PollingConnection.get_poll_request_kwargs`
-        """
-        return {'action': response.object['selfLink']}
-
-    def morph_action_hook(self, action):
-        """
-        Update action to correct request path.
-
-        In many places, the Google API returns a full URL to a resource.
-        This will strip the scheme and host off of the path and just return
-        the request.  Otherwise, it will prepend the base request_path to
-        the action.
-
-        :param  action: The action to be called in the http request
-        :type   action: ``str``
-
-        :return:  The modified request based on the action
-        :rtype:   ``str``
-        """
-        if action.startswith('https://'):
-            u = urlparse.urlsplit(action)
-            request = urlparse.urlunsplit(('', '', u[2], u[3], u[4]))
-        else:
-            request = self.request_path + action
-        return request

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/hostvirtual.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/hostvirtual.py b/apache-libcloud-1.0.0rc2/libcloud/common/hostvirtual.py
deleted file mode 100644
index e7ce14d..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/hostvirtual.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-try:
-    import simplejson as json
-except ImportError:
-    import json
-
-from libcloud.utils.py3 import httplib
-from libcloud.common.base import ConnectionKey, JsonResponse
-from libcloud.compute.types import InvalidCredsError
-from libcloud.common.types import LibcloudError
-
-API_HOST = 'vapi.vr.org'
-
-
-class HostVirtualException(LibcloudError):
-    def __init__(self, code, message):
-        self.code = code
-        self.message = message
-        self.args = (code, message)
-
-    def __str__(self):
-        return self.__repr__()
-
-    def __repr__(self):
-        return '<HostVirtualException in %d: %s>' % (self.code, self.message)
-
-
-class HostVirtualConnection(ConnectionKey):
-    host = API_HOST
-
-    allow_insecure = False
-
-    def add_default_params(self, params):
-        params['key'] = self.key
-        return params
-
-
-class HostVirtualResponse(JsonResponse):
-    valid_response_codes = [httplib.OK, httplib.ACCEPTED, httplib.CREATED,
-                            httplib.NO_CONTENT]
-
-    def parse_body(self):
-        if not self.body:
-            return None
-
-        data = json.loads(self.body)
-        return data
-
-    def parse_error(self):
-        data = self.parse_body()
-
-        if self.status == httplib.UNAUTHORIZED:
-            raise InvalidCredsError('%(code)s:%(message)s' % (data['error']))
-        elif self.status == httplib.PRECONDITION_FAILED:
-            raise HostVirtualException(
-                data['error']['code'], data['error']['message'])
-        elif self.status == httplib.NOT_FOUND:
-            raise HostVirtualException(
-                data['error']['code'], data['error']['message'])
-
-        return self.body
-
-    def success(self):
-        return self.status in self.valid_response_codes

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/linode.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/linode.py b/apache-libcloud-1.0.0rc2/libcloud/common/linode.py
deleted file mode 100644
index c991695..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/linode.py
+++ /dev/null
@@ -1,186 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from libcloud.common.base import ConnectionKey, JsonResponse
-from libcloud.common.types import InvalidCredsError
-
-from libcloud.utils.py3 import PY3
-from libcloud.utils.py3 import b
-
-__all__ = [
-    'API_HOST',
-    'API_ROOT',
-    'LinodeException',
-    'LinodeResponse',
-    'LinodeConnection'
-]
-
-# Endpoint for the Linode API
-API_HOST = 'api.linode.com'
-API_ROOT = '/'
-
-# Constants that map a RAM figure to a PlanID (updated 2014-08-25)
-LINODE_PLAN_IDS = {1024: '1',
-                   2048: '2',
-                   4096: '4',
-                   8192: '6',
-                   16384: '7',
-                   32768: '8',
-                   49152: '9',
-                   65536: '10',
-                   98304: '12'}
-
-# Available filesystems for disk creation
-LINODE_DISK_FILESYSTEMS = ['ext3', 'ext4', 'swap', 'raw']
-
-
-class LinodeException(Exception):
-    """Error originating from the Linode API
-
-    This class wraps a Linode API error, a list of which is available in the
-    API documentation.  All Linode API errors are a numeric code and a
-    human-readable description.
-    """
-    def __init__(self, code, message):
-        self.code = code
-        self.message = message
-        self.args = (code, message)
-
-    def __str__(self):
-        return "(%u) %s" % (self.code, self.message)
-
-    def __repr__(self):
-        return "<LinodeException code %u '%s'>" % (self.code, self.message)
-
-
-class LinodeResponse(JsonResponse):
-    """
-    Linode API response
-
-    Wraps the HTTP response returned by the Linode API.
-
-    libcloud does not take advantage of batching, so a response will always
-    reflect the above format. A few weird quirks are caught here as well.
-    """
-
-    objects = None
-
-    def __init__(self, response, connection):
-        """Instantiate a LinodeResponse from the HTTP response
-
-        :keyword response: The raw response returned by urllib
-        :return: parsed :class:`LinodeResponse`"""
-
-        self.connection = connection
-
-        self.headers = dict(response.getheaders())
-        self.error = response.reason
-        self.status = response.status
-
-        # This attribute is set when using LoggingConnection.
-        original_data = getattr(response, '_original_data', None)
-
-        if original_data:
-            # LoggingConnection already decompresses data so it can log it
-            # which means we don't need to decompress it here.
-            self.body = response._original_data
-        else:
-            self.body = self._decompress_response(body=response.read(),
-                                                  headers=self.headers)
-
-        if PY3:
-            self.body = b(self.body).decode('utf-8')
-
-        self.invalid = LinodeException(0xFF,
-                                       "Invalid JSON received from server")
-
-        # Move parse_body() to here;  we can't be sure of failure until we've
-        # parsed the body into JSON.
-        self.objects, self.errors = self.parse_body()
-
-        if not self.success():
-            # Raise the first error, as there will usually only be one
-            raise self.errors[0]
-
-    def parse_body(self):
-        """Parse the body of the response into JSON objects
-
-        If the response chokes the parser, action and data will be returned as
-        None and errorarray will indicate an invalid JSON exception.
-
-        :return: ``list`` of objects and ``list`` of errors"""
-        js = super(LinodeResponse, self).parse_body()
-
-        try:
-            if isinstance(js, dict):
-                # solitary response - promote to list
-                js = [js]
-            ret = []
-            errs = []
-            for obj in js:
-                if ("DATA" not in obj or "ERRORARRAY" not in obj or
-                        "ACTION" not in obj):
-                    ret.append(None)
-                    errs.append(self.invalid)
-                    continue
-                ret.append(obj["DATA"])
-                errs.extend(self._make_excp(e) for e in obj["ERRORARRAY"])
-            return (ret, errs)
-        except:
-            return (None, [self.invalid])
-
-    def success(self):
-        """Check the response for success
-
-        The way we determine success is by the presence of an error in
-        ERRORARRAY.  If one is there, we assume the whole request failed.
-
-        :return: ``bool`` indicating a successful request"""
-        return len(self.errors) == 0
-
-    def _make_excp(self, error):
-        """Convert an API error to a LinodeException instance
-
-        :keyword error: JSON object containing ``ERRORCODE`` and
-        ``ERRORMESSAGE``
-        :type error: dict"""
-        if "ERRORCODE" not in error or "ERRORMESSAGE" not in error:
-            return None
-        if error["ERRORCODE"] == 4:
-            return InvalidCredsError(error["ERRORMESSAGE"])
-        return LinodeException(error["ERRORCODE"], error["ERRORMESSAGE"])
-
-
-class LinodeConnection(ConnectionKey):
-    """
-    A connection to the Linode API
-
-    Wraps SSL connections to the Linode API, automagically injecting the
-    parameters that the API needs for each request.
-    """
-    host = API_HOST
-    responseCls = LinodeResponse
-
-    def add_default_params(self, params):
-        """
-        Add parameters that are necessary for every request
-
-        This method adds ``api_key`` and ``api_responseFormat`` to
-        the request.
-        """
-        params["api_key"] = self.key
-        # Be explicit about this in case the default changes.
-        params["api_responseFormat"] = "json"
-        return params

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/liquidweb.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/liquidweb.py b/apache-libcloud-1.0.0rc2/libcloud/common/liquidweb.py
deleted file mode 100644
index 123e82f..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/liquidweb.py
+++ /dev/null
@@ -1,229 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 base64
-
-from libcloud.common.base import JsonResponse
-from libcloud.common.base import ConnectionUserAndKey
-from libcloud.utils.py3 import b
-from libcloud.common.types import ProviderError
-
-
-__all__ = [
-    'API_HOST',
-    'LiquidWebException',
-    'LiquidWebResponse',
-    'LiquidWebConnection',
-]
-
-
-# Endpoint for liquidweb api.
-API_HOST = 'api.stormondemand.com'
-
-
-class LiquidWebException(ProviderError):
-    """The base class for other Liquidweb exceptions"""
-
-    def __init__(self, value, http_code, extra=None):
-        """
-        :param value: message contained in error
-        :type  value: ``str``
-
-        :param http_code: error code
-        :type  http_code: ``int``
-
-        :param extra: extra fields specific to error type
-        :type  extra: ``list``
-        """
-        self.extra = extra
-        super(LiquidWebException, self).__init__(value, http_code, driver=None)
-
-    def __str__(self):
-        return "%s  %s" % (self.code, self.value)
-
-    def __repr__(self):
-        return "LiquidWebException %s %s" % (self.code, self.value)
-
-
-class APIException(LiquidWebException):
-
-    def __init__(self, error_class, full_msg, http_code, extra=None):
-        self.error_class = error_class
-        super(APIException, self).__init__(full_msg, http_code, extra=extra)
-
-    def __str__(self):
-        return "%s: %s" % (self.error_class, self.value)
-
-    def __repr__(self):
-        return "%s: %s" % (self.error_class, self.value)
-
-
-EXCEPTIONS_FIELDS = {
-    'LW::Exception::API::Internal': {
-        'fields': []
-    },
-    'LW::Exception::API::InvalidEncoding': {
-        'fields': ['encoding']
-    },
-    'LW::Exception::API::InvalidMethod': {
-        'fields': ['method']
-    },
-    'LW::Exception::API::Maintenance': {
-        'fields': []
-    },
-    'LW::Exception::API::RateLimit': {
-        'fields': ['account', 'ip', 'method']
-    },
-    'LW::Exception::Authorization': {
-        'fields': ['username']
-    },
-    'LW::Exception::DNS::NoResponse': {
-        'fields': ['nameservers']
-    },
-    'LW::Exception::DNS::Servfail': {
-        'fields': ['nameservers']
-    },
-    'LW::Exception::Deserialize': {
-        'fields': ['data', 'encoding']
-    },
-    'LW::Exception::DuplicateRecord': {
-        'fields': ['field', 'input', 'statement']
-    },
-    'LW::Exception::Forbidden': {
-        'fields': []
-    },
-    'LW::Exception::Incapable': {
-        'fields': ['capability', 'thing']
-    },
-    'LW::Exception::Input': {
-        'fields': ['field']
-    },
-    'LW::Exception::Input::Disallowed': {
-        'fields': ['field']
-    },
-    'LW::Exception::Input::Multiple': {
-        'fields': ['errors', 'field', 'type']
-    },
-    'LW::Exception::Input::NotInRealm': {
-        'fields': ['field', 'valid', 'value']
-    },
-    'LW::Exception::Input::OutOfBounds': {
-        'fields': ['field', 'max', 'min', 'value']
-    },
-    'LW::Exception::Input::Required': {
-        'fields': ['field', 'position']
-    },
-    'LW::Exception::Input::Unknown': {
-        'fields': ['field', 'value']
-    },
-    'LW::Exception::Input::Validation': {
-        'fields': ['field', 'type', 'value']
-    },
-    'LW::Exception::Permission': {
-        'fields': ['account', 'identifier']
-    },
-    'LW::Exception::RecordNotFound': {
-        'fields': ['field', 'input']
-    },
-    'LW::Exception::RemoteService::Authorization': {
-        'fields': ['url']
-    },
-    'LW::Exception::Resource': {
-        'fields': ['resource']
-    },
-    'LW::Exception::Resource::Insufficient': {
-        'fields': ['available', 'requested', 'resource']
-    },
-    'LW::Exception::Resource::Unavailable': {
-        'fields': ['resource']
-    },
-    'LW::Exception::Serialize': {
-        'fields': ['data', 'encoding']
-    },
-    'LW::Exception::Workflow::Conflict': {
-        'fields': ['conflict', 'workflow']
-    }
-}
-
-
-class LiquidWebResponse(JsonResponse):
-    objects = None
-    errors = None
-    error_dict = {}
-
-    def __init__(self, response, connection):
-        self.errors = []
-        super(LiquidWebResponse, self).__init__(response=response,
-                                                connection=connection)
-        self.objects, self.errors = self.parse_body_and_errors()
-        if self.errors:
-            error = self.errors.pop()
-            raise self._make_excp(error, self.status)
-
-    def parse_body_and_errors(self):
-        data = []
-        errors = []
-        js = super(LiquidWebResponse, self).parse_body()
-        if 'items' in js:
-            data.append(js['items'])
-
-        if 'name' in js:
-            data.append(js)
-
-        if 'deleted' in js:
-            data.append(js['deleted'])
-
-        if 'error_class' in js:
-            errors.append(js)
-
-        return (data, errors)
-
-    def success(self):
-        """
-        Returns ``True`` if our request is successful.
-        """
-        return (len(self.errors) == 0)
-
-    def _make_excp(self, error, status):
-        """
-        Raise LiquidWebException.
-        """
-        exc_type = error.get('error_class')
-        message = error.get('full_message')
-        try:
-            _type = EXCEPTIONS_FIELDS[exc_type]
-            fields = _type.get('fields')
-            extra = {}
-        except KeyError:
-            fields = []
-
-        for field in fields:
-            extra[field] = error.get(field)
-        return APIException(exc_type, message, status, extra=extra)
-
-
-class LiquidWebConnection(ConnectionUserAndKey):
-    host = API_HOST
-    responseCls = LiquidWebResponse
-
-    def add_default_headers(self, headers):
-        b64string = b('%s:%s' % (self.user_id, self.key))
-        encoded = base64.b64encode(b64string).decode('utf-8')
-        authorization = 'Basic ' + encoded
-
-        headers['Authorization'] = authorization
-        headers['Content-Type'] = 'application/json'
-
-        return headers

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/luadns.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/luadns.py b/apache-libcloud-1.0.0rc2/libcloud/common/luadns.py
deleted file mode 100644
index e079835..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/luadns.py
+++ /dev/null
@@ -1,69 +0,0 @@
-import base64
-
-
-from libcloud.common.base import ConnectionUserAndKey, JsonResponse
-from libcloud.utils.py3 import b
-
-__all__ = [
-    'API_HOST',
-    'LuadnsException',
-    'LuadnsResponse',
-    'LuadnsConnection'
-]
-
-# Endpoint for luadns api
-API_HOST = 'api.luadns.com'
-
-
-class LuadnsResponse(JsonResponse):
-    errors = []
-    objects = []
-
-    def __init__(self, response, connection):
-        super(LuadnsResponse, self).__init__(response=response,
-                                             connection=connection)
-        self.errors, self.objects = self.parse_body_and_errors()
-        if not self.success():
-            raise LuadnsException(code=self.status,
-                                  message=self.errors.pop()['message'])
-
-    def parse_body_and_errors(self):
-        js = super(LuadnsResponse, self).parse_body()
-        if 'message' in js:
-            self.errors.append(js)
-        else:
-            self.objects.append(js)
-
-        return self.errors, self.objects
-
-    def success(self):
-        return len(self.errors) == 0
-
-
-class LuadnsConnection(ConnectionUserAndKey):
-    host = API_HOST
-    responseCls = LuadnsResponse
-
-    def add_default_headers(self, headers):
-        b64string = b('%s:%s' % (self.user_id, self.key))
-        encoded = base64.b64encode(b64string).decode('utf-8')
-        authorization = 'Basic ' + encoded
-
-        headers['Accept'] = 'application/json'
-        headers['Authorization'] = authorization
-
-        return headers
-
-
-class LuadnsException(Exception):
-
-    def __init__(self, code, message):
-        self.code = code
-        self.message = message
-        self.args = (code, message)
-
-    def __str__(self):
-        return "%s %s" % (self.code, self.message)
-
-    def __repr__(self):
-        return "Luadns %s %s" % (self.code, self.message)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/nfsn.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/nfsn.py b/apache-libcloud-1.0.0rc2/libcloud/common/nfsn.py
deleted file mode 100644
index 4286f0c..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/nfsn.py
+++ /dev/null
@@ -1,114 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 hashlib
-import random
-import string
-import time
-
-from libcloud.common.base import ConnectionUserAndKey
-from libcloud.common.base import JsonResponse
-from libcloud.common.types import InvalidCredsError, ProviderError
-from libcloud.utils.py3 import basestring, httplib, urlencode
-
-
-SALT_CHARACTERS = string.ascii_letters + string.digits
-
-
-class NFSNException(ProviderError):
-    def __init__(self, value, http_code, code, driver=None):
-        self.code = code
-        super(NFSNException, self).__init__(value, http_code, driver)
-
-
-class NFSNResponse(JsonResponse):
-
-    def parse_error(self):
-        if self.status == httplib.UNAUTHORIZED:
-            raise InvalidCredsError('Invalid provider credentials')
-
-        body = self.parse_body()
-
-        if isinstance(body, basestring):
-            return body + ' (HTTP Code: %d)' % self.status
-
-        error = body.get('error', None)
-        debug = body.get('debug', None)
-        # If we only have one of "error" or "debug", use the one that we have.
-        # If we have both, use both, with a space character in between them.
-        value = 'No message specified'
-        if error is not None:
-            value = error
-        if debug is not None:
-            value = debug
-        if error is not None and value is not None:
-            value = error + ' ' + value
-        value = value + ' (HTTP Code: %d)' % self.status
-
-        return value
-
-
-class NFSNConnection(ConnectionUserAndKey):
-    host = 'api.nearlyfreespeech.net'
-    responseCls = NFSNResponse
-    allow_insecure = False
-
-    def _header(self, action, data):
-        """ Build the contents of the X-NFSN-Authentication HTTP header. See
-        https://members.nearlyfreespeech.net/wiki/API/Introduction for
-        more explanation. """
-        login = self.user_id
-        timestamp = self._timestamp()
-        salt = self._salt()
-        api_key = self.key
-        data = urlencode(data)
-        data_hash = hashlib.sha1(data.encode('utf-8')).hexdigest()
-
-        string = ';'.join((login, timestamp, salt, api_key, action, data_hash))
-        string_hash = hashlib.sha1(string.encode('utf-8')).hexdigest()
-
-        return ';'.join((login, timestamp, salt, string_hash))
-
-    def request(self, action, params=None, data='', headers=None,
-                method='GET'):
-        """ Add the X-NFSN-Authentication header to an HTTP request. """
-        if not headers:
-            headers = {}
-        if not params:
-            params = {}
-        header = self._header(action, data)
-
-        headers['X-NFSN-Authentication'] = header
-        if method == 'POST':
-            headers['Content-Type'] = 'application/x-www-form-urlencoded'
-
-        return ConnectionUserAndKey.request(self, action, params, data,
-                                            headers, method)
-
-    def encode_data(self, data):
-        """ NFSN expects the body to be regular key-value pairs that are not
-        JSON-encoded. """
-        if data:
-            data = urlencode(data)
-        return data
-
-    def _salt(self):
-        """ Return a 16-character alphanumeric string. """
-        r = random.SystemRandom()
-        return ''.join(r.choice(SALT_CHARACTERS) for _ in range(16))
-
-    def _timestamp(self):
-        """ Return the current number of seconds since the Unix epoch,
-        as a string. """
-        return str(int(time.time()))

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/nsone.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/nsone.py b/apache-libcloud-1.0.0rc2/libcloud/common/nsone.py
deleted file mode 100644
index 5eb4e17..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/nsone.py
+++ /dev/null
@@ -1,62 +0,0 @@
-from libcloud.common.base import ConnectionKey, JsonResponse
-
-
-__all__ = [
-    'API_HOST',
-    'NsOneException',
-    'NsOneResponse',
-    'NsOneConnection'
-]
-
-# Endpoint for nsone api
-API_HOST = 'api.nsone.net'
-
-
-class NsOneResponse(JsonResponse):
-    errors = []
-    objects = []
-
-    def __init__(self, response, connection):
-        super(NsOneResponse, self).__init__(response=response,
-                                            connection=connection)
-        self.errors, self.objects = self.parse_body_and_errors()
-        if not self.success():
-            raise NsOneException(code=self.status,
-                                 message=self.errors.pop()['message'])
-
-    def parse_body_and_errors(self):
-        js = super(NsOneResponse, self).parse_body()
-        if 'message' in js:
-            self.errors.append(js)
-        else:
-            self.objects.append(js)
-
-        return self.errors, self.objects
-
-    def success(self):
-        return len(self.errors) == 0
-
-
-class NsOneConnection(ConnectionKey):
-    host = API_HOST
-    responseCls = NsOneResponse
-
-    def add_default_headers(self, headers):
-        headers['Content-Type'] = 'application/json'
-        headers['X-NSONE-KEY'] = self.key
-
-        return headers
-
-
-class NsOneException(Exception):
-
-    def __init__(self, code, message):
-        self.code = code
-        self.message = message
-        self.args = (code, message)
-
-    def __str__(self):
-        return "%s %s" % (self.code, self.message)
-
-    def __repr__(self):
-        return "NsOneException %s %s" % (self.code, self.message)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/onapp.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/onapp.py b/apache-libcloud-1.0.0rc2/libcloud/common/onapp.py
deleted file mode 100644
index 259e315..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/onapp.py
+++ /dev/null
@@ -1,49 +0,0 @@
-from base64 import b64encode
-
-from libcloud.utils.py3 import b
-from libcloud.utils.py3 import httplib
-from libcloud.common.base import ConnectionUserAndKey, JsonResponse
-
-
-class OnAppResponse(JsonResponse):
-    """
-    OnApp response class
-    """
-
-    def success(self):
-        """
-        Determine if our request was successful.
-
-        The meaning of this can be arbitrary; did we receive OK status? Did
-        the node get created? Were we authenticated?
-
-        :rtype: ``bool``
-        :return: ``True`` or ``False``
-        """
-        return self.status in [httplib.OK, httplib.CREATED, httplib.NO_CONTENT]
-
-
-class OnAppConnection(ConnectionUserAndKey):
-    """
-    OnApp connection class
-    """
-
-    responseCls = OnAppResponse
-
-    def add_default_headers(self, headers):
-        """
-        Add Basic Authentication header to all the requests.
-        It injects the "Authorization: Basic Base64String===" header
-        in each request
-
-        :type  headers: ``dict``
-        :param headers: Default input headers
-
-        :rtype:         ``dict``
-        :return:        Default input headers with the "Authorization" header.
-        """
-        b64string = b("%s:%s" % (self.user_id, self.key))
-        encoded = b64encode(b64string).decode("utf-8")
-
-        headers["Authorization"] = "Basic " + encoded
-        return headers

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/openstack.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/openstack.py b/apache-libcloud-1.0.0rc2/libcloud/common/openstack.py
deleted file mode 100644
index e63ee8a..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/openstack.py
+++ /dev/null
@@ -1,430 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-Common utilities for OpenStack
-"""
-
-try:
-    from lxml import etree as ET
-except ImportError:
-    from xml.etree import ElementTree as ET
-
-from libcloud.utils.py3 import httplib
-
-from libcloud.common.base import ConnectionUserAndKey, Response
-from libcloud.common.types import ProviderError
-from libcloud.compute.types import (LibcloudError, MalformedResponseError)
-from libcloud.compute.types import KeyPairDoesNotExistError
-from libcloud.common.openstack_identity import get_class_for_auth_version
-
-# Imports for backward compatibility reasons
-from libcloud.common.openstack_identity import OpenStackServiceCatalog
-
-
-try:
-    import simplejson as json
-except ImportError:
-    import json
-
-AUTH_API_VERSION = '1.1'
-
-# Auth versions which contain token expiration information.
-AUTH_VERSIONS_WITH_EXPIRES = [
-    '1.1',
-    '2.0',
-    '2.0_apikey',
-    '2.0_password',
-    '3.x',
-    '3.x_password'
-]
-
-__all__ = [
-    'OpenStackBaseConnection',
-    'OpenStackResponse',
-    'OpenStackException',
-    'OpenStackDriverMixin'
-]
-
-
-class OpenStackBaseConnection(ConnectionUserAndKey):
-
-    """
-    Base class for OpenStack connections.
-
-    :param user_id: User name to use when authenticating
-    :type user_id: ``str``
-
-    :param key: Secret to use when authenticating.
-    :type key: ``str``
-
-    :param secure: Use HTTPS?  (True by default.)
-    :type secure: ``bool``
-
-    :param ex_force_base_url: Base URL for connection requests.  If
-                              not specified, this will be determined by
-                              authenticating.
-    :type ex_force_base_url: ``str``
-
-    :param ex_force_auth_url: Base URL for authentication requests.
-    :type ex_force_auth_url: ``str``
-
-    :param ex_force_auth_version: Authentication version to use.  If
-                                  not specified, defaults to AUTH_API_VERSION.
-    :type ex_force_auth_version: ``str``
-
-    :param ex_force_auth_token: Authentication token to use for connection
-                                requests.  If specified, the connection will
-                                not attempt to authenticate, and the value
-                                of ex_force_base_url will be used to
-                                determine the base request URL.  If
-                                ex_force_auth_token is passed in,
-                                ex_force_base_url must also be provided.
-    :type ex_force_auth_token: ``str``
-
-    :param ex_tenant_name: When authenticating, provide this tenant name to the
-                           identity service. A scoped token will be returned.
-                           Some cloud providers require the tenant name to be
-                           provided at authentication time. Others will use a
-                           default tenant if none is provided.
-    :type ex_tenant_name: ``str``
-
-    :param ex_force_service_type: Service type to use when selecting an
-                                  service. If not specified, a provider
-                                  specific default will be used.
-    :type ex_force_service_type: ``str``
-
-    :param ex_force_service_name: Service name to use when selecting an
-                                  service. If not specified, a provider
-                                  specific default will be used.
-    :type ex_force_service_name: ``str``
-
-    :param ex_force_service_region: Region to use when selecting an service.
-                                    If not specified, a provider specific
-                                    default will be used.
-    :type ex_force_service_region: ``str``
-    """
-
-    auth_url = None
-    auth_token = None
-    auth_token_expires = None
-    auth_user_info = None
-    service_catalog = None
-    service_type = None
-    service_name = None
-    service_region = None
-    _auth_version = None
-
-    def __init__(self, user_id, key, secure=True,
-                 host=None, port=None, timeout=None, proxy_url=None,
-                 ex_force_base_url=None,
-                 ex_force_auth_url=None,
-                 ex_force_auth_version=None,
-                 ex_force_auth_token=None,
-                 ex_tenant_name=None,
-                 ex_force_service_type=None,
-                 ex_force_service_name=None,
-                 ex_force_service_region=None,
-                 retry_delay=None, backoff=None):
-        super(OpenStackBaseConnection, self).__init__(
-            user_id, key, secure=secure, timeout=timeout,
-            retry_delay=retry_delay, backoff=backoff, proxy_url=proxy_url)
-
-        if ex_force_auth_version:
-            self._auth_version = ex_force_auth_version
-
-        self._ex_force_base_url = ex_force_base_url
-        self._ex_force_auth_url = ex_force_auth_url
-        self._ex_force_auth_token = ex_force_auth_token
-        self._ex_tenant_name = ex_tenant_name
-        self._ex_force_service_type = ex_force_service_type
-        self._ex_force_service_name = ex_force_service_name
-        self._ex_force_service_region = ex_force_service_region
-        self._osa = None
-
-        if ex_force_auth_token and not ex_force_base_url:
-            raise LibcloudError(
-                'Must also provide ex_force_base_url when specifying '
-                'ex_force_auth_token.')
-
-        if ex_force_auth_token:
-            self.auth_token = ex_force_auth_token
-
-        if not self._auth_version:
-            self._auth_version = AUTH_API_VERSION
-
-        auth_url = self._get_auth_url()
-
-        if not auth_url:
-            raise LibcloudError('OpenStack instance must ' +
-                                'have auth_url set')
-
-    def get_auth_class(self):
-        """
-        Retrieve identity / authentication class instance.
-
-        :rtype: :class:`OpenStackIdentityConnection`
-        """
-        if not self._osa:
-            auth_url = self._get_auth_url()
-
-            cls = get_class_for_auth_version(auth_version=self._auth_version)
-            self._osa = cls(auth_url=auth_url,
-                            user_id=self.user_id,
-                            key=self.key,
-                            tenant_name=self._ex_tenant_name,
-                            timeout=self.timeout,
-                            parent_conn=self)
-
-        return self._osa
-
-    def request(self, action, params=None, data='', headers=None,
-                method='GET', raw=False):
-        headers = headers or {}
-        params = params or {}
-
-        # Include default content-type for POST and PUT request (if available)
-        default_content_type = getattr(self, 'default_content_type', None)
-        if method.upper() in ['POST', 'PUT'] and default_content_type:
-            headers = {'Content-Type': default_content_type}
-
-        return super(OpenStackBaseConnection, self).request(action=action,
-                                                            params=params,
-                                                            data=data,
-                                                            method=method,
-                                                            headers=headers,
-                                                            raw=raw)
-
-    def _get_auth_url(self):
-        """
-        Retrieve auth url for this instance using either "ex_force_auth_url"
-        constructor kwarg of "auth_url" class variable.
-        """
-        auth_url = self.auth_url
-
-        if self._ex_force_auth_url is not None:
-            auth_url = self._ex_force_auth_url
-
-        return auth_url
-
-    def get_service_catalog(self):
-        if self.service_catalog is None:
-            self._populate_hosts_and_request_paths()
-
-        return self.service_catalog
-
-    def get_service_name(self):
-        """
-        Gets the service name used to look up the endpoint in the service
-        catalog.
-
-        :return: name of the service in the catalog
-        """
-        if self._ex_force_service_name:
-            return self._ex_force_service_name
-
-        return self.service_name
-
-    def get_endpoint(self):
-        """
-        Selects the endpoint to use based on provider specific values,
-        or overrides passed in by the user when setting up the driver.
-
-        :returns: url of the relevant endpoint for the driver
-        """
-        service_type = self.service_type
-        service_name = self.service_name
-        service_region = self.service_region
-
-        if self._ex_force_service_type:
-            service_type = self._ex_force_service_type
-        if self._ex_force_service_name:
-            service_name = self._ex_force_service_name
-        if self._ex_force_service_region:
-            service_region = self._ex_force_service_region
-
-        endpoint = self.service_catalog.get_endpoint(service_type=service_type,
-                                                     name=service_name,
-                                                     region=service_region)
-
-        url = endpoint.url
-
-        if not url:
-            raise LibcloudError('Could not find specified endpoint')
-
-        return url
-
-    def add_default_headers(self, headers):
-        headers['X-Auth-Token'] = self.auth_token
-        headers['Accept'] = self.accept_format
-        return headers
-
-    def morph_action_hook(self, action):
-        self._populate_hosts_and_request_paths()
-        return super(OpenStackBaseConnection, self).morph_action_hook(action)
-
-    def _set_up_connection_info(self, url):
-        result = self._tuple_from_url(url)
-        (self.host, self.port, self.secure, self.request_path) = result
-
-    def _populate_hosts_and_request_paths(self):
-        """
-        OpenStack uses a separate host for API calls which is only provided
-        after an initial authentication request.
-        """
-        osa = self.get_auth_class()
-
-        if self._ex_force_auth_token:
-            # If ex_force_auth_token is provided we always hit the api directly
-            # and never try to authenticate.
-            #
-            # Note: When ex_force_auth_token is provided, ex_force_base_url
-            # must be provided as well.
-            self._set_up_connection_info(url=self._ex_force_base_url)
-            return
-
-        if not osa.is_token_valid():
-            # Token is not available or it has expired. Need to retrieve a
-            # new one.
-            if self._auth_version == '2.0_apikey':
-                kwargs = {'auth_type': 'api_key'}
-            elif self._auth_version == '2.0_password':
-                kwargs = {'auth_type': 'password'}
-            else:
-                kwargs = {}
-
-            osa = osa.authenticate(**kwargs)  # may throw InvalidCreds
-
-            self.auth_token = osa.auth_token
-            self.auth_token_expires = osa.auth_token_expires
-            self.auth_user_info = osa.auth_user_info
-
-            # Pull out and parse the service catalog
-            osc = OpenStackServiceCatalog(service_catalog=osa.urls,
-                                          auth_version=self._auth_version)
-            self.service_catalog = osc
-
-        url = self._ex_force_base_url or self.get_endpoint()
-        self._set_up_connection_info(url=url)
-
-
-class OpenStackException(ProviderError):
-    pass
-
-
-class OpenStackResponse(Response):
-    node_driver = None
-
-    def success(self):
-        i = int(self.status)
-        return i >= 200 and i <= 299
-
-    def has_content_type(self, content_type):
-        content_type_value = self.headers.get('content-type') or ''
-        content_type_value = content_type_value.lower()
-        return content_type_value.find(content_type.lower()) > -1
-
-    def parse_body(self):
-        if self.status == httplib.NO_CONTENT or not self.body:
-            return None
-
-        if self.has_content_type('application/xml'):
-            try:
-                return ET.XML(self.body)
-            except:
-                raise MalformedResponseError(
-                    'Failed to parse XML',
-                    body=self.body,
-                    driver=self.node_driver)
-
-        elif self.has_content_type('application/json'):
-            try:
-                return json.loads(self.body)
-            except:
-                raise MalformedResponseError(
-                    'Failed to parse JSON',
-                    body=self.body,
-                    driver=self.node_driver)
-        else:
-            return self.body
-
-    def parse_error(self):
-        text = None
-        body = self.parse_body()
-
-        if self.has_content_type('application/xml'):
-            text = '; '.join([err.text or '' for err in body.getiterator()
-                              if err.text])
-        elif self.has_content_type('application/json'):
-            values = list(body.values())
-
-            context = self.connection.context
-            driver = self.connection.driver
-            key_pair_name = context.get('key_pair_name', None)
-
-            if len(values) > 0 and values[0]['code'] == 404 and key_pair_name:
-                raise KeyPairDoesNotExistError(name=key_pair_name,
-                                               driver=driver)
-            elif len(values) > 0 and 'message' in values[0]:
-                text = ';'.join([fault_data['message'] for fault_data
-                                 in values])
-            else:
-                text = body
-        else:
-            # while we hope a response is always one of xml or json, we have
-            # seen html or text in the past, its not clear we can really do
-            # something to make it more readable here, so we will just pass
-            # it along as the whole response body in the text variable.
-            text = body
-
-        return '%s %s %s' % (self.status, self.error, text)
-
-
-class OpenStackDriverMixin(object):
-
-    def __init__(self, *args, **kwargs):
-        self._ex_force_base_url = kwargs.get('ex_force_base_url', None)
-        self._ex_force_auth_url = kwargs.get('ex_force_auth_url', None)
-        self._ex_force_auth_version = kwargs.get('ex_force_auth_version', None)
-        self._ex_force_auth_token = kwargs.get('ex_force_auth_token', None)
-        self._ex_tenant_name = kwargs.get('ex_tenant_name', None)
-        self._ex_force_service_type = kwargs.get('ex_force_service_type', None)
-        self._ex_force_service_name = kwargs.get('ex_force_service_name', None)
-        self._ex_force_service_region = kwargs.get('ex_force_service_region',
-                                                   None)
-
-    def openstack_connection_kwargs(self):
-        """
-
-        :rtype: ``dict``
-        """
-        rv = {}
-        if self._ex_force_base_url:
-            rv['ex_force_base_url'] = self._ex_force_base_url
-        if self._ex_force_auth_token:
-            rv['ex_force_auth_token'] = self._ex_force_auth_token
-        if self._ex_force_auth_url:
-            rv['ex_force_auth_url'] = self._ex_force_auth_url
-        if self._ex_force_auth_version:
-            rv['ex_force_auth_version'] = self._ex_force_auth_version
-        if self._ex_tenant_name:
-            rv['ex_tenant_name'] = self._ex_tenant_name
-        if self._ex_force_service_type:
-            rv['ex_force_service_type'] = self._ex_force_service_type
-        if self._ex_force_service_name:
-            rv['ex_force_service_name'] = self._ex_force_service_name
-        if self._ex_force_service_region:
-            rv['ex_force_service_region'] = self._ex_force_service_region
-        return rv


[07/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/slb.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/slb.py b/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/slb.py
deleted file mode 100644
index 03ca6be..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/slb.py
+++ /dev/null
@@ -1,831 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-__all__ = [
-    'SLB_API_VERSION',
-    'SLBDriver'
-]
-
-import sys
-
-try:
-    import simplejson as json
-except ImportError:
-    import json
-
-from libcloud.common.aliyun import AliyunXmlResponse, SignedAliyunConnection
-from libcloud.common.types import LibcloudError
-from libcloud.loadbalancer.types import State
-from libcloud.loadbalancer.base import Algorithm, Driver, LoadBalancer, Member
-from libcloud.utils.misc import ReprMixin
-from libcloud.utils.py3 import u
-from libcloud.utils.xml import findattr, findtext, findall
-
-
-SLB_API_VERSION = '2014-05-15'
-SLB_API_HOST = 'slb.aliyuncs.com'
-DEFAULT_SIGNATURE_VERSION = '1.0'
-
-
-STATE_MAPPINGS = {
-    'inactive': State.UNKNOWN,
-    'active': State.RUNNING,
-    'locked': State.PENDING
-}
-
-
-RESOURCE_EXTRA_ATTRIBUTES_MAP = {
-    'balancer': {
-        'create_timestamp': {
-            'xpath': 'CreateTimeStamp',
-            'transform_func': int
-        },
-        'address_type': {
-            'xpath': 'AddressType',
-            'transform_func': u
-        },
-        'region_id': {
-            'xpath': 'RegionId',
-            'transform_func': u
-        },
-        'region_id_alias': {
-            'xpath': 'RegionIdAlias',
-            'transform_func': u
-        },
-        'create_time': {
-            'xpath': 'CreateTime',
-            'transform_func': u
-        },
-        'master_zone_id': {
-            'xpath': 'MasterZoneId',
-            'transform_func': u
-        },
-        'slave_zone_id': {
-            'xpath': 'SlaveZoneId',
-            'transform_func': u
-        },
-        'network_type': {
-            'xpath': 'NetworkType',
-            'transform_func': u
-        }
-    }
-}
-
-
-SLB_SCHEDULER_TO_ALGORITHM = {
-    'wrr': Algorithm.WEIGHTED_ROUND_ROBIN,
-    'wlc': Algorithm.WEIGHTED_LEAST_CONNECTIONS
-}
-
-
-ALGORITHM_TO_SLB_SCHEDULER = {
-    Algorithm.WEIGHTED_ROUND_ROBIN: 'wrr',
-    Algorithm.WEIGHTED_LEAST_CONNECTIONS: 'wlc'
-}
-
-
-class SLBConnection(SignedAliyunConnection):
-    version = SLB_API_VERSION
-    host = SLB_API_HOST
-    responseCls = AliyunXmlResponse
-    service_name = 'slb'
-
-
-class SLBLoadBalancerAttribute(object):
-    """
-    This class used to get listeners and backend servers related to a balancer
-    listeners is a ``list`` of ``dict``, each element contains
-    'ListenerPort' and 'ListenerProtocol' keys.
-    backend_servers is a ``list`` of ``dict``, each element contains
-    'ServerId' and 'Weight' keys.
-    """
-    def __init__(self, balancer, listeners, backend_servers, extra=None):
-        self.balancer = balancer
-        self.listeners = listeners or []
-        self.backend_servers = backend_servers or []
-        self.extra = extra or {}
-
-    def is_listening(self, port):
-        for listener in self.listeners:
-            if listener.get('ListenerPort') == port:
-                return True
-        return False
-
-    def is_attached(self, member):
-        for server in self.backend_servers:
-            if server.get('Serverid') == member.id:
-                return True
-        return False
-
-    def __repr__(self):
-        return ('<SLBLoadBalancerAttribute id=%s, ports=%s, servers=%s ...>' %
-                (self.balancer.id, self.listeners, self.backend_servers))
-
-
-class SLBLoadBalancerListener(ReprMixin, object):
-    """
-    Base SLB load balancer listener class
-    """
-    _repr_attributes = ['port', 'backend_port', 'scheduler', 'bandwidth']
-    action = None
-    option_keys = []
-
-    def __init__(self, port, backend_port, algorithm, bandwidth, extra=None):
-        self.port = port
-        self.backend_port = backend_port
-        self.scheduler = ALGORITHM_TO_SLB_SCHEDULER.get(algorithm, 'wrr')
-        self.bandwidth = bandwidth
-        self.extra = extra or {}
-
-    @classmethod
-    def create(cls, port, backend_port, algorithm, bandwidth, extra=None):
-        return cls(port, backend_port, algorithm, bandwidth, extra=extra)
-
-    def get_create_params(self):
-        params = self.get_required_params()
-        options = self.get_optional_params()
-        options.update(params)
-        return options
-
-    def get_required_params(self):
-        params = {'Action': self.action,
-                  'ListenerPort': self.port,
-                  'BackendServerPort': self.backend_port,
-                  'Scheduler': self.scheduler,
-                  'Bandwidth': self.bandwidth}
-        return params
-
-    def get_optional_params(self):
-        options = {}
-        for option in self.option_keys:
-            if self.extra and option in self.extra:
-                options[option] = self.extra[option]
-        return options
-
-
-class SLBLoadBalancerHttpListener(SLBLoadBalancerListener):
-    """
-    This class represents a rule to route http request to the backends.
-    """
-    action = 'CreateLoadBalancerHTTPListener'
-    option_keys = ['XForwardedFor', 'StickySessionType', 'CookieTimeout',
-                   'Cookie', 'HealthCheckDomain', 'HealthCheckURI',
-                   'HealthCheckConnectPort', 'HealthyThreshold',
-                   'UnhealthyThreshold', 'HealthCheckTimeout',
-                   'HealthCheckInterval', 'HealthCheckHttpCode']
-
-    def __init__(self, port, backend_port, algorithm, bandwidth,
-                 sticky_session, health_check, extra=None):
-        super(SLBLoadBalancerHttpListener, self).__init__(
-            port, backend_port, algorithm, bandwidth, extra=extra)
-        self.sticky_session = sticky_session
-        self.health_check = health_check
-
-    def get_required_params(self):
-        params = super(SLBLoadBalancerHttpListener,
-                       self).get_required_params()
-        params['StickySession'] = self.sticky_session
-        params['HealthCheck'] = self.health_check
-        return params
-
-    @classmethod
-    def create(cls, port, backend_port, algorithm, bandwidth, extra={}):
-        if 'StickySession' not in extra:
-            raise AttributeError('StickySession is required')
-        if 'HealthCheck' not in extra:
-            raise AttributeError('HealthCheck is required')
-        sticky_session = extra['StickySession']
-        health_check = extra['HealthCheck']
-        return cls(port, backend_port, algorithm, bandwidth, sticky_session,
-                   health_check, extra=extra)
-
-
-class SLBLoadBalancerHttpsListener(SLBLoadBalancerListener):
-    """
-    This class represents a rule to route https request to the backends.
-    """
-    action = 'CreateLoadBalancerHTTPSListener'
-    option_keys = ['XForwardedFor', 'StickySessionType', 'CookieTimeout',
-                   'Cookie', 'HealthCheckDomain', 'HealthCheckURI',
-                   'HealthCheckConnectPort', 'HealthyThreshold',
-                   'UnhealthyThreshold', 'HealthCheckTimeout',
-                   'HealthCheckInterval', 'HealthCheckHttpCode']
-
-    def __init__(self, port, backend_port, algorithm, bandwidth,
-                 sticky_session, health_check, certificate_id, extra=None):
-        super(SLBLoadBalancerHttpsListener, self).__init__(
-            port, backend_port, algorithm, bandwidth, extra=extra)
-        self.sticky_session = sticky_session
-        self.health_check = health_check
-        self.certificate_id = certificate_id
-
-    def get_required_params(self):
-        params = super(SLBLoadBalancerHttpsListener,
-                       self).get_required_params()
-        params['StickySession'] = self.sticky_session
-        params['HealthCheck'] = self.health_check
-        params['ServerCertificateId'] = self.certificate_id
-        return params
-
-    @classmethod
-    def create(cls, port, backend_port, algorithm, bandwidth, extra={}):
-        if 'StickySession' not in extra:
-            raise AttributeError('StickySession is required')
-        if 'HealthCheck' not in extra:
-            raise AttributeError('HealthCheck is required')
-        if 'ServerCertificateId' not in extra:
-            raise AttributeError('ServerCertificateId is required')
-        sticky_session = extra['StickySession']
-        health_check = extra['HealthCheck']
-        certificate_id = extra['ServerCertificateId']
-        return cls(port, backend_port, algorithm, bandwidth, sticky_session,
-                   health_check, certificate_id, extra=extra)
-
-
-class SLBLoadBalancerTcpListener(SLBLoadBalancerListener):
-    """
-    This class represents a rule to route tcp request to the backends.
-    """
-    action = 'CreateLoadBalancerTCPListener'
-    option_keys = ['PersistenceTimeout', 'HealthCheckType',
-                   'HealthCheckDomain', 'HealthCheckURI',
-                   'HealthCheckConnectPort', 'HealthyThreshold',
-                   'UnhealthyThreshold', 'HealthCheckConnectTimeout',
-                   'HealthCheckInterval', 'HealthCheckHttpCode']
-
-
-class SLBLoadBalancerUdpListener(SLBLoadBalancerTcpListener):
-    """
-    This class represents a rule to route udp request to the backends.
-    """
-    action = 'CreateLoadBalancerUDPListener'
-    option_keys = ['PersistenceTimeout', 'HealthCheckConnectPort',
-                   'HealthyThreshold', 'UnhealthyThreshold',
-                   'HealthCheckConnectTimeout', 'HealthCheckInterval']
-
-
-class SLBServerCertificate(ReprMixin, object):
-    _repr_attributes = ['id', 'name', 'fingerprint']
-
-    def __init__(self, id, name, fingerprint):
-        self.id = id
-        self.name = name
-        self.fingerprint = fingerprint
-
-
-PROTOCOL_TO_LISTENER_MAP = {
-    'http': SLBLoadBalancerHttpListener,
-    'https': SLBLoadBalancerHttpsListener,
-    'tcp': SLBLoadBalancerTcpListener,
-    'udp': SLBLoadBalancerUdpListener
-}
-
-
-class SLBDriver(Driver):
-    """
-    Aliyun SLB load balancer driver.
-    """
-    name = 'Aliyun Server Load Balancer'
-    website = 'https://www.aliyun.com/product/slb'
-    connectionCls = SLBConnection
-    path = '/'
-    namespace = None
-
-    _VALUE_TO_ALGORITHM_MAP = SLB_SCHEDULER_TO_ALGORITHM
-
-    _ALGORITHM_TO_VALUE_MAP = ALGORITHM_TO_SLB_SCHEDULER
-
-    def __init__(self, access_id, secret, region):
-        super(SLBDriver, self).__init__(access_id, secret)
-        self.region = region
-
-    def list_protocols(self):
-        return list(PROTOCOL_TO_LISTENER_MAP.keys())
-
-    def list_balancers(self, ex_balancer_ids=None, ex_filters=None):
-        """
-        List all loadbalancers
-
-        @inherits :class:`Driver.list_balancers`
-
-        :keyword ex_balancer_ids: a list of balancer ids to filter results
-                                  Only balancers which's id in this list
-                                  will be returned
-        :type ex_balancer_ids: ``list`` of ``str``
-
-        :keyword ex_filters: attributes to filter results. Only balancers
-                             which have all the desired attributes
-                             and values will be returned
-        :type ex_filters: ``dict``
-        """
-
-        params = {'Action': 'DescribeLoadBalancers',
-                  'RegionId': self.region}
-        if ex_balancer_ids and isinstance(ex_balancer_ids, list):
-            params['LoadBalancerId'] = ','.join(ex_balancer_ids)
-
-        if ex_filters and isinstance(ex_filters, dict):
-            ex_filters.update(params)
-            params = ex_filters
-        resp_body = self.connection.request(self.path, params=params).object
-        return self._to_balancers(resp_body)
-
-    def create_balancer(self, name, port, protocol, algorithm, members,
-                        ex_bandwidth=None, ex_internet_charge_type=None,
-                        ex_address_type=None, ex_vswitch_id=None,
-                        ex_master_zone_id=None, ex_slave_zone_id=None,
-                        ex_client_token=None,
-                        **kwargs):
-        """
-        Create a new load balancer instance
-
-        @inherits: :class:`Driver.create_balancer`
-
-        :keyword ex_bandwidth: The max bandwidth limit for `paybybandwidth`
-                               internet charge type, in Mbps unit
-        :type ex_bandwidth: ``int`` in range [1, 1000]
-
-        :keyword ex_internet_charge_type: The internet charge type
-        :type ex_internet_charge_type: a ``str`` of `paybybandwidth`
-                                       or `paybytraffic`
-
-        :keyword ex_address_type: The listening IP address type
-        :type ex_address_type: a ``str`` of `internet` or `intranet`
-
-        :keyword ex_vswitch_id: The vswitch id in a VPC network
-        :type ex_vswitch_id: ``str``
-
-        :keyword ex_master_zone_id: The id of the master availability zone
-        :type ex_master_zone_id: ``str``
-
-        :keyword ex_slave_zone_id: The id of the slave availability zone
-        :type ex_slave_zone_id: ``str``
-
-        :keyword ex_client_token: The token generated by client to
-                                  identify requests
-        :type ex_client_token: ``str``
-        """
-
-        # 1.Create load balancer
-        params = {'Action': 'CreateLoadBalancer',
-                  'RegionId': self.region}
-        if name:
-            params['LoadBalancerName'] = name
-        if not port:
-            raise AttributeError('port is required')
-        if not protocol:
-            # NOTE(samsong8610): Use http listener as default
-            protocol = 'http'
-        if protocol not in PROTOCOL_TO_LISTENER_MAP:
-            raise AttributeError('unsupport protocol %s' % protocol)
-
-        # Bandwidth in range [1, 1000] Mbps
-        bandwidth = -1
-        if ex_bandwidth:
-            try:
-                bandwidth = int(ex_bandwidth)
-            except ValueError:
-                raise AttributeError('ex_bandwidth should be a integer in '
-                                     'range [1, 1000].')
-            params['Bandwidth'] = bandwidth
-
-        if ex_internet_charge_type:
-            if ex_internet_charge_type.lower() == 'paybybandwidth':
-                if bandwidth == -1:
-                    raise AttributeError('PayByBandwidth internet charge type'
-                                         ' need ex_bandwidth be set')
-            params['InternetChargeType'] = ex_internet_charge_type
-
-        if ex_address_type:
-            if ex_address_type.lower() not in ('internet', 'intranet'):
-                raise AttributeError('ex_address_type should be "internet" '
-                                     'or "intranet"')
-            params['AddressType'] = ex_address_type
-
-        if ex_vswitch_id:
-            params['VSwitchId'] = ex_vswitch_id
-
-        if ex_master_zone_id:
-            params['MasterZoneId'] = ex_master_zone_id
-        if ex_slave_zone_id:
-            params['SlaveZoneId'] = ex_slave_zone_id
-
-        if ex_client_token:
-            params['ClientToken'] = ex_client_token
-
-        if members and isinstance(members, list):
-            backend_ports = [member.port for member in members]
-            if len(set(backend_ports)) != 1:
-                raise AttributeError('the ports of members should be unique')
-            # NOTE(samsong8610): If members do not provide backend port,
-            #                    default to listening port
-            backend_port = backend_ports[0] or port
-        else:
-            backend_port = port
-
-        balancer = None
-        try:
-            resp_body = self.connection.request(self.path, params).object
-            balancer = self._to_balancer(resp_body)
-            balancer.port = port
-
-            # 2.Add backend servers
-            if members is None:
-                members = []
-            for member in members:
-                self.balancer_attach_member(balancer, member)
-            # 3.Create listener
-            # NOTE(samsong8610): Assume only create a listener which uses all
-            #                    the bandwidth.
-            self.ex_create_listener(balancer, backend_port, protocol,
-                                    algorithm, bandwidth, **kwargs)
-            self.ex_start_listener(balancer, port)
-            return balancer
-        except Exception:
-            e = sys.exc_info()[1]
-            if balancer is not None:
-                try:
-                    self.destroy_balancer(balancer)
-                except Exception:
-                    pass
-            raise e
-
-    def destroy_balancer(self, balancer):
-        params = {'Action': 'DeleteLoadBalancer',
-                  'LoadBalancerId': balancer.id}
-        resp = self.connection.request(self.path, params)
-        return resp.success()
-
-    def get_balancer(self, balancer_id):
-        balancers = self.list_balancers(ex_balancer_ids=[balancer_id])
-        if len(balancers) != 1:
-            raise LibcloudError('could not find load balancer with id %s' %
-                                balancer_id)
-        return balancers[0]
-
-    def balancer_attach_compute_node(self, balancer, node):
-        if len(node.public_ips) > 0:
-            ip = node.public_ips[0]
-        else:
-            ip = node.private_ips[0]
-        member = Member(id=node.id, ip=ip, port=balancer.port)
-        return self.balancer_attach_member(balancer, member)
-
-    def balancer_attach_member(self, balancer, member):
-        params = {'Action': 'AddBackendServers',
-                  'LoadBalancerId': balancer.id}
-        if member and isinstance(member, Member):
-            params['BackendServers'] = self._to_servers_json([member])
-        self.connection.request(self.path, params)
-        return member
-
-    def balancer_detach_member(self, balancer, member):
-        params = {'Action': 'RemoveBackendServers',
-                  'LoadBalancerId': balancer.id}
-        if member and isinstance(member, Member):
-            params['BackendServers'] = self._list_to_json([member.id])
-        self.connection.request(self.path, params)
-        return member
-
-    def balancer_list_members(self, balancer):
-        attribute = self.ex_get_balancer_attribute(balancer)
-        members = [Member(server['ServerId'], None, None, balancer=balancer,
-                          extra={'Weight': server['Weight']})
-                   for server in attribute.backend_servers]
-        return members
-
-    def ex_get_balancer_attribute(self, balancer):
-        """
-        Get balancer attribute
-
-        :param balancer: the balancer to get attribute
-        :type balancer: ``LoadBalancer``
-
-        :return: the balancer attribute
-        :rtype: ``SLBLoadBalancerAttribute``
-        """
-
-        params = {'Action': 'DescribeLoadBalancerAttribute',
-                  'LoadBalancerId': balancer.id}
-        resp_body = self.connection.request(self.path, params).object
-        attribute = self._to_balancer_attribute(resp_body)
-        return attribute
-
-    def ex_list_listeners(self, balancer):
-        """
-        Get all listener related to the given balancer
-
-        :param balancer: the balancer to list listeners
-        :type balancer: ``LoadBalancer``
-
-        :return: a list of listeners
-        :rtype: ``list`` of ``SLBLoadBalancerListener``
-        """
-
-        attribute = self.ex_get_balancer_attribute(balancer)
-        listeners = [SLBLoadBalancerListener(each['ListenerPort'], None,
-                                             None, None)
-                     for each in attribute.listeners]
-        return listeners
-
-    def ex_create_listener(self, balancer, backend_port, protocol, algorithm,
-                           bandwidth, **kwargs):
-        """
-        Create load balancer listening rule.
-
-        :param balancer: the balancer which the rule belongs to.
-                         The listener created will listen on the port of the
-                         the balancer as default. 'ListenerPort' in kwargs
-                         will *OVERRIDE* it.
-        :type balancer: ``LoadBalancer``
-
-        :param backend_port: the backend server port
-        :type backend_port: ``int``
-
-        :param protocol: the balancer protocol, default to http
-        :type protocol: ``str``
-
-        :param algorithm: the balancer routing algorithm
-        :type algorithm: ``Algorithm``
-
-        :param bandwidth: the listener bandwidth limits
-        :type bandwidth: ``str``
-
-        :return: the created listener
-        :rtype: ``SLBLoadBalancerListener``
-        """
-
-        cls = PROTOCOL_TO_LISTENER_MAP.get(protocol,
-                                           SLBLoadBalancerHttpListener)
-        if 'ListenerPort' in kwargs:
-            port = kwargs['ListenerPort']
-        else:
-            port = balancer.port
-        listener = cls.create(port, backend_port, algorithm,
-                              bandwidth, extra=kwargs)
-        params = listener.get_create_params()
-        params['LoadBalancerId'] = balancer.id
-        params['RegionId'] = self.region
-        resp = self.connection.request(self.path, params)
-        return resp.success()
-
-    def ex_start_listener(self, balancer, port):
-        """
-        Start balancer's listener listening the given port.
-
-        :param balancer: a load balancer
-        :type balancer: ``LoadBalancer``
-
-        :param port: listening port
-        :type port: ``int``
-
-        :return: whether operation is success
-        :rtype: ``bool``
-        """
-
-        params = {'Action': 'StartLoadBalancerListener',
-                  'LoadBalancerId': balancer.id,
-                  'ListenerPort': port}
-        resp = self.connection.request(self.path, params)
-        return resp.success()
-
-    def ex_stop_listener(self, balancer, port):
-        """
-        Stop balancer's listener listening the given port.
-
-        :param balancer: a load balancer
-        :type balancer: ``LoadBalancer``
-
-        :param port: listening port
-        :type port: ``int``
-
-        :return: whether operation is success
-        :rtype: ``bool``
-        """
-
-        params = {'Action': 'StopLoadBalancerListener',
-                  'LoadBalancerId': balancer.id,
-                  'ListenerPort': port}
-        resp = self.connection.request(self.path, params)
-        return resp.success()
-
-    def ex_upload_certificate(self, name, server_certificate,
-                              private_key):
-        """
-        Upload certificate and private key for https load balancer listener
-
-        :param name: the certificate name
-        :type name: ``str``
-
-        :param server_certificate: the content of the certificate to upload
-                                   in PEM format
-        :type server_certificate: ``str``
-
-        :param private_key: the content of the private key to upload
-                            in PEM format
-        :type private_key: ``str``
-
-        :return: new created certificate info
-        :rtype: ``SLBServerCertificate``
-        """
-
-        params = {'Action': 'UploadServerCertificate',
-                  'RegionId': self.region,
-                  'ServerCertificate': server_certificate,
-                  'PrivateKey': private_key}
-        if name:
-            params['ServerCertificateName'] = name
-        resp_body = self.connection.request(self.path, params).object
-        return self._to_server_certificate(resp_body)
-
-    def ex_list_certificates(self, certificate_ids=[]):
-        """
-        List all server certificates
-
-        :param certificate_ids: certificate ids to filter results
-        :type certificate_ids: ``str``
-
-        :return: certificates
-        :rtype: ``SLBServerCertificate``
-        """
-
-        params = {'Action': 'DescribeServerCertificates',
-                  'RegionId': self.region}
-        if certificate_ids and isinstance(certificate_ids, list):
-            params['ServerCertificateId'] = ','.join(certificate_ids)
-
-        resp_body = self.connection.request(self.path, params).object
-        cert_elements = findall(resp_body,
-                                'ServerCertificates/ServerCertificate',
-                                namespace=self.namespace)
-        certificates = [self._to_server_certificate(el)
-                        for el in cert_elements]
-        return certificates
-
-    def ex_delete_certificate(self, certificate_id):
-        """
-        Delete the given server certificate
-
-        :param certificate_id: the id of the certificate to delete
-        :type certificate_id: ``str``
-
-        :return: whether process is success
-        :rtype: ``bool``
-        """
-
-        params = {'Action': 'DeleteServerCertificate',
-                  'RegionId': self.region,
-                  'ServerCertificateId': certificate_id}
-        resp = self.connection.request(self.path, params)
-        return resp.success()
-
-    def ex_set_certificate_name(self, certificate_id, name):
-        """
-        Set server certificate name.
-
-        :param certificate_id: the id of the server certificate to update
-        :type certificate_id: ``str``
-
-        :param name: the new name
-        :type name: ``str``
-
-        :return: whether updating is success
-        :rtype: ``bool``
-        """
-
-        params = {'Action': 'SetServerCertificateName',
-                  'RegionId': self.region,
-                  'ServerCertificateId': certificate_id,
-                  'ServerCertificateName': name}
-        resp = self.connection.request(self.path, params)
-        return resp.success()
-
-    def _to_balancers(self, element):
-        xpath = 'LoadBalancers/LoadBalancer'
-        return [self._to_balancer(el)
-                for el in findall(element=element, xpath=xpath,
-                                  namespace=self.namespace)]
-
-    def _to_balancer(self, el):
-        _id = findtext(element=el, xpath='LoadBalancerId',
-                       namespace=self.namespace)
-        name = findtext(element=el, xpath='LoadBalancerName',
-                        namespace=self.namespace)
-        status = findtext(element=el, xpath='LoadBalancerStatus',
-                          namespace=self.namespace)
-        state = STATE_MAPPINGS.get(status, State.UNKNOWN)
-        address = findtext(element=el, xpath='Address',
-                           namespace=self.namespace)
-        extra = self._get_extra_dict(
-            el, RESOURCE_EXTRA_ATTRIBUTES_MAP['balancer'])
-
-        balancer = LoadBalancer(id=_id, name=name, state=state, ip=address,
-                                port=None, driver=self, extra=extra)
-        return balancer
-
-    def _create_list_params(self, params, items, label):
-        """
-        return parameter list
-        """
-        if isinstance(items, str):
-            items = [items]
-        for index, item in enumerate(items):
-            params[label % (index + 1)] = item
-        return params
-
-    def _get_extra_dict(self, element, mapping):
-        """
-        Extract attributes from the element based on rules provided in the
-        mapping dictionary.
-
-        :param      element: Element to parse the values from.
-        :type       element: xml.etree.ElementTree.Element.
-
-        :param      mapping: Dictionary with the extra layout
-        :type       node: :class:`Node`
-
-        :rtype: ``dict``
-        """
-        extra = {}
-        for attribute, values in mapping.items():
-            transform_func = values['transform_func']
-            value = findattr(element=element,
-                             xpath=values['xpath'],
-                             namespace=self.namespace)
-            if value:
-                try:
-                    extra[attribute] = transform_func(value)
-                except Exception:
-                    extra[attribute] = None
-            else:
-                extra[attribute] = value
-
-        return extra
-
-    def _to_servers_json(self, members):
-        servers = []
-        for each in members:
-            server = {'ServerId': each.id,
-                      'Weight': '100'}
-            if 'Weight' in each.extra:
-                server['Weight'] = each.extra['Weight']
-            servers.append(server)
-        try:
-            return json.dumps(servers)
-        except Exception:
-            raise AttributeError('could not convert member to backend server')
-
-    def _to_balancer_attribute(self, element):
-        balancer = self._to_balancer(element)
-        port_proto_elements = findall(
-            element, 'ListenerPortsAndProtocol/ListenerPortAndProtocol',
-            namespace=self.namespace)
-        if len(port_proto_elements) > 0:
-            listeners = [self._to_port_and_protocol(el)
-                         for el in port_proto_elements]
-        else:
-            port_elements = findall(element, 'ListenerPorts/ListenerPort',
-                                    namespace=self.namespace)
-            listeners = [{'ListenerPort': el.text, 'ListenerProtocol': 'http'}
-                         for el in port_elements]
-        server_elements = findall(element,
-                                  'BackendServers/BackendServer',
-                                  namespace=self.namespace)
-        backend_servers = [self._to_server_and_weight(el)
-                           for el in server_elements]
-        return SLBLoadBalancerAttribute(balancer, listeners, backend_servers)
-
-    def _to_port_and_protocol(self, el):
-        port = findtext(el, 'ListenerPort', namespace=self.namespace)
-        protocol = findtext(el, 'ListenerProtocol', namespace=self.namespace)
-        return {'ListenerPort': port, 'ListenerProtocol': protocol}
-
-    def _to_server_and_weight(self, el):
-        server_id = findtext(el, 'ServerId', namespace=self.namespace)
-        weight = findtext(el, 'Weight', namespace=self.namespace)
-        return {'ServerId': server_id, 'Weight': weight}
-
-    def _to_server_certificate(self, el):
-        _id = findtext(el, 'ServerCertificateId', namespace=self.namespace)
-        name = findtext(el, 'ServerCertificateName', namespace=self.namespace)
-        fingerprint = findtext(el, 'Fingerprint', namespace=self.namespace)
-        return SLBServerCertificate(id=_id, name=name,
-                                    fingerprint=fingerprint)
-
-    def _list_to_json(self, value):
-        try:
-            return json.dumps(value)
-        except Exception:
-            return '[]'

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/softlayer.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/softlayer.py b/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/softlayer.py
deleted file mode 100644
index 556e4fb..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/softlayer.py
+++ /dev/null
@@ -1,435 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance withv
-# 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.
-
-__all__ = [
-    'SoftlayerLBDriver'
-]
-
-from libcloud.common.types import LibcloudError
-from libcloud.common.softlayer import SoftLayerConnection
-from libcloud.utils.misc import find, reverse_dict
-from libcloud.loadbalancer.types import State
-from libcloud.loadbalancer.base import Algorithm, Driver, LoadBalancer
-from libcloud.loadbalancer.base import DEFAULT_ALGORITHM, Member
-
-lb_service = 'SoftLayer_Network_Application_Delivery_Controller_LoadBalancer_'\
-    'VirtualIpAddress'
-
-
-class LBPackage(object):
-
-    """
-    Defines a single Softlayer package to be used when placing orders (
-    e.g. via ex_place_balancer_order method).
-
-    :param id: Package id.
-    :type id: ``int``
-
-    :param name: Package name.
-    :type name: ``str``
-
-    :param description: Package short description.
-    :type description: ``str``
-
-    :param price_id: Id of the price for this package.
-    :type price_id: ``int``
-
-    :param capacity: Provides a numerical representation of the capacity given
-                     in the description of this package.
-    :type capacity: ``int``
-
-    """
-
-    def __init__(self, id, name, description, price_id, capacity):
-        self.id = id
-        self.name = name
-        self.description = description
-        self.price_id = price_id
-        self.capacity = capacity
-
-    def __repr__(self):
-        return (
-            '<LBPackage: id=%s, name=%s, description=%s, price_id=%s, '
-            'capacity=%s>' % (self.id, self.name, self.description,
-                              self.price_id, self.capacity))
-
-
-class SoftlayerLBDriver(Driver):
-    name = 'Softlayer Load Balancing'
-    website = 'http://www.softlayer.com/'
-    connectionCls = SoftLayerConnection
-
-    _VALUE_TO_ALGORITHM_MAP = {
-        'ROUND_ROBIN': Algorithm.ROUND_ROBIN,
-        'LEAST_CONNECTIONS': Algorithm.LEAST_CONNECTIONS,
-        'SHORTEST_RESPONSE': Algorithm.SHORTEST_RESPONSE,
-        'PERSISTENT_IP': Algorithm.PERSISTENT_IP
-    }
-
-    _ALGORITHM_TO_VALUE_MAP = reverse_dict(_VALUE_TO_ALGORITHM_MAP)
-
-    def list_balancers(self):
-        mask = {
-            'adcLoadBalancers': {
-                'ipAddress': '',
-                'loadBalancerHardware': {
-                    'datacenter': ''
-                },
-                'virtualServers': {
-                    'serviceGroups': {
-                        'routingMethod': '',
-                        'routingType': '',
-                        'services': {
-                            'ipAddress': ''
-                        }
-                    }
-                }
-            }
-        }
-
-        res = self.connection.request(
-            'SoftLayer_Account', 'getAdcLoadBalancers',
-            object_mask=mask).object
-
-        return [self._to_balancer(lb) for lb in res]
-
-    def get_balancer(self, balancer_id):
-        balancers = self.list_balancers()
-        balancer = find(balancers, lambda b: b.id == balancer_id)
-        if not balancer:
-            raise LibcloudError(value='No balancer found for id: %s' %
-                                balancer_id, driver=self)
-        return balancer
-
-    def list_protocols(self):
-        """
-        Return a list of supported protocols.
-
-        :rtype: ``list`` of ``str``
-        """
-        return ['dns', 'ftp', 'http', 'https', 'tcp', 'udp']
-
-    def balancer_list_members(self, balancer):
-        lb = self._get_balancer_model(balancer.id)
-        members = []
-        vs = self._locate_service_group(lb, balancer.port)
-        if vs:
-            if vs['serviceGroups']:
-                srvgrp = vs['serviceGroups'][0]
-                members = [self._to_member(srv, balancer) for
-                           srv in srvgrp['services']]
-
-        return members
-
-    def balancer_attach_member(self, balancer, member):
-        lb = self._get_balancer_model(balancer.id)
-        vs = self._locate_service_group(lb, balancer.port)
-        if not vs:
-            raise LibcloudError(value='No service_group found for balancer '
-                                'port: %s' % balancer.port, driver=self)
-
-        if vs['serviceGroups']:
-            services = vs['serviceGroups'][0]['services']
-            services.append(self._to_service_template(member.ip,
-                                                      member.port))
-
-        self.connection.request(lb_service, 'editObject', lb, id=balancer.id)
-
-        return [m for m in balancer.list_members() if m.ip == member.ip][0]
-
-    def balancer_detach_member(self, balancer, member):
-        svc_lbsrv = 'SoftLayer_Network_Application_Delivery_Controller_'\
-            'LoadBalancer_Service'
-
-        self.connection.request(svc_lbsrv, 'deleteObject', id=member.id)
-        return True
-
-    def destroy_balancer(self, balancer):
-        res_billing = self.connection.request(lb_service, 'getBillingItem',
-                                              id=balancer.id).object
-
-        self.connection.request('SoftLayer_Billing_Item', 'cancelService',
-                                id=res_billing['id'])
-        return True
-
-    def ex_list_balancer_packages(self):
-        """
-        Retrieves the available local load balancer packages.
-
-        :rtype: ``list`` of :class:`LBPackage`
-        """
-        mask = {
-            'prices': ''
-        }
-        res = self.connection.request('SoftLayer_Product_Package', 'getItems',
-                                      id=0, object_mask=mask).object
-
-        res_lb_pkgs = [r for r in res if r['description'].find
-                       ('Load Balancer') != -1]
-        res_lb_pkgs = [r for r in res_lb_pkgs if not r['description'].
-                       startswith('Global')]
-
-        return [self._to_lb_package(r) for r in res_lb_pkgs]
-
-    def ex_place_balancer_order(self, package, location):
-        """
-        Places an order for a local loadbalancer in the specified
-        location.
-
-        :param package: The package to create the loadbalancer from.
-        :type package: :class:`LBPackage`
-
-        :param string location: The location (datacenter) to create the
-                                loadbalancer.
-        :type location: :class:`NodeLocation`
-
-        :return: ``True`` if ex_place_balancer_order was successful.
-        :rtype: ``bool``
-        """
-        data = {
-            'complexType': 'SoftLayer_Container_Product_Order_Network_'
-                           'LoadBalancer',
-            'quantity': 1,
-            'packageId': 0,
-            'location': self._get_location(location.id),
-            'prices': [{'id': package.price_id}]
-        }
-
-        self.connection.request('SoftLayer_Product_Order', 'placeOrder',
-                                data)
-        return True
-
-    def ex_configure_load_balancer(self, balancer, port=80,
-                                   protocol='http',
-                                   algorithm=DEFAULT_ALGORITHM,
-                                   ex_allocation=100):
-        """
-        Configure the loadbalancer by adding it with a front-end port (aka
-        a service group in the Softlayer loadbalancer model).
-
-        Softlayer loadbalancer may be defined with multiple service
-        groups (front-end ports) each defined with a unique port number.
-
-        :param balancer: The loadbalancer.
-        :type  balancer: :class:`LoadBalancer`
-
-        :param port: Port of the service group, defaults to 80.
-        :type  port: ``int``
-
-        :param protocol: Loadbalancer protocol, defaults to http.
-        :type  protocol: ``str``
-
-        :param algorithm: Load balancing algorithm, defaults to
-                            Algorithm.ROUND_ROBIN
-        :type  algorithm: :class:`Algorithm`
-
-        :param ex_allocation: The percentage of the total connection
-                              allocations to allocate for this group.
-        :type  ex_allocation: ``int``
-
-        :return: ``True`` if ex_add_service_group was successful.
-        :rtype: ``bool``
-        """
-        _types = self._get_routing_types()
-        _methods = self._get_routing_methods()
-
-        rt = find(_types, lambda t: t['keyname'] == protocol.upper())
-        if not rt:
-            raise LibcloudError(value='Invalid protocol %s' % protocol,
-                                driver=self)
-
-        value = self._algorithm_to_value(algorithm)
-        meth = find(_methods, lambda m: m['keyname'] == value)
-        if not meth:
-            raise LibcloudError(value='Invalid algorithm %s' % algorithm,
-                                driver=self)
-
-        service_group_template = {
-            'port': port,
-            'allocation': ex_allocation,
-            'serviceGroups': [{
-                'routingTypeId': rt['id'],
-                'routingMethodId': meth['id']
-            }]
-        }
-
-        lb = self._get_balancer_model(balancer.id)
-        if len(lb['virtualServers']) > 0:
-            port = lb['virtualServers'][0]['port']
-            raise LibcloudError(value='Loadbalancer already configured with '
-                                'a service group (front-end port)' % port,
-                                driver=self)
-
-        lb['virtualServers'].append(service_group_template)
-        self.connection.request(lb_service, 'editObject', lb, id=balancer.id)
-        return True
-
-    def _get_balancer_model(self, balancer_id):
-        """
-        Retrieve Softlayer loadbalancer model.
-        """
-        lb_mask = {
-            'virtualServers': {
-                'serviceGroups': {
-                    'services': {
-                        'ipAddress': '',
-                        'groupReferences': '',
-                    }
-                }
-            }
-        }
-
-        lb_res = self.connection.request(lb_service, 'getObject',
-                                         object_mask=lb_mask, id=balancer_id).\
-            object
-        return lb_res
-
-    def _locate_service_group(self, lb, port):
-        """
-        Locate service group with given port.
-
-        Return virtualServers (vs) entry whose port matches the
-        supplied parameter port. For a negative port, just return
-        the first vs entry.
-        None is returned if no match found.
-
-        :param lb: Softlayer loadbalancer model.
-        :type lb: ``dict``
-
-        :param port: loadbalancer front-end port.
-        :type port: ``int``
-
-        :return: Matched entry in the virtualServers array of the supplied
-        model.
-        :rtype: ``dict``
-        """
-        vs = None
-        if port < 0:
-            vs = lb['virtualServers'][0] if lb['virtualServers']\
-                else None
-        else:
-            vs = find(lb['virtualServers'], lambda v: v['port'] == port)
-
-        return vs
-
-    def _get_routing_types(self):
-        svc_rtype = 'SoftLayer_Network_Application_Delivery_Controller_'\
-            'LoadBalancer_Routing_Type'
-
-        return self.connection.request(svc_rtype, 'getAllObjects').object
-
-    def _get_routing_methods(self):
-        svc_rmeth = 'SoftLayer_Network_Application_Delivery_Controller_'\
-            'LoadBalancer_Routing_Method'
-
-        return self.connection.request(svc_rmeth, 'getAllObjects').object
-
-    def _get_location(self, location_id):
-        res = self.connection.request('SoftLayer_Location_Datacenter',
-                                      'getDatacenters').object
-
-        dcenter = find(res, lambda d: d['name'] == location_id)
-        if not dcenter:
-            raise LibcloudError(value='Invalid value %s' % location_id,
-                                driver=self)
-        return dcenter['id']
-
-    def _get_ipaddress(self, ip):
-        svc_ipaddress = 'SoftLayer_Network_Subnet_IpAddress'
-
-        return self.connection.request(svc_ipaddress, 'getByIpAddress',
-                                       ip).object
-
-    def _to_lb_package(self, pkg):
-        try:
-            price_id = pkg['prices'][0]['id']
-        except:
-            price_id = -1
-
-        capacity = int(pkg.get('capacity', 0))
-        return LBPackage(id=pkg['id'], name=pkg['keyName'],
-                         description=pkg['description'],
-                         price_id=price_id, capacity=capacity)
-
-    def _to_service_template(self, ip, port):
-        """
-        Builds single member entry in Softlayer loadbalancer model
-        """
-        template = {
-            'enabled': 1,  # enable the service
-            'port': port,  # back-end port
-            'ipAddressId': self._get_ipaddress(ip)['id'],
-            'healthChecks': [{
-                'healthCheckTypeId': 21  # default health check
-            }],
-            'groupReferences': [{
-                'weight': 1
-            }]
-        }
-
-        return template
-
-    def _to_balancer(self, lb):
-        ipaddress = lb['ipAddress']['ipAddress']
-
-        extra = {}
-        extra['connection_limit'] = lb['connectionLimit']
-        extra['ssl_active'] = lb['sslActiveFlag']
-        extra['ssl_enabled'] = lb['sslEnabledFlag']
-        extra['ha'] = lb['highAvailabilityFlag']
-        extra['datacenter'] = \
-            lb['loadBalancerHardware'][0]['datacenter']['name']
-
-        # In Softlayer, there could be multiple group of members (aka service
-        # groups), so retrieve the first one
-        vs = self._locate_service_group(lb, -1)
-        if vs:
-            port = vs['port']
-            if vs['serviceGroups']:
-                srvgrp = vs['serviceGroups'][0]
-                routing_method = srvgrp['routingMethod']['keyname']
-                routing_type = srvgrp['routingType']['keyname']
-                try:
-                    extra['algorithm'] = self.\
-                        _value_to_algorithm(routing_method)
-                except:
-                    pass
-                extra['protocol'] = routing_type.lower()
-
-        if not vs:
-            port = -1
-
-        balancer = LoadBalancer(
-            id=lb['id'],
-            name='',
-            state=State.UNKNOWN,
-            ip=ipaddress,
-            port=port,
-            driver=self.connection.driver,
-            extra=extra
-        )
-
-        return balancer
-
-    def _to_member(self, srv, balancer=None):
-        svc_id = srv['id']
-        ip = srv['ipAddress']['ipAddress']
-        port = srv['port']
-
-        extra = {}
-        extra['status'] = srv['status']
-        extra['enabled'] = srv['enabled']
-        return Member(id=svc_id, ip=ip, port=port, balancer=balancer,
-                      extra=extra)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/providers.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/providers.py b/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/providers.py
deleted file mode 100644
index 49a0f3a..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/providers.py
+++ /dev/null
@@ -1,59 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from libcloud.loadbalancer.types import Provider
-from libcloud.loadbalancer.types import OLD_CONSTANT_TO_NEW_MAPPING
-from libcloud.common.providers import get_driver as _get_provider_driver
-from libcloud.common.providers import set_driver as _set_provider_driver
-
-__all__ = [
-    "Provider",
-    "DRIVERS",
-    "get_driver",
-]
-
-DRIVERS = {
-    Provider.RACKSPACE:
-    ('libcloud.loadbalancer.drivers.rackspace', 'RackspaceLBDriver'),
-    Provider.GOGRID:
-    ('libcloud.loadbalancer.drivers.gogrid', 'GoGridLBDriver'),
-    Provider.NINEFOLD:
-    ('libcloud.loadbalancer.drivers.ninefold', 'NinefoldLBDriver'),
-    Provider.BRIGHTBOX:
-    ('libcloud.loadbalancer.drivers.brightbox', 'BrightboxLBDriver'),
-    Provider.ELB:
-    ('libcloud.loadbalancer.drivers.elb', 'ElasticLBDriver'),
-    Provider.CLOUDSTACK:
-    ('libcloud.loadbalancer.drivers.cloudstack', 'CloudStackLBDriver'),
-    Provider.GCE:
-    ('libcloud.loadbalancer.drivers.gce', 'GCELBDriver'),
-    Provider.SOFTLAYER:
-    ('libcloud.loadbalancer.drivers.softlayer', 'SoftlayerLBDriver'),
-    Provider.DIMENSIONDATA:
-    ('libcloud.loadbalancer.drivers.dimensiondata', 'DimensionDataLBDriver'),
-    Provider.ALIYUN_SLB:
-    ('libcloud.loadbalancer.drivers.slb', 'SLBDriver'),
-}
-
-
-def get_driver(provider):
-    deprecated_constants = OLD_CONSTANT_TO_NEW_MAPPING
-    return _get_provider_driver(drivers=DRIVERS, provider=provider,
-                                deprecated_constants=deprecated_constants)
-
-
-def set_driver(provider, module, klass):
-    return _set_provider_driver(drivers=DRIVERS, provider=provider,
-                                module=module, klass=klass)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/types.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/types.py b/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/types.py
deleted file mode 100644
index b0fba05..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/types.py
+++ /dev/null
@@ -1,84 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-__all__ = [
-    "Provider",
-    "State",
-    "LibcloudLBError",
-    "LibcloudLBImmutableError",
-
-    "OLD_CONSTANT_TO_NEW_MAPPING"
-]
-
-from libcloud.common.types import LibcloudError
-
-
-class LibcloudLBError(LibcloudError):
-    pass
-
-
-class LibcloudLBImmutableError(LibcloudLBError):
-    pass
-
-
-class Provider(object):
-    """
-    :cvar ALIYUN_SLB: Aliyun SLB loadbalancer driver
-    """
-    RACKSPACE = 'rackspace'
-    GOGRID = 'gogrid'
-    NINEFOLD = 'ninefold'
-    BRIGHTBOX = 'brightbox'
-    ELB = 'elb'
-    CLOUDSTACK = 'cloudstack'
-    GCE = 'gce'
-    SOFTLAYER = 'softlayer'
-    DIMENSIONDATA = 'dimensiondata'
-    ALIYUN_SLB = 'aliyun_slb'
-
-    # Deprecated
-    RACKSPACE_US = 'rackspace_us'
-    RACKSPACE_UK = 'rackspace_uk'
-
-
-OLD_CONSTANT_TO_NEW_MAPPING = {
-    Provider.RACKSPACE_US: Provider.RACKSPACE,
-    Provider.RACKSPACE_UK: Provider.RACKSPACE,
-}
-
-
-class State(object):
-    """
-    Standard states for a loadbalancer
-
-    :cvar RUNNING: loadbalancer is running and ready to use
-    :cvar UNKNOWN: loabalancer state is unknown
-    """
-
-    RUNNING = 0
-    PENDING = 1
-    UNKNOWN = 2
-    ERROR = 3
-    DELETED = 4
-
-
-class MemberCondition(object):
-    """
-    Each member of a load balancer can have an associated condition
-    which determines its role within the load balancer.
-    """
-    ENABLED = 0
-    DISABLED = 1
-    DRAINING = 2

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/pricing.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/pricing.py b/apache-libcloud-1.0.0rc2/libcloud/pricing.py
deleted file mode 100644
index 42075fb..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/pricing.py
+++ /dev/null
@@ -1,224 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-from __future__ import with_statement
-
-"""
-A class which handles loading the pricing files.
-"""
-
-import os.path
-from os.path import join as pjoin
-
-try:
-    import simplejson as json
-    try:
-        JSONDecodeError = json.JSONDecodeError
-    except AttributeError:
-        # simplejson < 2.1.0 does not have the JSONDecodeError exception class
-        JSONDecodeError = ValueError
-except ImportError:
-    import json
-    JSONDecodeError = ValueError
-
-from libcloud.utils.connection import get_response_object
-
-__all__ = [
-    'get_pricing',
-    'get_size_price',
-    'set_pricing',
-    'clear_pricing_data',
-    'download_pricing_file'
-]
-
-# Default URL to the pricing file
-DEFAULT_FILE_URL = 'https://git-wip-us.apache.org/repos/asf?p=libcloud.git;a=blob_plain;f=libcloud/data/pricing.json'  # NOQA
-
-CURRENT_DIRECTORY = os.path.dirname(os.path.abspath(__file__))
-DEFAULT_PRICING_FILE_PATH = pjoin(CURRENT_DIRECTORY, 'data/pricing.json')
-CUSTOM_PRICING_FILE_PATH = os.path.expanduser('~/.libcloud/pricing.json')
-
-# Pricing data cache
-PRICING_DATA = {
-    'compute': {},
-    'storage': {}
-}
-
-VALID_PRICING_DRIVER_TYPES = ['compute', 'storage']
-
-
-def get_pricing_file_path(file_path=None):
-    if os.path.exists(CUSTOM_PRICING_FILE_PATH) and \
-       os.path.isfile(CUSTOM_PRICING_FILE_PATH):
-        # Custom pricing file is available, use it
-        return CUSTOM_PRICING_FILE_PATH
-
-    return DEFAULT_PRICING_FILE_PATH
-
-
-def get_pricing(driver_type, driver_name, pricing_file_path=None):
-    """
-    Return pricing for the provided driver.
-
-    :type driver_type: ``str``
-    :param driver_type: Driver type ('compute' or 'storage')
-
-    :type driver_name: ``str``
-    :param driver_name: Driver name
-
-    :type pricing_file_path: ``str``
-    :param pricing_file_path: Custom path to a price file. If not provided
-                              it uses a default path.
-
-    :rtype: ``dict``
-    :return: Dictionary with pricing where a key name is size ID and
-             the value is a price.
-    """
-    if driver_type not in VALID_PRICING_DRIVER_TYPES:
-        raise AttributeError('Invalid driver type: %s', driver_type)
-
-    if driver_name in PRICING_DATA[driver_type]:
-        return PRICING_DATA[driver_type][driver_name]
-
-    if not pricing_file_path:
-        pricing_file_path = get_pricing_file_path(file_path=pricing_file_path)
-
-    with open(pricing_file_path) as fp:
-        content = fp.read()
-
-    pricing_data = json.loads(content)
-    size_pricing = pricing_data[driver_type][driver_name]
-
-    for driver_type in VALID_PRICING_DRIVER_TYPES:
-        # pylint: disable=maybe-no-member
-        pricing = pricing_data.get(driver_type, None)
-        if pricing:
-            PRICING_DATA[driver_type] = pricing
-
-    return size_pricing
-
-
-def set_pricing(driver_type, driver_name, pricing):
-    """
-    Populate the driver pricing dictionary.
-
-    :type driver_type: ``str``
-    :param driver_type: Driver type ('compute' or 'storage')
-
-    :type driver_name: ``str``
-    :param driver_name: Driver name
-
-    :type pricing: ``dict``
-    :param pricing: Dictionary where a key is a size ID and a value is a price.
-    """
-
-    PRICING_DATA[driver_type][driver_name] = pricing
-
-
-def get_size_price(driver_type, driver_name, size_id):
-    """
-    Return price for the provided size.
-
-    :type driver_type: ``str``
-    :param driver_type: Driver type ('compute' or 'storage')
-
-    :type driver_name: ``str``
-    :param driver_name: Driver name
-
-    :type size_id: ``str`` or ``int``
-    :param size_id: Unique size ID (can be an integer or a string - depends on
-                    the driver)
-
-    :rtype: ``float``
-    :return: Size price.
-    """
-    pricing = get_pricing(driver_type=driver_type, driver_name=driver_name)
-    price = float(pricing[size_id])
-    return price
-
-
-def invalidate_pricing_cache():
-    """
-    Invalidate pricing cache for all the drivers.
-    """
-    PRICING_DATA['compute'] = {}
-    PRICING_DATA['storage'] = {}
-
-
-def clear_pricing_data():
-    """
-    Invalidate pricing cache for all the drivers.
-
-    Note: This method does the same thing as invalidate_pricing_cache and is
-    here for backward compatibility reasons.
-    """
-    invalidate_pricing_cache()
-
-
-def invalidate_module_pricing_cache(driver_type, driver_name):
-    """
-    Invalidate the cache for the specified driver.
-
-    :type driver_type: ``str``
-    :param driver_type: Driver type ('compute' or 'storage')
-
-    :type driver_name: ``str``
-    :param driver_name: Driver name
-    """
-    if driver_name in PRICING_DATA[driver_type]:
-        del PRICING_DATA[driver_type][driver_name]
-
-
-def download_pricing_file(file_url=DEFAULT_FILE_URL,
-                          file_path=CUSTOM_PRICING_FILE_PATH):
-    """
-    Download pricing file from the file_url and save it to file_path.
-
-    :type file_url: ``str``
-    :param file_url: URL pointing to the pricing file.
-
-    :type file_path: ``str``
-    :param file_path: Path where a download pricing file will be saved.
-    """
-    dir_name = os.path.dirname(file_path)
-
-    if not os.path.exists(dir_name):
-        # Verify a valid path is provided
-        msg = ('Can\'t write to %s, directory %s, doesn\'t exist' %
-               (file_path, dir_name))
-        raise ValueError(msg)
-
-    if os.path.exists(file_path) and os.path.isdir(file_path):
-        msg = ('Can\'t write to %s file path because it\'s a'
-               ' directory' % (file_path))
-        raise ValueError(msg)
-
-    response = get_response_object(file_url)
-    body = response.body
-
-    # Verify pricing file is valid
-    try:
-        data = json.loads(body)
-    except JSONDecodeError:
-        msg = 'Provided URL doesn\'t contain valid pricing data'
-        raise Exception(msg)
-
-    # pylint: disable=maybe-no-member
-    if not data.get('updated', None):
-        msg = 'Provided URL doesn\'t contain valid pricing data'
-        raise Exception(msg)
-
-    # No need to stream it since file is small
-    with open(file_path, 'w') as file_handle:
-        file_handle.write(body)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/security.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/security.py b/apache-libcloud-1.0.0rc2/libcloud/security.py
deleted file mode 100644
index 4d024db..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/security.py
+++ /dev/null
@@ -1,89 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-Security (SSL) Settings
-
-Usage:
-    import libcloud.security
-    libcloud.security.VERIFY_SSL_CERT = True
-
-    # Optional.
-    libcloud.security.CA_CERTS_PATH.append('/path/to/cacert.txt')
-"""
-
-import os
-import ssl
-
-__all__ = [
-    'VERIFY_SSL_CERT',
-    'SSL_VERSION',
-    'CA_CERTS_PATH'
-]
-
-VERIFY_SSL_CERT = True
-
-SSL_VERSION = ssl.PROTOCOL_TLSv1
-
-# File containing one or more PEM-encoded CA certificates
-# concatenated together.
-CA_CERTS_PATH = [
-    # centos/fedora: openssl
-    '/etc/pki/tls/certs/ca-bundle.crt',
-
-    # debian/ubuntu/arch/gentoo: ca-certificates
-    '/etc/ssl/certs/ca-certificates.crt',
-
-    # freebsd: ca_root_nss
-    '/usr/local/share/certs/ca-root-nss.crt',
-
-    # macports: curl-ca-bundle
-    '/opt/local/share/curl/curl-ca-bundle.crt',
-
-    # homebrew: openssl
-    '/usr/local/etc/openssl/cert.pem',
-
-    # homebrew: curl-ca-bundle (backward compatibility)
-    '/usr/local/opt/curl-ca-bundle/share/ca-bundle.crt',
-]
-
-# Allow user to explicitly specify which CA bundle to use, using an environment
-# variable
-environment_cert_file = os.getenv('SSL_CERT_FILE', None)
-if environment_cert_file is not None:
-    # Make sure the file exists
-    if not os.path.exists(environment_cert_file):
-        raise ValueError('Certificate file %s doesn\'t exist' %
-                         (environment_cert_file))
-
-    if not os.path.isfile(environment_cert_file):
-        raise ValueError('Certificate file can\'t be a directory')
-
-    # If a provided file exists we ignore other common paths because we
-    # don't want to fall-back to a potentially less restrictive bundle
-    CA_CERTS_PATH = [environment_cert_file]
-
-CA_CERTS_UNAVAILABLE_ERROR_MSG = (
-    'No CA Certificates were found in CA_CERTS_PATH. For information on '
-    'how to get required certificate files, please visit '
-    'https://libcloud.readthedocs.org/en/latest/other/'
-    'ssl-certificate-validation.html'
-)
-
-VERIFY_SSL_DISABLED_MSG = (
-    'SSL certificate verification is disabled, this can pose a '
-    'security risk. For more information how to enable the SSL '
-    'certificate verification, please visit the libcloud '
-    'documentation.'
-)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/storage/__init__.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/storage/__init__.py b/apache-libcloud-1.0.0rc2/libcloud/storage/__init__.py
deleted file mode 100644
index f73ddf0..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/storage/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-"""
-Module for working with Storage
-"""


[06/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/storage/base.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/storage/base.py b/apache-libcloud-1.0.0rc2/libcloud/storage/base.py
deleted file mode 100644
index f13dd0a..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/storage/base.py
+++ /dev/null
@@ -1,831 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-Provides base classes for working with storage
-"""
-
-# Backward compatibility for Python 2.5
-from __future__ import with_statement
-
-import os.path                          # pylint: disable-msg=W0404
-import hashlib
-from os.path import join as pjoin
-
-from libcloud.utils.py3 import httplib
-from libcloud.utils.py3 import next
-from libcloud.utils.py3 import b
-
-import libcloud.utils.files
-from libcloud.common.types import LibcloudError
-from libcloud.common.base import ConnectionUserAndKey, BaseDriver
-from libcloud.storage.types import ObjectDoesNotExistError
-
-__all__ = [
-    'Object',
-    'Container',
-    'StorageDriver',
-
-    'CHUNK_SIZE',
-    'DEFAULT_CONTENT_TYPE'
-]
-
-CHUNK_SIZE = 8096
-
-# Default Content-Type which is sent when uploading an object if one is not
-# supplied and can't be detected when using non-strict mode.
-DEFAULT_CONTENT_TYPE = 'application/octet-stream'
-
-
-class Object(object):
-    """
-    Represents an object (BLOB).
-    """
-
-    def __init__(self, name, size, hash, extra, meta_data, container,
-                 driver):
-        """
-        :param name: Object name (must be unique per container).
-        :type  name: ``str``
-
-        :param size: Object size in bytes.
-        :type  size: ``int``
-
-        :param hash: Object hash.
-        :type  hash: ``str``
-
-        :param container: Object container.
-        :type  container: :class:`Container`
-
-        :param extra: Extra attributes.
-        :type  extra: ``dict``
-
-        :param meta_data: Optional object meta data.
-        :type  meta_data: ``dict``
-
-        :param driver: StorageDriver instance.
-        :type  driver: :class:`StorageDriver`
-        """
-
-        self.name = name
-        self.size = size
-        self.hash = hash
-        self.container = container
-        self.extra = extra or {}
-        self.meta_data = meta_data or {}
-        self.driver = driver
-
-    def get_cdn_url(self):
-        return self.driver.get_object_cdn_url(obj=self)
-
-    def enable_cdn(self, **kwargs):
-        return self.driver.enable_object_cdn(obj=self, **kwargs)
-
-    def download(self, destination_path, overwrite_existing=False,
-                 delete_on_failure=True):
-        return self.driver.download_object(self, destination_path,
-                                           overwrite_existing,
-                                           delete_on_failure)
-
-    def as_stream(self, chunk_size=None):
-        return self.driver.download_object_as_stream(self, chunk_size)
-
-    def delete(self):
-        return self.driver.delete_object(self)
-
-    def __repr__(self):
-        return ('<Object: name=%s, size=%s, hash=%s, provider=%s ...>' %
-                (self.name, self.size, self.hash, self.driver.name))
-
-
-class Container(object):
-    """
-    Represents a container (bucket) which can hold multiple objects.
-    """
-
-    def __init__(self, name, extra, driver):
-        """
-        :param name: Container name (must be unique).
-        :type name: ``str``
-
-        :param extra: Extra attributes.
-        :type extra: ``dict``
-
-        :param driver: StorageDriver instance.
-        :type driver: :class:`StorageDriver`
-        """
-
-        self.name = name
-        self.extra = extra or {}
-        self.driver = driver
-
-    def iterate_objects(self):
-        return self.driver.iterate_container_objects(container=self)
-
-    def list_objects(self):
-        return self.driver.list_container_objects(container=self)
-
-    def get_cdn_url(self):
-        return self.driver.get_container_cdn_url(container=self)
-
-    def enable_cdn(self, **kwargs):
-        return self.driver.enable_container_cdn(container=self, **kwargs)
-
-    def get_object(self, object_name):
-        return self.driver.get_object(container_name=self.name,
-                                      object_name=object_name)
-
-    def upload_object(self, file_path, object_name, extra=None, **kwargs):
-        return self.driver.upload_object(
-            file_path, self, object_name, extra=extra, **kwargs)
-
-    def upload_object_via_stream(self, iterator, object_name, extra=None,
-                                 **kwargs):
-        return self.driver.upload_object_via_stream(
-            iterator, self, object_name, extra=extra, **kwargs)
-
-    def download_object(self, obj, destination_path, overwrite_existing=False,
-                        delete_on_failure=True):
-        return self.driver.download_object(
-            obj, destination_path, overwrite_existing=overwrite_existing,
-            delete_on_failure=delete_on_failure)
-
-    def download_object_as_stream(self, obj, chunk_size=None):
-        return self.driver.download_object_as_stream(obj, chunk_size)
-
-    def delete_object(self, obj):
-        return self.driver.delete_object(obj)
-
-    def delete(self):
-        return self.driver.delete_container(self)
-
-    def __repr__(self):
-        return ('<Container: name=%s, provider=%s>'
-                % (self.name, self.driver.name))
-
-
-class StorageDriver(BaseDriver):
-    """
-    A base StorageDriver to derive from.
-    """
-
-    connectionCls = ConnectionUserAndKey
-    name = None
-    hash_type = 'md5'
-    supports_chunked_encoding = False
-
-    # When strict mode is used, exception will be thrown if no content type is
-    # provided and none can be detected when uploading an object
-    strict_mode = False
-
-    def iterate_containers(self):
-        """
-        Return a generator of containers for the given account
-
-        :return: A generator of Container instances.
-        :rtype: ``generator`` of :class:`Container`
-        """
-        raise NotImplementedError(
-            'iterate_containers not implemented for this driver')
-
-    def list_containers(self):
-        """
-        Return a list of containers.
-
-        :return: A list of Container instances.
-        :rtype: ``list`` of :class:`Container`
-        """
-        return list(self.iterate_containers())
-
-    def iterate_container_objects(self, container):
-        """
-        Return a generator of objects for the given container.
-
-        :param container: Container instance
-        :type container: :class:`Container`
-
-        :return: A generator of Object instances.
-        :rtype: ``generator`` of :class:`Object`
-        """
-        raise NotImplementedError(
-            'iterate_container_objects not implemented for this driver')
-
-    def list_container_objects(self, container):
-        """
-        Return a list of objects for the given container.
-
-        :param container: Container instance.
-        :type container: :class:`Container`
-
-        :return: A list of Object instances.
-        :rtype: ``list`` of :class:`Object`
-        """
-        return list(self.iterate_container_objects(container))
-
-    def get_container(self, container_name):
-        """
-        Return a container instance.
-
-        :param container_name: Container name.
-        :type container_name: ``str``
-
-        :return: :class:`Container` instance.
-        :rtype: :class:`Container`
-        """
-        raise NotImplementedError(
-            'get_object not implemented for this driver')
-
-    def get_container_cdn_url(self, container):
-        """
-        Return a container CDN URL.
-
-        :param container: Container instance
-        :type  container: :class:`Container`
-
-        :return: A CDN URL for this container.
-        :rtype: ``str``
-        """
-        raise NotImplementedError(
-            'get_container_cdn_url not implemented for this driver')
-
-    def get_object(self, container_name, object_name):
-        """
-        Return an object instance.
-
-        :param container_name: Container name.
-        :type  container_name: ``str``
-
-        :param object_name: Object name.
-        :type  object_name: ``str``
-
-        :return: :class:`Object` instance.
-        :rtype: :class:`Object`
-        """
-        raise NotImplementedError(
-            'get_object not implemented for this driver')
-
-    def get_object_cdn_url(self, obj):
-        """
-        Return an object CDN URL.
-
-        :param obj: Object instance
-        :type  obj: :class:`Object`
-
-        :return: A CDN URL for this object.
-        :rtype: ``str``
-        """
-        raise NotImplementedError(
-            'get_object_cdn_url not implemented for this driver')
-
-    def enable_container_cdn(self, container):
-        """
-        Enable container CDN.
-
-        :param container: Container instance
-        :type  container: :class:`Container`
-
-        :rtype: ``bool``
-        """
-        raise NotImplementedError(
-            'enable_container_cdn not implemented for this driver')
-
-    def enable_object_cdn(self, obj):
-        """
-        Enable object CDN.
-
-        :param obj: Object instance
-        :type  obj: :class:`Object`
-
-        :rtype: ``bool``
-        """
-        raise NotImplementedError(
-            'enable_object_cdn not implemented for this driver')
-
-    def download_object(self, obj, destination_path, overwrite_existing=False,
-                        delete_on_failure=True):
-        """
-        Download an object to the specified destination path.
-
-        :param obj: Object instance.
-        :type obj: :class:`Object`
-
-        :param destination_path: Full path to a file or a directory where the
-                                 incoming file will be saved.
-        :type destination_path: ``str``
-
-        :param overwrite_existing: True to overwrite an existing file,
-                                   defaults to False.
-        :type overwrite_existing: ``bool``
-
-        :param delete_on_failure: True to delete a partially downloaded file if
-                                   the download was not successful (hash
-                                   mismatch / file size).
-        :type delete_on_failure: ``bool``
-
-        :return: True if an object has been successfully downloaded, False
-                 otherwise.
-        :rtype: ``bool``
-        """
-        raise NotImplementedError(
-            'download_object not implemented for this driver')
-
-    def download_object_as_stream(self, obj, chunk_size=None):
-        """
-        Return a generator which yields object data.
-
-        :param obj: Object instance
-        :type obj: :class:`Object`
-
-        :param chunk_size: Optional chunk size (in bytes).
-        :type chunk_size: ``int``
-        """
-        raise NotImplementedError(
-            'download_object_as_stream not implemented for this driver')
-
-    def upload_object(self, file_path, container, object_name, extra=None,
-                      verify_hash=True, headers=None):
-        """
-        Upload an object currently located on a disk.
-
-        :param file_path: Path to the object on disk.
-        :type file_path: ``str``
-
-        :param container: Destination container.
-        :type container: :class:`Container`
-
-        :param object_name: Object name.
-        :type object_name: ``str``
-
-        :param verify_hash: Verify hash
-        :type verify_hash: ``bool``
-
-        :param extra: Extra attributes (driver specific). (optional)
-        :type extra: ``dict``
-
-        :param headers: (optional) Additional request headers,
-            such as CORS headers. For example:
-            headers = {'Access-Control-Allow-Origin': 'http://mozilla.com'}
-        :type headers: ``dict``
-
-        :rtype: :class:`Object`
-        """
-        raise NotImplementedError(
-            'upload_object not implemented for this driver')
-
-    def upload_object_via_stream(self, iterator, container,
-                                 object_name,
-                                 extra=None,
-                                 headers=None):
-        """
-        Upload an object using an iterator.
-
-        If a provider supports it, chunked transfer encoding is used and you
-        don't need to know in advance the amount of data to be uploaded.
-
-        Otherwise if a provider doesn't support it, iterator will be exhausted
-        so a total size for data to be uploaded can be determined.
-
-        Note: Exhausting the iterator means that the whole data must be
-        buffered in memory which might result in memory exhausting when
-        uploading a very large object.
-
-        If a file is located on a disk you are advised to use upload_object
-        function which uses fs.stat function to determine the file size and it
-        doesn't need to buffer whole object in the memory.
-
-        :param iterator: An object which implements the iterator interface.
-        :type iterator: :class:`object`
-
-        :param container: Destination container.
-        :type container: :class:`Container`
-
-        :param object_name: Object name.
-        :type object_name: ``str``
-
-        :param extra: (optional) Extra attributes (driver specific). Note:
-            This dictionary must contain a 'content_type' key which represents
-            a content type of the stored object.
-        :type extra: ``dict``
-
-        :param headers: (optional) Additional request headers,
-            such as CORS headers. For example:
-            headers = {'Access-Control-Allow-Origin': 'http://mozilla.com'}
-        :type headers: ``dict``
-
-        :rtype: ``object``
-        """
-        raise NotImplementedError(
-            'upload_object_via_stream not implemented for this driver')
-
-    def delete_object(self, obj):
-        """
-        Delete an object.
-
-        :param obj: Object instance.
-        :type obj: :class:`Object`
-
-        :return: ``bool`` True on success.
-        :rtype: ``bool``
-        """
-        raise NotImplementedError(
-            'delete_object not implemented for this driver')
-
-    def create_container(self, container_name):
-        """
-        Create a new container.
-
-        :param container_name: Container name.
-        :type container_name: ``str``
-
-        :return: Container instance on success.
-        :rtype: :class:`Container`
-        """
-        raise NotImplementedError(
-            'create_container not implemented for this driver')
-
-    def delete_container(self, container):
-        """
-        Delete a container.
-
-        :param container: Container instance
-        :type container: :class:`Container`
-
-        :return: ``True`` on success, ``False`` otherwise.
-        :rtype: ``bool``
-        """
-        raise NotImplementedError(
-            'delete_container not implemented for this driver')
-
-    def _get_object(self, obj, callback, callback_kwargs, response,
-                    success_status_code=None):
-        """
-        Call passed callback and start transfer of the object'
-
-        :param obj: Object instance.
-        :type obj: :class:`Object`
-
-        :param callback: Function which is called with the passed
-            callback_kwargs
-        :type callback: :class:`function`
-
-        :param callback_kwargs: Keyword arguments which are passed to the
-             callback.
-        :type callback_kwargs: ``dict``
-
-        :param response: Response instance.
-        :type response: :class:`Response`
-
-        :param success_status_code: Status code which represents a successful
-                                    transfer (defaults to httplib.OK)
-        :type success_status_code: ``int``
-
-        :return: ``True`` on success, ``False`` otherwise.
-        :rtype: ``bool``
-        """
-        success_status_code = success_status_code or httplib.OK
-
-        if response.status == success_status_code:
-            return callback(**callback_kwargs)
-        elif response.status == httplib.NOT_FOUND:
-            raise ObjectDoesNotExistError(object_name=obj.name,
-                                          value='', driver=self)
-
-        raise LibcloudError(value='Unexpected status code: %s' %
-                                  (response.status),
-                            driver=self)
-
-    def _save_object(self, response, obj, destination_path,
-                     overwrite_existing=False, delete_on_failure=True,
-                     chunk_size=None):
-        """
-        Save object to the provided path.
-
-        :param response: RawResponse instance.
-        :type response: :class:`RawResponse`
-
-        :param obj: Object instance.
-        :type obj: :class:`Object`
-
-        :param destination_path: Destination directory.
-        :type destination_path: ``str``
-
-        :param delete_on_failure: True to delete partially downloaded object if
-                                  the download fails.
-        :type delete_on_failure: ``bool``
-
-        :param overwrite_existing: True to overwrite a local path if it already
-                                   exists.
-        :type overwrite_existing: ``bool``
-
-        :param chunk_size: Optional chunk size
-            (defaults to ``libcloud.storage.base.CHUNK_SIZE``, 8kb)
-        :type chunk_size: ``int``
-
-        :return: ``True`` on success, ``False`` otherwise.
-        :rtype: ``bool``
-        """
-
-        chunk_size = chunk_size or CHUNK_SIZE
-
-        base_name = os.path.basename(destination_path)
-
-        if not base_name and not os.path.exists(destination_path):
-            raise LibcloudError(
-                value='Path %s does not exist' % (destination_path),
-                driver=self)
-
-        if not base_name:
-            file_path = pjoin(destination_path, obj.name)
-        else:
-            file_path = destination_path
-
-        if os.path.exists(file_path) and not overwrite_existing:
-            raise LibcloudError(
-                value='File %s already exists, but ' % (file_path) +
-                'overwrite_existing=False',
-                driver=self)
-
-        stream = libcloud.utils.files.read_in_chunks(response, chunk_size)
-
-        try:
-            data_read = next(stream)
-        except StopIteration:
-            # Empty response?
-            return False
-
-        bytes_transferred = 0
-
-        with open(file_path, 'wb') as file_handle:
-            while len(data_read) > 0:
-                file_handle.write(b(data_read))
-                bytes_transferred += len(data_read)
-
-                try:
-                    data_read = next(stream)
-                except StopIteration:
-                    data_read = ''
-
-        if int(obj.size) != int(bytes_transferred):
-            # Transfer failed, support retry?
-            if delete_on_failure:
-                try:
-                    os.unlink(file_path)
-                except Exception:
-                    pass
-
-            return False
-
-        return True
-
-    def _upload_object(self, object_name, content_type, upload_func,
-                       upload_func_kwargs, request_path, request_method='PUT',
-                       headers=None, file_path=None, iterator=None):
-        """
-        Helper function for setting common request headers and calling the
-        passed in callback which uploads an object.
-        """
-        headers = headers or {}
-
-        if file_path and not os.path.exists(file_path):
-            raise OSError('File %s does not exist' % (file_path))
-
-        if iterator is not None and not hasattr(iterator, 'next') and not \
-                hasattr(iterator, '__next__'):
-            raise AttributeError('iterator object must implement next() ' +
-                                 'method.')
-
-        if not content_type:
-            if file_path:
-                name = file_path
-            else:
-                name = object_name
-            content_type, _ = libcloud.utils.files.guess_file_mime_type(name)
-
-            if not content_type:
-                if self.strict_mode:
-                    raise AttributeError('File content-type could not be '
-                                         'guessed and no content_type value '
-                                         'is provided')
-                else:
-                    # Fallback to a content-type
-                    content_type = DEFAULT_CONTENT_TYPE
-
-        file_size = None
-
-        if iterator:
-            if self.supports_chunked_encoding:
-                headers['Transfer-Encoding'] = 'chunked'
-                upload_func_kwargs['chunked'] = True
-            else:
-                # Chunked transfer encoding is not supported. Need to buffer
-                # all the data in memory so we can determine file size.
-                iterator = libcloud.utils.files.read_in_chunks(
-                    iterator=iterator)
-                data = libcloud.utils.files.exhaust_iterator(iterator=iterator)
-
-                file_size = len(data)
-                upload_func_kwargs['data'] = data
-        else:
-            file_size = os.path.getsize(file_path)
-            upload_func_kwargs['chunked'] = False
-
-        if file_size is not None and 'Content-Length' not in headers:
-            headers['Content-Length'] = file_size
-
-        headers['Content-Type'] = content_type
-        response = self.connection.request(request_path,
-                                           method=request_method, data=None,
-                                           headers=headers, raw=True)
-
-        upload_func_kwargs['response'] = response
-        success, data_hash, bytes_transferred = upload_func(
-            **upload_func_kwargs)
-
-        if not success:
-            raise LibcloudError(
-                value='Object upload failed, Perhaps a timeout?', driver=self)
-
-        result_dict = {'response': response, 'data_hash': data_hash,
-                       'bytes_transferred': bytes_transferred}
-        return result_dict
-
-    def _upload_data(self, response, data, calculate_hash=True):
-        """
-        Upload data stored in a string.
-
-        :param response: RawResponse object.
-        :type response: :class:`RawResponse`
-
-        :param data: Data to upload.
-        :type data: ``str``
-
-        :param calculate_hash: True to calculate hash of the transferred data.
-                               (defaults to True).
-        :type calculate_hash: ``bool``
-
-        :return: First item is a boolean indicator of success, second
-                 one is the uploaded data MD5 hash and the third one
-                 is the number of transferred bytes.
-        :rtype: ``tuple``
-        """
-        bytes_transferred = 0
-        data_hash = None
-
-        if calculate_hash:
-            data_hash = self._get_hash_function()
-            data_hash.update(b(data))
-
-        try:
-            response.connection.connection.send(b(data))
-        except Exception:
-            # TODO: let this exception propagate
-            # Timeout, etc.
-            return False, None, bytes_transferred
-
-        bytes_transferred = len(data)
-
-        if calculate_hash:
-            data_hash = data_hash.hexdigest()
-
-        return True, data_hash, bytes_transferred
-
-    def _stream_data(self, response, iterator, chunked=False,
-                     calculate_hash=True, chunk_size=None, data=None):
-        """
-        Stream a data over an http connection.
-
-        :param response: RawResponse object.
-        :type response: :class:`RawResponse`
-
-        :param response: An object which implements an iterator interface
-                         or a File like object with read method.
-        :type iterator: :class:`object`
-
-        :param chunked: True if the chunked transfer encoding should be used
-                        (defaults to False).
-        :type chunked: ``bool``
-
-        :param calculate_hash: True to calculate hash of the transferred data.
-                               (defaults to True).
-        :type calculate_hash: ``bool``
-
-        :param chunk_size: Optional chunk size (defaults to ``CHUNK_SIZE``)
-        :type chunk_size: ``int``
-
-        :rtype: ``tuple``
-        :return: First item is a boolean indicator of success, second
-                 one is the uploaded data MD5 hash and the third one
-                 is the number of transferred bytes.
-        """
-
-        chunk_size = chunk_size or CHUNK_SIZE
-
-        data_hash = None
-        if calculate_hash:
-            data_hash = self._get_hash_function()
-
-        generator = libcloud.utils.files.read_in_chunks(iterator, chunk_size,
-                                                        fill_size=True)
-
-        bytes_transferred = 0
-        try:
-            chunk = next(generator)
-        except StopIteration:
-            # Special case when StopIteration is thrown on the first iteration
-            # create a 0-byte long object
-            chunk = ''
-            if chunked:
-                response.connection.connection.send(b('%X\r\n' %
-                                                      (len(chunk))))
-                response.connection.connection.send(chunk)
-                response.connection.connection.send(b('\r\n'))
-                response.connection.connection.send(b('0\r\n\r\n'))
-            else:
-                response.connection.connection.send(chunk)
-            return True, data_hash.hexdigest(), bytes_transferred
-
-        while len(chunk) > 0:
-            try:
-                if chunked:
-                    response.connection.connection.send(b('%X\r\n' %
-                                                          (len(chunk))))
-                    response.connection.connection.send(b(chunk))
-                    response.connection.connection.send(b('\r\n'))
-                else:
-                    response.connection.connection.send(b(chunk))
-            except Exception:
-                # TODO: let this exception propagate
-                # Timeout, etc.
-                return False, None, bytes_transferred
-
-            bytes_transferred += len(chunk)
-            if calculate_hash:
-                data_hash.update(b(chunk))
-
-            try:
-                chunk = next(generator)
-            except StopIteration:
-                chunk = ''
-
-        if chunked:
-            response.connection.connection.send(b('0\r\n\r\n'))
-
-        if calculate_hash:
-            data_hash = data_hash.hexdigest()
-
-        return True, data_hash, bytes_transferred
-
-    def _upload_file(self, response, file_path, chunked=False,
-                     calculate_hash=True):
-        """
-        Upload a file to the server.
-
-        :type response: :class:`RawResponse`
-        :param response: RawResponse object.
-
-        :type file_path: ``str``
-        :param file_path: Path to a local file.
-
-        :type iterator: :class:`object`
-        :param response: An object which implements an iterator interface (File
-                         object, etc.)
-
-        :rtype: ``tuple``
-        :return: First item is a boolean indicator of success, second
-                 one is the uploaded data MD5 hash and the third one
-                 is the number of transferred bytes.
-        """
-        with open(file_path, 'rb') as file_handle:
-            success, data_hash, bytes_transferred = (
-                self._stream_data(
-                    response=response,
-                    iterator=iter(file_handle),
-                    chunked=chunked,
-                    calculate_hash=calculate_hash))
-
-        return success, data_hash, bytes_transferred
-
-    def _get_hash_function(self):
-        """
-        Return instantiated hash function for the hash type supported by
-        the provider.
-        """
-        try:
-            func = getattr(hashlib, self.hash_type)()
-        except AttributeError:
-            raise RuntimeError('Invalid or unsupported hash type: %s' %
-                               (self.hash_type))
-
-        return func

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/__init__.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/__init__.py b/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/__init__.py
deleted file mode 100644
index fe8b04f..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/__init__.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-Drivers for working with different providers
-"""
-
-__all__ = [
-    'dummy',
-    'cloudfiles'
-]

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/atmos.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/atmos.py b/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/atmos.py
deleted file mode 100644
index c52be03..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/atmos.py
+++ /dev/null
@@ -1,472 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 sys
-import base64
-import hashlib
-import hmac
-import time
-
-from libcloud.utils.py3 import PY3
-from libcloud.utils.py3 import b
-from libcloud.utils.py3 import httplib
-from libcloud.utils.py3 import next
-from libcloud.utils.py3 import urlparse
-from libcloud.utils.py3 import urlencode
-from libcloud.utils.py3 import urlquote
-from libcloud.utils.py3 import urlunquote
-
-if PY3:
-    from io import FileIO as file
-
-from libcloud.utils.files import read_in_chunks, guess_file_mime_type
-from libcloud.common.base import ConnectionUserAndKey, XmlResponse
-from libcloud.common.types import LibcloudError
-
-from libcloud.storage.base import Object, Container, StorageDriver, CHUNK_SIZE
-from libcloud.storage.types import ContainerAlreadyExistsError, \
-    ContainerDoesNotExistError, ContainerIsNotEmptyError, \
-    ObjectDoesNotExistError
-
-
-def collapse(s):
-    return ' '.join([x for x in s.split(' ') if x])
-
-
-class AtmosError(LibcloudError):
-    def __init__(self, code, message, driver=None):
-        super(AtmosError, self).__init__(value=message, driver=driver)
-        self.code = code
-
-
-class AtmosResponse(XmlResponse):
-    def success(self):
-        return self.status in (httplib.OK, httplib.CREATED, httplib.NO_CONTENT,
-                               httplib.PARTIAL_CONTENT)
-
-    def parse_error(self):
-        tree = self.parse_body()
-
-        if tree is None:
-            return None
-
-        code = int(tree.find('Code').text)
-        message = tree.find('Message').text
-        raise AtmosError(code=code, message=message,
-                         driver=self.connection.driver)
-
-
-class AtmosConnection(ConnectionUserAndKey):
-    responseCls = AtmosResponse
-
-    def add_default_headers(self, headers):
-        headers['x-emc-uid'] = self.user_id
-        headers['Date'] = time.strftime('%a, %d %b %Y %H:%M:%S GMT',
-                                        time.gmtime())
-        headers['x-emc-date'] = headers['Date']
-
-        if 'Content-Type' not in headers:
-            headers['Content-Type'] = 'application/octet-stream'
-        if 'Accept' not in headers:
-            headers['Accept'] = '*/*'
-
-        return headers
-
-    def pre_connect_hook(self, params, headers):
-        headers['x-emc-signature'] = self._calculate_signature(params, headers)
-
-        return params, headers
-
-    def _calculate_signature(self, params, headers):
-        pathstring = urlunquote(self.action)
-        if pathstring.startswith(self.driver.path):
-            pathstring = pathstring[len(self.driver.path):]
-        if params:
-            if type(params) is dict:
-                params = list(params.items())
-            pathstring += '?' + urlencode(params)
-        pathstring = pathstring.lower()
-
-        xhdrs = [(k, v) for k, v in list(headers.items()) if
-                 k.startswith('x-emc-')]
-        xhdrs.sort(key=lambda x: x[0])
-
-        signature = [
-            self.method,
-            headers.get('Content-Type', ''),
-            headers.get('Range', ''),
-            headers.get('Date', ''),
-            pathstring,
-        ]
-        signature.extend([k + ':' + collapse(v) for k, v in xhdrs])
-        signature = '\n'.join(signature)
-        key = base64.b64decode(self.key)
-        signature = hmac.new(b(key), b(signature), hashlib.sha1).digest()
-        return base64.b64encode(b(signature)).decode('utf-8')
-
-
-class AtmosDriver(StorageDriver):
-    connectionCls = AtmosConnection
-
-    host = None
-    path = None
-    api_name = 'atmos'
-    supports_chunked_encoding = True
-    website = 'http://atmosonline.com/'
-    name = 'atmos'
-
-    DEFAULT_CDN_TTL = 60 * 60 * 24 * 7  # 1 week
-
-    def __init__(self, key, secret=None, secure=True, host=None, port=None):
-        host = host or self.host
-        super(AtmosDriver, self).__init__(key, secret, secure, host, port)
-
-    def iterate_containers(self):
-        result = self.connection.request(self._namespace_path(''))
-        entries = self._list_objects(result.object, object_type='directory')
-        for entry in entries:
-            extra = {
-                'object_id': entry['id']
-            }
-            yield Container(entry['name'], extra, self)
-
-    def get_container(self, container_name):
-        path = self._namespace_path(container_name) + '/?metadata/system'
-        try:
-            result = self.connection.request(path)
-        except AtmosError:
-            e = sys.exc_info()[1]
-            if e.code != 1003:
-                raise
-            raise ContainerDoesNotExistError(e, self, container_name)
-        meta = self._emc_meta(result)
-        extra = {
-            'object_id': meta['objectid']
-        }
-        return Container(container_name, extra, self)
-
-    def create_container(self, container_name):
-        path = self._namespace_path(container_name) + '/'
-        try:
-            self.connection.request(path, method='POST')
-        except AtmosError:
-            e = sys.exc_info()[1]
-            if e.code != 1016:
-                raise
-            raise ContainerAlreadyExistsError(e, self, container_name)
-        return self.get_container(container_name)
-
-    def delete_container(self, container):
-        try:
-            self.connection.request(self._namespace_path(container.name) + '/',
-                                    method='DELETE')
-        except AtmosError:
-            e = sys.exc_info()[1]
-            if e.code == 1003:
-                raise ContainerDoesNotExistError(e, self, container.name)
-            elif e.code == 1023:
-                raise ContainerIsNotEmptyError(e, self, container.name)
-        return True
-
-    def get_object(self, container_name, object_name):
-        container = self.get_container(container_name)
-        object_name_cleaned = self._clean_object_name(object_name)
-        path = self._namespace_path(container_name) + '/' + object_name_cleaned
-
-        try:
-            result = self.connection.request(path + '?metadata/system')
-            system_meta = self._emc_meta(result)
-
-            result = self.connection.request(path + '?metadata/user')
-            user_meta = self._emc_meta(result)
-        except AtmosError:
-            e = sys.exc_info()[1]
-            if e.code != 1003:
-                raise
-            raise ObjectDoesNotExistError(e, self, object_name)
-
-        last_modified = time.strptime(system_meta['mtime'],
-                                      '%Y-%m-%dT%H:%M:%SZ')
-        last_modified = time.strftime('%a, %d %b %Y %H:%M:%S GMT',
-                                      last_modified)
-        extra = {
-            'object_id': system_meta['objectid'],
-            'last_modified': last_modified
-        }
-        data_hash = user_meta.pop('md5', '')
-        return Object(object_name, int(system_meta['size']), data_hash, extra,
-                      user_meta, container, self)
-
-    def upload_object(self, file_path, container, object_name, extra=None,
-                      verify_hash=True):
-        upload_func = self._upload_file
-        upload_func_kwargs = {'file_path': file_path}
-        method = 'PUT'
-
-        extra = extra or {}
-        object_name_cleaned = self._clean_object_name(object_name)
-        request_path = self._namespace_path(container.name) + '/' +\
-            object_name_cleaned
-        content_type = extra.get('content_type', None)
-
-        try:
-            self.connection.request(request_path + '?metadata/system')
-        except AtmosError:
-            e = sys.exc_info()[1]
-            if e.code != 1003:
-                raise
-            method = 'POST'
-
-        result_dict = self._upload_object(
-            object_name=object_name,
-            content_type=content_type,
-            upload_func=upload_func,
-            upload_func_kwargs=upload_func_kwargs,
-            request_path=request_path,
-            request_method=method,
-            headers={}, file_path=file_path)
-
-        bytes_transferred = result_dict['bytes_transferred']
-
-        if extra is None:
-            meta_data = {}
-        else:
-            meta_data = extra.get('meta_data', {})
-        meta_data['md5'] = result_dict['data_hash']
-        user_meta = ', '.join([k + '=' + str(v) for k, v in
-                               list(meta_data.items())])
-        self.connection.request(request_path + '?metadata/user', method='POST',
-                                headers={'x-emc-meta': user_meta})
-        result = self.connection.request(request_path + '?metadata/system')
-        meta = self._emc_meta(result)
-        del meta_data['md5']
-        extra = {
-            'object_id': meta['objectid'],
-            'meta_data': meta_data,
-        }
-
-        return Object(object_name, bytes_transferred, result_dict['data_hash'],
-                      extra, meta_data, container, self)
-
-    def upload_object_via_stream(self, iterator, container, object_name,
-                                 extra=None):
-        if isinstance(iterator, file):
-            iterator = iter(iterator)
-
-        data_hash = hashlib.md5()
-        generator = read_in_chunks(iterator, CHUNK_SIZE, True)
-        bytes_transferred = 0
-        try:
-            chunk = next(generator)
-        except StopIteration:
-            chunk = ''
-
-        path = self._namespace_path(container.name + '/' + object_name)
-        method = 'PUT'
-
-        if extra is not None:
-            content_type = extra.get('content_type', None)
-        else:
-            content_type = None
-        if not content_type:
-            content_type, _ = guess_file_mime_type(object_name)
-
-            if not content_type:
-                raise AttributeError(
-                    'File content-type could not be guessed and' +
-                    ' no content_type value provided')
-
-        try:
-            self.connection.request(path + '?metadata/system')
-        except AtmosError:
-            e = sys.exc_info()[1]
-            if e.code != 1003:
-                raise
-            method = 'POST'
-
-        while True:
-            end = bytes_transferred + len(chunk) - 1
-            data_hash.update(b(chunk))
-            headers = {
-                'x-emc-meta': 'md5=' + data_hash.hexdigest(),
-                'Content-Type': content_type,
-            }
-
-            if len(chunk) > 0 and bytes_transferred > 0:
-                headers['Range'] = 'Bytes=%d-%d' % (bytes_transferred, end)
-                method = 'PUT'
-
-            result = self.connection.request(path, method=method, data=chunk,
-                                             headers=headers)
-            bytes_transferred += len(chunk)
-
-            try:
-                chunk = next(generator)
-            except StopIteration:
-                break
-            if len(chunk) == 0:
-                break
-
-        data_hash = data_hash.hexdigest()
-
-        if extra is None:
-            meta_data = {}
-        else:
-            meta_data = extra.get('meta_data', {})
-        meta_data['md5'] = data_hash
-        user_meta = ', '.join([k + '=' + str(v) for k, v in
-                               list(meta_data.items())])
-        self.connection.request(path + '?metadata/user', method='POST',
-                                headers={'x-emc-meta': user_meta})
-
-        result = self.connection.request(path + '?metadata/system')
-
-        meta = self._emc_meta(result)
-        extra = {
-            'object_id': meta['objectid'],
-            'meta_data': meta_data,
-        }
-
-        return Object(object_name, bytes_transferred, data_hash, extra,
-                      meta_data, container, self)
-
-    def download_object(self, obj, destination_path, overwrite_existing=False,
-                        delete_on_failure=True):
-        path = self._namespace_path(obj.container.name + '/' + obj.name)
-        response = self.connection.request(path, method='GET', raw=True)
-
-        return self._get_object(obj=obj, callback=self._save_object,
-                                response=response,
-                                callback_kwargs={
-                                    'obj': obj,
-                                    'response': response.response,
-                                    'destination_path': destination_path,
-                                    'overwrite_existing': overwrite_existing,
-                                    'delete_on_failure': delete_on_failure
-                                },
-                                success_status_code=httplib.OK)
-
-    def download_object_as_stream(self, obj, chunk_size=None):
-        path = self._namespace_path(obj.container.name + '/' + obj.name)
-        response = self.connection.request(path, method='GET', raw=True)
-
-        return self._get_object(obj=obj, callback=read_in_chunks,
-                                response=response,
-                                callback_kwargs={
-                                    'iterator': response.response,
-                                    'chunk_size': chunk_size
-                                },
-                                success_status_code=httplib.OK)
-
-    def delete_object(self, obj):
-        path = self._namespace_path(obj.container.name) + '/' +\
-            self._clean_object_name(obj.name)
-        try:
-            self.connection.request(path, method='DELETE')
-        except AtmosError:
-            e = sys.exc_info()[1]
-            if e.code != 1003:
-                raise
-            raise ObjectDoesNotExistError(e, self, obj.name)
-        return True
-
-    def enable_object_cdn(self, obj):
-        return True
-
-    def get_object_cdn_url(self, obj, expiry=None, use_object=False):
-        """
-        Return an object CDN URL.
-
-        :param obj: Object instance
-        :type  obj: :class:`Object`
-
-        :param expiry: Expiry
-        :type expiry: ``str``
-
-        :param use_object: Use object
-        :type use_object: ``bool``
-
-        :rtype: ``str``
-        """
-        if use_object:
-            path = '/rest/objects' + obj.meta_data['object_id']
-        else:
-            path = '/rest/namespace/' + obj.container.name + '/' + obj.name
-
-        if self.secure:
-            protocol = 'https'
-        else:
-            protocol = 'http'
-
-        expiry = str(expiry or int(time.time()) + self.DEFAULT_CDN_TTL)
-        params = [
-            ('uid', self.key),
-            ('expires', expiry),
-        ]
-        params.append(('signature', self._cdn_signature(path, params, expiry)))
-
-        params = urlencode(params)
-        path = self.path + path
-        return urlparse.urlunparse((protocol, self.host, path, '', params, ''))
-
-    def _cdn_signature(self, path, params, expiry):
-        key = base64.b64decode(self.secret)
-        signature = '\n'.join(['GET', path.lower(), self.key, expiry])
-        signature = hmac.new(key, signature, hashlib.sha1).digest()
-
-        return base64.b64encode(signature)
-
-    def _list_objects(self, tree, object_type=None):
-        listing = tree.find(self._emc_tag('DirectoryList'))
-        entries = []
-        for entry in listing.findall(self._emc_tag('DirectoryEntry')):
-            file_type = entry.find(self._emc_tag('FileType')).text
-            if object_type is not None and object_type != file_type:
-                continue
-            entries.append({
-                'id': entry.find(self._emc_tag('ObjectID')).text,
-                'type': file_type,
-                'name': entry.find(self._emc_tag('Filename')).text
-            })
-        return entries
-
-    def _clean_object_name(self, name):
-        return urlquote(name.encode('ascii'))
-
-    def _namespace_path(self, path):
-        return self.path + '/rest/namespace/' + urlquote(path.encode('ascii'))
-
-    def _object_path(self, object_id):
-        return self.path + '/rest/objects/' + object_id.encode('ascii')
-
-    @staticmethod
-    def _emc_tag(tag):
-        return '{http://www.emc.com/cos/}' + tag
-
-    def _emc_meta(self, response):
-        meta = response.headers.get('x-emc-meta', '')
-        if len(meta) == 0:
-            return {}
-        meta = meta.split(', ')
-        return dict([x.split('=', 1) for x in meta])
-
-    def iterate_container_objects(self, container):
-        headers = {'x-emc-include-meta': '1'}
-        path = self._namespace_path(container.name) + '/'
-        result = self.connection.request(path, headers=headers)
-        entries = self._list_objects(result.object, object_type='regular')
-        for entry in entries:
-            metadata = {'object_id': entry['id']}
-            yield Object(entry['name'], 0, '', {}, metadata, container, self)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/auroraobjects.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/auroraobjects.py b/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/auroraobjects.py
deleted file mode 100644
index 96e7313..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/auroraobjects.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from libcloud.common.types import LibcloudError
-from libcloud.storage.providers import Provider
-from libcloud.storage.drivers.s3 import BaseS3StorageDriver, BaseS3Connection
-
-__all__ = [
-    'AuroraObjectsStorageDriver'
-]
-
-AURORA_OBJECTS_EU_HOST = 'o.auroraobjects.eu'
-
-NO_CDN_SUPPORT_ERROR = 'CDN is not supported by AuroraObjects'
-
-
-class BaseAuroraObjectsConnection(BaseS3Connection):
-    host = AURORA_OBJECTS_EU_HOST
-
-
-class BaseAuroraObjectsStorageDriver(BaseS3StorageDriver):
-    type = Provider.AURORAOBJECTS
-    name = 'PCextreme AuroraObjects'
-    website = 'https://www.pcextreme.com/aurora/objects'
-
-
-class AuroraObjectsStorageDriver(BaseAuroraObjectsStorageDriver):
-    connectionCls = BaseAuroraObjectsConnection
-
-    def enable_container_cdn(self, *argv):
-        raise LibcloudError(NO_CDN_SUPPORT_ERROR, driver=self)
-
-    def enable_object_cdn(self, *argv):
-        raise LibcloudError(NO_CDN_SUPPORT_ERROR, driver=self)
-
-    def get_container_cdn_url(self, *argv):
-        raise LibcloudError(NO_CDN_SUPPORT_ERROR, driver=self)
-
-    def get_object_cdn_url(self, *argv):
-        raise LibcloudError(NO_CDN_SUPPORT_ERROR, driver=self)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/azure_blobs.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/azure_blobs.py b/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/azure_blobs.py
deleted file mode 100644
index 13d42f6..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/azure_blobs.py
+++ /dev/null
@@ -1,986 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from __future__ import with_statement
-
-import base64
-import os
-import binascii
-
-from xml.etree.ElementTree import Element, SubElement
-
-from libcloud.utils.py3 import PY3
-from libcloud.utils.py3 import httplib
-from libcloud.utils.py3 import urlquote
-from libcloud.utils.py3 import tostring
-from libcloud.utils.py3 import b
-
-from libcloud.utils.xml import fixxpath
-from libcloud.utils.files import read_in_chunks
-from libcloud.common.types import LibcloudError
-from libcloud.common.azure import AzureConnection
-
-from libcloud.storage.base import Object, Container, StorageDriver
-from libcloud.storage.types import ContainerIsNotEmptyError
-from libcloud.storage.types import ContainerAlreadyExistsError
-from libcloud.storage.types import InvalidContainerNameError
-from libcloud.storage.types import ContainerDoesNotExistError
-from libcloud.storage.types import ObjectDoesNotExistError
-from libcloud.storage.types import ObjectHashMismatchError
-
-if PY3:
-    from io import FileIO as file
-
-# Desired number of items in each response inside a paginated request
-RESPONSES_PER_REQUEST = 100
-
-# As per the Azure documentation, if the upload file size is less than
-# 64MB, we can upload it in a single request. However, in real life azure
-# servers seem to disconnect randomly after around 5 MB or 200s of upload.
-# So, it is better that for file sizes greater than 4MB, we upload it in
-# chunks.
-# Also, with large sizes, if we use a lease, the lease will timeout after
-# 60 seconds, but the upload might still be in progress. This can be
-# handled in code, but if we use chunked uploads, the lease renewal will
-# happen automatically.
-AZURE_BLOCK_MAX_SIZE = 4 * 1024 * 1024
-
-# Azure block blocks must be maximum 4MB
-# Azure page blobs must be aligned in 512 byte boundaries (4MB fits that)
-AZURE_CHUNK_SIZE = 4 * 1024 * 1024
-
-# Azure page blob must be aligned in 512 byte boundaries
-AZURE_PAGE_CHUNK_SIZE = 512
-
-# The time period (in seconds) for which a lease must be obtained.
-# If set as -1, we get an infinite lease, but that is a bad idea. If
-# after getting an infinite lease, there was an issue in releasing the
-# lease, the object will remain 'locked' forever, unless the lease is
-# released using the lease_id (which is not exposed to the user)
-AZURE_LEASE_PERIOD = 60
-
-AZURE_STORAGE_HOST_SUFFIX = 'blob.core.windows.net'
-
-
-class AzureBlobLease(object):
-    """
-    A class to help in leasing an azure blob and renewing the lease
-    """
-    def __init__(self, driver, object_path, use_lease):
-        """
-        :param driver: The Azure storage driver that is being used
-        :type driver: :class:`AzureStorageDriver`
-
-        :param object_path: The path of the object we need to lease
-        :type object_path: ``str``
-
-        :param use_lease: Indicates if we must take a lease or not
-        :type use_lease: ``bool``
-        """
-        self.object_path = object_path
-        self.driver = driver
-        self.use_lease = use_lease
-        self.lease_id = None
-        self.params = {'comp': 'lease'}
-
-    def renew(self):
-        """
-        Renew the lease if it is older than a predefined time period
-        """
-        if self.lease_id is None:
-            return
-
-        headers = {'x-ms-lease-action': 'renew',
-                   'x-ms-lease-id': self.lease_id,
-                   'x-ms-lease-duration': '60'}
-
-        response = self.driver.connection.request(self.object_path,
-                                                  headers=headers,
-                                                  params=self.params,
-                                                  method='PUT')
-
-        if response.status != httplib.OK:
-            raise LibcloudError('Unable to obtain lease', driver=self)
-
-    def update_headers(self, headers):
-        """
-        Update the lease id in the headers
-        """
-        if self.lease_id:
-            headers['x-ms-lease-id'] = self.lease_id
-
-    def __enter__(self):
-        if not self.use_lease:
-            return self
-
-        headers = {'x-ms-lease-action': 'acquire',
-                   'x-ms-lease-duration': '60'}
-
-        response = self.driver.connection.request(self.object_path,
-                                                  headers=headers,
-                                                  params=self.params,
-                                                  method='PUT')
-
-        if response.status == httplib.NOT_FOUND:
-            return self
-        elif response.status != httplib.CREATED:
-            raise LibcloudError('Unable to obtain lease', driver=self)
-
-        self.lease_id = response.headers['x-ms-lease-id']
-        return self
-
-    def __exit__(self, type, value, traceback):
-        if self.lease_id is None:
-            return
-
-        headers = {'x-ms-lease-action': 'release',
-                   'x-ms-lease-id': self.lease_id}
-        response = self.driver.connection.request(self.object_path,
-                                                  headers=headers,
-                                                  params=self.params,
-                                                  method='PUT')
-
-        if response.status != httplib.OK:
-            raise LibcloudError('Unable to release lease', driver=self)
-
-
-class AzureBlobsConnection(AzureConnection):
-    """
-    Represents a single connection to Azure Blobs
-    """
-
-
-class AzureBlobsStorageDriver(StorageDriver):
-    name = 'Microsoft Azure (blobs)'
-    website = 'http://windows.azure.com/'
-    connectionCls = AzureBlobsConnection
-    hash_type = 'md5'
-    supports_chunked_encoding = False
-    ex_blob_type = 'BlockBlob'
-
-    def __init__(self, key, secret=None, secure=True, host=None, port=None,
-                 **kwargs):
-        self._host_argument_set = bool(host)
-
-        # B64decode() this key and keep it, so that we don't have to do
-        # so for every request. Minor performance improvement
-        secret = base64.b64decode(b(secret))
-
-        super(AzureBlobsStorageDriver, self).__init__(key=key, secret=secret,
-                                                      secure=secure, host=host,
-                                                      port=port, **kwargs)
-
-    def _ex_connection_class_kwargs(self):
-        result = {}
-
-        # host argument has precedence
-        if not self._host_argument_set:
-            result['host'] = '%s.%s' % (self.key, AZURE_STORAGE_HOST_SUFFIX)
-
-        return result
-
-    def _xml_to_container(self, node):
-        """
-        Converts a container XML node to a container instance
-
-        :param node: XML info of the container
-        :type node: :class:`xml.etree.ElementTree.Element`
-
-        :return: A container instance
-        :rtype: :class:`Container`
-        """
-
-        name = node.findtext(fixxpath(xpath='Name'))
-        props = node.find(fixxpath(xpath='Properties'))
-        metadata = node.find(fixxpath(xpath='Metadata'))
-
-        extra = {
-            'url': node.findtext(fixxpath(xpath='Url')),
-            'last_modified': node.findtext(fixxpath(xpath='Last-Modified')),
-            'etag': props.findtext(fixxpath(xpath='Etag')),
-            'lease': {
-                'status': props.findtext(fixxpath(xpath='LeaseStatus')),
-                'state': props.findtext(fixxpath(xpath='LeaseState')),
-                'duration': props.findtext(fixxpath(xpath='LeaseDuration')),
-            },
-            'meta_data': {}
-        }
-
-        for meta in metadata.getchildren():
-            extra['meta_data'][meta.tag] = meta.text
-
-        return Container(name=name, extra=extra, driver=self)
-
-    def _response_to_container(self, container_name, response):
-        """
-        Converts a HTTP response to a container instance
-
-        :param container_name: Name of the container
-        :type container_name: ``str``
-
-        :param response: HTTP Response
-        :type node: L{}
-
-        :return: A container instance
-        :rtype: :class:`Container`
-        """
-
-        headers = response.headers
-        extra = {
-            'url': 'http://%s%s' % (response.connection.host,
-                                    response.connection.action),
-            'etag': headers['etag'],
-            'last_modified': headers['last-modified'],
-            'lease': {
-                'status': headers.get('x-ms-lease-status', None),
-                'state': headers.get('x-ms-lease-state', None),
-                'duration': headers.get('x-ms-lease-duration', None),
-            },
-            'meta_data': {}
-        }
-
-        for key, value in response.headers.items():
-            if key.startswith('x-ms-meta-'):
-                key = key.split('x-ms-meta-')[1]
-                extra['meta_data'][key] = value
-
-        return Container(name=container_name, extra=extra, driver=self)
-
-    def _xml_to_object(self, container, blob):
-        """
-        Converts a BLOB XML node to an object instance
-
-        :param container: Instance of the container holding the blob
-        :type: :class:`Container`
-
-        :param blob: XML info of the blob
-        :type blob: L{}
-
-        :return: An object instance
-        :rtype: :class:`Object`
-        """
-
-        name = blob.findtext(fixxpath(xpath='Name'))
-        props = blob.find(fixxpath(xpath='Properties'))
-        metadata = blob.find(fixxpath(xpath='Metadata'))
-        etag = props.findtext(fixxpath(xpath='Etag'))
-        size = int(props.findtext(fixxpath(xpath='Content-Length')))
-
-        extra = {
-            'content_type': props.findtext(fixxpath(xpath='Content-Type')),
-            'etag': etag,
-            'md5_hash': props.findtext(fixxpath(xpath='Content-MD5')),
-            'last_modified': props.findtext(fixxpath(xpath='Last-Modified')),
-            'url': blob.findtext(fixxpath(xpath='Url')),
-            'hash': props.findtext(fixxpath(xpath='Etag')),
-            'lease': {
-                'status': props.findtext(fixxpath(xpath='LeaseStatus')),
-                'state': props.findtext(fixxpath(xpath='LeaseState')),
-                'duration': props.findtext(fixxpath(xpath='LeaseDuration')),
-            },
-            'content_encoding': props.findtext(fixxpath(
-                                               xpath='Content-Encoding')),
-            'content_language': props.findtext(fixxpath(
-                                               xpath='Content-Language')),
-            'blob_type': props.findtext(fixxpath(xpath='BlobType'))
-        }
-
-        if extra['md5_hash']:
-            value = binascii.hexlify(base64.b64decode(b(extra['md5_hash'])))
-            value = value.decode('ascii')
-            extra['md5_hash'] = value
-
-        meta_data = {}
-        for meta in metadata.getchildren():
-            meta_data[meta.tag] = meta.text
-
-        return Object(name=name, size=size, hash=etag, meta_data=meta_data,
-                      extra=extra, container=container, driver=self)
-
-    def _response_to_object(self, object_name, container, response):
-        """
-        Converts a HTTP response to an object (from headers)
-
-        :param object_name: Name of the object
-        :type object_name: ``str``
-
-        :param container: Instance of the container holding the blob
-        :type: :class:`Container`
-
-        :param response: HTTP Response
-        :type node: L{}
-
-        :return: An object instance
-        :rtype: :class:`Object`
-        """
-
-        headers = response.headers
-        size = int(headers['content-length'])
-        etag = headers['etag']
-
-        extra = {
-            'url': 'http://%s%s' % (response.connection.host,
-                                    response.connection.action),
-            'etag': etag,
-            'md5_hash': headers.get('content-md5', None),
-            'content_type': headers.get('content-type', None),
-            'content_language': headers.get('content-language', None),
-            'content_encoding': headers.get('content-encoding', None),
-            'last_modified': headers['last-modified'],
-            'lease': {
-                'status': headers.get('x-ms-lease-status', None),
-                'state': headers.get('x-ms-lease-state', None),
-                'duration': headers.get('x-ms-lease-duration', None),
-            },
-            'blob_type': headers['x-ms-blob-type']
-        }
-
-        if extra['md5_hash']:
-            value = binascii.hexlify(base64.b64decode(b(extra['md5_hash'])))
-            value = value.decode('ascii')
-            extra['md5_hash'] = value
-
-        meta_data = {}
-        for key, value in response.headers.items():
-            if key.startswith('x-ms-meta-'):
-                key = key.split('x-ms-meta-')[1]
-                meta_data[key] = value
-
-        return Object(name=object_name, size=size, hash=etag, extra=extra,
-                      meta_data=meta_data, container=container, driver=self)
-
-    def iterate_containers(self):
-        """
-        @inherits: :class:`StorageDriver.iterate_containers`
-        """
-        params = {'comp': 'list',
-                  'maxresults': RESPONSES_PER_REQUEST,
-                  'include': 'metadata'}
-
-        while True:
-            response = self.connection.request('/', params)
-            if response.status != httplib.OK:
-                raise LibcloudError('Unexpected status code: %s' %
-                                    (response.status), driver=self)
-
-            body = response.parse_body()
-            containers = body.find(fixxpath(xpath='Containers'))
-            containers = containers.findall(fixxpath(xpath='Container'))
-
-            for container in containers:
-                yield self._xml_to_container(container)
-
-            params['marker'] = body.findtext('NextMarker')
-            if not params['marker']:
-                break
-
-    def iterate_container_objects(self, container):
-        """
-        @inherits: :class:`StorageDriver.iterate_container_objects`
-        """
-        params = {'restype': 'container',
-                  'comp': 'list',
-                  'maxresults': RESPONSES_PER_REQUEST,
-                  'include': 'metadata'}
-
-        container_path = self._get_container_path(container)
-
-        while True:
-            response = self.connection.request(container_path,
-                                               params=params)
-
-            if response.status == httplib.NOT_FOUND:
-                raise ContainerDoesNotExistError(value=None,
-                                                 driver=self,
-                                                 container_name=container.name)
-
-            elif response.status != httplib.OK:
-                raise LibcloudError('Unexpected status code: %s' %
-                                    (response.status), driver=self)
-
-            body = response.parse_body()
-            blobs = body.find(fixxpath(xpath='Blobs'))
-            blobs = blobs.findall(fixxpath(xpath='Blob'))
-
-            for blob in blobs:
-                yield self._xml_to_object(container, blob)
-
-            params['marker'] = body.findtext('NextMarker')
-            if not params['marker']:
-                break
-
-    def get_container(self, container_name):
-        """
-        @inherits: :class:`StorageDriver.get_container`
-        """
-        params = {'restype': 'container'}
-
-        container_path = '/%s' % (container_name)
-
-        response = self.connection.request(container_path, params=params,
-                                           method='HEAD')
-
-        if response.status == httplib.NOT_FOUND:
-            raise ContainerDoesNotExistError('Container %s does not exist' %
-                                             (container_name), driver=self,
-                                             container_name=container_name)
-        elif response.status != httplib.OK:
-            raise LibcloudError('Unexpected status code: %s' %
-                                (response.status), driver=self)
-
-        return self._response_to_container(container_name, response)
-
-    def get_object(self, container_name, object_name):
-        """
-        @inherits: :class:`StorageDriver.get_object`
-        """
-
-        container = self.get_container(container_name=container_name)
-        object_path = self._get_object_path(container, object_name)
-
-        response = self.connection.request(object_path, method='HEAD')
-
-        if response.status == httplib.OK:
-            obj = self._response_to_object(object_name, container, response)
-            return obj
-
-        raise ObjectDoesNotExistError(value=None, driver=self,
-                                      object_name=object_name)
-
-    def _get_container_path(self, container):
-        """
-        Return a container path
-
-        :param container: Container instance
-        :type  container: :class:`Container`
-
-        :return: A path for this container.
-        :rtype: ``str``
-        """
-        return '/%s' % (container.name)
-
-    def _get_object_path(self, container, object_name):
-        """
-        Return an object's CDN path.
-
-        :param container: Container instance
-        :type  container: :class:`Container`
-
-        :param object_name: Object name
-        :type  object_name: :class:`str`
-
-        :return: A  path for this object.
-        :rtype: ``str``
-        """
-        container_url = self._get_container_path(container)
-        object_name_cleaned = urlquote(object_name)
-        object_path = '%s/%s' % (container_url, object_name_cleaned)
-        return object_path
-
-    def create_container(self, container_name):
-        """
-        @inherits: :class:`StorageDriver.create_container`
-        """
-        params = {'restype': 'container'}
-
-        container_path = '/%s' % (container_name)
-        response = self.connection.request(container_path, params=params,
-                                           method='PUT')
-
-        if response.status == httplib.CREATED:
-            return self._response_to_container(container_name, response)
-        elif response.status == httplib.CONFLICT:
-            raise ContainerAlreadyExistsError(
-                value='Container with this name already exists. The name must '
-                      'be unique among all the containers in the system',
-                container_name=container_name, driver=self)
-        elif response.status == httplib.BAD_REQUEST:
-            raise InvalidContainerNameError(value='Container name contains ' +
-                                            'invalid characters.',
-                                            container_name=container_name,
-                                            driver=self)
-
-        raise LibcloudError('Unexpected status code: %s' % (response.status),
-                            driver=self)
-
-    def delete_container(self, container):
-        """
-        @inherits: :class:`StorageDriver.delete_container`
-        """
-        # Azure does not check if the container is empty. So, we will do
-        # a check to ensure that the behaviour is similar to other drivers
-        for obj in container.iterate_objects():
-            raise ContainerIsNotEmptyError(
-                value='Container must be empty before it can be deleted.',
-                container_name=container.name, driver=self)
-
-        params = {'restype': 'container'}
-        container_path = self._get_container_path(container)
-
-        # Note: All the objects in the container must be deleted first
-        response = self.connection.request(container_path, params=params,
-                                           method='DELETE')
-
-        if response.status == httplib.ACCEPTED:
-            return True
-        elif response.status == httplib.NOT_FOUND:
-            raise ContainerDoesNotExistError(value=None,
-                                             driver=self,
-                                             container_name=container.name)
-
-        return False
-
-    def download_object(self, obj, destination_path, overwrite_existing=False,
-                        delete_on_failure=True):
-        """
-        @inherits: :class:`StorageDriver.download_object`
-        """
-        obj_path = self._get_object_path(obj.container, obj.name)
-        response = self.connection.request(obj_path, raw=True, data=None)
-
-        return self._get_object(obj=obj, callback=self._save_object,
-                                response=response,
-                                callback_kwargs={
-                                    'obj': obj,
-                                    'response': response.response,
-                                    'destination_path': destination_path,
-                                    'overwrite_existing': overwrite_existing,
-                                    'delete_on_failure': delete_on_failure},
-                                success_status_code=httplib.OK)
-
-    def download_object_as_stream(self, obj, chunk_size=None):
-        """
-        @inherits: :class:`StorageDriver.download_object_as_stream`
-        """
-        obj_path = self._get_object_path(obj.container, obj.name)
-        response = self.connection.request(obj_path, raw=True, data=None)
-
-        return self._get_object(obj=obj, callback=read_in_chunks,
-                                response=response,
-                                callback_kwargs={'iterator': response.response,
-                                                 'chunk_size': chunk_size},
-                                success_status_code=httplib.OK)
-
-    def _upload_in_chunks(self, response, data, iterator, object_path,
-                          blob_type, lease, calculate_hash=True):
-        """
-        Uploads data from an interator in fixed sized chunks to S3
-
-        :param response: Response object from the initial POST request
-        :type response: :class:`RawResponse`
-
-        :param data: Any data from the initial POST request
-        :type data: ``str``
-
-        :param iterator: The generator for fetching the upload data
-        :type iterator: ``generator``
-
-        :param object_path: The path of the object to which we are uploading
-        :type object_name: ``str``
-
-        :param blob_type: The blob type being uploaded
-        :type blob_type: ``str``
-
-        :param lease: The lease object to be used for renewal
-        :type lease: :class:`AzureBlobLease`
-
-        :keyword calculate_hash: Indicates if we must calculate the data hash
-        :type calculate_hash: ``bool``
-
-        :return: A tuple of (status, checksum, bytes transferred)
-        :rtype: ``tuple``
-        """
-
-        # Get the upload id from the response xml
-        if response.status != httplib.CREATED:
-            raise LibcloudError('Error initializing upload. Code: %d' %
-                                (response.status), driver=self)
-
-        data_hash = None
-        if calculate_hash:
-            data_hash = self._get_hash_function()
-
-        bytes_transferred = 0
-        count = 1
-        chunks = []
-        headers = {}
-
-        lease.update_headers(headers)
-
-        if blob_type == 'BlockBlob':
-            params = {'comp': 'block'}
-        else:
-            params = {'comp': 'page'}
-
-        # Read the input data in chunk sizes suitable for AWS
-        for data in read_in_chunks(iterator, AZURE_CHUNK_SIZE):
-            data = b(data)
-            content_length = len(data)
-            offset = bytes_transferred
-            bytes_transferred += content_length
-
-            if calculate_hash:
-                data_hash.update(data)
-
-            chunk_hash = self._get_hash_function()
-            chunk_hash.update(data)
-            chunk_hash = base64.b64encode(b(chunk_hash.digest()))
-
-            headers['Content-MD5'] = chunk_hash.decode('utf-8')
-            headers['Content-Length'] = content_length
-
-            if blob_type == 'BlockBlob':
-                # Block id can be any unique string that is base64 encoded
-                # A 10 digit number can hold the max value of 50000 blocks
-                # that are allowed for azure
-                block_id = base64.b64encode(b('%10d' % (count)))
-                block_id = block_id.decode('utf-8')
-                params['blockid'] = block_id
-
-                # Keep this data for a later commit
-                chunks.append(block_id)
-            else:
-                headers['x-ms-page-write'] = 'update'
-                headers['x-ms-range'] = 'bytes=%d-%d' % \
-                    (offset, (bytes_transferred - 1))
-
-            # Renew lease before updating
-            lease.renew()
-
-            resp = self.connection.request(object_path, method='PUT',
-                                           data=data, headers=headers,
-                                           params=params)
-
-            if resp.status != httplib.CREATED:
-                resp.parse_error()
-                raise LibcloudError('Error uploading chunk %d. Code: %d' %
-                                    (count, resp.status), driver=self)
-
-            count += 1
-
-        if calculate_hash:
-            data_hash = data_hash.hexdigest()
-
-        if blob_type == 'BlockBlob':
-            self._commit_blocks(object_path, chunks, lease)
-
-        # The Azure service does not return a hash immediately for
-        # chunked uploads. It takes some time for the data to get synced
-        response.headers['content-md5'] = None
-
-        return (True, data_hash, bytes_transferred)
-
-    def _commit_blocks(self, object_path, chunks, lease):
-        """
-        Makes a final commit of the data.
-
-        :param object_path: Server side object path.
-        :type object_path: ``str``
-
-        :param upload_id: A list of (chunk_number, chunk_hash) tuples.
-        :type upload_id: ``list``
-        """
-
-        root = Element('BlockList')
-
-        for block_id in chunks:
-            part = SubElement(root, 'Uncommitted')
-            part.text = str(block_id)
-
-        data = tostring(root)
-        params = {'comp': 'blocklist'}
-        headers = {}
-
-        lease.update_headers(headers)
-        lease.renew()
-
-        response = self.connection.request(object_path, data=data,
-                                           params=params, headers=headers,
-                                           method='PUT')
-
-        if response.status != httplib.CREATED:
-            raise LibcloudError('Error in blocklist commit', driver=self)
-
-    def _check_values(self, blob_type, object_size):
-        """
-        Checks if extension arguments are valid
-
-        :param blob_type: The blob type that is being uploaded
-        :type blob_type: ``str``
-
-        :param object_size: The (max) size of the object being uploaded
-        :type object_size: ``int``
-        """
-
-        if blob_type not in ['BlockBlob', 'PageBlob']:
-            raise LibcloudError('Invalid blob type', driver=self)
-
-        if blob_type == 'PageBlob':
-            if not object_size:
-                raise LibcloudError('Max blob size is mandatory for page blob',
-                                    driver=self)
-
-            if object_size % AZURE_PAGE_CHUNK_SIZE:
-                raise LibcloudError('Max blob size is not aligned to '
-                                    'page boundary', driver=self)
-
-    def upload_object(self, file_path, container, object_name, extra=None,
-                      verify_hash=True, ex_blob_type=None, ex_use_lease=False):
-        """
-        Upload an object currently located on a disk.
-
-        @inherits: :class:`StorageDriver.upload_object`
-
-        :param ex_blob_type: Storage class
-        :type ex_blob_type: ``str``
-
-        :param ex_use_lease: Indicates if we must take a lease before upload
-        :type ex_use_lease: ``bool``
-        """
-
-        if ex_blob_type is None:
-            ex_blob_type = self.ex_blob_type
-
-        # Get the size of the file
-        file_size = os.stat(file_path).st_size
-
-        # The presumed size of the object
-        object_size = file_size
-
-        self._check_values(ex_blob_type, file_size)
-
-        with file(file_path, 'rb') as file_handle:
-            iterator = iter(file_handle)
-
-            # If size is greater than 64MB or type is Page, upload in chunks
-            if ex_blob_type == 'PageBlob' or file_size > AZURE_BLOCK_MAX_SIZE:
-                # For chunked upload of block blobs, the initial size must
-                # be 0.
-                if ex_blob_type == 'BlockBlob':
-                    object_size = None
-
-                object_path = self._get_object_path(container, object_name)
-
-                upload_func = self._upload_in_chunks
-                upload_func_kwargs = {'iterator': iterator,
-                                      'object_path': object_path,
-                                      'blob_type': ex_blob_type,
-                                      'lease': None}
-            else:
-                upload_func = self._stream_data
-                upload_func_kwargs = {'iterator': iterator,
-                                      'chunked': False,
-                                      'calculate_hash': verify_hash}
-
-            return self._put_object(container=container,
-                                    object_name=object_name,
-                                    object_size=object_size,
-                                    upload_func=upload_func,
-                                    upload_func_kwargs=upload_func_kwargs,
-                                    file_path=file_path, extra=extra,
-                                    verify_hash=verify_hash,
-                                    blob_type=ex_blob_type,
-                                    use_lease=ex_use_lease)
-
-    def upload_object_via_stream(self, iterator, container, object_name,
-                                 verify_hash=False, extra=None,
-                                 ex_use_lease=False, ex_blob_type=None,
-                                 ex_page_blob_size=None):
-        """
-        @inherits: :class:`StorageDriver.upload_object_via_stream`
-
-        :param ex_blob_type: Storage class
-        :type ex_blob_type: ``str``
-
-        :param ex_page_blob_size: The maximum size to which the
-            page blob can grow to
-        :type ex_page_blob_size: ``int``
-
-        :param ex_use_lease: Indicates if we must take a lease before upload
-        :type ex_use_lease: ``bool``
-        """
-
-        if ex_blob_type is None:
-            ex_blob_type = self.ex_blob_type
-
-        self._check_values(ex_blob_type, ex_page_blob_size)
-
-        object_path = self._get_object_path(container, object_name)
-
-        upload_func = self._upload_in_chunks
-        upload_func_kwargs = {'iterator': iterator,
-                              'object_path': object_path,
-                              'blob_type': ex_blob_type,
-                              'lease': None}
-
-        return self._put_object(container=container,
-                                object_name=object_name,
-                                object_size=ex_page_blob_size,
-                                upload_func=upload_func,
-                                upload_func_kwargs=upload_func_kwargs,
-                                extra=extra, verify_hash=verify_hash,
-                                blob_type=ex_blob_type,
-                                use_lease=ex_use_lease)
-
-    def delete_object(self, obj):
-        """
-        @inherits: :class:`StorageDriver.delete_object`
-        """
-        object_path = self._get_object_path(obj.container, obj.name)
-        response = self.connection.request(object_path, method='DELETE')
-
-        if response.status == httplib.ACCEPTED:
-            return True
-        elif response.status == httplib.NOT_FOUND:
-            raise ObjectDoesNotExistError(value=None, driver=self,
-                                          object_name=obj.name)
-
-        return False
-
-    def _update_metadata(self, headers, meta_data):
-        """
-        Update the given metadata in the headers
-
-        :param headers: The headers dictionary to be updated
-        :type headers: ``dict``
-
-        :param meta_data: Metadata key value pairs
-        :type meta_data: ``dict``
-        """
-        for key, value in list(meta_data.items()):
-            key = 'x-ms-meta-%s' % (key)
-            headers[key] = value
-
-    def _prepare_upload_headers(self, object_name, object_size,
-                                extra, meta_data, blob_type):
-        """
-        Prepare headers for uploading an object
-
-        :param object_name: The full name of the object being updated
-        :type object_name: ``str``
-
-        :param object_size: The size of the object. In case of PageBlobs,
-            this indicates the maximum size the blob can grow to
-        :type object_size: ``int``
-
-        :param extra: Extra control data for the upload
-        :type extra: ``dict``
-
-        :param meta_data: Metadata key value pairs
-        :type meta_data: ``dict``
-
-        :param blob_type: Page or Block blob type
-        :type blob_type: ``str``
-        """
-        headers = {}
-
-        if blob_type is None:
-            blob_type = self.ex_blob_type
-
-        headers['x-ms-blob-type'] = blob_type
-
-        self._update_metadata(headers, meta_data)
-
-        if object_size is not None:
-            headers['Content-Length'] = object_size
-
-        if blob_type == 'PageBlob':
-            headers['Content-Length'] = 0
-            headers['x-ms-blob-content-length'] = object_size
-
-        return headers
-
-    def _put_object(self, container, object_name, object_size, upload_func,
-                    upload_func_kwargs, file_path=None, extra=None,
-                    verify_hash=True, blob_type=None, use_lease=False):
-        """
-        Control function that does the real job of uploading data to a blob
-        """
-        extra = extra or {}
-        meta_data = extra.get('meta_data', {})
-        content_type = extra.get('content_type', None)
-
-        headers = self._prepare_upload_headers(object_name, object_size,
-                                               extra, meta_data, blob_type)
-
-        object_path = self._get_object_path(container, object_name)
-
-        # Get a lease if required and do the operations
-        with AzureBlobLease(self, object_path, use_lease) as lease:
-            if 'lease' in upload_func_kwargs:
-                upload_func_kwargs['lease'] = lease
-
-            lease.update_headers(headers)
-
-            iterator = iter('')
-            result_dict = self._upload_object(object_name, content_type,
-                                              upload_func, upload_func_kwargs,
-                                              object_path, headers=headers,
-                                              file_path=file_path,
-                                              iterator=iterator)
-
-            response = result_dict['response']
-            bytes_transferred = result_dict['bytes_transferred']
-            data_hash = result_dict['data_hash']
-            headers = response.headers
-            response = response.response
-
-        if response.status != httplib.CREATED:
-            raise LibcloudError(
-                'Unexpected status code, status_code=%s' % (response.status),
-                driver=self)
-
-        server_hash = headers['content-md5']
-
-        if server_hash:
-            server_hash = binascii.hexlify(base64.b64decode(b(server_hash)))
-            server_hash = server_hash.decode('utf-8')
-        else:
-            # TODO: HACK - We could poll the object for a while and get
-            # the hash
-            pass
-
-        if (verify_hash and server_hash and data_hash != server_hash):
-            raise ObjectHashMismatchError(
-                value='MD5 hash checksum does not match',
-                object_name=object_name, driver=self)
-
-        return Object(name=object_name, size=bytes_transferred,
-                      hash=headers['etag'], extra=None,
-                      meta_data=meta_data, container=container,
-                      driver=self)
-
-    def ex_set_object_metadata(self, obj, meta_data):
-        """
-        Set metadata for an object
-
-        :param obj: The blob object
-        :type obj: :class:`Object`
-
-        :param meta_data: Metadata key value pairs
-        :type meta_data: ``dict``
-        """
-        object_path = self._get_object_path(obj.container, obj.name)
-        params = {'comp': 'metadata'}
-        headers = {}
-
-        self._update_metadata(headers, meta_data)
-
-        response = self.connection.request(object_path, method='PUT',
-                                           params=params,
-                                           headers=headers)
-
-        if response.status != httplib.OK:
-            response.parse_error('Setting metadata')


[47/56] [abbrv] libcloud git commit: Force expires_on as tick int

Posted by an...@apache.org.
Force expires_on as tick int


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/dd0e3962
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/dd0e3962
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/dd0e3962

Branch: refs/heads/trunk
Commit: dd0e396246a1305079d6c75e6189e4f70626ac9e
Parents: c705fcf
Author: anthony-shaw <an...@apache.org>
Authored: Thu Apr 14 21:47:32 2016 +1000
Committer: anthony-shaw <an...@apache.org>
Committed: Thu Apr 14 21:47:32 2016 +1000

----------------------------------------------------------------------
 libcloud/common/azure_arm.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/dd0e3962/libcloud/common/azure_arm.py
----------------------------------------------------------------------
diff --git a/libcloud/common/azure_arm.py b/libcloud/common/azure_arm.py
index 2611921..0021682 100644
--- a/libcloud/common/azure_arm.py
+++ b/libcloud/common/azure_arm.py
@@ -115,7 +115,7 @@ class AzureResourceManagementConnection(ConnectionUserAndKey):
 
         # Log in again if the token has expired or is going to expire soon
         # (next 5 minutes).
-        if (time.time() + 300) >= self.expires_on:
+        if (time.time() + 300) >= int(self.expires_on):
             self.get_token_from_credentials(self)
 
         return super(AzureResourceManagementConnection, self) \


[21/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/openstack.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/openstack.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/openstack.py
deleted file mode 100644
index 1fa3479..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/openstack.py
+++ /dev/null
@@ -1,2528 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-OpenStack driver
-"""
-from libcloud.utils.iso8601 import parse_date
-
-try:
-    import simplejson as json
-except ImportError:
-    import json
-
-try:
-    from lxml import etree as ET
-except ImportError:
-    from xml.etree import ElementTree as ET
-
-import warnings
-import base64
-
-from libcloud.utils.py3 import httplib
-from libcloud.utils.py3 import b
-from libcloud.utils.py3 import next
-from libcloud.utils.py3 import urlparse
-
-
-from libcloud.common.openstack import OpenStackBaseConnection
-from libcloud.common.openstack import OpenStackDriverMixin
-from libcloud.common.openstack import OpenStackException
-from libcloud.common.openstack import OpenStackResponse
-from libcloud.utils.networking import is_public_subnet
-from libcloud.compute.base import NodeSize, NodeImage
-from libcloud.compute.base import (NodeDriver, Node, NodeLocation,
-                                   StorageVolume, VolumeSnapshot)
-from libcloud.compute.base import KeyPair
-from libcloud.compute.types import NodeState, StorageVolumeState, Provider, \
-    VolumeSnapshotState
-from libcloud.pricing import get_size_price
-from libcloud.utils.xml import findall
-
-__all__ = [
-    'OpenStack_1_0_Response',
-    'OpenStack_1_0_Connection',
-    'OpenStack_1_0_NodeDriver',
-    'OpenStack_1_0_SharedIpGroup',
-    'OpenStack_1_0_NodeIpAddresses',
-    'OpenStack_1_1_Response',
-    'OpenStack_1_1_Connection',
-    'OpenStack_1_1_NodeDriver',
-    'OpenStack_1_1_FloatingIpPool',
-    'OpenStack_1_1_FloatingIpAddress',
-    'OpenStackNodeDriver'
-]
-
-ATOM_NAMESPACE = "http://www.w3.org/2005/Atom"
-
-DEFAULT_API_VERSION = '1.1'
-
-
-class OpenStackComputeConnection(OpenStackBaseConnection):
-    # default config for http://devstack.org/
-    service_type = 'compute'
-    service_name = 'nova'
-    service_region = 'RegionOne'
-
-
-class OpenStackNodeDriver(NodeDriver, OpenStackDriverMixin):
-    """
-    Base OpenStack node driver. Should not be used directly.
-    """
-    api_name = 'openstack'
-    name = 'OpenStack'
-    website = 'http://openstack.org/'
-
-    NODE_STATE_MAP = {
-        'BUILD': NodeState.PENDING,
-        'REBUILD': NodeState.PENDING,
-        'ACTIVE': NodeState.RUNNING,
-        'SUSPENDED': NodeState.STOPPED,
-        'SHUTOFF': NodeState.STOPPED,
-        'DELETED': NodeState.TERMINATED,
-        'QUEUE_RESIZE': NodeState.PENDING,
-        'PREP_RESIZE': NodeState.PENDING,
-        'VERIFY_RESIZE': NodeState.RUNNING,
-        'PASSWORD': NodeState.PENDING,
-        'RESCUE': NodeState.PENDING,
-        'REBOOT': NodeState.REBOOTING,
-        'HARD_REBOOT': NodeState.REBOOTING,
-        'SHARE_IP': NodeState.PENDING,
-        'SHARE_IP_NO_CONFIG': NodeState.PENDING,
-        'DELETE_IP': NodeState.PENDING,
-        'ERROR': NodeState.ERROR,
-        'UNKNOWN': NodeState.UNKNOWN
-    }
-
-    # http://developer.openstack.org/api-ref-blockstorage-v2.html#volumes-v2
-    VOLUME_STATE_MAP = {
-        'creating': StorageVolumeState.CREATING,
-        'available': StorageVolumeState.AVAILABLE,
-        'attaching': StorageVolumeState.ATTACHING,
-        'in-use': StorageVolumeState.INUSE,
-        'deleting': StorageVolumeState.DELETING,
-        'error': StorageVolumeState.ERROR,
-        'error_deleting': StorageVolumeState.ERROR,
-        'backing-up': StorageVolumeState.BACKUP,
-        'restoring-backup': StorageVolumeState.BACKUP,
-        'error_restoring': StorageVolumeState.ERROR,
-        'error_extending': StorageVolumeState.ERROR,
-    }
-
-    # http://developer.openstack.org/api-ref-blockstorage-v2.html#ext-backups-v2
-    SNAPSHOT_STATE_MAP = {
-        'creating': VolumeSnapshotState.CREATING,
-        'available': VolumeSnapshotState.AVAILABLE,
-        'deleting': VolumeSnapshotState.DELETING,
-        'error': VolumeSnapshotState.ERROR,
-        'restoring': VolumeSnapshotState.RESTORING,
-        'error_restoring': VolumeSnapshotState.ERROR
-    }
-
-    def __new__(cls, key, secret=None, secure=True, host=None, port=None,
-                api_version=DEFAULT_API_VERSION, **kwargs):
-        if cls is OpenStackNodeDriver:
-            if api_version == '1.0':
-                cls = OpenStack_1_0_NodeDriver
-            elif api_version == '1.1':
-                cls = OpenStack_1_1_NodeDriver
-            else:
-                raise NotImplementedError(
-                    "No OpenStackNodeDriver found for API version %s" %
-                    (api_version))
-        return super(OpenStackNodeDriver, cls).__new__(cls)
-
-    def __init__(self, *args, **kwargs):
-        OpenStackDriverMixin.__init__(self, **kwargs)
-        super(OpenStackNodeDriver, self).__init__(*args, **kwargs)
-
-    def destroy_node(self, node):
-        uri = '/servers/%s' % (node.id)
-        resp = self.connection.request(uri, method='DELETE')
-        # The OpenStack and Rackspace documentation both say this API will
-        # return a 204, but in-fact, everyone everywhere agrees it actually
-        # returns a 202, so we are going to accept either, and someday,
-        # someone will fix either the implementation or the documentation to
-        # agree.
-        return resp.status in (httplib.NO_CONTENT, httplib.ACCEPTED)
-
-    def reboot_node(self, node):
-        return self._reboot_node(node, reboot_type='HARD')
-
-    def list_nodes(self, ex_all_tenants=False):
-        """
-        List the nodes in a tenant
-
-        :param ex_all_tenants: List nodes for all the tenants. Note: Your user
-                               must have admin privileges for this
-                               functionality to work.
-        :type ex_all_tenants: ``bool``
-        """
-        params = {}
-        if ex_all_tenants:
-            params = {'all_tenants': 1}
-        return self._to_nodes(
-            self.connection.request('/servers/detail', params=params).object)
-
-    def create_volume(self, size, name, location=None, snapshot=None,
-                      ex_volume_type=None):
-        """
-        Create a new volume.
-
-        :param size: Size of volume in gigabytes (required)
-        :type size: ``int``
-
-        :param name: Name of the volume to be created
-        :type name: ``str``
-
-        :param location: Which data center to create a volume in. If
-                               empty, undefined behavior will be selected.
-                               (optional)
-        :type location: :class:`.NodeLocation`
-
-        :param snapshot:  Snapshot from which to create the new
-                          volume.  (optional)
-        :type snapshot:  :class:`.VolumeSnapshot`
-
-        :param ex_volume_type: What kind of volume to create.
-                            (optional)
-        :type ex_volume_type: ``str``
-
-        :return: The newly created volume.
-        :rtype: :class:`StorageVolume`
-        """
-        volume = {
-            'display_name': name,
-            'display_description': name,
-            'size': size,
-            'volume_type': ex_volume_type,
-            'metadata': {
-                'contents': name,
-            },
-            'availability_zone': location
-        }
-
-        if snapshot:
-            volume['snapshot_id'] = snapshot.id
-
-        resp = self.connection.request('/os-volumes',
-                                       method='POST',
-                                       data={'volume': volume})
-        return self._to_volume(resp.object)
-
-    def destroy_volume(self, volume):
-        return self.connection.request('/os-volumes/%s' % volume.id,
-                                       method='DELETE').success()
-
-    def attach_volume(self, node, volume, device="auto"):
-        # when "auto" or None is provided for device, openstack will let
-        # the guest OS pick the next available device (fi. /dev/vdb)
-        return self.connection.request(
-            '/servers/%s/os-volume_attachments' % node.id,
-            method='POST',
-            data={
-                'volumeAttachment': {
-                    'volumeId': volume.id,
-                    'device': device,
-                }
-            }).success()
-
-    def detach_volume(self, volume, ex_node=None):
-        # when ex_node is not provided, volume is detached from all nodes
-        failed_nodes = []
-        for attachment in volume.extra['attachments']:
-            if not ex_node or ex_node.id == attachment['serverId']:
-                response = self.connection.request(
-                    '/servers/%s/os-volume_attachments/%s' %
-                    (attachment['serverId'], attachment['id']),
-                    method='DELETE')
-
-                if not response.success():
-                    failed_nodes.append(attachment['serverId'])
-        if failed_nodes:
-            raise OpenStackException(
-                'detach_volume failed for nodes with id: %s' %
-                ', '.join(failed_nodes), 500, self
-            )
-        return True
-
-    def list_volumes(self):
-        return self._to_volumes(
-            self.connection.request('/os-volumes').object)
-
-    def ex_get_volume(self, volumeId):
-        return self._to_volume(
-            self.connection.request('/os-volumes/%s' % volumeId).object)
-
-    def list_images(self, location=None, ex_only_active=True):
-        """
-        Lists all active images
-
-        @inherits: :class:`NodeDriver.list_images`
-
-        :param ex_only_active: True if list only active
-        :type ex_only_active: ``bool``
-
-        """
-        return self._to_images(
-            self.connection.request('/images/detail').object, ex_only_active)
-
-    def get_image(self, image_id):
-        """
-        Get an image based on an image_id
-
-        @inherits: :class:`NodeDriver.get_image`
-
-        :param image_id: Image identifier
-        :type image_id: ``str``
-
-        :return: A NodeImage object
-        :rtype: :class:`NodeImage`
-
-        """
-        return self._to_image(self.connection.request(
-            '/images/%s' % (image_id,)).object['image'])
-
-    def list_sizes(self, location=None):
-        return self._to_sizes(
-            self.connection.request('/flavors/detail').object)
-
-    def list_locations(self):
-        return [NodeLocation(0, '', '', self)]
-
-    def _ex_connection_class_kwargs(self):
-        return self.openstack_connection_kwargs()
-
-    def ex_get_node_details(self, node_id):
-        """
-        Lists details of the specified server.
-
-        :param       node_id: ID of the node which should be used
-        :type        node_id: ``str``
-
-        :rtype: :class:`Node`
-        """
-        # @TODO: Remove this if in 0.6
-        if isinstance(node_id, Node):
-            node_id = node_id.id
-
-        uri = '/servers/%s' % (node_id)
-        resp = self.connection.request(uri, method='GET')
-        if resp.status == httplib.NOT_FOUND:
-            return None
-
-        return self._to_node_from_obj(resp.object)
-
-    def ex_soft_reboot_node(self, node):
-        """
-        Soft reboots the specified server
-
-        :param      node:  node
-        :type       node: :class:`Node`
-
-        :rtype: ``bool``
-        """
-        return self._reboot_node(node, reboot_type='SOFT')
-
-    def ex_hard_reboot_node(self, node):
-        """
-        Hard reboots the specified server
-
-        :param      node:  node
-        :type       node: :class:`Node`
-
-        :rtype: ``bool``
-        """
-        return self._reboot_node(node, reboot_type='HARD')
-
-
-class OpenStackNodeSize(NodeSize):
-    """
-    NodeSize class for the OpenStack.org driver.
-
-    Following the example of OpenNebula.org driver
-    and following guidelines:
-    https://issues.apache.org/jira/browse/LIBCLOUD-119
-    """
-
-    def __init__(self, id, name, ram, disk, bandwidth, price, driver,
-                 vcpus=None, ephemeral_disk=None, swap=None, extra=None):
-        super(OpenStackNodeSize, self).__init__(id=id, name=name, ram=ram,
-                                                disk=disk,
-                                                bandwidth=bandwidth,
-                                                price=price, driver=driver)
-        self.vcpus = vcpus
-        self.ephemeral_disk = ephemeral_disk
-        self.swap = swap
-        self.extra = extra
-
-    def __repr__(self):
-        return (('<OpenStackNodeSize: id=%s, name=%s, ram=%s, disk=%s, '
-                 'bandwidth=%s, price=%s, driver=%s, vcpus=%s,  ...>')
-                % (self.id, self.name, self.ram, self.disk, self.bandwidth,
-                   self.price, self.driver.name, self.vcpus))
-
-
-class OpenStack_1_0_Response(OpenStackResponse):
-    def __init__(self, *args, **kwargs):
-        # done because of a circular reference from
-        # NodeDriver -> Connection -> Response
-        self.node_driver = OpenStack_1_0_NodeDriver
-        super(OpenStack_1_0_Response, self).__init__(*args, **kwargs)
-
-
-class OpenStack_1_0_Connection(OpenStackComputeConnection):
-    responseCls = OpenStack_1_0_Response
-    default_content_type = 'application/xml; charset=UTF-8'
-    accept_format = 'application/xml'
-    XML_NAMESPACE = 'http://docs.rackspacecloud.com/servers/api/v1.0'
-
-
-class OpenStack_1_0_NodeDriver(OpenStackNodeDriver):
-    """
-    OpenStack node driver.
-
-    Extra node attributes:
-        - password: root password, available after create.
-        - hostId: represents the host your cloud server runs on
-        - imageId: id of image
-        - flavorId: id of flavor
-    """
-    connectionCls = OpenStack_1_0_Connection
-    type = Provider.OPENSTACK
-
-    features = {'create_node': ['generates_password']}
-
-    def __init__(self, *args, **kwargs):
-        self._ex_force_api_version = str(kwargs.pop('ex_force_api_version',
-                                                    None))
-        self.XML_NAMESPACE = self.connectionCls.XML_NAMESPACE
-        super(OpenStack_1_0_NodeDriver, self).__init__(*args, **kwargs)
-
-    def _to_images(self, object, ex_only_active):
-        images = []
-        for image in findall(object, 'image', self.XML_NAMESPACE):
-            if ex_only_active and image.get('status') != 'ACTIVE':
-                continue
-            images.append(self._to_image(image))
-
-        return images
-
-    def _to_image(self, element):
-        return NodeImage(id=element.get('id'),
-                         name=element.get('name'),
-                         driver=self.connection.driver,
-                         extra={'updated': element.get('updated'),
-                                'created': element.get('created'),
-                                'status': element.get('status'),
-                                'serverId': element.get('serverId'),
-                                'progress': element.get('progress'),
-                                'minDisk': element.get('minDisk'),
-                                'minRam': element.get('minRam')
-                                }
-                         )
-
-    def _change_password_or_name(self, node, name=None, password=None):
-        uri = '/servers/%s' % (node.id)
-
-        if not name:
-            name = node.name
-
-        body = {'xmlns': self.XML_NAMESPACE,
-                'name': name}
-
-        if password is not None:
-            body['adminPass'] = password
-
-        server_elm = ET.Element('server', body)
-
-        resp = self.connection.request(
-            uri, method='PUT', data=ET.tostring(server_elm))
-
-        if resp.status == httplib.NO_CONTENT and password is not None:
-            node.extra['password'] = password
-
-        return resp.status == httplib.NO_CONTENT
-
-    def create_node(self, **kwargs):
-        """
-        Create a new node
-
-        @inherits: :class:`NodeDriver.create_node`
-
-        :keyword    ex_metadata: Key/Value metadata to associate with a node
-        :type       ex_metadata: ``dict``
-
-        :keyword    ex_files:   File Path => File contents to create on
-                                the node
-        :type       ex_files:   ``dict``
-
-        :keyword    ex_shared_ip_group_id: The server is launched into
-            that shared IP group
-        :type       ex_shared_ip_group_id: ``str``
-        """
-        name = kwargs['name']
-        image = kwargs['image']
-        size = kwargs['size']
-
-        attributes = {'xmlns': self.XML_NAMESPACE,
-                      'name': name,
-                      'imageId': str(image.id),
-                      'flavorId': str(size.id)}
-
-        if 'ex_shared_ip_group' in kwargs:
-            # Deprecate this. Be explicit and call the variable
-            # ex_shared_ip_group_id since user needs to pass in the id, not the
-            # name.
-            warnings.warn('ex_shared_ip_group argument is deprecated.'
-                          ' Please use ex_shared_ip_group_id')
-
-        if 'ex_shared_ip_group_id' in kwargs:
-            shared_ip_group_id = kwargs['ex_shared_ip_group_id']
-            attributes['sharedIpGroupId'] = shared_ip_group_id
-
-        server_elm = ET.Element('server', attributes)
-
-        metadata_elm = self._metadata_to_xml(kwargs.get("ex_metadata", {}))
-        if metadata_elm:
-            server_elm.append(metadata_elm)
-
-        files_elm = self._files_to_xml(kwargs.get("ex_files", {}))
-        if files_elm:
-            server_elm.append(files_elm)
-
-        resp = self.connection.request("/servers",
-                                       method='POST',
-                                       data=ET.tostring(server_elm))
-        return self._to_node(resp.object)
-
-    def ex_set_password(self, node, password):
-        """
-        Sets the Node's root password.
-
-        This will reboot the instance to complete the operation.
-
-        :class:`Node.extra['password']` will be set to the new value if the
-        operation was successful.
-
-        :param      node: node to set password
-        :type       node: :class:`Node`
-
-        :param      password: new password.
-        :type       password: ``str``
-
-        :rtype: ``bool``
-        """
-        return self._change_password_or_name(node, password=password)
-
-    def ex_set_server_name(self, node, name):
-        """
-        Sets the Node's name.
-
-        This will reboot the instance to complete the operation.
-
-        :param      node: node to set name
-        :type       node: :class:`Node`
-
-        :param      name: new name
-        :type       name: ``str``
-
-        :rtype: ``bool``
-        """
-        return self._change_password_or_name(node, name=name)
-
-    def ex_resize(self, node, size):
-        """
-        Change an existing server flavor / scale the server up or down.
-
-        :param      node: node to resize.
-        :type       node: :class:`Node`
-
-        :param      size: new size.
-        :type       size: :class:`NodeSize`
-
-        :rtype: ``bool``
-        """
-        elm = ET.Element(
-            'resize',
-            {'xmlns': self.XML_NAMESPACE,
-             'flavorId': str(size.id)}
-        )
-
-        resp = self.connection.request("/servers/%s/action" % (node.id),
-                                       method='POST',
-                                       data=ET.tostring(elm))
-        return resp.status == httplib.ACCEPTED
-
-    def ex_confirm_resize(self, node):
-        """
-        Confirm a resize request which is currently in progress. If a resize
-        request is not explicitly confirmed or reverted it's automatically
-        confirmed after 24 hours.
-
-        For more info refer to the API documentation: http://goo.gl/zjFI1
-
-        :param      node: node for which the resize request will be confirmed.
-        :type       node: :class:`Node`
-
-        :rtype: ``bool``
-        """
-        elm = ET.Element(
-            'confirmResize',
-            {'xmlns': self.XML_NAMESPACE},
-        )
-
-        resp = self.connection.request("/servers/%s/action" % (node.id),
-                                       method='POST',
-                                       data=ET.tostring(elm))
-        return resp.status == httplib.NO_CONTENT
-
-    def ex_revert_resize(self, node):
-        """
-        Revert a resize request which is currently in progress.
-        All resizes are automatically confirmed after 24 hours if they have
-        not already been confirmed explicitly or reverted.
-
-        For more info refer to the API documentation: http://goo.gl/AizBu
-
-        :param      node: node for which the resize request will be reverted.
-        :type       node: :class:`Node`
-
-        :rtype: ``bool``
-        """
-        elm = ET.Element(
-            'revertResize',
-            {'xmlns': self.XML_NAMESPACE}
-        )
-
-        resp = self.connection.request("/servers/%s/action" % (node.id),
-                                       method='POST',
-                                       data=ET.tostring(elm))
-        return resp.status == httplib.NO_CONTENT
-
-    def ex_rebuild(self, node_id, image_id):
-        """
-        Rebuilds the specified server.
-
-        :param       node_id: ID of the node which should be used
-        :type        node_id: ``str``
-
-        :param       image_id: ID of the image which should be used
-        :type        image_id: ``str``
-
-        :rtype: ``bool``
-        """
-        # @TODO: Remove those ifs in 0.6
-        if isinstance(node_id, Node):
-            node_id = node_id.id
-
-        if isinstance(image_id, NodeImage):
-            image_id = image_id.id
-
-        elm = ET.Element(
-            'rebuild',
-            {'xmlns': self.XML_NAMESPACE,
-             'imageId': image_id}
-        )
-
-        resp = self.connection.request("/servers/%s/action" % node_id,
-                                       method='POST',
-                                       data=ET.tostring(elm))
-        return resp.status == httplib.ACCEPTED
-
-    def ex_create_ip_group(self, group_name, node_id=None):
-        """
-        Creates a shared IP group.
-
-        :param       group_name:  group name which should be used
-        :type        group_name: ``str``
-
-        :param       node_id: ID of the node which should be used
-        :type        node_id: ``str``
-
-        :rtype: ``bool``
-        """
-        # @TODO: Remove this if in 0.6
-        if isinstance(node_id, Node):
-            node_id = node_id.id
-
-        group_elm = ET.Element(
-            'sharedIpGroup',
-            {'xmlns': self.XML_NAMESPACE,
-             'name': group_name}
-        )
-
-        if node_id:
-            ET.SubElement(
-                group_elm,
-                'server',
-                {'id': node_id}
-            )
-
-        resp = self.connection.request('/shared_ip_groups',
-                                       method='POST',
-                                       data=ET.tostring(group_elm))
-        return self._to_shared_ip_group(resp.object)
-
-    def ex_list_ip_groups(self, details=False):
-        """
-        Lists IDs and names for shared IP groups.
-        If details lists all details for shared IP groups.
-
-        :param       details: True if details is required
-        :type        details: ``bool``
-
-        :rtype: ``list`` of :class:`OpenStack_1_0_SharedIpGroup`
-        """
-        uri = '/shared_ip_groups/detail' if details else '/shared_ip_groups'
-        resp = self.connection.request(uri,
-                                       method='GET')
-        groups = findall(resp.object, 'sharedIpGroup',
-                         self.XML_NAMESPACE)
-        return [self._to_shared_ip_group(el) for el in groups]
-
-    def ex_delete_ip_group(self, group_id):
-        """
-        Deletes the specified shared IP group.
-
-        :param       group_id:  group id which should be used
-        :type        group_id: ``str``
-
-        :rtype: ``bool``
-        """
-        uri = '/shared_ip_groups/%s' % group_id
-        resp = self.connection.request(uri, method='DELETE')
-        return resp.status == httplib.NO_CONTENT
-
-    def ex_share_ip(self, group_id, node_id, ip, configure_node=True):
-        """
-        Shares an IP address to the specified server.
-
-        :param       group_id:  group id which should be used
-        :type        group_id: ``str``
-
-        :param       node_id: ID of the node which should be used
-        :type        node_id: ``str``
-
-        :param       ip: ip which should be used
-        :type        ip: ``str``
-
-        :param       configure_node: configure node
-        :type        configure_node: ``bool``
-
-        :rtype: ``bool``
-        """
-        # @TODO: Remove this if in 0.6
-        if isinstance(node_id, Node):
-            node_id = node_id.id
-
-        if configure_node:
-            str_configure = 'true'
-        else:
-            str_configure = 'false'
-
-        elm = ET.Element(
-            'shareIp',
-            {'xmlns': self.XML_NAMESPACE,
-             'sharedIpGroupId': group_id,
-             'configureServer': str_configure},
-        )
-
-        uri = '/servers/%s/ips/public/%s' % (node_id, ip)
-
-        resp = self.connection.request(uri,
-                                       method='PUT',
-                                       data=ET.tostring(elm))
-        return resp.status == httplib.ACCEPTED
-
-    def ex_unshare_ip(self, node_id, ip):
-        """
-        Removes a shared IP address from the specified server.
-
-        :param       node_id: ID of the node which should be used
-        :type        node_id: ``str``
-
-        :param       ip: ip which should be used
-        :type        ip: ``str``
-
-        :rtype: ``bool``
-        """
-        # @TODO: Remove this if in 0.6
-        if isinstance(node_id, Node):
-            node_id = node_id.id
-
-        uri = '/servers/%s/ips/public/%s' % (node_id, ip)
-
-        resp = self.connection.request(uri,
-                                       method='DELETE')
-        return resp.status == httplib.ACCEPTED
-
-    def ex_list_ip_addresses(self, node_id):
-        """
-        List all server addresses.
-
-        :param       node_id: ID of the node which should be used
-        :type        node_id: ``str``
-
-        :rtype: :class:`OpenStack_1_0_NodeIpAddresses`
-        """
-        # @TODO: Remove this if in 0.6
-        if isinstance(node_id, Node):
-            node_id = node_id.id
-
-        uri = '/servers/%s/ips' % node_id
-        resp = self.connection.request(uri,
-                                       method='GET')
-        return self._to_ip_addresses(resp.object)
-
-    def _metadata_to_xml(self, metadata):
-        if len(metadata) == 0:
-            return None
-
-        metadata_elm = ET.Element('metadata')
-        for k, v in list(metadata.items()):
-            meta_elm = ET.SubElement(metadata_elm, 'meta', {'key': str(k)})
-            meta_elm.text = str(v)
-
-        return metadata_elm
-
-    def _files_to_xml(self, files):
-        if len(files) == 0:
-            return None
-
-        personality_elm = ET.Element('personality')
-        for k, v in list(files.items()):
-            file_elm = ET.SubElement(personality_elm,
-                                     'file',
-                                     {'path': str(k)})
-            file_elm.text = base64.b64encode(b(v))
-
-        return personality_elm
-
-    def _reboot_node(self, node, reboot_type='SOFT'):
-        resp = self._node_action(node, ['reboot', ('type', reboot_type)])
-        return resp.status == httplib.ACCEPTED
-
-    def _node_action(self, node, body):
-        if isinstance(body, list):
-            attr = ' '.join(['%s="%s"' % (item[0], item[1])
-                             for item in body[1:]])
-            body = '<%s xmlns="%s" %s/>' % (body[0], self.XML_NAMESPACE, attr)
-        uri = '/servers/%s/action' % (node.id)
-        resp = self.connection.request(uri, method='POST', data=body)
-        return resp
-
-    def _to_nodes(self, object):
-        node_elements = findall(object, 'server', self.XML_NAMESPACE)
-        return [self._to_node(el) for el in node_elements]
-
-    def _to_node_from_obj(self, obj):
-        return self._to_node(findall(obj, 'server', self.XML_NAMESPACE)[0])
-
-    def _to_node(self, el):
-        def get_ips(el):
-            return [ip.get('addr') for ip in el]
-
-        def get_meta_dict(el):
-            d = {}
-            for meta in el:
-                d[meta.get('key')] = meta.text
-            return d
-
-        public_ip = get_ips(findall(el, 'addresses/public/ip',
-                                    self.XML_NAMESPACE))
-        private_ip = get_ips(findall(el, 'addresses/private/ip',
-                                     self.XML_NAMESPACE))
-        metadata = get_meta_dict(findall(el, 'metadata/meta',
-                                         self.XML_NAMESPACE))
-
-        n = Node(id=el.get('id'),
-                 name=el.get('name'),
-                 state=self.NODE_STATE_MAP.get(
-                     el.get('status'), NodeState.UNKNOWN),
-                 public_ips=public_ip,
-                 private_ips=private_ip,
-                 driver=self.connection.driver,
-                 extra={
-                     'password': el.get('adminPass'),
-                     'hostId': el.get('hostId'),
-                     'imageId': el.get('imageId'),
-                     'flavorId': el.get('flavorId'),
-                     'uri': "https://%s%s/servers/%s" % (
-                         self.connection.host,
-                         self.connection.request_path, el.get('id')),
-                     'service_name': self.connection.get_service_name(),
-                     'metadata': metadata})
-        return n
-
-    def _to_sizes(self, object):
-        elements = findall(object, 'flavor', self.XML_NAMESPACE)
-        return [self._to_size(el) for el in elements]
-
-    def _to_size(self, el):
-        vcpus = int(el.get('vcpus')) if el.get('vcpus', None) else None
-        return OpenStackNodeSize(id=el.get('id'),
-                                 name=el.get('name'),
-                                 ram=int(el.get('ram')),
-                                 disk=int(el.get('disk')),
-                                 # XXX: needs hardcode
-                                 vcpus=vcpus,
-                                 bandwidth=None,
-                                 # Hardcoded
-                                 price=self._get_size_price(el.get('id')),
-                                 driver=self.connection.driver)
-
-    def ex_limits(self):
-        """
-        Extra call to get account's limits, such as
-        rates (for example amount of POST requests per day)
-        and absolute limits like total amount of available
-        RAM to be used by servers.
-
-        :return: dict with keys 'rate' and 'absolute'
-        :rtype: ``dict``
-        """
-
-        def _to_rate(el):
-            rate = {}
-            for item in list(el.items()):
-                rate[item[0]] = item[1]
-
-            return rate
-
-        def _to_absolute(el):
-            return {el.get('name'): el.get('value')}
-
-        limits = self.connection.request("/limits").object
-        rate = [_to_rate(el) for el in findall(limits, 'rate/limit',
-                                               self.XML_NAMESPACE)]
-        absolute = {}
-        for item in findall(limits, 'absolute/limit',
-                            self.XML_NAMESPACE):
-            absolute.update(_to_absolute(item))
-
-        return {"rate": rate, "absolute": absolute}
-
-    def create_image(self, node, name, description=None, reboot=True):
-        """Create an image for node.
-
-        @inherits: :class:`NodeDriver.create_image`
-
-        :param      node: node to use as a base for image
-        :type       node: :class:`Node`
-
-        :param      name: name for new image
-        :type       name: ``str``
-
-        :rtype: :class:`NodeImage`
-        """
-
-        image_elm = ET.Element(
-            'image',
-            {'xmlns': self.XML_NAMESPACE,
-             'name': name,
-             'serverId': node.id}
-        )
-
-        return self._to_image(
-            self.connection.request("/images", method="POST",
-                                    data=ET.tostring(image_elm)).object)
-
-    def delete_image(self, image):
-        """Delete an image for node.
-
-        @inherits: :class:`NodeDriver.delete_image`
-
-        :param      image: the image to be deleted
-        :type       image: :class:`NodeImage`
-
-        :rtype: ``bool``
-        """
-        uri = '/images/%s' % image.id
-        resp = self.connection.request(uri, method='DELETE')
-        return resp.status == httplib.NO_CONTENT
-
-    def _to_shared_ip_group(self, el):
-        servers_el = findall(el, 'servers', self.XML_NAMESPACE)
-        if servers_el:
-            servers = [s.get('id')
-                       for s in findall(servers_el[0], 'server',
-                                        self.XML_NAMESPACE)]
-        else:
-            servers = None
-        return OpenStack_1_0_SharedIpGroup(id=el.get('id'),
-                                           name=el.get('name'),
-                                           servers=servers)
-
-    def _to_ip_addresses(self, el):
-        public_ips = [ip.get('addr') for ip in findall(
-            findall(el, 'public', self.XML_NAMESPACE)[0],
-            'ip', self.XML_NAMESPACE)]
-        private_ips = [ip.get('addr') for ip in findall(
-            findall(el, 'private', self.XML_NAMESPACE)[0],
-            'ip', self.XML_NAMESPACE)]
-
-        return OpenStack_1_0_NodeIpAddresses(public_ips, private_ips)
-
-    def _get_size_price(self, size_id):
-        try:
-            return get_size_price(driver_type='compute',
-                                  driver_name=self.api_name,
-                                  size_id=size_id)
-        except KeyError:
-            return 0.0
-
-
-class OpenStack_1_0_SharedIpGroup(object):
-    """
-    Shared IP group info.
-    """
-
-    def __init__(self, id, name, servers=None):
-        self.id = str(id)
-        self.name = name
-        self.servers = servers
-
-
-class OpenStack_1_0_NodeIpAddresses(object):
-    """
-    List of public and private IP addresses of a Node.
-    """
-
-    def __init__(self, public_addresses, private_addresses):
-        self.public_addresses = public_addresses
-        self.private_addresses = private_addresses
-
-
-class OpenStack_1_1_Response(OpenStackResponse):
-    def __init__(self, *args, **kwargs):
-        # done because of a circular reference from
-        # NodeDriver -> Connection -> Response
-        self.node_driver = OpenStack_1_1_NodeDriver
-        super(OpenStack_1_1_Response, self).__init__(*args, **kwargs)
-
-
-class OpenStackNetwork(object):
-    """
-    A Virtual Network.
-    """
-
-    def __init__(self, id, name, cidr, driver, extra=None):
-        self.id = str(id)
-        self.name = name
-        self.cidr = cidr
-        self.driver = driver
-        self.extra = extra or {}
-
-    def __repr__(self):
-        return '<OpenStackNetwork id="%s" name="%s" cidr="%s">' % (self.id,
-                                                                   self.name,
-                                                                   self.cidr,)
-
-
-class OpenStackSecurityGroup(object):
-    """
-    A Security Group.
-    """
-
-    def __init__(self, id, tenant_id, name, description, driver, rules=None,
-                 extra=None):
-        """
-        Constructor.
-
-        :keyword    id: Group id.
-        :type       id: ``str``
-
-        :keyword    tenant_id: Owner of the security group.
-        :type       tenant_id: ``str``
-
-        :keyword    name: Human-readable name for the security group. Might
-                          not be unique.
-        :type       name: ``str``
-
-        :keyword    description: Human-readable description of a security
-                                 group.
-        :type       description: ``str``
-
-        :keyword    rules: Rules associated with this group.
-        :type       rules: ``list`` of
-                    :class:`OpenStackSecurityGroupRule`
-
-        :keyword    extra: Extra attributes associated with this group.
-        :type       extra: ``dict``
-        """
-        self.id = id
-        self.tenant_id = tenant_id
-        self.name = name
-        self.description = description
-        self.driver = driver
-        self.rules = rules or []
-        self.extra = extra or {}
-
-    def __repr__(self):
-        return ('<OpenStackSecurityGroup id=%s tenant_id=%s name=%s \
-        description=%s>' % (self.id, self.tenant_id, self.name,
-                            self.description))
-
-
-class OpenStackSecurityGroupRule(object):
-    """
-    A Rule of a Security Group.
-    """
-
-    def __init__(self, id, parent_group_id, ip_protocol, from_port, to_port,
-                 driver, ip_range=None, group=None, tenant_id=None,
-                 extra=None):
-        """
-        Constructor.
-
-        :keyword    id: Rule id.
-        :type       id: ``str``
-
-        :keyword    parent_group_id: ID of the parent security group.
-        :type       parent_group_id: ``str``
-
-        :keyword    ip_protocol: IP Protocol (icmp, tcp, udp, etc).
-        :type       ip_protocol: ``str``
-
-        :keyword    from_port: Port at start of range.
-        :type       from_port: ``int``
-
-        :keyword    to_port: Port at end of range.
-        :type       to_port: ``int``
-
-        :keyword    ip_range: CIDR for address range.
-        :type       ip_range: ``str``
-
-        :keyword    group: Name of a source security group to apply to rule.
-        :type       group: ``str``
-
-        :keyword    tenant_id: Owner of the security group.
-        :type       tenant_id: ``str``
-
-        :keyword    extra: Extra attributes associated with this rule.
-        :type       extra: ``dict``
-        """
-        self.id = id
-        self.parent_group_id = parent_group_id
-        self.ip_protocol = ip_protocol
-        self.from_port = from_port
-        self.to_port = to_port
-        self.driver = driver
-        self.ip_range = ''
-        self.group = {}
-
-        if group is None:
-            self.ip_range = ip_range
-        else:
-            self.group = {'name': group, 'tenant_id': tenant_id}
-
-        self.tenant_id = tenant_id
-        self.extra = extra or {}
-
-    def __repr__(self):
-        return ('<OpenStackSecurityGroupRule id=%s parent_group_id=%s \
-                ip_protocol=%s from_port=%s to_port=%s>' % (self.id,
-                self.parent_group_id, self.ip_protocol, self.from_port,
-                self.to_port))
-
-
-class OpenStackKeyPair(object):
-    """
-    A KeyPair.
-    """
-
-    def __init__(self, name, fingerprint, public_key, driver, private_key=None,
-                 extra=None):
-        """
-        Constructor.
-
-        :keyword    name: Name of the KeyPair.
-        :type       name: ``str``
-
-        :keyword    fingerprint: Fingerprint of the KeyPair
-        :type       fingerprint: ``str``
-
-        :keyword    public_key: Public key in OpenSSH format.
-        :type       public_key: ``str``
-
-        :keyword    private_key: Private key in PEM format.
-        :type       private_key: ``str``
-
-        :keyword    extra: Extra attributes associated with this KeyPair.
-        :type       extra: ``dict``
-        """
-        self.name = name
-        self.fingerprint = fingerprint
-        self.public_key = public_key
-        self.private_key = private_key
-        self.driver = driver
-        self.extra = extra or {}
-
-    def __repr__(self):
-        return ('<OpenStackKeyPair name=%s fingerprint=%s public_key=%s ...>'
-                % (self.name, self.fingerprint, self.public_key))
-
-
-class OpenStack_1_1_Connection(OpenStackComputeConnection):
-    responseCls = OpenStack_1_1_Response
-    accept_format = 'application/json'
-    default_content_type = 'application/json; charset=UTF-8'
-
-    def encode_data(self, data):
-        return json.dumps(data)
-
-
-class OpenStack_1_1_NodeDriver(OpenStackNodeDriver):
-    """
-    OpenStack node driver.
-    """
-    connectionCls = OpenStack_1_1_Connection
-    type = Provider.OPENSTACK
-
-    features = {"create_node": ["generates_password"]}
-    _networks_url_prefix = '/os-networks'
-
-    def __init__(self, *args, **kwargs):
-        self._ex_force_api_version = str(kwargs.pop('ex_force_api_version',
-                                                    None))
-        super(OpenStack_1_1_NodeDriver, self).__init__(*args, **kwargs)
-
-    def create_node(self, **kwargs):
-        """Create a new node
-
-        @inherits:  :class:`NodeDriver.create_node`
-
-        :keyword    ex_keyname:  The name of the key pair
-        :type       ex_keyname:  ``str``
-
-        :keyword    ex_userdata: String containing user data
-                                 see
-                                 https://help.ubuntu.com/community/CloudInit
-        :type       ex_userdata: ``str``
-
-        :keyword    ex_config_drive: Enable config drive
-                                     see
-                                     http://docs.openstack.org/grizzly/openstack-compute/admin/content/config-drive.html
-        :type       ex_config_drive: ``bool``
-
-        :keyword    ex_security_groups: List of security groups to assign to
-                                        the node
-        :type       ex_security_groups: ``list`` of
-                                       :class:`OpenStackSecurityGroup`
-
-        :keyword    ex_metadata: Key/Value metadata to associate with a node
-        :type       ex_metadata: ``dict``
-
-        :keyword    ex_files:   File Path => File contents to create on
-                                the no  de
-        :type       ex_files:   ``dict``
-
-
-        :keyword    networks: The server is launched into a set of Networks.
-        :type       networks: ``list`` of :class:`OpenStackNetwork`
-
-        :keyword    ex_disk_config: Name of the disk configuration.
-                                    Can be either ``AUTO`` or ``MANUAL``.
-        :type       ex_disk_config: ``str``
-
-        :keyword    ex_config_drive: If True enables metadata injection in a
-                                     server through a configuration drive.
-        :type       ex_config_drive: ``bool``
-
-        :keyword    ex_admin_pass: The root password for the node
-        :type       ex_admin_pass: ``str``
-
-        :keyword    ex_availability_zone: Nova availability zone for the node
-        :type       ex_availability_zone: ``str``
-        """
-
-        server_params = self._create_args_to_params(None, **kwargs)
-
-        resp = self.connection.request("/servers",
-                                       method='POST',
-                                       data={'server': server_params})
-
-        create_response = resp.object['server']
-        server_resp = self.connection.request(
-            '/servers/%s' % create_response['id'])
-        server_object = server_resp.object['server']
-
-        # adminPass is not always present
-        # http://docs.openstack.org/essex/openstack-compute/admin/
-        # content/configuring-compute-API.html#d6e1833
-        server_object['adminPass'] = create_response.get('adminPass', None)
-
-        return self._to_node(server_object)
-
-    def _to_images(self, obj, ex_only_active):
-        images = []
-        for image in obj['images']:
-            if ex_only_active and image.get('status') != 'ACTIVE':
-                continue
-            images.append(self._to_image(image))
-
-        return images
-
-    def _to_image(self, api_image):
-        server = api_image.get('server', {})
-        return NodeImage(
-            id=api_image['id'],
-            name=api_image['name'],
-            driver=self,
-            extra=dict(
-                updated=api_image['updated'],
-                created=api_image['created'],
-                status=api_image['status'],
-                progress=api_image.get('progress'),
-                metadata=api_image.get('metadata'),
-                serverId=server.get('id'),
-                minDisk=api_image.get('minDisk'),
-                minRam=api_image.get('minRam'),
-            )
-        )
-
-    def _to_nodes(self, obj):
-        servers = obj['servers']
-        return [self._to_node(server) for server in servers]
-
-    def _to_volumes(self, obj):
-        volumes = obj['volumes']
-        return [self._to_volume(volume) for volume in volumes]
-
-    def _to_snapshots(self, obj):
-        snapshots = obj['snapshots']
-        return [self._to_snapshot(snapshot) for snapshot in snapshots]
-
-    def _to_sizes(self, obj):
-        flavors = obj['flavors']
-        return [self._to_size(flavor) for flavor in flavors]
-
-    def _create_args_to_params(self, node, **kwargs):
-        server_params = {
-            'name': kwargs.get('name'),
-            'metadata': kwargs.get('ex_metadata', {}),
-            'personality': self._files_to_personality(kwargs.get("ex_files",
-                                                                 {}))
-        }
-
-        if 'ex_availability_zone' in kwargs:
-            server_params['availability_zone'] = kwargs['ex_availability_zone']
-
-        if 'ex_keyname' in kwargs:
-            server_params['key_name'] = kwargs['ex_keyname']
-
-        if 'ex_userdata' in kwargs:
-            server_params['user_data'] = base64.b64encode(
-                b(kwargs['ex_userdata'])).decode('ascii')
-
-        if 'ex_config_drive' in kwargs:
-            server_params['config_drive'] = kwargs['ex_config_drive']
-
-        if 'ex_disk_config' in kwargs:
-            server_params['OS-DCF:diskConfig'] = kwargs['ex_disk_config']
-
-        if 'ex_config_drive' in kwargs:
-            server_params['config_drive'] = str(kwargs['ex_config_drive'])
-
-        if 'ex_admin_pass' in kwargs:
-            server_params['adminPass'] = kwargs['ex_admin_pass']
-
-        if 'networks' in kwargs:
-            networks = kwargs['networks']
-            networks = [{'uuid': network.id} for network in networks]
-            server_params['networks'] = networks
-
-        if 'ex_security_groups' in kwargs:
-            server_params['security_groups'] = []
-            for security_group in kwargs['ex_security_groups']:
-                name = security_group.name
-                server_params['security_groups'].append({'name': name})
-
-        if 'ex_blockdevicemappings' in kwargs:
-            server_params['block_device_mapping_v2'] = \
-                kwargs['ex_blockdevicemappings']
-
-        if 'name' in kwargs:
-            server_params['name'] = kwargs.get('name')
-        else:
-            server_params['name'] = node.name
-
-        if 'image' in kwargs:
-            server_params['imageRef'] = kwargs.get('image').id
-        else:
-            server_params['imageRef'] = node.extra.get('imageId')
-
-        if 'size' in kwargs:
-            server_params['flavorRef'] = kwargs.get('size').id
-        else:
-            server_params['flavorRef'] = node.extra.get('flavorId')
-
-        return server_params
-
-    def _files_to_personality(self, files):
-        rv = []
-
-        for k, v in list(files.items()):
-            rv.append({'path': k, 'contents': base64.b64encode(b(v))})
-
-        return rv
-
-    def _reboot_node(self, node, reboot_type='SOFT'):
-        resp = self._node_action(node, 'reboot', type=reboot_type)
-        return resp.status == httplib.ACCEPTED
-
-    def ex_set_password(self, node, password):
-        """
-        Changes the administrator password for a specified server.
-
-        :param      node: Node to rebuild.
-        :type       node: :class:`Node`
-
-        :param      password: The administrator password.
-        :type       password: ``str``
-
-        :rtype: ``bool``
-        """
-        resp = self._node_action(node, 'changePassword', adminPass=password)
-        node.extra['password'] = password
-        return resp.status == httplib.ACCEPTED
-
-    def ex_rebuild(self, node, image, **kwargs):
-        """
-        Rebuild a Node.
-
-        :param      node: Node to rebuild.
-        :type       node: :class:`Node`
-
-        :param      image: New image to use.
-        :type       image: :class:`NodeImage`
-
-        :keyword    ex_metadata: Key/Value metadata to associate with a node
-        :type       ex_metadata: ``dict``
-
-        :keyword    ex_files:   File Path => File contents to create on
-                                the no  de
-        :type       ex_files:   ``dict``
-
-        :keyword    ex_keyname:  Name of existing public key to inject into
-                                 instance
-        :type       ex_keyname:  ``str``
-
-        :keyword    ex_userdata: String containing user data
-                                 see
-                                 https://help.ubuntu.com/community/CloudInit
-        :type       ex_userdata: ``str``
-
-        :keyword    ex_security_groups: List of security groups to assign to
-                                        the node
-        :type       ex_security_groups: ``list`` of
-                                       :class:`OpenStackSecurityGroup`
-
-        :keyword    ex_disk_config: Name of the disk configuration.
-                                    Can be either ``AUTO`` or ``MANUAL``.
-        :type       ex_disk_config: ``str``
-
-        :keyword    ex_config_drive: If True enables metadata injection in a
-                                     server through a configuration drive.
-        :type       ex_config_drive: ``bool``
-
-        :rtype: ``bool``
-        """
-        server_params = self._create_args_to_params(node, image=image,
-                                                    **kwargs)
-        resp = self._node_action(node, 'rebuild', **server_params)
-        return resp.status == httplib.ACCEPTED
-
-    def ex_resize(self, node, size):
-        """
-        Change a node size.
-
-        :param      node: Node to resize.
-        :type       node: :class:`Node`
-
-        :type       size: :class:`NodeSize`
-        :param      size: New size to use.
-
-        :rtype: ``bool``
-        """
-        server_params = self._create_args_to_params(node, size=size)
-        resp = self._node_action(node, 'resize', **server_params)
-        return resp.status == httplib.ACCEPTED
-
-    def ex_confirm_resize(self, node):
-        """
-        Confirms a pending resize action.
-
-        :param      node: Node to resize.
-        :type       node: :class:`Node`
-
-        :rtype: ``bool``
-        """
-        resp = self._node_action(node, 'confirmResize')
-        return resp.status == httplib.NO_CONTENT
-
-    def ex_revert_resize(self, node):
-        """
-        Cancels and reverts a pending resize action.
-
-        :param      node: Node to resize.
-        :type       node: :class:`Node`
-
-        :rtype: ``bool``
-        """
-        resp = self._node_action(node, 'revertResize')
-        return resp.status == httplib.ACCEPTED
-
-    def create_image(self, node, name, metadata=None):
-        """
-        Creates a new image.
-
-        :param      node: Node
-        :type       node: :class:`Node`
-
-        :param      name: The name for the new image.
-        :type       name: ``str``
-
-        :param      metadata: Key and value pairs for metadata.
-        :type       metadata: ``dict``
-
-        :rtype: :class:`NodeImage`
-        """
-        optional_params = {}
-        if metadata:
-            optional_params['metadata'] = metadata
-        resp = self._node_action(node, 'createImage', name=name,
-                                 **optional_params)
-        image_id = self._extract_image_id_from_url(resp.headers['location'])
-        return self.get_image(image_id=image_id)
-
-    def ex_set_server_name(self, node, name):
-        """
-        Sets the Node's name.
-
-        :param      node: Node
-        :type       node: :class:`Node`
-
-        :param      name: The name of the server.
-        :type       name: ``str``
-
-        :rtype: :class:`Node`
-        """
-        return self._update_node(node, name=name)
-
-    def ex_get_metadata(self, node):
-        """
-        Get a Node's metadata.
-
-        :param      node: Node
-        :type       node: :class:`Node`
-
-        :return: Key/Value metadata associated with node.
-        :rtype: ``dict``
-        """
-        return self.connection.request(
-            '/servers/%s/metadata' % (node.id,),
-            method='GET',).object['metadata']
-
-    def ex_set_metadata(self, node, metadata):
-        """
-        Sets the Node's metadata.
-
-        :param      node: Node
-        :type       node: :class:`Node`
-
-        :param      metadata: Key/Value metadata to associate with a node
-        :type       metadata: ``dict``
-
-        :rtype: ``dict``
-        """
-        return self.connection.request(
-            '/servers/%s/metadata' % (node.id,), method='PUT',
-            data={'metadata': metadata}
-        ).object['metadata']
-
-    def ex_update_node(self, node, **node_updates):
-        """
-        Update the Node's editable attributes.  The OpenStack API currently
-        supports editing name and IPv4/IPv6 access addresses.
-
-        The driver currently only supports updating the node name.
-
-        :param      node: Node
-        :type       node: :class:`Node`
-
-        :keyword    name:   New name for the server
-        :type       name:   ``str``
-
-        :rtype: :class:`Node`
-        """
-        potential_data = self._create_args_to_params(node, **node_updates)
-        updates = {'name': potential_data['name']}
-        return self._update_node(node, **updates)
-
-    def _to_networks(self, obj):
-        networks = obj['networks']
-        return [self._to_network(network) for network in networks]
-
-    def _to_network(self, obj):
-        return OpenStackNetwork(id=obj['id'],
-                                name=obj['label'],
-                                cidr=obj.get('cidr', None),
-                                driver=self)
-
-    def ex_list_networks(self):
-        """
-        Get a list of Networks that are available.
-
-        :rtype: ``list`` of :class:`OpenStackNetwork`
-        """
-        response = self.connection.request(self._networks_url_prefix).object
-        return self._to_networks(response)
-
-    def ex_create_network(self, name, cidr):
-        """
-        Create a new Network
-
-        :param name: Name of network which should be used
-        :type name: ``str``
-
-        :param cidr: cidr of network which should be used
-        :type cidr: ``str``
-
-        :rtype: :class:`OpenStackNetwork`
-        """
-        data = {'network': {'cidr': cidr, 'label': name}}
-        response = self.connection.request(self._networks_url_prefix,
-                                           method='POST', data=data).object
-        return self._to_network(response['network'])
-
-    def ex_delete_network(self, network):
-        """
-        Get a list of NodeNetorks that are available.
-
-        :param network: Network which should be used
-        :type network: :class:`OpenStackNetwork`
-
-        :rtype: ``bool``
-        """
-        resp = self.connection.request('%s/%s' % (self._networks_url_prefix,
-                                                  network.id),
-                                       method='DELETE')
-        return resp.status == httplib.ACCEPTED
-
-    def ex_get_console_output(self, node, length=None):
-        """
-        Get console output
-
-        :param      node: node
-        :type       node: :class:`Node`
-
-        :param      length: Optional number of lines to fetch from the
-                            console log
-        :type       length: ``int``
-
-        :return: Dictionary with the output
-        :rtype: ``dict``
-        """
-
-        data = {
-            "os-getConsoleOutput": {
-                "length": length
-            }
-        }
-
-        resp = self.connection.request('/servers/%s/action' % node.id,
-                                       method='POST', data=data).object
-        return resp
-
-    def ex_list_snapshots(self):
-        return self._to_snapshots(
-            self.connection.request('/os-snapshots').object)
-
-    def list_volume_snapshots(self, volume):
-        return [snapshot for snapshot in self.ex_list_snapshots()
-                if snapshot.extra['volume_id'] == volume.id]
-
-    def create_volume_snapshot(self, volume, name=None, ex_description=None,
-                               ex_force=True):
-        """
-        Create snapshot from volume
-
-        :param volume: Instance of `StorageVolume`
-        :type  volume: `StorageVolume`
-
-        :param name: Name of snapshot (optional)
-        :type  name: `str`
-
-        :param ex_description: Description of the snapshot (optional)
-        :type  ex_description: `str`
-
-        :param ex_force: Specifies if we create a snapshot that is not in
-                         state `available`. For example `in-use`. Defaults
-                         to True. (optional)
-        :type  ex_force: `bool`
-
-        :rtype: :class:`VolumeSnapshot`
-        """
-        data = {'snapshot': {'display_name': name,
-                             'display_description': ex_description,
-                             'volume_id': volume.id,
-                             'force': ex_force}}
-
-        return self._to_snapshot(self.connection.request('/os-snapshots',
-                                                         method='POST',
-                                                         data=data).object)
-
-    def destroy_volume_snapshot(self, snapshot):
-        resp = self.connection.request('/os-snapshots/%s' % snapshot.id,
-                                       method='DELETE')
-        return resp.status == httplib.NO_CONTENT
-
-    def ex_create_snapshot(self, volume, name, description=None, force=False):
-        """
-        Create a snapshot based off of a volume.
-
-        :param      volume: volume
-        :type       volume: :class:`StorageVolume`
-
-        :keyword    name: New name for the volume snapshot
-        :type       name: ``str``
-
-        :keyword    description: Description of the snapshot (optional)
-        :type       description: ``str``
-
-        :keyword    force: Whether to force creation (optional)
-        :type       force: ``bool``
-
-        :rtype:     :class:`VolumeSnapshot`
-        """
-        warnings.warn('This method has been deprecated in favor of the '
-                      'create_volume_snapshot method')
-        return self.create_volume_snapshot(volume, name,
-                                           ex_description=description,
-                                           ex_force=force)
-
-    def ex_delete_snapshot(self, snapshot):
-        """
-        Delete a VolumeSnapshot
-
-        :param      snapshot: snapshot
-        :type       snapshot: :class:`VolumeSnapshot`
-
-        :rtype:     ``bool``
-        """
-        warnings.warn('This method has been deprecated in favor of the '
-                      'destroy_volume_snapshot method')
-        return self.destroy_volume_snapshot(snapshot)
-
-    def _to_security_group_rules(self, obj):
-        return [self._to_security_group_rule(security_group_rule) for
-                security_group_rule in obj]
-
-    def _to_security_group_rule(self, obj):
-        ip_range = group = tenant_id = None
-        if obj['group'] == {}:
-            ip_range = obj['ip_range'].get('cidr', None)
-        else:
-            group = obj['group'].get('name', None)
-            tenant_id = obj['group'].get('tenant_id', None)
-
-        return OpenStackSecurityGroupRule(
-            id=obj['id'], parent_group_id=obj['parent_group_id'],
-            ip_protocol=obj['ip_protocol'], from_port=obj['from_port'],
-            to_port=obj['to_port'], driver=self, ip_range=ip_range,
-            group=group, tenant_id=tenant_id)
-
-    def _to_security_groups(self, obj):
-        security_groups = obj['security_groups']
-        return [self._to_security_group(security_group) for security_group in
-                security_groups]
-
-    def _to_security_group(self, obj):
-        rules = self._to_security_group_rules(obj.get('rules', []))
-        return OpenStackSecurityGroup(id=obj['id'],
-                                      tenant_id=obj['tenant_id'],
-                                      name=obj['name'],
-                                      description=obj.get('description', ''),
-                                      rules=rules,
-                                      driver=self)
-
-    def ex_list_security_groups(self):
-        """
-        Get a list of Security Groups that are available.
-
-        :rtype: ``list`` of :class:`OpenStackSecurityGroup`
-        """
-        return self._to_security_groups(
-            self.connection.request('/os-security-groups').object)
-
-    def ex_get_node_security_groups(self, node):
-        """
-        Get Security Groups of the specified server.
-
-        :rtype: ``list`` of :class:`OpenStackSecurityGroup`
-        """
-        return self._to_security_groups(
-            self.connection.request('/servers/%s/os-security-groups' %
-                                    (node.id)).object)
-
-    def ex_create_security_group(self, name, description):
-        """
-        Create a new Security Group
-
-        :param name: Name of the new Security Group
-        :type  name: ``str``
-
-        :param description: Description of the new Security Group
-        :type  description: ``str``
-
-        :rtype: :class:`OpenStackSecurityGroup`
-        """
-        return self._to_security_group(self.connection.request(
-            '/os-security-groups', method='POST',
-            data={'security_group': {'name': name, 'description': description}}
-        ).object['security_group'])
-
-    def ex_delete_security_group(self, security_group):
-        """
-        Delete a Security Group.
-
-        :param security_group: Security Group should be deleted
-        :type  security_group: :class:`OpenStackSecurityGroup`
-
-        :rtype: ``bool``
-        """
-        resp = self.connection.request('/os-security-groups/%s' %
-                                       (security_group.id),
-                                       method='DELETE')
-        return resp.status in (httplib.NO_CONTENT, httplib.ACCEPTED)
-
-    def ex_create_security_group_rule(self, security_group, ip_protocol,
-                                      from_port, to_port, cidr=None,
-                                      source_security_group=None):
-        """
-        Create a new Rule in a Security Group
-
-        :param security_group: Security Group in which to add the rule
-        :type  security_group: :class:`OpenStackSecurityGroup`
-
-        :param ip_protocol: Protocol to which this rule applies
-                            Examples: tcp, udp, ...
-        :type  ip_protocol: ``str``
-
-        :param from_port: First port of the port range
-        :type  from_port: ``int``
-
-        :param to_port: Last port of the port range
-        :type  to_port: ``int``
-
-        :param cidr: CIDR notation of the source IP range for this rule
-        :type  cidr: ``str``
-
-        :param source_security_group: Existing Security Group to use as the
-                                      source (instead of CIDR)
-        :type  source_security_group: L{OpenStackSecurityGroup
-
-        :rtype: :class:`OpenStackSecurityGroupRule`
-        """
-        source_security_group_id = None
-        if type(source_security_group) == OpenStackSecurityGroup:
-            source_security_group_id = source_security_group.id
-
-        return self._to_security_group_rule(self.connection.request(
-            '/os-security-group-rules', method='POST',
-            data={'security_group_rule': {
-                'ip_protocol': ip_protocol,
-                'from_port': from_port,
-                'to_port': to_port,
-                'cidr': cidr,
-                'group_id': source_security_group_id,
-                'parent_group_id': security_group.id}}
-        ).object['security_group_rule'])
-
-    def ex_delete_security_group_rule(self, rule):
-        """
-        Delete a Rule from a Security Group.
-
-        :param rule: Rule should be deleted
-        :type  rule: :class:`OpenStackSecurityGroupRule`
-
-        :rtype: ``bool``
-        """
-        resp = self.connection.request('/os-security-group-rules/%s' %
-                                       (rule.id), method='DELETE')
-        return resp.status == httplib.NO_CONTENT
-
-    def _to_key_pairs(self, obj):
-        key_pairs = obj['keypairs']
-        key_pairs = [self._to_key_pair(key_pair['keypair']) for key_pair in
-                     key_pairs]
-        return key_pairs
-
-    def _to_key_pair(self, obj):
-        key_pair = KeyPair(name=obj['name'],
-                           fingerprint=obj['fingerprint'],
-                           public_key=obj['public_key'],
-                           private_key=obj.get('private_key', None),
-                           driver=self)
-        return key_pair
-
-    def list_key_pairs(self):
-        response = self.connection.request('/os-keypairs')
-        key_pairs = self._to_key_pairs(response.object)
-        return key_pairs
-
-    def get_key_pair(self, name):
-        self.connection.set_context({'key_pair_name': name})
-
-        response = self.connection.request('/os-keypairs/%s' % (name))
-        key_pair = self._to_key_pair(response.object['keypair'])
-        return key_pair
-
-    def create_key_pair(self, name):
-        data = {'keypair': {'name': name}}
-        response = self.connection.request('/os-keypairs', method='POST',
-                                           data=data)
-        key_pair = self._to_key_pair(response.object['keypair'])
-        return key_pair
-
-    def import_key_pair_from_string(self, name, key_material):
-        data = {'keypair': {'name': name, 'public_key': key_material}}
-        response = self.connection.request('/os-keypairs', method='POST',
-                                           data=data)
-        key_pair = self._to_key_pair(response.object['keypair'])
-        return key_pair
-
-    def delete_key_pair(self, key_pair):
-        """
-        Delete a KeyPair.
-
-        :param keypair: KeyPair to delete
-        :type  keypair: :class:`OpenStackKeyPair`
-
-        :rtype: ``bool``
-        """
-        response = self.connection.request('/os-keypairs/%s' % (key_pair.name),
-                                           method='DELETE')
-        return response.status == httplib.ACCEPTED
-
-    def ex_list_keypairs(self):
-        """
-        Get a list of KeyPairs that are available.
-
-        :rtype: ``list`` of :class:`OpenStackKeyPair`
-        """
-        warnings.warn('This method has been deprecated in favor of '
-                      'list_key_pairs method')
-
-        return self.list_key_pairs()
-
-    def ex_create_keypair(self, name):
-        """
-        Create a new KeyPair
-
-        :param name: Name of the new KeyPair
-        :type  name: ``str``
-
-        :rtype: :class:`OpenStackKeyPair`
-        """
-        warnings.warn('This method has been deprecated in favor of '
-                      'create_key_pair method')
-
-        return self.create_key_pair(name=name)
-
-    def ex_import_keypair(self, name, keyfile):
-        """
-        Import a KeyPair from a file
-
-        :param name: Name of the new KeyPair
-        :type  name: ``str``
-
-        :param keyfile: Path to the public key file (in OpenSSH format)
-        :type  keyfile: ``str``
-
-        :rtype: :class:`OpenStackKeyPair`
-        """
-        warnings.warn('This method has been deprecated in favor of '
-                      'import_key_pair_from_file method')
-
-        return self.import_key_pair_from_file(name=name, key_file_path=keyfile)
-
-    def ex_import_keypair_from_string(self, name, key_material):
-        """
-        Import a KeyPair from a string
-
-        :param name: Name of the new KeyPair
-        :type  name: ``str``
-
-        :param key_material: Public key (in OpenSSH format)
-        :type  key_material: ``str``
-
-        :rtype: :class:`OpenStackKeyPair`
-        """
-        warnings.warn('This method has been deprecated in favor of '
-                      'import_key_pair_from_string method')
-
-        return self.import_key_pair_from_string(name=name,
-                                                key_material=key_material)
-
-    def ex_delete_keypair(self, keypair):
-        """
-        Delete a KeyPair.
-
-        :param keypair: KeyPair to delete
-        :type  keypair: :class:`OpenStackKeyPair`
-
-        :rtype: ``bool``
-        """
-        warnings.warn('This method has been deprecated in favor of '
-                      'delete_key_pair method')
-
-        return self.delete_key_pair(key_pair=keypair)
-
-    def ex_get_size(self, size_id):
-        """
-        Get a NodeSize
-
-        :param      size_id: ID of the size which should be used
-        :type       size_id: ``str``
-
-        :rtype: :class:`NodeSize`
-        """
-        return self._to_size(self.connection.request(
-            '/flavors/%s' % (size_id,)) .object['flavor'])
-
-    def get_image(self, image_id):
-        """
-        Get a NodeImage
-
-        @inherits: :class:`NodeDriver.get_image`
-
-        :param      image_id: ID of the image which should be used
-        :type       image_id: ``str``
-
-        :rtype: :class:`NodeImage`
-        """
-        return self._to_image(self.connection.request(
-            '/images/%s' % (image_id,)).object['image'])
-
-    def delete_image(self, image):
-        """
-        Delete a NodeImage
-
-        @inherits: :class:`NodeDriver.delete_image`
-
-        :param      image: image witch should be used
-        :type       image: :class:`NodeImage`
-
-        :rtype: ``bool``
-        """
-        resp = self.connection.request('/images/%s' % (image.id,),
-                                       method='DELETE')
-        return resp.status == httplib.NO_CONTENT
-
-    def _node_action(self, node, action, **params):
-        params = params or None
-        return self.connection.request('/servers/%s/action' % (node.id,),
-                                       method='POST', data={action: params})
-
-    def _update_node(self, node, **node_updates):
-        """
-        Updates the editable attributes of a server, which currently include
-        its name and IPv4/IPv6 access addresses.
-        """
-        return self._to_node(
-            self.connection.request(
-                '/servers/%s' % (node.id,), method='PUT',
-                data={'server': node_updates}
-            ).object['server']
-        )
-
-    def _to_node_from_obj(self, obj):
-        return self._to_node(obj['server'])
-
-    def _to_node(self, api_node):
-        public_networks_labels = ['public', 'internet']
-
-        public_ips, private_ips = [], []
-
-        for label, values in api_node['addresses'].items():
-            for value in values:
-                ip = value['addr']
-                is_public_ip = False
-
-                try:
-                    is_public_ip = is_public_subnet(ip)
-                except:
-                    # IPv6
-
-                    # Openstack Icehouse sets 'OS-EXT-IPS:type' to 'floating'
-                    # for public and 'fixed' for private
-                    explicit_ip_type = value.get('OS-EXT-IPS:type', None)
-
-                    if label in public_networks_labels:
-                        is_public_ip = True
-                    elif explicit_ip_type == 'floating':
-                        is_public_ip = True
-                    elif explicit_ip_type == 'fixed':
-                        is_public_ip = False
-
-                if is_public_ip:
-                    public_ips.append(ip)
-                else:
-                    private_ips.append(ip)
-
-        # Sometimes 'image' attribute is not present if the node is in an error
-        # state
-        image = api_node.get('image', None)
-        image_id = image.get('id', None) if image else None
-        config_drive = api_node.get("config_drive", False)
-        volumes_attached = api_node.get('os-extended-volumes:volumes_attached')
-        created = parse_date(api_node["created"])
-
-        return Node(
-            id=api_node['id'],
-            name=api_node['name'],
-            state=self.NODE_STATE_MAP.get(api_node['status'],
-                                          NodeState.UNKNOWN),
-            public_ips=public_ips,
-            private_ips=private_ips,
-            created_at=created,
-            driver=self,
-            extra=dict(
-                addresses=api_node['addresses'],
-                hostId=api_node['hostId'],
-                access_ip=api_node.get('accessIPv4'),
-                access_ipv6=api_node.get('accessIPv6', None),
-                # Docs says "tenantId", but actual is "tenant_id". *sigh*
-                # Best handle both.
-                tenantId=api_node.get('tenant_id') or api_node['tenantId'],
-                userId=api_node.get('user_id', None),
-                imageId=image_id,
-                flavorId=api_node['flavor']['id'],
-                uri=next(link['href'] for link in api_node['links'] if
-                         link['rel'] == 'self'),
-                service_name=self.connection.get_service_name(),
-                metadata=api_node['metadata'],
-                password=api_node.get('adminPass', None),
-                created=api_node['created'],
-                updated=api_node['updated'],
-                key_name=api_node.get('key_name', None),
-                disk_config=api_node.get('OS-DCF:diskConfig', None),
-                config_drive=config_drive,
-                availability_zone=api_node.get('OS-EXT-AZ:availability_zone'),
-                volumes_attached=volumes_attached,
-                task_state=api_node.get("OS-EXT-STS:task_state", None),
-                vm_state=api_node.get("OS-EXT-STS:vm_state", None),
-                power_state=api_node.get("OS-EXT-STS:power_state", None),
-                progress=api_node.get("progress", None),
-                fault=api_node.get('fault')
-            ),
-        )
-
-    def _to_volume(self, api_node):
-        if 'volume' in api_node:
-            api_node = api_node['volume']
-
-        state = self.VOLUME_STATE_MAP.get(api_node['status'],
-                                          StorageVolumeState.UNKNOWN)
-
-        return StorageVolume(
-            id=api_node['id'],
-            name=api_node['displayName'],
-            size=api_node['size'],
-            state=state,
-            driver=self,
-            extra={
-                'description': api_node['displayDescription'],
-                'attachments': [att for att in api_node['attachments'] if att],
-                # TODO: remove in 1.18.0
-                'state': api_node.get('status', None),
-                'snapshot_id': api_node.get('snapshotId', None),
-                'location': api_node.get('availabilityZone', None),
-                'volume_type': api_node.get('volumeType', None),
-                'metadata': api_node.get('metadata', None),
-                'created_at': api_node.get('createdAt', None)
-            }
-        )
-
-    def _to_snapshot(self, data):
-        if 'snapshot' in data:
-            data = data['snapshot']
-
-        volume_id = data.get('volume_id', data.get('volumeId', None))
-        display_name = data.get('display_name', data.get('displayName', None))
-        created_at = data.get('created_at', data.get('createdAt', None))
-        description = data.get('display_description',
-                               data.get('displayDescription', None))
-        status = data.get('status', None)
-
-        extra = {'volume_id': volume_id,
-                 'name': display_name,
-                 'created': created_at,
-                 'description': description,
-                 'status': status}
-
-        state = self.SNAPSHOT_STATE_MAP.get(
-            status,
-            VolumeSnapshotState.UNKNOWN
-        )
-
-        try:
-            created_dt = parse_date(created_at)
-        except ValueError:
-            created_dt = None
-
-        snapshot = VolumeSnapshot(id=data['id'], driver=self,
-                                  size=data['size'], extra=extra,
-                                  created=created_dt, state=state)
-        return snapshot
-
-    def _to_size(self, api_flavor, price=None, bandwidth=None):
-        # if provider-specific subclasses can get better values for
-        # price/bandwidth, then can pass them in when they super().
-        if not price:
-            price = self._get_size_price(str(api_flavor['id']))
-
-        extra = api_flavor.get('OS-FLV-WITH-EXT-SPECS:extra_specs', {})
-        return OpenStackNodeSize(
-            id=api_flavor['id'],
-            name=api_flavor['name'],
-            ram=api_flavor['ram'],
-            disk=api_flavor['disk'],
-            vcpus=api_flavor['vcpus'],
-            ephemeral_disk=api_flavor.get('OS-FLV-EXT-DATA:ephemeral', None),
-            swap=api_flavor['swap'],
-            extra=extra,
-            bandwidth=bandwidth,
-            price=price,
-            driver=self,
-        )
-
-    def _get_size_price(self, size_id):
-        try:
-            return get_size_price(
-                driver_type='compute',
-                driver_name=self.api_name,
-                size_id=size_id,
-            )
-        except KeyError:
-            return(0.0)
-
-    def _extract_image_id_from_url(self, location_header):
-        path = urlparse.urlparse(location_header).path
-        image_id = path.split('/')[-1]
-        return image_id
-
-    def ex_rescue(self, node, password=None):
-        # Requires Rescue Mode extension
-        """
-        Rescue a node
-
-        :param      node: node
-        :type       node: :class:`Node`
-
-        :param      password: password
-        :type       password: ``str``
-
-        :rtype: :class:`Node`
-        """
-        if password:
-            resp = self._node_action(node, 'rescue', adminPass=password)
-        else:
-            resp = self._node_action(node, 'rescue')
-            password = json.loads(resp.body)['adminPass']
-        node.extra['password'] = password
-        return node
-
-    def ex_unrescue(self, node):
-        """
-        Unrescue a node
-
-        :param      node: node
-        :type       node: :class:`Node`
-
-        :rtype: ``bool``
-        """
-        resp = self._node_action(node, 'unrescue')
-        return resp.status == httplib.ACCEPTED
-
-    def _to_floating_ip_pools(self, obj):
-        pool_elements = obj['floating_ip_pools']
-        return [self._to_floating_ip_pool(pool) for pool in pool_elements]
-
-    def _to_floating_ip_pool(self, obj):
-        return OpenStack_1_1_FloatingIpPool(obj['name'], self.connection)
-
-    def ex_list_floating_ip_pools(self):
-        """
-        List available floating IP pools
-
-        :rtype: ``list`` of :class:`OpenStack_1_1_FloatingIpPool`
-        """
-        return self._to_floating_ip_pools(
-            self.connection.request('/os-floating-ip-pools').object)
-
-    def _to_floating_ips(self, obj):
-        ip_elements = obj['floating_ips']
-        return [self._to_floating_ip(ip) for ip in ip_elements]
-
-    def _to_floating_ip(self, obj):
-        return OpenStack_1_1_FloatingIpAddress(id=obj['id'],
-                                               ip_address=obj['ip'],
-                                               pool=None,
-                                               node_id=obj['instance_id'],
-                                               driver=self)
-
-    def ex_list_floating_ips(self):
-        """
-        List floating IPs
-
-        :rtype: ``list`` of :class:`OpenStack_1_1_FloatingIpAddress`
-        """
-        return self._to_floating_ips(
-            self.connection.request('/os-floating-ips').object)
-
-    def ex_get_floating_ip(self, ip):
-        """
-        Get specified floating IP
-
-        :param      ip: floating IP to get
-        :type       ip: ``str``
-
-        :rtype: :class:`OpenStack_1_1_FloatingIpAddress`
-        """
-        floating_ips = self.ex_list_floating_ips()
-        ip_obj, = [x for x in floating_ips if x.ip_address == ip]
-        return ip_obj
-
-    def ex_create_floating_ip(self, ip_pool=None):
-        """
-        Create new floating IP. The ip_pool attribute is optional only if your
-        infrastructure has only one IP pool available.
-
-        :param      ip_pool: name of the floating IP pool
-        :type       ip_pool: ``str``
-
-        :rtype: :class:`OpenStack_1_1_FloatingIpAddress`
-        """
-        data = {'pool': ip_pool} if ip_pool is not None else {}
-        resp = self.connection.request('/os-floating-ips',
-                                       method='POST',
-                                       data=data)
-
-        data = resp.object['floating_ip']
-        id = data['id']
-        ip_address = data['ip']
-        return OpenStack_1_1_FloatingIpAddress(id=id,
-                                               ip_address=ip_address,
-                                               pool=None,
-                                               node_id=None,
-                                               driver=self)
-
-    def ex_delete_floating_ip(self, ip):
-        """
-        Delete specified floating IP
-
-        :param      ip: floating IP to remove
-        :type       ip: :class:`OpenStack_1_1_FloatingIpAddress`
-
-        :rtype: ``bool``
-        """
-        resp = self.connection.request('/os-floating-ips/%s' % ip.id,
-                                       method='DELETE')
-        return resp.status in (httplib.NO_CONTENT, httplib.ACCEPTED)
-
-    def ex_attach_floating_ip_to_node(self, node, ip):
-        """
-        Attach the floating IP to the node
-
-        :param      node: node
-        :type       node: :class:`Node`
-
-        :param      ip: floating IP to attach
-        :type       ip: ``str`` or :class:`OpenStack_1_1_FloatingIpAddress`
-
-        :rtype: ``bool``
-        """
-        address = ip.ip_address if hasattr(ip, 'ip_address') else ip
-        data = {
-            'addFloatingIp': {'address': address}
-        }
-        resp = self.connection.request('/servers/%s/action' % node.id,
-                                       method='POST', data=data)
-        return resp.status == httplib.ACCEPTED
-
-    def ex_detach_floating_ip_from_node(self, node, ip):
-        """
-        Detach the floating IP from the node
-
-        :param      node: node
-        :type       node: :class:`Node`
-
-        :param      ip: floating IP to remove
-        :type       ip: ``str`` or :class:`OpenStack_1_1_FloatingIpAddress`
-
-        :rtype: ``bool``
-        """
-        address = ip.ip_address if hasattr(ip, 'ip_address') else ip
-        data = {
-            'removeFloatingIp': {'address': address}
-        }
-        resp = self.connection.request('/servers/%s/action' % node.id,
-                                       method='POST', data=data)
-        return resp.status == httplib.ACCEPTED
-
-    def ex_get_metadata_for_node(self, node):
-        """
-        Return the metadata associated with the node.
-
-        :param      node: Node instance
-        :type       node: :class:`Node`
-
-        :return: A dictionary or other mapping of strings to strings,
-                 associating tag names with tag values.
-        :type tags: ``dict``
-        """
-        return node.extra['metadata']
-
-    def ex_pause_node(self, node):
-        uri = '/servers/%s/action' % (node.id)
-        data = {'pause': None}
-        resp = self.connection.request(uri, method='POST', data=data)
-        return resp.status == httplib.ACCEPTED
-
-    def ex_unpause_node(self, node):
-        uri = '/servers/%s/action' % (node.id)
-        data = {'unpause': None}
-        resp = self.connection.request(uri, method='POST', data=data)
-        return resp.status == httplib.ACCEPTED
-
-    def ex_suspend_node(self, node):
-        uri = '/servers/%s/action' % (node.id)
-        data = {'suspend': None}
-        resp = self.connection.request(uri, method='POST', data=data)
-        return resp.status == httplib.ACCEPTED
-
-    def ex_resume_node(self, node):
-        uri = '/servers/%s/action' % (node.id)
-        data = {'resume': None}
-        resp = self.connection.request(uri, method='POST', data=data)
-        return resp.status == httplib.ACCEPTED
-
-
-class OpenStack_1_1_FloatingIpPool(object):
-    """
-    Floating IP Pool info.
-    """
-
-    def __init__(self, name, connection):
-        self.name = name
-        self.connection = connection
-
-    def list_floating_ips(self):
-        """
-        List floating IPs in the pool
-
-        :rtype: ``list`` of :class:`OpenStack_1_1_FloatingIpAddress`
-        """
-        return self._to_floating_ips(
-            self.connection.request('/os-floating-ips').object)
-
-    def _to_floating_ips(self, obj):
-        ip_elements = obj['floating_ips']
-        return [self._to_floating_ip(ip) for ip in ip_elements]
-
-    def _to_floating_ip(self, obj):
-        return OpenStack_1_1_FloatingIpAddress(id=obj['id'],
-                                               ip_address=obj['ip'],
-                                               pool=self,
-                                               node_id=obj['instance_id'],
-                                               driver=self.connection.driver)
-
-    def get_floating_ip(self, ip):
-        """
-        Get specified floating IP from the pool
-
-        :param      ip: floating IP to get
-        :type       ip: ``str``
-
-        :rtype: :class:`OpenStack_1_1_FloatingIpAddress`
-        """
-        ip_obj, = [x for x in self.list_floating_ips() if x.ip_address == ip]
-        return ip_obj
-
-    def create_floating_ip(self):
-        """
-        Create new floating IP in the pool
-
-        :rtype: :class:`OpenStack_1_1_FloatingIpAddress`
-        """
-        resp = self.connection.request('/os-floating-ips',
-                                       method='POST',
-                                       data={'pool': self.name})
-        data = resp.object['floating_ip']
-        id = data['id']
-        ip_address = data['ip']
-        return OpenStack_1_1_FloatingIpAddress(id=id,
-                                               ip_address=ip_address,
-                                               pool=self,
-                                               node_id=None,
-                                               driver=self.connection.driver)
-
-    def delete_floating_ip(self, ip):
-        """
-        Delete specified floating IP from the pool
-
-        :param      ip: floating IP to remove
-        :type       ip::class:`OpenStack_1_1_FloatingIpAddress`
-
-        :rtype: ``bool``
-        """
-        resp = self.connection.request('/os-floating-ips/%s' % ip.id,
-                                       method='DELETE')
-        return resp.status in (httplib.NO_CONTENT, httplib.ACCEPTED)
-
-    def __repr__(self):
-        return ('<OpenStack_1_1_FloatingIpPool: name=%s>' % self.name)
-
-
-cl

<TRUNCATED>

[09/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/elb.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/elb.py b/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/elb.py
deleted file mode 100644
index f67a522..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/elb.py
+++ /dev/null
@@ -1,351 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-__all__ = [
-    'ElasticLBDriver'
-]
-
-
-from libcloud.utils.py3 import httplib
-from libcloud.utils.xml import findtext, findall
-from libcloud.loadbalancer.types import State
-from libcloud.loadbalancer.base import Driver, LoadBalancer, Member
-from libcloud.common.aws import AWSGenericResponse, SignedAWSConnection
-
-
-VERSION = '2012-06-01'
-HOST = 'elasticloadbalancing.%s.amazonaws.com'
-ROOT = '/%s/' % (VERSION)
-NS = 'http://elasticloadbalancing.amazonaws.com/doc/%s/' % (VERSION, )
-
-
-class ELBResponse(AWSGenericResponse):
-    """
-    Amazon ELB response class.
-    """
-    namespace = NS
-    exceptions = {}
-    xpath = 'Error'
-
-
-class ELBConnection(SignedAWSConnection):
-    version = VERSION
-    host = HOST
-    responseCls = ELBResponse
-    service_name = 'elb'
-
-
-class ElasticLBDriver(Driver):
-    name = 'Amazon Elastic Load Balancing'
-    website = 'http://aws.amazon.com/elasticloadbalancing/'
-    connectionCls = ELBConnection
-
-    def __init__(self, access_id, secret, region):
-        super(ElasticLBDriver, self).__init__(access_id, secret)
-        self.region = region
-        self.connection.host = HOST % (region)
-
-    def list_protocols(self):
-        return ['tcp', 'ssl', 'http', 'https']
-
-    def list_balancers(self):
-        params = {'Action': 'DescribeLoadBalancers'}
-        data = self.connection.request(ROOT, params=params).object
-        return self._to_balancers(data)
-
-    def create_balancer(self, name, port, protocol, algorithm, members,
-                        ex_members_availability_zones=None):
-        if ex_members_availability_zones is None:
-            ex_members_availability_zones = ['a']
-
-        params = {
-            'Action': 'CreateLoadBalancer',
-            'LoadBalancerName': name,
-            'Listeners.member.1.InstancePort': str(port),
-            'Listeners.member.1.InstanceProtocol': protocol.upper(),
-            'Listeners.member.1.LoadBalancerPort': str(port),
-            'Listeners.member.1.Protocol': protocol.upper(),
-        }
-
-        for i, z in enumerate(ex_members_availability_zones):
-            zone = ''.join((self.region, z))
-            params['AvailabilityZones.member.%d' % (i + 1)] = zone
-
-        data = self.connection.request(ROOT, params=params).object
-
-        balancer = LoadBalancer(
-            id=name,
-            name=name,
-            state=State.PENDING,
-            ip=findtext(element=data, xpath='DNSName', namespace=NS),
-            port=port,
-            driver=self.connection.driver
-        )
-        balancer._members = []
-        return balancer
-
-    def destroy_balancer(self, balancer):
-        params = {
-            'Action': 'DeleteLoadBalancer',
-            'LoadBalancerName': balancer.id
-        }
-        self.connection.request(ROOT, params=params)
-        return True
-
-    def get_balancer(self, balancer_id):
-        params = {
-            'Action': 'DescribeLoadBalancers',
-            'LoadBalancerNames.member.1': balancer_id
-        }
-        data = self.connection.request(ROOT, params=params).object
-        return self._to_balancers(data)[0]
-
-    def balancer_attach_compute_node(self, balancer, node):
-        params = {
-            'Action': 'RegisterInstancesWithLoadBalancer',
-            'LoadBalancerName': balancer.id,
-            'Instances.member.1.InstanceId': node.id
-        }
-        self.connection.request(ROOT, params=params)
-        balancer._members.append(Member(node.id, None, None, balancer=self))
-
-    def balancer_detach_member(self, balancer, member):
-        params = {
-            'Action': 'DeregisterInstancesFromLoadBalancer',
-            'LoadBalancerName': balancer.id,
-            'Instances.member.1.InstanceId': member.id
-        }
-        self.connection.request(ROOT, params=params)
-        balancer._members = [m for m in balancer._members if m.id != member.id]
-        return True
-
-    def balancer_list_members(self, balancer):
-        return balancer._members
-
-    def ex_list_balancer_policies(self, balancer):
-        """
-        Return a list of policy description string.
-
-        :rtype: ``list`` of ``str``
-        """
-        params = {
-            'Action': 'DescribeLoadBalancerPolicies',
-            'LoadBalancerName': balancer.id
-        }
-
-        data = self.connection.request(ROOT, params=params).object
-        return self._to_policies(data)
-
-    def ex_list_balancer_policy_types(self):
-        """
-        Return a list of policy type description string.
-
-        :rtype: ``list`` of ``str``
-        """
-        params = {'Action': 'DescribeLoadBalancerPolicyTypes'}
-
-        data = self.connection.request(ROOT, params=params).object
-        return self._to_policy_types(data)
-
-    def ex_create_balancer_policy(self, name, policy_name, policy_type,
-                                  policy_attributes=None):
-        """
-        Create a new load balancer policy
-
-        :param name: Balancer name to create the policy for
-        :type  name: ``str``
-
-        :param policy_name: policy to be created
-        :type  policy_name: ``str``
-
-        :param policy_type: policy type being used to create policy.
-        :type  policy_type: ``str``
-
-        :param policy_attributes: Each list contain values, ['AttributeName',
-                                                             'value']
-        :type  policy_attributes: ``PolicyAttribute list``
-        """
-        params = {
-            'Action': 'CreateLoadBalancerPolicy',
-            'LoadBalancerName': name,
-            'PolicyName': policy_name,
-            'PolicyTypeName': policy_type
-        }
-
-        if policy_attributes is not None:
-            for index, (name, value) in enumerate(
-                    policy_attributes.iteritems(), 1):
-                params['PolicyAttributes.member.%d. \
-                        AttributeName' % (index)] = name
-                params['PolicyAttributes.member.%d. \
-                        AttributeValue' % (index)] = value
-
-        response = self.connection.request(ROOT, params=params)
-        return response.status == httplib.OK
-
-    def ex_delete_balancer_policy(self, name, policy_name):
-        """
-        Delete a load balancer policy
-
-        :param name: balancer name for which policy will be deleted
-        :type  name: ``str``
-
-        :param policy_name: The Mnemonic name for the policy being deleted
-        :type  policy_name: ``str``
-        """
-        params = {
-            'Action': 'DeleteLoadBalancerPolicy',
-            'LoadBalancerName': name,
-            'PolicyName': policy_name
-        }
-
-        response = self.connection.request(ROOT, params=params)
-        return response.status == httplib.OK
-
-    def ex_set_balancer_policies_listener(self, name, port, policies):
-        """
-        Associates, updates, or disables a policy with a listener on
-        the load balancer
-
-        :param name: balancer name to set policies for listerner
-        :type  name: ``str``
-
-        :param port: port to use
-        :type  port: ``str``
-
-        :param policies: List of policies to be associated with the balancer
-        :type  policies: ``string list``
-        """
-        params = {
-            'Action': 'SetLoadBalancerPoliciesOfListener',
-            'LoadBalancerName': name,
-            'LoadBalancerPort': str(port)
-        }
-
-        if policies:
-            params = self._create_list_params(params, policies,
-                                              'PolicyNames.member.%d')
-
-        response = self.connection.request(ROOT, params=params)
-        return response.status == httplib.OK
-
-    def ex_set_balancer_policies_backend_server(self, name, instance_port,
-                                                policies):
-        """
-        Replaces the current set of policies associated with a port on
-        which the back-end server is listening with a new set of policies
-
-        :param name: balancer name to set policies of backend server
-        :type  name: ``str``
-
-        :param instance_port: Instance Port
-        :type  instance_port: ``int``
-
-        :param policies: List of policies to be associated with the balancer
-        :type  policies: ``string list`
-        """
-        params = {
-            'Action': 'SetLoadBalancerPoliciesForBackendServer',
-            'LoadBalancerName': name,
-            'InstancePort': str(instance_port)
-        }
-
-        if policies:
-            params = self._create_list_params(params, policies,
-                                              'PolicyNames.member.%d')
-
-        response = self.connection.request(ROOT, params=params)
-        return response.status == httplib.OK
-
-    def ex_create_balancer_listeners(self, name, listeners=None):
-        """
-        Creates one or more listeners on a load balancer for the specified port
-
-        :param name: The mnemonic name associated with the load balancer
-        :type  name: ``str``
-
-        :param listeners: Each tuple contain values, (LoadBalancerPortNumber,
-                          InstancePortNumber, Protocol,[SSLCertificateId])
-        :type  listeners: ``list of tuple`
-        """
-        params = {
-            'Action': 'CreateLoadBalancerListeners',
-            'LoadBalancerName': name
-        }
-
-        for index, listener in enumerate(listeners):
-            i = index + 1
-            protocol = listener[2].upper()
-            params['Listeners.member.%d.LoadBalancerPort' % i] = listener[0]
-            params['Listeners.member.%d.InstancePort' % i] = listener[1]
-            params['Listeners.member.%d.Protocol' % i] = listener[2]
-            if protocol == 'HTTPS' or protocol == 'SSL':
-                params['Listeners.member.%d.   \
-                        SSLCertificateId' % i] = listener[3]
-        else:
-            return False
-
-        response = self.connection.request(ROOT, params=params)
-        return response.status == httplib.OK
-
-    def _to_policies(self, data):
-        xpath = 'DescribeLoadBalancerPoliciesResult/PolicyDescriptions/member'
-        return [findtext(element=el, xpath='PolicyName', namespace=NS)
-                for el in findall(element=data, xpath=xpath, namespace=NS)]
-
-    def _to_policy_types(self, data):
-        xpath = 'DescribeLoadBalancerPolicyTypesResult/'
-        xpath += 'PolicyTypeDescriptions/member'
-        return [findtext(element=el, xpath='PolicyTypeName', namespace=NS)
-                for el in findall(element=data, xpath=xpath, namespace=NS)]
-
-    def _to_balancers(self, data):
-        xpath = 'DescribeLoadBalancersResult/LoadBalancerDescriptions/member'
-        return [self._to_balancer(el)
-                for el in findall(element=data, xpath=xpath, namespace=NS)]
-
-    def _to_balancer(self, el):
-        name = findtext(element=el, xpath='LoadBalancerName', namespace=NS)
-        dns_name = findtext(el, xpath='DNSName', namespace=NS)
-        port = findtext(el, xpath='LoadBalancerPort', namespace=NS)
-
-        balancer = LoadBalancer(
-            id=name,
-            name=name,
-            state=State.UNKNOWN,
-            ip=dns_name,
-            port=port,
-            driver=self.connection.driver
-        )
-
-        xpath = 'Instances/member/InstanceId'
-        members = findall(element=el, xpath=xpath, namespace=NS)
-        balancer._members = []
-
-        for m in members:
-            balancer._members.append(Member(m.text, None, None,
-                                            balancer=balancer))
-
-        return balancer
-
-    def _create_list_params(self, params, items, label):
-        """
-        return parameter list
-        """
-        if isinstance(items, str):
-            items = [items]
-        for index, item in enumerate(items):
-            params[label % (index + 1)] = item
-        return params

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/gce.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/gce.py b/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/gce.py
deleted file mode 100644
index c754221..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/gce.py
+++ /dev/null
@@ -1,369 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-try:
-    import simplejson as json
-except ImportError:
-    import json  # NOQA
-
-from libcloud.loadbalancer.base import LoadBalancer, Member, Driver, Algorithm
-from libcloud.compute.drivers.gce import GCEConnection, GCENodeDriver
-
-# GCE doesn't actually give you an algorithm choice, but this is here simply as
-# the closest match.  The actual algorithm is described here:
-# https://developers.google.com/compute/docs/load-balancing/#overview
-DEFAULT_ALGORITHM = Algorithm.RANDOM
-
-
-class GCELBDriver(Driver):
-    connectionCls = GCEConnection
-    apiname = 'googleapis'
-    name = 'Google Compute Engine Load Balancer'
-    website = 'https://cloud.google.com/'
-
-    _VALUE_TO_ALGORITHM_MAP = {
-        'RANDOM': Algorithm.RANDOM
-    }
-
-    def __init__(self, *args, **kwargs):
-
-        if kwargs.get('gce_driver'):
-            self.gce = kwargs['gce_driver']
-        else:
-            self.gce = GCENodeDriver(*args, **kwargs)
-
-        self.connection = self.gce.connection
-
-    def _get_node_from_ip(self, ip):
-        """
-        Return the node object that matches a given public IP address.
-
-        :param  ip: Public IP address to search for
-        :type   ip: ``str``
-
-        :return:  Node object that has the given IP, or None if not found.
-        :rtype:   :class:`Node` or None
-        """
-        all_nodes = self.gce.list_nodes(ex_zone='all')
-        for node in all_nodes:
-            if ip in node.public_ips:
-                return node
-        return None
-
-    def list_protocols(self):
-        """
-        Return a list of supported protocols.
-
-        For GCE, this is simply a hardcoded list.
-
-        :rtype: ``list`` of ``str``
-        """
-        return ['TCP', 'UDP']
-
-    def list_balancers(self, ex_region=None):
-        """
-        List all loadbalancers
-
-        :keyword  ex_region: The region to return balancers from.  If None,
-                             will default to self.region.  If 'all', will
-                             return all balancers.
-        :type     ex_region: ``str`` or :class:`GCERegion` or ``None``
-
-        :rtype: ``list`` of :class:`LoadBalancer`
-        """
-        balancers = []
-        for fwr in self.gce.ex_list_forwarding_rules(region=ex_region):
-            balancers.append(self._forwarding_rule_to_loadbalancer(fwr))
-        return balancers
-
-    def create_balancer(self, name, port, protocol, algorithm, members,
-                        ex_region=None, ex_healthchecks=None, ex_address=None,
-                        ex_session_affinity=None):
-        """
-        Create a new load balancer instance.
-
-        For GCE, this means creating a forwarding rule and a matching target
-        pool, then adding the members to the target pool.
-
-        :param  name: Name of the new load balancer (required)
-        :type   name: ``str``
-
-        :param  port: Port or range of ports the load balancer should listen
-                      on, defaults to all ports.  Examples: '80', '5000-5999'
-        :type   port: ``str``
-
-        :param  protocol: Load balancer protocol.  Should be 'tcp' or 'udp',
-                          defaults to 'tcp'.
-        :type   protocol: ``str``
-
-        :param  members: List of Members to attach to balancer.  Can be Member
-                         objects or Node objects.  Node objects are preferred
-                         for GCE, but Member objects are accepted to comply
-                         with the established libcloud API.  Note that the
-                         'port' attribute of the members is ignored.
-        :type   members: ``list`` of :class:`Member` or :class:`Node`
-
-        :param  algorithm: Load balancing algorithm.  Ignored for GCE which
-                           uses a hashing-based algorithm.
-        :type   algorithm: :class:`Algorithm` or ``None``
-
-        :keyword  ex_region:  Optional region to create the load balancer in.
-                              Defaults to the default region of the GCE Node
-                              Driver.
-        :type     ex_region:  C{GCERegion} or ``str``
-
-        :keyword  ex_healthchecks: Optional list of healthcheck objects or
-                                   names to add to the load balancer.
-        :type     ex_healthchecks: ``list`` of :class:`GCEHealthCheck` or
-                                   ``list`` of ``str``
-
-        :keyword  ex_address: Optional static address object to be assigned to
-                              the load balancer.
-        :type     ex_address: C{GCEAddress}
-
-        :keyword  ex_session_affinity: Optional algorithm to use for session
-                                       affinity.  This will modify the hashing
-                                       algorithm such that a client will tend
-                                       to stick to a particular Member.
-        :type     ex_session_affinity: ``str``
-
-        :return:  LoadBalancer object
-        :rtype:   :class:`LoadBalancer`
-        """
-        node_list = []
-        for member in members:
-            # Member object
-            if hasattr(member, 'ip'):
-                if member.extra.get('node'):
-                    node_list.append(member.extra['node'])
-                else:
-                    node_list.append(self._get_node_from_ip(member.ip))
-            # Node object
-            elif hasattr(member, 'name'):
-                node_list.append(member)
-            # Assume it's a node name otherwise
-            else:
-                node_list.append(self.gce.ex_get_node(member, 'all'))
-
-        # Create Target Pool
-        tp_name = '%s-tp' % name
-        targetpool = self.gce.ex_create_targetpool(
-            tp_name, region=ex_region, healthchecks=ex_healthchecks,
-            nodes=node_list, session_affinity=ex_session_affinity)
-
-        # Create the Forwarding rule, but if it fails, delete the target pool.
-        try:
-            forwarding_rule = self.gce.ex_create_forwarding_rule(
-                name, targetpool, region=ex_region, protocol=protocol,
-                port_range=port, address=ex_address)
-        except:
-            targetpool.destroy()
-            raise
-
-        # Reformat forwarding rule to LoadBalancer object
-        return self._forwarding_rule_to_loadbalancer(forwarding_rule)
-
-    def destroy_balancer(self, balancer):
-        """
-        Destroy a load balancer.
-
-        For GCE, this means destroying the associated forwarding rule, then
-        destroying the target pool that was attached to the forwarding rule.
-
-        :param  balancer: LoadBalancer which should be used
-        :type   balancer: :class:`LoadBalancer`
-
-        :return:  True if successful
-        :rtype:   ``bool``
-        """
-        destroy = balancer.extra['forwarding_rule'].destroy()
-        if destroy:
-            tp_destroy = balancer.extra['targetpool'].destroy()
-            return tp_destroy
-        else:
-            return destroy
-
-    def get_balancer(self, balancer_id):
-        """
-        Return a :class:`LoadBalancer` object.
-
-        :param  balancer_id: Name of load balancer you wish to fetch.  For GCE,
-                             this is the name of the associated forwarding
-                             rule.
-        :param  balancer_id: ``str``
-
-        :rtype: :class:`LoadBalancer`
-        """
-        fwr = self.gce.ex_get_forwarding_rule(balancer_id)
-        return self._forwarding_rule_to_loadbalancer(fwr)
-
-    def balancer_attach_compute_node(self, balancer, node):
-        """
-        Attach a compute node as a member to the load balancer.
-
-        :param balancer: LoadBalancer which should be used
-        :type  balancer: :class:`LoadBalancer`
-
-        :param node: Node to join to the balancer
-        :type  node: :class:`Node`
-
-        :return: Member after joining the balancer.
-        :rtype: :class:`Member`
-        """
-        add_node = balancer.extra['targetpool'].add_node(node)
-        if add_node:
-            return self._node_to_member(node, balancer)
-
-    def balancer_attach_member(self, balancer, member):
-        """
-        Attach a member to balancer
-
-        :param balancer: LoadBalancer which should be used
-        :type  balancer: :class:`LoadBalancer`
-
-        :param member: Member to join to the balancer
-        :type member: :class:`Member`
-
-        :return: Member after joining the balancer.
-        :rtype: :class:`Member`
-        """
-        node = member.extra.get('node') or self._get_node_from_ip(member.ip)
-        add_node = balancer.extra['targetpool'].add_node(node)
-        if add_node:
-            return self._node_to_member(node, balancer)
-
-    def balancer_detach_member(self, balancer, member):
-        """
-        Detach member from balancer
-
-        :param balancer: LoadBalancer which should be used
-        :type  balancer: :class:`LoadBalancer`
-
-        :param member: Member which should be used
-        :type member: :class:`Member`
-
-        :return: True if member detach was successful, otherwise False
-        :rtype: ``bool``
-        """
-        node = member.extra.get('node') or self._get_node_from_ip(member.ip)
-        remove_node = balancer.extra['targetpool'].remove_node(node)
-        return remove_node
-
-    def balancer_list_members(self, balancer):
-        """
-        Return list of members attached to balancer
-
-        :param balancer: LoadBalancer which should be used
-        :type  balancer: :class:`LoadBalancer`
-
-        :rtype: ``list`` of :class:`Member`
-        """
-        return [self._node_to_member(n, balancer) for n in
-                balancer.extra['targetpool'].nodes]
-
-    def ex_create_healthcheck(self, *args, **kwargs):
-        return self.gce.ex_create_healthcheck(*args, **kwargs)
-
-    def ex_list_healthchecks(self):
-        return self.gce.ex_list_healthchecks()
-
-    def ex_balancer_attach_healthcheck(self, balancer, healthcheck):
-        """
-        Attach a healthcheck to balancer
-
-        :param balancer: LoadBalancer which should be used
-        :type  balancer: :class:`LoadBalancer`
-
-        :param healthcheck: Healthcheck to add
-        :type  healthcheck: :class:`GCEHealthCheck`
-
-        :return: True if successful
-        :rtype:  ``bool``
-        """
-        return balancer.extra['targetpool'].add_healthcheck(healthcheck)
-
-    def ex_balancer_detach_healthcheck(self, balancer, healthcheck):
-        """
-        Detach healtcheck from balancer
-
-        :param balancer: LoadBalancer which should be used
-        :type  balancer: :class:`LoadBalancer`
-
-        :param healthcheck: Healthcheck to remove
-        :type  healthcheck: :class:`GCEHealthCheck`
-
-        :return: True if successful
-        :rtype: ``bool``
-        """
-        return balancer.extra['targetpool'].remove_healthcheck(healthcheck)
-
-    def ex_balancer_list_healthchecks(self, balancer):
-        """
-        Return list of healthchecks attached to balancer
-
-        :param  balancer: LoadBalancer which should be used
-        :type   balancer: :class:`LoadBalancer`
-
-        :rtype: ``list`` of :class:`HealthChecks`
-        """
-        return balancer.extra['healthchecks']
-
-    def _node_to_member(self, node, balancer):
-        """
-        Return a Member object based on a Node.
-
-        :param  node: Node object
-        :type   node: :class:`Node`
-
-        :keyword  balancer: The balancer the member is attached to.
-        :type     balancer: :class:`LoadBalancer`
-
-        :return:  Member object
-        :rtype:   :class:`Member`
-        """
-        # A balancer can have a node as a member, even if the node doesn't
-        # exist.  In this case, 'node' is simply a string to where the resource
-        # would be found if it was there.
-        if hasattr(node, 'name'):
-            member_id = node.name
-            member_ip = node.public_ips[0]
-        else:
-            member_id = node
-            member_ip = None
-
-        extra = {'node': node}
-        return Member(id=member_id, ip=member_ip, port=balancer.port,
-                      balancer=balancer, extra=extra)
-
-    def _forwarding_rule_to_loadbalancer(self, forwarding_rule):
-        """
-        Return a Load Balancer object based on a GCEForwardingRule object.
-
-        :param  forwarding_rule: ForwardingRule object
-        :type   forwarding_rule: :class:`GCEForwardingRule`
-
-        :return:  LoadBalancer object
-        :rtype:   :class:`LoadBalancer`
-        """
-        extra = {}
-        extra['forwarding_rule'] = forwarding_rule
-        extra['targetpool'] = forwarding_rule.targetpool
-        extra['healthchecks'] = forwarding_rule.targetpool.healthchecks
-
-        return LoadBalancer(id=forwarding_rule.id,
-                            name=forwarding_rule.name, state=None,
-                            ip=forwarding_rule.address,
-                            port=forwarding_rule.extra['portRange'],
-                            driver=self, extra=extra)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/gogrid.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/gogrid.py b/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/gogrid.py
deleted file mode 100644
index 201ad03..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/gogrid.py
+++ /dev/null
@@ -1,239 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 sys
-import time
-
-from libcloud.utils.py3 import httplib
-
-try:
-    import simplejson as json
-except ImportError:
-    import json
-
-from libcloud.utils.misc import reverse_dict
-from libcloud.common.types import LibcloudError
-from libcloud.common.gogrid import GoGridConnection, GoGridResponse,\
-    BaseGoGridDriver
-from libcloud.loadbalancer.base import LoadBalancer, Member, Driver, Algorithm
-from libcloud.loadbalancer.base import DEFAULT_ALGORITHM
-from libcloud.loadbalancer.types import State, LibcloudLBImmutableError
-
-
-class GoGridLBResponse(GoGridResponse):
-    def success(self):
-        if self.status == httplib.INTERNAL_SERVER_ERROR:
-            # Hack, but at least this error message is more useful than
-            # "unexpected server error"
-            body = json.loads(self.body)
-            if body['method'] == '/grid/loadbalancer/add' and \
-                len(body['list']) >= 1 and \
-                body['list'][0]['message'].find(
-                    'unexpected server error') != -1:
-                raise LibcloudError(
-                    value='You mostly likely tried to add a member with an IP'
-                          ' address not assigned to your account', driver=self)
-        return super(GoGridLBResponse, self).success()
-
-
-class GoGridLBConnection(GoGridConnection):
-    """
-    Connection class for the GoGrid load-balancer driver.
-    """
-    responseCls = GoGridLBResponse
-
-
-class GoGridLBDriver(BaseGoGridDriver, Driver):
-    connectionCls = GoGridLBConnection
-    api_name = 'gogrid_lb'
-    name = 'GoGrid LB'
-    website = 'http://www.gogrid.com/'
-
-    LB_STATE_MAP = {'On': State.RUNNING,
-                    'Unknown': State.UNKNOWN}
-    _VALUE_TO_ALGORITHM_MAP = {
-        'round robin': Algorithm.ROUND_ROBIN,
-        'least connect': Algorithm.LEAST_CONNECTIONS
-    }
-    _ALGORITHM_TO_VALUE_MAP = reverse_dict(_VALUE_TO_ALGORITHM_MAP)
-
-    def __init__(self, *args, **kwargs):
-        """
-        @inherits: :class:`Driver.__init__`
-        """
-        super(GoGridLBDriver, self).__init__(*args, **kwargs)
-
-    def list_protocols(self):
-        # GoGrid only supports http
-        return ['http']
-
-    def list_balancers(self):
-        return self._to_balancers(
-            self.connection.request('/api/grid/loadbalancer/list').object)
-
-    def ex_create_balancer_nowait(self, name, members, protocol='http',
-                                  port=80, algorithm=DEFAULT_ALGORITHM):
-        """
-        @inherits: :class:`Driver.create_balancer`
-        """
-        algorithm = self._algorithm_to_value(algorithm)
-
-        params = {'name': name,
-                  'loadbalancer.type': algorithm,
-                  'virtualip.ip': self._get_first_ip(),
-                  'virtualip.port': port}
-        params.update(self._members_to_params(members))
-
-        resp = self.connection.request('/api/grid/loadbalancer/add',
-                                       method='GET',
-                                       params=params)
-        return self._to_balancers(resp.object)[0]
-
-    def create_balancer(self, name, members, protocol='http', port=80,
-                        algorithm=DEFAULT_ALGORITHM):
-        balancer = self.ex_create_balancer_nowait(name, members, protocol,
-                                                  port, algorithm)
-
-        timeout = 60 * 20
-        waittime = 0
-        interval = 2 * 15
-
-        if balancer.id is not None:
-            return balancer
-        else:
-            while waittime < timeout:
-                balancers = self.list_balancers()
-
-                for i in balancers:
-                    if i.name == balancer.name and i.id is not None:
-                        return i
-
-                waittime += interval
-                time.sleep(interval)
-
-        raise Exception('Failed to get id')
-
-    def destroy_balancer(self, balancer):
-        try:
-            resp = self.connection.request(
-                '/api/grid/loadbalancer/delete', method='POST',
-                params={'id': balancer.id})
-        except Exception:
-            e = sys.exc_info()[1]
-            if "Update request for LoadBalancer" in str(e):
-                raise LibcloudLBImmutableError(
-                    "Cannot delete immutable object", GoGridLBDriver)
-            else:
-                raise
-
-        return resp.status == 200
-
-    def get_balancer(self, **kwargs):
-        params = {}
-
-        try:
-            params['name'] = kwargs['ex_balancer_name']
-        except KeyError:
-            balancer_id = kwargs['balancer_id']
-            params['id'] = balancer_id
-
-        resp = self.connection.request('/api/grid/loadbalancer/get',
-                                       params=params)
-
-        return self._to_balancers(resp.object)[0]
-
-    def balancer_attach_member(self, balancer, member):
-        members = self.balancer_list_members(balancer)
-        members.append(member)
-
-        params = {"id": balancer.id}
-
-        params.update(self._members_to_params(members))
-
-        resp = self._update_balancer(params)
-        return [m for m in
-                self._to_members(resp.object["list"][0]["realiplist"],
-                                 balancer)
-                if m.ip == member.ip][0]
-
-    def balancer_detach_member(self, balancer, member):
-        members = self.balancer_list_members(balancer)
-
-        remaining_members = [n for n in members if n.id != member.id]
-
-        params = {"id": balancer.id}
-        params.update(self._members_to_params(remaining_members))
-
-        resp = self._update_balancer(params)
-
-        return resp.status == 200
-
-    def balancer_list_members(self, balancer):
-        resp = self.connection.request('/api/grid/loadbalancer/get',
-                                       params={'id': balancer.id})
-        return self._to_members(resp.object["list"][0]["realiplist"], balancer)
-
-    def _update_balancer(self, params):
-        try:
-            return self.connection.request('/api/grid/loadbalancer/edit',
-                                           method='POST',
-                                           params=params)
-        except Exception:
-            e = sys.exc_info()[1]
-            if "Update already pending" in str(e):
-                raise LibcloudLBImmutableError(
-                    "Balancer is immutable", GoGridLBDriver)
-
-        raise LibcloudError(value='Exception: %s' % str(e), driver=self)
-
-    def _members_to_params(self, members):
-        """
-        Helper method to convert list of :class:`Member` objects
-        to GET params.
-
-        """
-
-        params = {}
-
-        i = 0
-        for member in members:
-            params["realiplist.%s.ip" % i] = member.ip
-            params["realiplist.%s.port" % i] = member.port
-            i += 1
-
-        return params
-
-    def _to_balancers(self, object):
-        return [self._to_balancer(el) for el in object["list"]]
-
-    def _to_balancer(self, el):
-        lb = LoadBalancer(id=el.get("id"),
-                          name=el["name"],
-                          state=self.LB_STATE_MAP.get(
-                              el["state"]["name"], State.UNKNOWN),
-                          ip=el["virtualip"]["ip"]["ip"],
-                          port=el["virtualip"]["port"],
-                          driver=self.connection.driver)
-        return lb
-
-    def _to_members(self, object, balancer=None):
-        return [self._to_member(el, balancer) for el in object]
-
-    def _to_member(self, el, balancer=None):
-        member = Member(id=el["ip"]["id"],
-                        ip=el["ip"]["ip"],
-                        port=el["port"],
-                        balancer=balancer)
-        return member

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/ninefold.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/ninefold.py b/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/ninefold.py
deleted file mode 100644
index cb28f6c..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/ninefold.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from libcloud.loadbalancer.providers import Provider
-
-from libcloud.loadbalancer.drivers.cloudstack import CloudStackLBDriver
-
-
-class NinefoldLBDriver(CloudStackLBDriver):
-    "Driver for load balancers on Ninefold's Compute platform."
-
-    host = 'api.ninefold.com'
-    path = '/compute/v1.0/'
-
-    type = Provider.NINEFOLD
-    name = 'Ninefold LB'
-    website = 'http://ninefold.com/'


[40/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/cloudstack.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/cloudstack.py b/apache-libcloud-1.0.0rc2/libcloud/common/cloudstack.py
deleted file mode 100644
index c40ed0f..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/cloudstack.py
+++ /dev/null
@@ -1,199 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 base64
-import hashlib
-import copy
-import hmac
-
-from libcloud.utils.py3 import httplib
-from libcloud.utils.py3 import urlencode
-from libcloud.utils.py3 import urlquote
-from libcloud.utils.py3 import b
-
-from libcloud.common.types import ProviderError
-from libcloud.common.base import ConnectionUserAndKey, PollingConnection
-from libcloud.common.base import JsonResponse
-from libcloud.common.types import MalformedResponseError
-from libcloud.compute.types import InvalidCredsError
-
-
-class CloudStackResponse(JsonResponse):
-    def parse_error(self):
-        if self.status == httplib.UNAUTHORIZED:
-            raise InvalidCredsError('Invalid provider credentials')
-
-        value = None
-        body = self.parse_body()
-        if hasattr(body, 'values'):
-            values = list(body.values())[0]
-            if 'errortext' in values:
-                value = values['errortext']
-        if value is None:
-            value = self.body
-
-        if not value:
-            value = 'WARNING: error message text sent by provider was empty.'
-
-        error = ProviderError(value=value, http_code=self.status,
-                              driver=self.connection.driver)
-        raise error
-
-
-class CloudStackConnection(ConnectionUserAndKey, PollingConnection):
-    responseCls = CloudStackResponse
-    poll_interval = 1
-    request_method = '_sync_request'
-    timeout = 600
-
-    ASYNC_PENDING = 0
-    ASYNC_SUCCESS = 1
-    ASYNC_FAILURE = 2
-
-    def encode_data(self, data):
-        """
-        Must of the data is sent as part of query params (eeww),
-        but in newer versions, userdata argument can be sent as a
-        urlencoded data in the request body.
-        """
-        if data:
-            data = urlencode(data)
-
-        return data
-
-    def _make_signature(self, params):
-        signature = [(k.lower(), v) for k, v in list(params.items())]
-        signature.sort(key=lambda x: x[0])
-
-        pairs = []
-        for pair in signature:
-            key = urlquote(str(pair[0]), safe='[]')
-            value = urlquote(str(pair[1]), safe='[]')
-            item = '%s=%s' % (key, value)
-            pairs .append(item)
-
-        signature = '&'.join(pairs)
-
-        signature = signature.lower().replace('+', '%20')
-        signature = hmac.new(b(self.key), msg=b(signature),
-                             digestmod=hashlib.sha1)
-        return base64.b64encode(b(signature.digest()))
-
-    def add_default_params(self, params):
-        params['apiKey'] = self.user_id
-        params['response'] = 'json'
-
-        return params
-
-    def pre_connect_hook(self, params, headers):
-        params['signature'] = self._make_signature(params)
-
-        return params, headers
-
-    def _async_request(self, command, action=None, params=None, data=None,
-                       headers=None, method='GET', context=None):
-        if params:
-            context = copy.deepcopy(params)
-        else:
-            context = {}
-
-        # Command is specified as part of GET call
-        context['command'] = command
-        result = super(CloudStackConnection, self).async_request(
-            action=action, params=params, data=data, headers=headers,
-            method=method, context=context)
-        return result['jobresult']
-
-    def get_request_kwargs(self, action, params=None, data='', headers=None,
-                           method='GET', context=None):
-        command = context['command']
-        request_kwargs = {'command': command, 'action': action,
-                          'params': params, 'data': data,
-                          'headers': headers, 'method': method}
-        return request_kwargs
-
-    def get_poll_request_kwargs(self, response, context, request_kwargs):
-        job_id = response['jobid']
-        params = {'jobid': job_id}
-        kwargs = {'command': 'queryAsyncJobResult', 'params': params}
-        return kwargs
-
-    def has_completed(self, response):
-        status = response.get('jobstatus', self.ASYNC_PENDING)
-
-        if status == self.ASYNC_FAILURE:
-            msg = response.get('jobresult', {}).get('errortext', status)
-            raise Exception(msg)
-
-        return status == self.ASYNC_SUCCESS
-
-    def _sync_request(self, command, action=None, params=None, data=None,
-                      headers=None, method='GET'):
-        """
-        This method handles synchronous calls which are generally fast
-        information retrieval requests and thus return 'quickly'.
-        """
-        # command is always sent as part of "command" query parameter
-        if params:
-            params = copy.deepcopy(params)
-        else:
-            params = {}
-
-        params['command'] = command
-        result = self.request(action=self.driver.path, params=params,
-                              data=data, headers=headers, method=method)
-
-        command = command.lower()
-
-        # Work around for older verions which don't return "response" suffix
-        # in delete ingress rule response command name
-        if (command == 'revokesecuritygroupingress' and
-                'revokesecuritygroupingressresponse' not in result.object):
-            command = command
-        else:
-            command = command + 'response'
-
-        if command not in result.object:
-            raise MalformedResponseError(
-                "Unknown response format",
-                body=result.body,
-                driver=self.driver)
-        result = result.object[command]
-        return result
-
-
-class CloudStackDriverMixIn(object):
-    host = None
-    path = None
-
-    connectionCls = CloudStackConnection
-
-    def __init__(self, key, secret=None, secure=True, host=None, port=None):
-        host = host or self.host
-        super(CloudStackDriverMixIn, self).__init__(key, secret, secure, host,
-                                                    port)
-
-    def _sync_request(self, command, action=None, params=None, data=None,
-                      headers=None, method='GET'):
-        return self.connection._sync_request(command=command, action=action,
-                                             params=params, data=data,
-                                             headers=headers, method=method)
-
-    def _async_request(self, command, action=None, params=None, data=None,
-                       headers=None, method='GET', context=None):
-        return self.connection._async_request(command=command, action=action,
-                                              params=params, data=data,
-                                              headers=headers, method=method,
-                                              context=context)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/digitalocean.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/digitalocean.py b/apache-libcloud-1.0.0rc2/libcloud/common/digitalocean.py
deleted file mode 100644
index 2e6f329..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/digitalocean.py
+++ /dev/null
@@ -1,250 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-Common settings and connection objects for DigitalOcean Cloud
-"""
-import warnings
-
-from libcloud.utils.py3 import httplib, parse_qs, urlparse
-
-from libcloud.common.base import BaseDriver
-from libcloud.common.base import ConnectionUserAndKey, ConnectionKey
-from libcloud.common.base import JsonResponse
-from libcloud.common.types import InvalidCredsError
-
-__all__ = [
-    'DigitalOcean_v1_Response',
-    'DigitalOcean_v1_Connection',
-    'DigitalOcean_v2_Response',
-    'DigitalOcean_v2_Connection',
-    'DigitalOceanBaseDriver'
-]
-
-
-class DigitalOcean_v1_Response(JsonResponse):
-    def parse_error(self):
-        if self.status == httplib.FOUND and '/api/error' in self.body:
-            # Hacky, but DigitalOcean error responses are awful
-            raise InvalidCredsError(self.body)
-        elif self.status == httplib.UNAUTHORIZED:
-            body = self.parse_body()
-            raise InvalidCredsError(body['message'])
-        else:
-            body = self.parse_body()
-
-            if 'error_message' in body:
-                error = '%s (code: %s)' % (body['error_message'], self.status)
-            else:
-                error = body
-            return error
-
-
-class DigitalOcean_v1_Connection(ConnectionUserAndKey):
-    """
-    Connection class for the DigitalOcean (v1) driver.
-    """
-
-    host = 'api.digitalocean.com'
-    responseCls = DigitalOcean_v1_Response
-
-    def add_default_params(self, params):
-        """
-        Add parameters that are necessary for every request
-
-        This method adds ``client_id`` and ``api_key`` to
-        the request.
-        """
-        params['client_id'] = self.user_id
-        params['api_key'] = self.key
-        return params
-
-
-class DigitalOcean_v2_Response(JsonResponse):
-    valid_response_codes = [httplib.OK, httplib.ACCEPTED, httplib.CREATED,
-                            httplib.NO_CONTENT]
-
-    def parse_error(self):
-        if self.status == httplib.UNAUTHORIZED:
-            body = self.parse_body()
-            raise InvalidCredsError(body['message'])
-        else:
-            body = self.parse_body()
-            if 'message' in body:
-                error = '%s (code: %s)' % (body['message'], self.status)
-            else:
-                error = body
-            return error
-
-    def success(self):
-        return self.status in self.valid_response_codes
-
-
-class DigitalOcean_v2_Connection(ConnectionKey):
-    """
-    Connection class for the DigitalOcean (v2) driver.
-    """
-
-    host = 'api.digitalocean.com'
-    responseCls = DigitalOcean_v2_Response
-
-    def add_default_headers(self, headers):
-        """
-        Add headers that are necessary for every request
-
-        This method adds ``token`` to the request.
-        """
-        headers['Authorization'] = 'Bearer %s' % (self.key)
-        headers['Content-Type'] = 'application/json'
-        return headers
-
-    def add_default_params(self, params):
-        """
-        Add parameters that are necessary for every request
-
-        This method adds ``per_page`` to the request to reduce the total
-        number of paginated requests to the API.
-        """
-        params['per_page'] = self.driver.ex_per_page
-        return params
-
-
-class DigitalOceanConnection(DigitalOcean_v2_Connection):
-    """
-    Connection class for the DigitalOcean driver.
-    """
-    pass
-
-
-class DigitalOceanResponse(DigitalOcean_v2_Response):
-    pass
-
-
-class DigitalOceanBaseDriver(BaseDriver):
-    """
-    DigitalOcean BaseDriver
-    """
-    name = 'DigitalOcean'
-    website = 'https://www.digitalocean.com'
-
-    def __new__(cls, key, secret=None, api_version='v2', **kwargs):
-        if cls is DigitalOceanBaseDriver:
-            if api_version == 'v1' or secret is not None:
-                cls = DigitalOcean_v1_BaseDriver
-                warnings.warn("The v1 API has become deprecated. Please "
-                              "consider utilizing the v2 API.")
-            elif api_version == 'v2':
-                cls = DigitalOcean_v2_BaseDriver
-            else:
-                raise NotImplementedError('Unsupported API version: %s' %
-                                          (api_version))
-        return super(DigitalOceanBaseDriver, cls).__new__(cls, **kwargs)
-
-    def ex_account_info(self):
-        raise NotImplementedError(
-            'ex_account_info not implemented for this driver')
-
-    def ex_list_events(self):
-        raise NotImplementedError(
-            'ex_list_events not implemented for this driver')
-
-    def ex_get_event(self, event_id):
-        raise NotImplementedError(
-            'ex_get_event not implemented for this driver')
-
-    def _paginated_request(self, url, obj):
-        raise NotImplementedError(
-            '_paginated_requests not implemented for this driver')
-
-
-class DigitalOcean_v1_BaseDriver(DigitalOceanBaseDriver):
-    """
-    DigitalOcean BaseDriver using v1 of the API.
-    """
-    connectionCls = DigitalOcean_v1_Connection
-
-    def ex_get_event(self, event_id):
-        """
-        Get an event object
-
-        :param      event_id: Event id (required)
-        :type       event_id: ``str``
-        """
-        return self.connection.request('/v1/events/%s' % event_id).object
-
-
-class DigitalOcean_v2_BaseDriver(DigitalOceanBaseDriver):
-    """
-    DigitalOcean BaseDriver using v2 of the API.
-
-    Supports `ex_per_page` ``int`` value keyword parameter to adjust per page
-    requests against the API.
-    """
-    connectionCls = DigitalOcean_v2_Connection
-
-    def __init__(self, key, secret=None, secure=True, host=None, port=None,
-                 api_version=None, region=None, ex_per_page=200, **kwargs):
-        self.ex_per_page = ex_per_page
-        super(DigitalOcean_v2_BaseDriver, self).__init__(key, **kwargs)
-
-    def ex_account_info(self):
-        return self.connection.request('/v2/account').object['account']
-
-    def ex_list_events(self):
-        return self._paginated_request('/v2/actions', 'actions')
-
-    def ex_get_event(self, event_id):
-        """
-        Get an event object
-
-        :param      event_id: Event id (required)
-        :type       event_id: ``str``
-        """
-        params = {}
-        return self.connection.request('/v2/actions/%s' % event_id,
-                                       params=params).object['action']
-
-    def _paginated_request(self, url, obj):
-        """
-        Perform multiple calls in order to have a full list of elements when
-        the API responses are paginated.
-
-        :param url: API endpoint
-        :type url: ``str``
-
-        :param obj: Result object key
-        :type obj: ``str``
-
-        :return: ``list`` of API response objects
-        :rtype: ``list``
-        """
-        params = {}
-        data = self.connection.request(url)
-        try:
-            query = urlparse.urlparse(data.object['links']['pages']['last'])
-            # The query[4] references the query parameters from the url
-            pages = parse_qs(query[4])['page'][0]
-            values = data.object[obj]
-            for page in range(2, int(pages) + 1):
-                params.update({'page': page})
-                new_data = self.connection.request(url, params=params)
-
-                more_values = new_data.object[obj]
-                for value in more_values:
-                    values.append(value)
-            data = values
-        except KeyError:  # No pages.
-            data = data.object[obj]
-        return data

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/dimensiondata.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/dimensiondata.py b/apache-libcloud-1.0.0rc2/libcloud/common/dimensiondata.py
deleted file mode 100644
index 40319a2..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/dimensiondata.py
+++ /dev/null
@@ -1,1406 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-Dimension Data Common Components
-"""
-from base64 import b64encode
-from time import sleep
-from libcloud.utils.py3 import httplib
-from libcloud.utils.py3 import b
-from libcloud.common.base import ConnectionUserAndKey, XmlResponse
-from libcloud.common.types import LibcloudError, InvalidCredsError
-from libcloud.compute.base import Node
-from libcloud.utils.py3 import basestring
-from libcloud.utils.xml import findtext
-
-# Roadmap / TODO:
-#
-# 1.0 - Copied from OpSource API, named provider details.
-
-# setup a few variables to represent all of the DimensionData cloud namespaces
-NAMESPACE_BASE = "http://oec.api.opsource.net/schemas"
-ORGANIZATION_NS = NAMESPACE_BASE + "/organization"
-SERVER_NS = NAMESPACE_BASE + "/server"
-NETWORK_NS = NAMESPACE_BASE + "/network"
-DIRECTORY_NS = NAMESPACE_BASE + "/directory"
-GENERAL_NS = NAMESPACE_BASE + "/general"
-BACKUP_NS = NAMESPACE_BASE + "/backup"
-
-# API 2.0 Namespaces and URNs
-TYPES_URN = "urn:didata.com:api:cloud:types"
-
-# API end-points
-API_ENDPOINTS = {
-    'dd-na': {
-        'name': 'North America (NA)',
-        'host': 'api-na.dimensiondata.com',
-        'vendor': 'DimensionData'
-    },
-    'dd-eu': {
-        'name': 'Europe (EU)',
-        'host': 'api-eu.dimensiondata.com',
-        'vendor': 'DimensionData'
-    },
-    'dd-au': {
-        'name': 'Australia (AU)',
-        'host': 'api-au.dimensiondata.com',
-        'vendor': 'DimensionData'
-    },
-    'dd-au-gov': {
-        'name': 'Australia Canberra ACT (AU)',
-        'host': 'api-canberra.dimensiondata.com',
-        'vendor': 'DimensionData'
-    },
-    'dd-af': {
-        'name': 'Africa (AF)',
-        'host': 'api-mea.dimensiondata.com',
-        'vendor': 'DimensionData'
-    },
-    'dd-ap': {
-        'name': 'Asia Pacific (AP)',
-        'host': 'api-ap.dimensiondata.com',
-        'vendor': 'DimensionData'
-    },
-    'dd-latam': {
-        'name': 'South America (LATAM)',
-        'host': 'api-latam.dimensiondata.com',
-        'vendor': 'DimensionData'
-    },
-    'dd-canada': {
-        'name': 'Canada (CA)',
-        'host': 'api-canada.dimensiondata.com',
-        'vendor': 'DimensionData'
-    },
-    'is-na': {
-        'name': 'North America (NA)',
-        'host': 'usapi.cloud.is.co.za',
-        'vendor': 'InternetSolutions'
-    },
-    'is-eu': {
-        'name': 'Europe (EU)',
-        'host': 'euapi.cloud.is.co.za',
-        'vendor': 'InternetSolutions'
-    },
-    'is-au': {
-        'name': 'Australia (AU)',
-        'host': 'auapi.cloud.is.co.za',
-        'vendor': 'InternetSolutions'
-    },
-    'is-af': {
-        'name': 'Africa (AF)',
-        'host': 'meaapi.cloud.is.co.za',
-        'vendor': 'InternetSolutions'
-    },
-    'is-ap': {
-        'name': 'Asia Pacific (AP)',
-        'host': 'apapi.cloud.is.co.za',
-        'vendor': 'InternetSolutions'
-    },
-    'is-latam': {
-        'name': 'South America (LATAM)',
-        'host': 'latamapi.cloud.is.co.za',
-        'vendor': 'InternetSolutions'
-    },
-    'is-canada': {
-        'name': 'Canada (CA)',
-        'host': 'canadaapi.cloud.is.co.za',
-        'vendor': 'InternetSolutions'
-    },
-    'ntta-na': {
-        'name': 'North America (NA)',
-        'host': 'cloudapi.nttamerica.com',
-        'vendor': 'NTTNorthAmerica'
-    },
-    'ntta-eu': {
-        'name': 'Europe (EU)',
-        'host': 'eucloudapi.nttamerica.com',
-        'vendor': 'NTTNorthAmerica'
-    },
-    'ntta-au': {
-        'name': 'Australia (AU)',
-        'host': 'aucloudapi.nttamerica.com',
-        'vendor': 'NTTNorthAmerica'
-    },
-    'ntta-af': {
-        'name': 'Africa (AF)',
-        'host': 'sacloudapi.nttamerica.com',
-        'vendor': 'NTTNorthAmerica'
-    },
-    'ntta-ap': {
-        'name': 'Asia Pacific (AP)',
-        'host': 'hkcloudapi.nttamerica.com',
-        'vendor': 'NTTNorthAmerica'
-    },
-    'cisco-na': {
-        'name': 'North America (NA)',
-        'host': 'iaas-api-na.cisco-ccs.com',
-        'vendor': 'Cisco'
-    },
-    'cisco-eu': {
-        'name': 'Europe (EU)',
-        'host': 'iaas-api-eu.cisco-ccs.com',
-        'vendor': 'Cisco'
-    },
-    'cisco-au': {
-        'name': 'Australia (AU)',
-        'host': 'iaas-api-au.cisco-ccs.com',
-        'vendor': 'Cisco'
-    },
-    'cisco-af': {
-        'name': 'Africa (AF)',
-        'host': 'iaas-api-mea.cisco-ccs.com',
-        'vendor': 'Cisco'
-    },
-    'cisco-ap': {
-        'name': 'Asia Pacific (AP)',
-        'host': 'iaas-api-ap.cisco-ccs.com',
-        'vendor': 'Cisco'
-    },
-    'cisco-latam': {
-        'name': 'South America (LATAM)',
-        'host': 'iaas-api-sa.cisco-ccs.com',
-        'vendor': 'Cisco'
-    },
-    'cisco-canada': {
-        'name': 'Canada (CA)',
-        'host': 'iaas-api-ca.cisco-ccs.com',
-        'vendor': 'Cisco'
-    },
-    'med1-il': {
-        'name': 'Israel (IL)',
-        'host': 'api.cloud.med-1.com',
-        'vendor': 'Med-1'
-    },
-    'med1-na': {
-        'name': 'North America (NA)',
-        'host': 'api-na.cloud.med-1.com',
-        'vendor': 'Med-1'
-    },
-    'med1-eu': {
-        'name': 'Europe (EU)',
-        'host': 'api-eu.cloud.med-1.com',
-        'vendor': 'Med-1'
-    },
-    'med1-au': {
-        'name': 'Australia (AU)',
-        'host': 'api-au.cloud.med-1.com',
-        'vendor': 'Med-1'
-    },
-    'med1-af': {
-        'name': 'Africa (AF)',
-        'host': 'api-af.cloud.med-1.com',
-        'vendor': 'Med-1'
-    },
-    'med1-ap': {
-        'name': 'Asia Pacific (AP)',
-        'host': 'api-ap.cloud.med-1.com',
-        'vendor': 'Med-1'
-    },
-    'med1-latam': {
-        'name': 'South America (LATAM)',
-        'host': 'api-sa.cloud.med-1.com',
-        'vendor': 'Med-1'
-    },
-    'med1-canada': {
-        'name': 'Canada (CA)',
-        'host': 'api-ca.cloud.med-1.com',
-        'vendor': 'Med-1'
-    },
-    'indosat-id': {
-        'name': 'Indonesia (ID)',
-        'host': 'iaas-api.indosat.com',
-        'vendor': 'Indosat'
-    },
-    'indosat-na': {
-        'name': 'North America (NA)',
-        'host': 'iaas-usapi.indosat.com',
-        'vendor': 'Indosat'
-    },
-    'indosat-eu': {
-        'name': 'Europe (EU)',
-        'host': 'iaas-euapi.indosat.com',
-        'vendor': 'Indosat'
-    },
-    'indosat-au': {
-        'name': 'Australia (AU)',
-        'host': 'iaas-auapi.indosat.com',
-        'vendor': 'Indosat'
-    },
-    'indosat-af': {
-        'name': 'Africa (AF)',
-        'host': 'iaas-afapi.indosat.com',
-        'vendor': 'Indosat'
-    },
-    'bsnl-in': {
-        'name': 'India (IN)',
-        'host': 'api.bsnlcloud.com',
-        'vendor': 'BSNL'
-    },
-    'bsnl-na': {
-        'name': 'North America (NA)',
-        'host': 'usapi.bsnlcloud.com',
-        'vendor': 'BSNL'
-    },
-    'bsnl-eu': {
-        'name': 'Europe (EU)',
-        'host': 'euapi.bsnlcloud.com',
-        'vendor': 'BSNL'
-    },
-    'bsnl-au': {
-        'name': 'Australia (AU)',
-        'host': 'auapi.bsnlcloud.com',
-        'vendor': 'BSNL'
-    },
-    'bsnl-af': {
-        'name': 'Africa (AF)',
-        'host': 'afapi.bsnlcloud.com',
-        'vendor': 'BSNL'
-    },
-}
-
-# Default API end-point for the base connection class.
-DEFAULT_REGION = 'dd-na'
-
-BAD_CODE_XML_ELEMENTS = (
-    ('responseCode', SERVER_NS),
-    ('responseCode', TYPES_URN),
-    ('result', GENERAL_NS)
-)
-
-BAD_MESSAGE_XML_ELEMENTS = (
-    ('message', SERVER_NS),
-    ('message', TYPES_URN),
-    ('resultDetail', GENERAL_NS)
-)
-
-
-def dd_object_to_id(obj, obj_type, id_value='id'):
-    """
-    Takes in a DD object or string and prints out it's id
-    This is a helper method, as many of our functions can take either an object
-    or a string, and we need an easy way of converting them
-
-    :param obj: The object to get the id for
-    :type  obj: ``object``
-
-    :param  func: The function to call, e.g. ex_get_vlan. Note: This
-                  function needs to return an object which has ``status``
-                  attribute.
-    :type   func: ``function``
-
-    :rtype: ``str``
-    """
-    if isinstance(obj, obj_type):
-        return getattr(obj, id_value)
-    elif isinstance(obj, (basestring)):
-        return obj
-    else:
-        raise TypeError(
-            "Invalid type %s looking for basestring or %s"
-            % (type(obj).__name__, obj_type.__name__)
-        )
-
-
-class NetworkDomainServicePlan(object):
-    ESSENTIALS = "ESSENTIALS"
-    ADVANCED = "ADVANCED"
-
-
-class DimensionDataResponse(XmlResponse):
-    def parse_error(self):
-        if self.status == httplib.UNAUTHORIZED:
-            raise InvalidCredsError(self.body)
-        elif self.status == httplib.FORBIDDEN:
-            raise InvalidCredsError(self.body)
-
-        body = self.parse_body()
-
-        if self.status == httplib.BAD_REQUEST:
-            for response_code in BAD_CODE_XML_ELEMENTS:
-                code = findtext(body, response_code[0], response_code[1])
-                if code is not None:
-                    break
-            for message in BAD_MESSAGE_XML_ELEMENTS:
-                message = findtext(body, message[0], message[1])
-                if message is not None:
-                    break
-            raise DimensionDataAPIException(code=code,
-                                            msg=message,
-                                            driver=self.connection.driver)
-        if self.status is not httplib.OK:
-            raise DimensionDataAPIException(code=self.status,
-                                            msg=body,
-                                            driver=self.connection.driver)
-
-        return self.body
-
-
-class DimensionDataAPIException(LibcloudError):
-    def __init__(self, code, msg, driver):
-        self.code = code
-        self.msg = msg
-        self.driver = driver
-
-    def __str__(self):
-        return "%s: %s" % (self.code, self.msg)
-
-    def __repr__(self):
-        return ("<DimensionDataAPIException: code='%s', msg='%s'>" %
-                (self.code, self.msg))
-
-
-class DimensionDataConnection(ConnectionUserAndKey):
-    """
-    Connection class for the DimensionData driver
-    """
-
-    api_path_version_1 = '/oec'
-    api_path_version_2 = '/caas'
-    api_version_1 = '0.9'
-    api_version_2 = '2.1'
-
-    _orgId = None
-    responseCls = DimensionDataResponse
-
-    allow_insecure = False
-
-    def __init__(self, user_id, key, secure=True, host=None, port=None,
-                 url=None, timeout=None, proxy_url=None, **conn_kwargs):
-        super(DimensionDataConnection, self).__init__(
-            user_id=user_id,
-            key=key,
-            secure=secure,
-            host=host, port=port,
-            url=url, timeout=timeout,
-            proxy_url=proxy_url)
-
-        if conn_kwargs['region']:
-            self.host = conn_kwargs['region']['host']
-
-    def add_default_headers(self, headers):
-        headers['Authorization'] = \
-            ('Basic %s' % b64encode(b('%s:%s' % (self.user_id,
-                                                 self.key))).decode('utf-8'))
-        headers['Content-Type'] = 'application/xml'
-        return headers
-
-    def request_api_1(self, action, params=None, data='',
-                      headers=None, method='GET'):
-        action = "%s/%s/%s" % (self.api_path_version_1,
-                               self.api_version_1, action)
-
-        return super(DimensionDataConnection, self).request(
-            action=action,
-            params=params, data=data,
-            method=method, headers=headers)
-
-    def request_api_2(self, path, action, params=None, data='',
-                      headers=None, method='GET'):
-        action = "%s/%s/%s/%s" % (self.api_path_version_2,
-                                  self.api_version_2, path, action)
-
-        return super(DimensionDataConnection, self).request(
-            action=action,
-            params=params, data=data,
-            method=method, headers=headers)
-
-    def request_with_orgId_api_1(self, action, params=None, data='',
-                                 headers=None, method='GET'):
-        action = "%s/%s" % (self.get_resource_path_api_1(), action)
-
-        return super(DimensionDataConnection, self).request(
-            action=action,
-            params=params, data=data,
-            method=method, headers=headers)
-
-    def request_with_orgId_api_2(self, action, params=None, data='',
-                                 headers=None, method='GET'):
-        action = "%s/%s" % (self.get_resource_path_api_2(), action)
-
-        return super(DimensionDataConnection, self).request(
-            action=action,
-            params=params, data=data,
-            method=method, headers=headers)
-
-    def paginated_request_with_orgId_api_2(self, action, params=None, data='',
-                                           headers=None, method='GET',
-                                           page_size=250):
-        """
-        A paginated request to the MCP2.0 API
-        This essentially calls out to request_with_orgId_api_2 for each page
-        and yields the response to make a generator
-        This generator can be looped through to grab all the pages.
-
-        :param action: The resource to access (i.e. 'network/vlan')
-        :type  action: ``str``
-
-        :param params: Parameters to give to the action
-        :type  params: ``dict`` or ``None``
-
-        :param data: The data payload to be added to the request
-        :type  data: ``str``
-
-        :param headers: Additional header to be added to the request
-        :type  headers: ``str`` or ``dict`` or ``None``
-
-        :param method: HTTP Method for the request (i.e. 'GET', 'POST')
-        :type  method: ``str``
-
-        :param page_size: The size of each page to be returned
-                          Note: Max page size in MCP2.0 is currently 250
-        :type  page_size: ``int``
-        """
-        if params is None:
-            params = {}
-        params['pageSize'] = page_size
-
-        paged_resp = self.request_with_orgId_api_2(action, params,
-                                                   data, headers,
-                                                   method).object
-        yield paged_resp
-
-        while paged_resp.get('pageCount') >= paged_resp.get('pageSize'):
-            params['pageNumber'] = int(paged_resp.get('pageNumber')) + 1
-            paged_resp = self.request_with_orgId_api_2(action, params,
-                                                       data, headers,
-                                                       method).object
-            yield paged_resp
-
-    def get_resource_path_api_1(self):
-        """
-        This method returns a resource path which is necessary for referencing
-        resources that require a full path instead of just an ID, such as
-        networks, and customer snapshots.
-        """
-        return ("%s/%s/%s" % (self.api_path_version_1, self.api_version_1,
-                              self._get_orgId()))
-
-    def get_resource_path_api_2(self):
-        """
-        This method returns a resource path which is necessary for referencing
-        resources that require a full path instead of just an ID, such as
-        networks, and customer snapshots.
-        """
-        return ("%s/%s/%s" % (self.api_path_version_2, self.api_version_2,
-                              self._get_orgId()))
-
-    def wait_for_state(self, state, func, poll_interval=2, timeout=60, *args,
-                       **kwargs):
-        """
-        Wait for the function which returns a instance with field status/state
-        to match.
-
-        Keep polling func until one of the desired states is matched
-
-        :param state: Either the desired state (`str`) or a `list` of states
-        :type  state: ``str`` or ``list``
-
-        :param  func: The function to call, e.g. ex_get_vlan. Note: This
-                      function needs to return an object which has ``status``
-                      attribute.
-        :type   func: ``function``
-
-        :param  poll_interval: The number of seconds to wait between checks
-        :type   poll_interval: `int`
-
-        :param  timeout: The total number of seconds to wait to reach a state
-        :type   timeout: `int`
-
-        :param  args: The arguments for func
-        :type   args: Positional arguments
-
-        :param  kwargs: The arguments for func
-        :type   kwargs: Keyword arguments
-
-        :return: Result from the calling function.
-        """
-        cnt = 0
-        while cnt < timeout / poll_interval:
-            result = func(*args, **kwargs)
-            if isinstance(result, Node):
-                object_state = result.state
-            else:
-                object_state = result.status
-
-            if object_state is state or object_state in state:
-                return result
-            sleep(poll_interval)
-            cnt += 1
-
-        msg = 'Status check for object %s timed out' % (result)
-        raise DimensionDataAPIException(code=object_state,
-                                        msg=msg,
-                                        driver=self.driver)
-
-    def _get_orgId(self):
-        """
-        Send the /myaccount API request to DimensionData cloud and parse the
-        'orgId' from the XML response object. We need the orgId to use most
-        of the other API functions
-        """
-        if self._orgId is None:
-            body = self.request_api_1('myaccount').object
-            self._orgId = findtext(body, 'orgId', DIRECTORY_NS)
-        return self._orgId
-
-    def get_account_details(self):
-        """
-        Get the details of this account
-
-        :rtype: :class:`DimensionDataAccountDetails`
-        """
-        body = self.request_api_1('myaccount').object
-        return DimensionDataAccountDetails(
-            user_name=findtext(body, 'userName', DIRECTORY_NS),
-            full_name=findtext(body, 'fullName', DIRECTORY_NS),
-            first_name=findtext(body, 'firstName', DIRECTORY_NS),
-            last_name=findtext(body, 'lastName', DIRECTORY_NS),
-            email=findtext(body, 'emailAddress', DIRECTORY_NS))
-
-
-class DimensionDataAccountDetails(object):
-    """
-    Dimension Data account class details
-    """
-    def __init__(self, user_name, full_name, first_name, last_name, email):
-        self.user_name = user_name
-        self.full_name = full_name
-        self.first_name = first_name
-        self.last_name = last_name
-        self.email = email
-
-
-class DimensionDataStatus(object):
-    """
-    DimensionData API pending operation status class
-        action, request_time, user_name, number_of_steps, update_time,
-        step.name, step.number, step.percent_complete, failure_reason,
-    """
-    def __init__(self, action=None, request_time=None, user_name=None,
-                 number_of_steps=None, update_time=None, step_name=None,
-                 step_number=None, step_percent_complete=None,
-                 failure_reason=None):
-        self.action = action
-        self.request_time = request_time
-        self.user_name = user_name
-        self.number_of_steps = number_of_steps
-        self.update_time = update_time
-        self.step_name = step_name
-        self.step_number = step_number
-        self.step_percent_complete = step_percent_complete
-        self.failure_reason = failure_reason
-
-    def __repr__(self):
-        return (('<DimensionDataStatus: action=%s, request_time=%s, '
-                 'user_name=%s, number_of_steps=%s, update_time=%s, '
-                 'step_name=%s, step_number=%s, '
-                 'step_percent_complete=%s, failure_reason=%s>')
-                % (self.action, self.request_time, self.user_name,
-                   self.number_of_steps, self.update_time, self.step_name,
-                   self.step_number, self.step_percent_complete,
-                   self.failure_reason))
-
-
-class DimensionDataNetwork(object):
-    """
-    DimensionData network with location.
-    """
-
-    def __init__(self, id, name, description, location, private_net,
-                 multicast, status):
-        self.id = str(id)
-        self.name = name
-        self.description = description
-        self.location = location
-        self.private_net = private_net
-        self.multicast = multicast
-        self.status = status
-
-    def __repr__(self):
-        return (('<DimensionDataNetwork: id=%s, name=%s, description=%s, '
-                 'location=%s, private_net=%s, multicast=%s>')
-                % (self.id, self.name, self.description, self.location,
-                   self.private_net, self.multicast))
-
-
-class DimensionDataNetworkDomain(object):
-    """
-    DimensionData network domain with location.
-    """
-
-    def __init__(self, id, name, description, location, status, plan):
-        self.id = str(id)
-        self.name = name
-        self.description = description
-        self.location = location
-        self.status = status
-        self.plan = plan
-
-    def __repr__(self):
-        return (('<DimensionDataNetworkDomain: id=%s, name=%s, '
-                 'description=%s, location=%s, status=%s>')
-                % (self.id, self.name, self.description, self.location,
-                   self.status))
-
-
-class DimensionDataPublicIpBlock(object):
-    """
-    DimensionData Public IP Block with location.
-    """
-
-    def __init__(self, id, base_ip, size, location, network_domain,
-                 status):
-        self.id = str(id)
-        self.base_ip = base_ip
-        self.size = size
-        self.location = location
-        self.network_domain = network_domain
-        self.status = status
-
-    def __repr__(self):
-        return (('<DimensionDataNetworkDomain: id=%s, base_ip=%s, '
-                 'size=%s, location=%s, status=%s>')
-                % (self.id, self.base_ip, self.size, self.location,
-                   self.status))
-
-
-class DimensionDataServerCpuSpecification(object):
-    """
-    A class that represents the specification of the CPU(s) for a
-    node
-    """
-    def __init__(self, cpu_count, cores_per_socket, performance):
-        """
-        Instantiate a new :class:`DimensionDataServerCpuSpecification`
-
-        :param cpu_count: The number of CPUs
-        :type  cpu_count: ``int``
-
-        :param cores_per_socket: The number of cores per socket, the
-            recommendation is 1
-        :type  cores_per_socket: ``int``
-
-        :param performance: The performance type, e.g. HIGHPERFORMANCE
-        :type  performance: ``str``
-        """
-        self.cpu_count = cpu_count
-        self.cores_per_socket = cores_per_socket
-        self.performance = performance
-
-    def __repr__(self):
-        return (('<DimensionDataServerCpuSpecification: '
-                 'cpu_count=%s, cores_per_socket=%s, '
-                 'performance=%s>')
-                % (self.cpu_count, self.cores_per_socket, self.performance))
-
-
-class DimensionDataServerDisk(object):
-    """
-    A class that represents the disk on a server
-    """
-    def __init__(self, id, scsi_id, size_gb, speed, state):
-        """
-        Instantiate a new :class:`DimensionDataServerDisk`
-
-        :param id: The id of the disk
-        :type  id: ``str``
-
-        :param scsi_id: Representation for scsi
-        :type  scsi_id: ``int``
-
-        :param size_gb: Size of the disk
-        :type  size_gb: ``int``
-
-        :param speed: Speed of the disk (i.e. STANDARD)
-        :type  speed: ``str``
-
-        :param state: State of the disk (i.e. PENDING)
-        :type  state: ``str``
-        """
-        self.id = id
-        self.scsi_id = scsi_id
-        self.size_gb = size_gb
-        self.speed = speed
-        self.state = state
-
-    def __repr__(self):
-        return (('<DimensionDataServerDisk: '
-                 'id=%s, size_gb=%s')
-                % (self.id, self.size_gb))
-
-
-class DimensionDataServerVMWareTools(object):
-    """
-    A class that represents the VMWareTools for a node
-    """
-    def __init__(self, status, version_status, api_version):
-        """
-        Instantiate a new :class:`DimensionDataServerVMWareTools` object
-
-        :param status: The status of VMWare Tools
-        :type  status: ``str``
-
-        :param version_status: The status for the version of VMWare Tools
-            (i.e NEEDS_UPGRADE)
-        :type  version_status: ``str``
-
-        :param api_version: The API version of VMWare Tools
-        :type  api_version: ``str``
-        """
-        self.status = status
-        self.version_status = version_status
-        self.api_version = api_version
-
-    def __repr__(self):
-        return (('<DimensionDataServerVMWareTools '
-                 'status=%s, version_status=%s, '
-                 'api_version=%s>')
-                % (self.status, self.version_status, self.api_version))
-
-
-class DimensionDataFirewallRule(object):
-    """
-    DimensionData Firewall Rule for a network domain
-    """
-
-    def __init__(self, id, name, action, location, network_domain,
-                 status, ip_version, protocol, source, destination,
-                 enabled):
-        self.id = str(id)
-        self.name = name
-        self.action = action
-        self.location = location
-        self.network_domain = network_domain
-        self.status = status
-        self.ip_version = ip_version
-        self.protocol = protocol
-        self.source = source
-        self.destination = destination
-        self.enabled = enabled
-
-    def __repr__(self):
-        return (('<DimensionDataFirewallRule: id=%s, name=%s, '
-                 'action=%s, location=%s, network_domain=%s, '
-                 'status=%s, ip_version=%s, protocol=%s, source=%s, '
-                 'destination=%s, enabled=%s>')
-                % (self.id, self.name, self.action, self.location,
-                   self.network_domain, self.status, self.ip_version,
-                   self.protocol, self.source, self.destination,
-                   self.enabled))
-
-
-class DimensionDataFirewallAddress(object):
-    """
-    The source or destination model in a firewall rule
-    """
-    def __init__(self, any_ip, ip_address, ip_prefix_size,
-                 port_begin, port_end):
-        self.any_ip = any_ip
-        self.ip_address = ip_address
-        self.ip_prefix_size = ip_prefix_size
-        self.port_begin = port_begin
-        self.port_end = port_end
-
-
-class DimensionDataNatRule(object):
-    """
-    An IP NAT rule in a network domain
-    """
-    def __init__(self, id, network_domain, internal_ip, external_ip, status):
-        self.id = id
-        self.network_domain = network_domain
-        self.internal_ip = internal_ip
-        self.external_ip = external_ip
-        self.status = status
-
-    def __repr__(self):
-        return (('<DimensionDataNatRule: id=%s, status=%s>')
-                % (self.id, self.status))
-
-
-class DimensionDataAntiAffinityRule(object):
-    """
-    Anti-Affinity rule for DimensionData
-
-    An Anti-Affinity rule ensures that servers in the rule will
-    not reside on the same VMware ESX host.
-    """
-    def __init__(self, id, node_list):
-        """
-        Instantiate a new :class:`DimensionDataAntiAffinityRule`
-
-        :param id: The ID of the Anti-Affinity rule
-        :type  id: ``str``
-
-        :param node_list: List of node ids that belong in this rule
-        :type  node_list: ``list`` of ``str``
-        """
-        self.id = id
-        self.node_list = node_list
-
-    def __repr__(self):
-        return (('<DimensionDataAntiAffinityRule: id=%s>')
-                % (self.id))
-
-
-class DimensionDataVlan(object):
-    """
-    DimensionData VLAN.
-    """
-
-    def __init__(self, id, name, description, location, network_domain,
-                 status, private_ipv4_range_address, private_ipv4_range_size,
-                 ipv6_range_address, ipv6_range_size, ipv4_gateway,
-                 ipv6_gateway):
-        """
-        Initialize an instance of ``DimensionDataVlan``
-
-        :param id: The ID of the VLAN
-        :type  id: ``str``
-
-        :param name: The name of the VLAN
-        :type  name: ``str``
-
-        :param description: Plan text description of the VLAN
-        :type  description: ``str``
-
-        :param location: The location (data center) of the VLAN
-        :type  location: ``NodeLocation``
-
-        :param network_domain: The Network Domain that owns this VLAN
-        :type  network_domain: :class:`DimensionDataNetworkDomain`
-
-        :param status: The status of the VLAN
-        :type  status: :class:`DimensionDataStatus`
-
-        :param private_ipv4_range_address: The host address of the VLAN
-                                            IP space
-        :type  private_ipv4_range_address: ``str``
-
-        :param private_ipv4_range_size: The size (e.g. '24') of the VLAN
-                                            as a CIDR range size
-        :type  private_ipv4_range_size: ``int``
-
-        :param ipv6_range_address: The host address of the VLAN
-                                            IP space
-        :type  ipv6_range_address: ``str``
-
-        :param ipv6_range_size: The size (e.g. '32') of the VLAN
-                                            as a CIDR range size
-        :type  ipv6_range_size: ``int``
-
-        :param ipv4_gateway: The IPv4 default gateway address
-        :type  ipv4_gateway: ``str``
-
-        :param ipv6_gateway: The IPv6 default gateway address
-        :type  ipv6_gateway: ``str``
-        """
-        self.id = str(id)
-        self.name = name
-        self.location = location
-        self.description = description
-        self.network_domain = network_domain
-        self.status = status
-        self.private_ipv4_range_address = private_ipv4_range_address
-        self.private_ipv4_range_size = private_ipv4_range_size
-        self.ipv6_range_address = ipv6_range_address
-        self.ipv6_range_size = ipv6_range_size
-        self.ipv4_gateway = ipv4_gateway
-        self.ipv6_gateway = ipv6_gateway
-
-    def __repr__(self):
-        return (('<DimensionDataVlan: id=%s, name=%s, '
-                 'description=%s, location=%s, status=%s>')
-                % (self.id, self.name, self.description,
-                   self.location, self.status))
-
-
-class DimensionDataPool(object):
-    """
-    DimensionData VIP Pool.
-    """
-
-    def __init__(self, id, name, description, status, load_balance_method,
-                 health_monitor_id, service_down_action, slow_ramp_time):
-        """
-        Initialize an instance of ``DimensionDataPool``
-
-        :param id: The ID of the pool
-        :type  id: ``str``
-
-        :param name: The name of the pool
-        :type  name: ``str``
-
-        :param description: Plan text description of the pool
-        :type  description: ``str``
-
-        :param status: The status of the pool
-        :type  status: :class:`DimensionDataStatus`
-
-        :param load_balance_method: The load balancer method
-        :type  load_balance_method: ``str``
-
-        :param health_monitor_id: The ID of the health monitor
-        :type  health_monitor_id: ``str``
-
-        :param service_down_action: Action to take when pool is down
-        :type  service_down_action: ``str``
-
-        :param slow_ramp_time: The ramp-up time for service recovery
-        :type  slow_ramp_time: ``int``
-        """
-        self.id = str(id)
-        self.name = name
-        self.description = description
-        self.status = status
-        self.load_balance_method = load_balance_method
-        self.health_monitor_id = health_monitor_id
-        self.service_down_action = service_down_action
-        self.slow_ramp_time = slow_ramp_time
-
-    def __repr__(self):
-        return (('<DimensionDataPool: id=%s, name=%s, '
-                 'description=%s, status=%s>')
-                % (self.id, self.name, self.description,
-                   self.status))
-
-
-class DimensionDataPoolMember(object):
-    """
-    DimensionData VIP Pool Member.
-    """
-
-    def __init__(self, id, name, status, ip, port, node_id):
-        """
-        Initialize an instance of ``DimensionDataPoolMember``
-
-        :param id: The ID of the pool member
-        :type  id: ``str``
-
-        :param name: The name of the pool member
-        :type  name: ``str``
-
-        :param status: The status of the pool
-        :type  status: :class:`DimensionDataStatus`
-
-        :param ip: The IP of the pool member
-        :type  ip: ``str``
-
-        :param port: The port of the pool member
-        :type  port: ``int``
-
-        :param node_id: The ID of the associated node
-        :type  node_id: ``str``
-        """
-        self.id = str(id)
-        self.name = name
-        self.status = status
-        self.ip = ip
-        self.port = port
-        self.node_id = node_id
-
-    def __repr__(self):
-        return (('<DimensionDataPoolMember: id=%s, name=%s, '
-                 'ip=%s, status=%s, port=%s, node_id=%s>')
-                % (self.id, self.name,
-                   self.ip, self.status, self.port,
-                   self.node_id))
-
-
-class DimensionDataVIPNode(object):
-    def __init__(self, id, name, status, ip, connection_limit='10000',
-                 connection_rate_limit='10000'):
-        """
-        Initialize an instance of :class:`DimensionDataVIPNode`
-
-        :param id: The ID of the node
-        :type  id: ``str``
-
-        :param name: The name of the node
-        :type  name: ``str``
-
-        :param status: The status of the node
-        :type  status: :class:`DimensionDataStatus`
-
-        :param ip: The IP of the node
-        :type  ip: ``str``
-
-        :param connection_limit: The total connection limit for the node
-        :type  connection_limit: ``int``
-
-        :param connection_rate_limit: The rate limit for the node
-        :type  connection_rate_limit: ``int``
-        """
-        self.id = str(id)
-        self.name = name
-        self.status = status
-        self.ip = ip
-        self.connection_limit = connection_limit
-        self.connection_rate_limit = connection_rate_limit
-
-    def __repr__(self):
-        return (('<DimensionDataVIPNode: id=%s, name=%s, '
-                 'status=%s, ip=%s>')
-                % (self.id, self.name,
-                   self.status, self.ip))
-
-
-class DimensionDataVirtualListener(object):
-    """
-    DimensionData Virtual Listener.
-    """
-
-    def __init__(self, id, name, status, ip):
-        """
-        Initialize an instance of :class:`DimensionDataVirtualListener`
-
-        :param id: The ID of the listener
-        :type  id: ``str``
-
-        :param name: The name of the listener
-        :type  name: ``str``
-
-        :param status: The status of the listener
-        :type  status: :class:`DimensionDataStatus`
-
-        :param ip: The IP of the listener
-        :type  ip: ``str``
-        """
-        self.id = str(id)
-        self.name = name
-        self.status = status
-        self.ip = ip
-
-    def __repr__(self):
-        return (('<DimensionDataVirtualListener: id=%s, name=%s, '
-                 'status=%s, ip=%s>')
-                % (self.id, self.name,
-                   self.status, self.ip))
-
-
-class DimensionDataDefaultHealthMonitor(object):
-    """
-    A default health monitor for a VIP (node, pool or listener)
-    """
-    def __init__(self, id, name, node_compatible, pool_compatible):
-        """
-        Initialize an instance of :class:`DimensionDataDefaultHealthMonitor`
-
-        :param id: The ID of the monitor
-        :type  id: ``str``
-
-        :param name: The name of the monitor
-        :type  name: ``str``
-
-        :param node_compatible: Is a monitor capable of monitoring nodes
-        :type  node_compatible: ``bool``
-
-        :param pool_compatible: Is a monitor capable of monitoring pools
-        :type  pool_compatible: ``bool``
-        """
-        self.id = id
-        self.name = name
-        self.node_compatible = node_compatible
-        self.pool_compatible = pool_compatible
-
-    def __repr__(self):
-        return (('<DimensionDataDefaultHealthMonitor: id=%s, name=%s>')
-                % (self.id, self.name))
-
-
-class DimensionDataPersistenceProfile(object):
-    """
-    Each Persistence Profile declares the combination of Virtual Listener
-    type and protocol with which it is
-    compatible and whether or not it is compatible as a
-    Fallback Persistence Profile.
-    """
-    def __init__(self, id, name, compatible_listeners, fallback_compatible):
-        """
-        Initialize an instance of :class:`DimensionDataPersistenceProfile`
-
-        :param id: The ID of the profile
-        :type  id: ``str``
-
-        :param name: The name of the profile
-        :type  name: ``str``
-
-        :param compatible_listeners: List of compatible Virtual Listener types
-        :type  compatible_listeners: ``list`` of
-            :class:`DimensionDataVirtualListenerCompatibility`
-
-        :param fallback_compatible: Is capable as a fallback profile
-        :type  fallback_compatible: ``bool``
-        """
-        self.id = id
-        self.name = name
-        self.compatible_listeners = compatible_listeners
-        self.fallback_compatible = fallback_compatible
-
-    def __repr__(self):
-        return (('<DimensionDataPersistenceProfile: id=%s, name=%s>')
-                % (self.id, self.name))
-
-
-class DimensionDataDefaultiRule(object):
-    """
-    A default iRule for a network domain, can be applied to a listener
-    """
-    def __init__(self, id, name, compatible_listeners):
-        """
-        Initialize an instance of :class:`DimensionDataDefaultiRule`
-
-        :param id: The ID of the iRule
-        :type  id: ``str``
-
-        :param name: The name of the iRule
-        :type  name: ``str``
-
-        :param compatible_listeners: List of compatible Virtual Listener types
-        :type  compatible_listeners: ``list`` of
-            :class:`DimensionDataVirtualListenerCompatibility`
-        """
-        self.id = id
-        self.name = name
-        self.compatible_listeners = compatible_listeners
-
-    def __repr__(self):
-        return (('<DimensionDataDefaultiRule: id=%s, name=%s>')
-                % (self.id, self.name))
-
-
-class DimensionDataVirtualListenerCompatibility(object):
-    """
-    A compatibility preference for a persistence profile or iRule
-    specifies which virtual listener types this profile or iRule can be
-    applied to.
-    """
-    def __init__(self, type, protocol):
-        self.type = type
-        self.protocol = protocol
-
-    def __repr__(self):
-        return (('<DimensionDataVirtualListenerCompatibility: '
-                 'type=%s, protocol=%s>')
-                % (self.type, self.protocol))
-
-
-class DimensionDataBackupDetails(object):
-    """
-    Dimension Data Backup Details represents information about
-    a targets backups configuration
-    """
-
-    def __init__(self, asset_id, service_plan, status, clients=None):
-        """
-        Initialize an instance of :class:`DimensionDataBackupDetails`
-
-        :param asset_id: Asset identification for backups
-        :type  asset_id: ``str``
-
-        :param service_plan: The service plan for backups. i.e (Essentials)
-        :type  service_plan: ``str``
-
-        :param status: The overall status this backup target.
-                       i.e. (unregistered)
-        :type  status: ``str``
-
-        :param clients: Backup clients attached to this target
-        :type  clients: ``list`` of :class:`DimensionDataBackupClient`
-        """
-        self.asset_id = asset_id
-        self.service_plan = service_plan
-        self.status = status
-        self.clients = clients
-
-    def __repr__(self):
-        return (('<DimensionDataBackupDetails: id=%s>')
-                % (self.asset_id))
-
-
-class DimensionDataBackupClient(object):
-    """
-    An object that represents a backup client
-    """
-    def __init__(self, id, type, status,
-                 schedule_policy, storage_policy, download_url,
-                 alert=None, running_job=None):
-        """
-        Initialize an instance of :class:`DimensionDataBackupClient`
-
-        :param id: Unique ID for the client
-        :type  id: ``str``
-
-        :param type: The type of client that this client is
-        :type  type: :class:`DimensionDataBackupClientType`
-
-        :param status: The states of this particular backup client.
-                       i.e. (Unregistered)
-        :type  status: ``str``
-
-        :param schedule_policy: The schedule policy for this client
-                                NOTE: Dimension Data only sends back the name
-                                of the schedule policy, no further details
-        :type  schedule_policy: ``str``
-
-        :param storage_policy: The storage policy for this client
-                               NOTE: Dimension Data only sends back the name
-                               of the storage policy, no further details
-        :type  storage_policy: ``str``
-
-        :param download_url: The download url for this client
-        :type  download_url: ``str``
-
-        :param alert: The alert configured for this backup client (optional)
-        :type  alert: :class:`DimensionDataBackupClientAlert`
-
-        :param alert: The running job for the client (optional)
-        :type  alert: :class:`DimensionDataBackupClientRunningJob`
-        """
-        self.id = id
-        self.type = type
-        self.status = status
-        self.schedule_policy = schedule_policy
-        self.storage_policy = storage_policy
-        self.download_url = download_url
-        self.alert = alert
-        self.running_job = running_job
-
-    def __repr__(self):
-        return (('<DimensionDataBackupClient: id=%s>')
-                % (self.id))
-
-
-class DimensionDataBackupClientAlert(object):
-    """
-    An alert for a backup client
-    """
-    def __init__(self, trigger, notify_list=[]):
-        """
-        Initialize an instance of :class:`DimensionDataBackupClientAlert`
-
-        :param trigger: Trigger type for the client i.e. ON_FAILURE
-        :type  trigger: ``str``
-
-        :param notify_list: List of email addresses that are notified
-                            when the alert is fired
-        :type  notify_list: ``list`` of ``str``
-        """
-        self.trigger = trigger
-        self.notify_list = notify_list
-
-    def __repr__(self):
-        return (('<DimensionDataBackupClientAlert: trigger=%s>')
-                % (self.trigger))
-
-
-class DimensionDataBackupClientRunningJob(object):
-    """
-    A running job for a given backup client
-    """
-    def __init__(self, id, status, percentage=0):
-        """
-        Initialize an instance of :class:`DimensionDataBackupClientRunningJob`
-
-        :param id: The unqiue ID of the job
-        :type  id: ``str``
-
-        :param status: The status of the job i.e. Waiting
-        :type  status: ``str``
-
-        :param percentage: The percentage completion of the job
-        :type  percentage: ``int``
-        """
-        self.id = id
-        self.percentage = percentage
-        self.status = status
-
-    def __repr__(self):
-        return (('<DimensionDataBackupClientRunningJob: id=%s>')
-                % (self.id))
-
-
-class DimensionDataBackupClientType(object):
-    """
-    A client type object for backups
-    """
-    def __init__(self, type, is_file_system, description):
-        """
-        Initialize an instance of :class:`DimensionDataBackupClientType`
-
-        :param type: The type of client i.e. (FA.Linux, MySQL, ect.)
-        :type  type: ``str``
-
-        :param is_file_system: The name of the iRule
-        :type  is_file_system: ``bool``
-
-        :param description: Description of the client
-        :type  description: ``str``
-        """
-        self.type = type
-        self.is_file_system = is_file_system
-        self.description = description
-
-    def __repr__(self):
-        return (('<DimensionDataBackupClientType: type=%s>')
-                % (self.type))
-
-
-class DimensionDataBackupStoragePolicy(object):
-    """
-    A representation of a storage policy
-    """
-    def __init__(self, name, retention_period, secondary_location):
-        """
-        Initialize an instance of :class:`DimensionDataBackupStoragePolicy`
-
-        :param name: The name of the storage policy i.e. 14 Day Storage Policy
-        :type  name: ``str``
-
-        :param retention_period: How long to keep the backup in days
-        :type  retention_period: ``int``
-
-        :param secondary_location: The secondary location i.e. Primary
-        :type  secondary_location: ``str``
-        """
-        self.name = name
-        self.retention_period = retention_period
-        self.secondary_location = secondary_location
-
-    def __repr__(self):
-        return (('<DimensionDataBackupStoragePolicy: name=%s>')
-                % (self.name))
-
-
-class DimensionDataBackupSchedulePolicy(object):
-    """
-    A representation of a schedule policy
-    """
-    def __init__(self, name, description):
-        """
-        Initialize an instance of :class:`DimensionDataBackupSchedulePolicy`
-
-        :param name: The name of the policy i.e 12AM - 6AM
-        :type  name: ``str``
-
-        :param description: Short summary of the details of the policy
-        :type  description: ``str``
-        """
-        self.name = name
-        self.description = description
-
-    def __repr__(self):
-        return (('<DimensionDataBackupSchedulePolicy: name=%s>')
-                % (self.name))

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/dnsimple.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/dnsimple.py b/apache-libcloud-1.0.0rc2/libcloud/common/dnsimple.py
deleted file mode 100644
index 6a5da41..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/dnsimple.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from libcloud.utils.py3 import httplib
-from libcloud.common.base import ConnectionUserAndKey
-from libcloud.common.base import JsonResponse
-
-
-class DNSimpleDNSResponse(JsonResponse):
-
-    def success(self):
-        """
-        Determine if our request was successful.
-
-        The meaning of this can be arbitrary; did we receive OK status? Did
-        the node get created? Were we authenticated?
-
-        :rtype: ``bool``
-        :return: ``True`` or ``False``
-        """
-        # response.success() only checks for 200 and 201 codes. Should we
-        # add 204?
-        return self.status in [httplib.OK, httplib.CREATED, httplib.NO_CONTENT]
-
-
-class DNSimpleDNSConnection(ConnectionUserAndKey):
-    host = 'api.dnsimple.com'
-    responseCls = DNSimpleDNSResponse
-
-    def add_default_headers(self, headers):
-        """
-        Add headers that are necessary for every request
-
-        This method adds ``token`` to the request.
-        """
-        # TODO: fijarse sobre que info se paso como parametro y en base
-        # a esto, fijar el header
-        headers['X-DNSimple-Token'] = '%s:%s' % (self.user_id, self.key)
-        headers['Accept'] = 'application/json'
-        headers['Content-Type'] = 'application/json'
-        return headers

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/durabledns.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/durabledns.py b/apache-libcloud-1.0.0rc2/libcloud/common/durabledns.py
deleted file mode 100644
index 5859f6e..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/durabledns.py
+++ /dev/null
@@ -1,285 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 re
-from xml.etree import ElementTree as ET   # noqa
-
-from libcloud.common.base import ConnectionUserAndKey
-from libcloud.common.base import XmlResponse
-
-
-# API HOST to connect
-API_HOST = 'durabledns.com'
-
-
-def _schema_builder(urn_nid, method, attributes):
-    """
-    Return a xml schema used to do an API request.
-
-    :param urn_nid: API urn namespace id.
-    :type urn_nid: type: ``str``
-
-    :param method: API method.
-    :type method: type: ``str``
-
-    :param attributes: List of attributes to include.
-    :type attributes: ``list`` of ``str``
-
-    rtype: :class:`Element`
-    """
-    soap = ET.Element(
-        'soap:Body',
-        {'xmlns:m': "https://durabledns.com/services/dns/%s" % method}
-    )
-    urn = ET.SubElement(soap, 'urn:%s:%s' % (urn_nid, method))
-    # Attributes specification
-    for attribute in attributes:
-        ET.SubElement(urn, 'urn:%s:%s' % (urn_nid, attribute))
-    return soap
-
-
-SCHEMA_BUILDER_MAP = {
-    'list_zones': {
-        'urn_nid': 'listZoneswsdl',
-        'method': 'listZones',
-        'attributes': ['apiuser', 'apikey']
-    },
-    'list_records': {
-        'urn_nid': 'listRecordswsdl',
-        'method': 'listRecords',
-        'attributes': ['apiuser', 'apikey', 'zonename']
-    },
-    'get_zone': {
-        'urn_nid': 'getZonewsdl',
-        'method': 'getZone',
-        'attributes': ['apiuser', 'apikey', 'zonename']
-    },
-    'get_record': {
-        'urn_nid': 'getRecordwsdl',
-        'method': 'getRecord',
-        'attributes': ['apiuser', 'apikey', 'zonename', 'recordid']
-    },
-    'create_zone': {
-        'urn_nid': 'createZonewsdl',
-        'method': 'createZone',
-        'attributes': ['apiuser', 'apikey', 'zonename', 'ns', 'mbox',
-                       'refresh', 'retry', 'expire', 'minimum', 'ttl',
-                       'xfer', 'update_acl']
-    },
-    'create_record': {
-        'urn_nid': 'createRecordwsdl',
-        'method': 'createRecord',
-        'attributes': ['apiuser', 'apikey', 'zonename', 'name', 'type',
-                       'data', 'aux', 'ttl', 'ddns_enabled']
-    },
-    'update_zone': {
-        'urn_nid': 'updateZonewsdl',
-        'method': 'updateZone',
-        'attributes': ['apiuser', 'apikey', 'zonename', 'ns', 'mbox',
-                       'refresh', 'retry', 'expire', 'minimum', 'ttl',
-                       'xfer', 'update_acl']
-    },
-    'update_record': {
-        'urn_nid': 'updateRecordwsdl',
-        'method': 'updateRecord',
-        'attributes': ['apiuser', 'apikey', 'zonename', 'id', 'name', 'aux',
-                       'data', 'ttl', 'ddns_enabled']
-    },
-    'delete_zone': {
-        'urn_nid': 'deleteZonewsdl',
-        'method': 'deleteZone',
-        'attributes': ['apiuser', 'apikey', 'zonename']
-    },
-    'delete_record': {
-        'urn_nid': 'deleteRecordwsdl',
-        'method': 'deleteRecord',
-        'attributes': ['apiuser', 'apikey', 'zonename', 'id']
-    }
-}
-
-
-class DurableDNSException(Exception):
-
-    def __init__(self, code, message):
-        self.code = code
-        self.message = message
-        self.args = (code, message)
-
-    def __str__(self):
-        return "%s %s" % (self.code, self.message)
-
-    def __repr__(self):
-        return "DurableDNSException %s %s" % (self.code, self.message)
-
-
-class DurableResponse(XmlResponse):
-
-    errors = []
-    objects = []
-
-    def __init__(self, response, connection):
-        super(DurableResponse, self).__init__(response=response,
-                                              connection=connection)
-
-        self.objects, self.errors = self.parse_body_and_error()
-        if self.errors:
-            raise self._make_excp(self.errors[0])
-
-    def parse_body_and_error(self):
-        """
-        Used to parse body from httplib.HttpResponse object.
-        """
-        objects = []
-        errors = []
-        error_dict = {}
-        extra = {}
-        zone_dict = {}
-        record_dict = {}
-        xml_obj = self.parse_body()
-        envelop_body = xml_obj.getchildren()[0]
-        method_resp = envelop_body.getchildren()[0]
-        # parse the xml_obj
-        # handle errors
-        if 'Fault' in method_resp.tag:
-            fault = [fault for fault in method_resp.getchildren()
-                     if fault.tag == 'faultstring'][0]
-            error_dict['ERRORMESSAGE'] = fault.text.strip()
-            error_dict['ERRORCODE'] = self.status
-            errors.append(error_dict)
-
-        # parsing response from listZonesResponse
-        if 'listZonesResponse' in method_resp.tag:
-            answer = method_resp.getchildren()[0]
-            for element in answer:
-                zone_dict['id'] = element.getchildren()[0].text
-                objects.append(zone_dict)
-                # reset the zone_dict
-                zone_dict = {}
-        # parse response from listRecordsResponse
-        if 'listRecordsResponse' in method_resp.tag:
-            answer = method_resp.getchildren()[0]
-            for element in answer:
-                for child in element.getchildren():
-                    if child.tag == 'id':
-                        record_dict['id'] = child.text.strip()
-                objects.append(record_dict)
-                # reset the record_dict for later usage
-                record_dict = {}
-        # parse response from getZoneResponse
-        if 'getZoneResponse' in method_resp.tag:
-            for child in method_resp.getchildren():
-                if child.tag == 'origin':
-                    zone_dict['id'] = child.text.strip()
-                    zone_dict['domain'] = child.text.strip()
-                elif child.tag == 'ttl':
-                    zone_dict['ttl'] = int(child.text.strip())
-                elif child.tag == 'retry':
-                    extra['retry'] = int(child.text.strip())
-                elif child.tag == 'expire':
-                    extra['expire'] = int(child.text.strip())
-                elif child.tag == 'minimum':
-                    extra['minimum'] = int(child.text.strip())
-                else:
-                    if child.text:
-                        extra[child.tag] = child.text.strip()
-                    else:
-                        extra[child.tag] = ''
-                    zone_dict['extra'] = extra
-            objects.append(zone_dict)
-        # parse response from getRecordResponse
-        if 'getRecordResponse' in method_resp.tag:
-            answer = method_resp.getchildren()[0]
-            for child in method_resp.getchildren():
-                if child.tag == 'id' and child.text:
-                    record_dict['id'] = child.text.strip()
-                elif child.tag == 'name' and child.text:
-                    record_dict['name'] = child.text.strip()
-                elif child.tag == 'type' and child.text:
-                    record_dict['type'] = child.text.strip()
-                elif child.tag == 'data' and child.text:
-                    record_dict['data'] = child.text.strip()
-                elif child.tag == 'aux' and child.text:
-                    record_dict['aux'] = child.text.strip()
-                elif child.tag == 'ttl' and child.text:
-                    record_dict['ttl'] = child.text.strip()
-            if not record_dict:
-                error_dict['ERRORMESSAGE'] = 'Record does not exist'
-                error_dict['ERRORCODE'] = 404
-                errors.append(error_dict)
-            objects.append(record_dict)
-            record_dict = {}
-        if 'createZoneResponse' in method_resp.tag:
-            answer = method_resp.getchildren()[0]
-            if answer.tag == 'return' and answer.text:
-                record_dict['id'] = answer.text.strip()
-            objects.append(record_dict)
-        # catch Record does not exists error when deleting record
-        if 'deleteRecordResponse' in method_resp.tag:
-            answer = method_resp.getchildren()[0]
-            if 'Record does not exists' in answer.text.strip():
-                errors.append({'ERRORMESSAGE': answer.text.strip(),
-                               'ERRORCODE': self.status})
-        # parse response in createRecordResponse
-        if 'createRecordResponse' in method_resp.tag:
-            answer = method_resp.getchildren()[0]
-            record_dict['id'] = answer.text.strip()
-            objects.append(record_dict)
-            record_dict = {}
-
-        return (objects, errors)
-
-    def parse_body(self):
-        # A problem arise in the api response because there are undeclared
-        # xml namespaces. In order to fix that at the moment, we use the
-        # _fix_response method to clean up since we won't always have lxml
-        # library.
-        self._fix_response()
-        body = super(DurableResponse, self).parse_body()
-        return body
-
-    def success(self):
-        """
-        Used to determine if the request was successful.
-        """
-        return len(self.errors) == 0
-
-    def _make_excp(self, error):
-        return DurableDNSException(error['ERRORCODE'], error['ERRORMESSAGE'])
-
-    def _fix_response(self):
-        items = re.findall('<ns1:.+ xmlns:ns1="">', self.body, flags=0)
-        for item in items:
-            parts = item.split(' ')
-            prefix = parts[0].replace('<', '').split(':')[1]
-            new_item = "<" + prefix + ">"
-            close_tag = "</" + parts[0].replace('<', '') + ">"
-            new_close_tag = "</" + prefix + ">"
-            self.body = self.body.replace(item, new_item)
-            self.body = self.body.replace(close_tag, new_close_tag)
-
-
-class DurableConnection(ConnectionUserAndKey):
-    host = API_HOST
-    responseCls = DurableResponse
-
-    def add_default_params(self, params):
-        params['user_id'] = self.user_id
-        params['key'] = self.key
-        return params
-
-    def add_default_headers(self, headers):
-        headers['Content-Type'] = 'text/xml'
-        headers['Content-Encoding'] = 'gzip; charset=ISO-8859-1'
-        return headers

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/exceptions.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/exceptions.py b/apache-libcloud-1.0.0rc2/libcloud/common/exceptions.py
deleted file mode 100644
index 14dcea8..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/exceptions.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-__all__ = [
-    'BaseHTTPError',
-    'RateLimitReachedError',
-
-    'exception_from_message'
-]
-
-
-class BaseHTTPError(Exception):
-
-    """
-    The base exception class for all HTTP related exceptions.
-    """
-
-    def __init__(self, code, message, headers=None):
-        self.code = code
-        self.message = message
-        self.headers = headers
-        # preserve old exception behavior for tests that
-        # look for e.args[0]
-        super(BaseHTTPError, self).__init__(message)
-
-    def __str__(self):
-        return self.message
-
-
-class RateLimitReachedError(BaseHTTPError):
-    """
-    HTTP 429 - Rate limit: you've sent too many requests for this time period.
-    """
-    code = 429
-    message = '%s Rate limit exceeded' % (code)
-
-    def __init__(self, *args, **kwargs):
-        self.retry_after = int(kwargs.pop('retry_after', 0))
-
-
-_error_classes = [RateLimitReachedError]
-_code_map = dict((c.code, c) for c in _error_classes)
-
-
-def exception_from_message(code, message, headers=None):
-    """
-    Return an instance of BaseHTTPException or subclass based on response code.
-
-    Usage::
-        raise exception_from_message(code=self.status,
-                                     message=self.parse_error())
-    """
-    kwargs = {
-        'code': code,
-        'message': message,
-        'headers': headers
-    }
-
-    if headers and 'retry_after' in headers:
-        kwargs['retry_after'] = headers['retry_after']
-
-    cls = _code_map.get(code, BaseHTTPError)
-    return cls(**kwargs)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/gandi.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/gandi.py b/apache-libcloud-1.0.0rc2/libcloud/common/gandi.py
deleted file mode 100644
index be326f3..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/gandi.py
+++ /dev/null
@@ -1,194 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-Gandi driver base classes
-"""
-
-import time
-import hashlib
-import sys
-
-from libcloud.utils.py3 import b
-
-from libcloud.common.base import ConnectionKey
-from libcloud.common.xmlrpc import XMLRPCResponse, XMLRPCConnection
-
-# Global constants
-
-DEFAULT_TIMEOUT = 600   # operation pooling max seconds
-DEFAULT_INTERVAL = 20   # seconds between 2 operation.info
-
-
-class GandiException(Exception):
-    """
-    Exception class for Gandi driver
-    """
-    def __str__(self):
-        return '(%u) %s' % (self.args[0], self.args[1])
-
-    def __repr__(self):
-        return '<GandiException code %u "%s">' % (self.args[0], self.args[1])
-
-
-class GandiResponse(XMLRPCResponse):
-    """
-    A Base Gandi Response class to derive from.
-    """
-
-
-class GandiConnection(XMLRPCConnection, ConnectionKey):
-    """
-    Connection class for the Gandi driver
-    """
-
-    responseCls = GandiResponse
-    host = 'rpc.gandi.net'
-    endpoint = '/xmlrpc/'
-
-    def __init__(self, key, secure=True, timeout=None,
-                 retry_delay=None, backoff=None, proxy_url=None):
-        # Note: Method resolution order in this case is
-        # XMLRPCConnection -> Connection and Connection doesn't take key as the
-        # first argument so we specify a keyword argument instead.
-        # Previously it was GandiConnection -> ConnectionKey so it worked fine.
-        super(GandiConnection, self).__init__(key=key, secure=secure,
-                                              timeout=timeout,
-                                              retry_delay=retry_delay,
-                                              backoff=backoff,
-                                              proxy_url=proxy_url)
-        self.driver = BaseGandiDriver
-
-    def request(self, method, *args):
-        args = (self.key, ) + args
-        return super(GandiConnection, self).request(method, *args)
-
-
-class BaseGandiDriver(object):
-    """
-    Gandi base driver
-
-    """
-    connectionCls = GandiConnection
-    name = 'Gandi'
-
-    # Specific methods for gandi
-    def _wait_operation(self, id, timeout=DEFAULT_TIMEOUT,
-                        check_interval=DEFAULT_INTERVAL):
-        """ Wait for an operation to succeed"""
-
-        for i in range(0, timeout, check_interval):
-            try:
-                op = self.connection.request('operation.info', int(id)).object
-
-                if op['step'] == 'DONE':
-                    return True
-                if op['step'] in ['ERROR', 'CANCEL']:
-                    return False
-            except (KeyError, IndexError):
-                pass
-            except Exception:
-                e = sys.exc_info()[1]
-                raise GandiException(1002, e)
-
-            time.sleep(check_interval)
-        return False
-
-
-class BaseObject(object):
-    """Base class for objects not conventional"""
-
-    uuid_prefix = ''
-
-    def __init__(self, id, state, driver):
-        self.id = str(id) if id else None
-        self.state = state
-        self.driver = driver
-        self.uuid = self.get_uuid()
-
-    def get_uuid(self):
-        """Unique hash for this object
-
-        :return: ``str``
-
-        The hash is a function of an SHA1 hash of prefix, the object's ID and
-        its driver which means that it should be unique between all
-        interfaces.
-        TODO : to review
-        >>> from libcloud.compute.drivers.dummy import DummyNodeDriver
-        >>> driver = DummyNodeDriver(0)
-        >>> vif = driver.create_interface()
-        >>> vif.get_uuid()
-        'd3748461511d8b9b0e0bfa0d4d3383a619a2bb9f'
-
-        Note, for example, that this example will always produce the
-        same UUID!
-        """
-        hashstring = '%s:%s:%s' % \
-            (self.uuid_prefix, self.id, self.driver.type)
-        return hashlib.sha1(b(hashstring)).hexdigest()
-
-
-class IPAddress(BaseObject):
-    """
-    Provide a common interface for ip addresses
-    """
-
-    uuid_prefix = 'inet:'
-
-    def __init__(self, id, state, inet, driver, version=4, extra=None):
-        super(IPAddress, self).__init__(id, state, driver)
-        self.inet = inet
-        self.version = version
-        self.extra = extra or {}
-
-    def __repr__(self):
-        return (('<IPAddress: id=%s, address=%s, state=%s, driver=%s ...>')
-                % (self.id, self.inet, self.state, self.driver.name))
-
-
-class NetworkInterface(BaseObject):
-    """
-    Provide a common interface for network interfaces
-    """
-
-    uuid_prefix = 'if:'
-
-    def __init__(self, id, state, mac_address, driver,
-                 ips=None, node_id=None, extra=None):
-        super(NetworkInterface, self).__init__(id, state, driver)
-        self.mac = mac_address
-        self.ips = ips or {}
-        self.node_id = node_id
-        self.extra = extra or {}
-
-    def __repr__(self):
-        return (('<Interface: id=%s, mac=%s, state=%s, driver=%s ...>')
-                % (self.id, self.mac, self.state, self.driver.name))
-
-
-class Disk(BaseObject):
-    """
-    Gandi disk component
-    """
-    def __init__(self, id, state, name, driver, size, extra=None):
-        super(Disk, self).__init__(id, state, driver)
-        self.name = name
-        self.size = size
-        self.extra = extra or {}
-
-    def __repr__(self):
-        return (
-            ('<Disk: id=%s, name=%s, state=%s, size=%s, driver=%s ...>')
-            % (self.id, self.name, self.state, self.size, self.driver.name))


[34/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/azure_arm.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/azure_arm.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/azure_arm.py
deleted file mode 100644
index c7d0441..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/azure_arm.py
+++ /dev/null
@@ -1,1281 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-Driver for Microsoft Azure Resource Manager (ARM) Virtual Machines provider.
-
-http://azure.microsoft.com/en-us/services/virtual-machines/
-"""
-
-import base64
-import binascii
-import os
-import time
-
-from libcloud.common.azure_arm import AzureResourceManagementConnection
-from libcloud.compute.providers import Provider
-from libcloud.compute.base import Node, NodeDriver, NodeLocation, NodeSize
-from libcloud.compute.base import NodeImage, NodeAuthSSHKey
-from libcloud.compute.base import NodeAuthPassword
-from libcloud.compute.types import NodeState
-from libcloud.common.types import LibcloudError
-from libcloud.storage.types import ObjectDoesNotExistError
-from libcloud.common.exceptions import BaseHTTPError
-from libcloud.storage.drivers.azure_blobs import AzureBlobsStorageDriver
-from libcloud.utils.py3 import basestring
-
-
-class AzureImage(NodeImage):
-    """Represents a Marketplace node image that an Azure VM can boot from."""
-
-    def __init__(self, version, sku, offer, publisher, location, driver):
-        self.publisher = publisher
-        self.offer = offer
-        self.sku = sku
-        self.version = version
-        self.location = location
-        urn = "%s:%s:%s:%s" % (self.publisher, self.offer,
-                               self.sku, self.version)
-        name = "%s %s %s %s" % (self.publisher, self.offer,
-                                self.sku, self.version)
-        super(AzureImage, self).__init__(urn, name, driver)
-
-    def __repr__(self):
-        return (('<AzureImage: id=%s, name=%s, location=%s>')
-                % (self.id, self.name, self.location))
-
-
-class AzureVhdImage(NodeImage):
-    """Represents a VHD node image that an Azure VM can boot from."""
-
-    def __init__(self, storage_account, blob_container, name, driver):
-        urn = "https://%s.blob.core.windows.net/%s/%s" % (storage_account,
-                                                          blob_container,
-                                                          name)
-        super(AzureVhdImage, self).__init__(urn, name, driver)
-
-    def __repr__(self):
-        return (('<AzureVhdImage: id=%s, name=%s, location=%s>')
-                % (self.id, self.name, self.location))
-
-
-class AzureNetwork(object):
-    """Represent an Azure virtual network."""
-
-    def __init__(self, id, name, location, extra):
-        self.id = id
-        self.name = name
-        self.location = location
-        self.extra = extra
-
-    def __repr__(self):
-        return (('<AzureNetwork: id=%s, name=%s, location=%s ...>')
-                % (self.id, self.name, self.location))
-
-
-class AzureSubnet(object):
-    """Represents a subnet of an Azure virtual network."""
-
-    def __init__(self, id, name, extra):
-        self.id = id
-        self.name = name
-        self.extra = extra
-
-    def __repr__(self):
-        return (('<AzureSubnet: id=%s, name=%s ...>')
-                % (self.id, self.name))
-
-
-class AzureNic(object):
-    """Represents an Azure virtual network interface controller (NIC)."""
-
-    def __init__(self, id, name, location, extra):
-        self.id = id
-        self.name = name
-        self.location = location
-        self.extra = extra
-
-    def __repr__(self):
-        return (('<AzureNic: id=%s, name=%s ...>')
-                % (self.id, self.name))
-
-
-class AzureIPAddress(object):
-    """Represents an Azure public IP address resource."""
-
-    def __init__(self, id, name, extra):
-        self.id = id
-        self.name = name
-        self.extra = extra
-
-    def __repr__(self):
-        return (('<AzureIPAddress: id=%s, name=%s ...>')
-                % (self.id, self.name))
-
-
-class AzureNodeDriver(NodeDriver):
-    """Compute node driver for Azure Resource Manager."""
-
-    connectionCls = AzureResourceManagementConnection
-    name = 'Azure Virtual machines'
-    website = 'http://azure.microsoft.com/en-us/services/virtual-machines/'
-    type = Provider.AZURE_ARM
-    features = {'create_node': ['ssh_key', 'password']}
-
-    # The API doesn't provide state or country information, so fill it in.
-    # Information from https://azure.microsoft.com/en-us/regions/
-    _location_to_country = {
-        "centralus": "Iowa, USA",
-        "eastus": "Virginia, USA",
-        "eastus2": "Virginia, USA",
-        "usgoviowa": "Iowa, USA",
-        "usgovvirginia": "Virginia, USA",
-        "northcentralus": "Illinois, USA",
-        "southcentralus": "Texas, USA",
-        "westus": "California, USA",
-        "northeurope": "Ireland",
-        "westeurope": "Netherlands",
-        "eastasia": "Hong Kong",
-        "southeastasia": "Singapore",
-        "japaneast": "Tokyo, Japan",
-        "japanwest": "Osaka, Japan",
-        "brazilsouth": "Sao Paulo State, Brazil",
-        "australiaeast": "New South Wales, Australia",
-        "australiasoutheast": "Victoria, Australia"
-    }
-
-    def __init__(self, tenant_id, subscription_id, key, secret,
-                 secure=True, host=None, port=None,
-                 api_version=None, region=None, **kwargs):
-        self.tenant_id = tenant_id
-        self.subscription_id = subscription_id
-        super(AzureNodeDriver, self).__init__(key=key, secret=secret,
-                                              secure=secure,
-                                              host=host, port=port,
-                                              api_version=api_version,
-                                              region=region, **kwargs)
-        if self.region is not None:
-            loc_id = self.region.lower().replace(" ", "")
-            country = self._location_to_country.get(loc_id)
-            self.default_location = NodeLocation(loc_id,
-                                                 self.region,
-                                                 country,
-                                                 self)
-        else:
-            self.default_location = None
-
-    def list_locations(self):
-        """
-        List data centers available with the current subscription.
-
-        :return: list of node location objects
-        :rtype: ``list`` of :class:`.NodeLocation`
-        """
-
-        action = "/subscriptions/%s/providers/Microsoft.Compute" % (
-            self.subscription_id)
-        r = self.connection.request(action,
-                                    params={"api-version": "2015-01-01"})
-
-        for rt in r.object["resourceTypes"]:
-            if rt["resourceType"] == "virtualMachines":
-                return [self._to_location(l) for l in rt["locations"]]
-
-        return []
-
-    def list_sizes(self, location=None):
-        """
-        List available VM sizes.
-
-        :param location: The location at which to list sizes
-        (if None, use default location specified as 'region' in __init__)
-        :type location: :class:`.NodeLocation`
-
-        :return: list of node size objects
-        :rtype: ``list`` of :class:`.NodeSize`
-        """
-
-        if location is None:
-            if self.default_location:
-                location = self.default_location
-            else:
-                raise ValueError("location is required.")
-        action = \
-            "/subscriptions/%s/providers/Microsoft" \
-            ".Compute/locations/%s/vmSizes" \
-            % (self.subscription_id, location.id)
-        r = self.connection.request(action,
-                                    params={"api-version": "2015-06-15"})
-        return [self._to_node_size(d) for d in r.object["value"]]
-
-    def list_images(self, location=None, ex_publisher=None, ex_offer=None,
-                    ex_sku=None, ex_version=None):
-        """
-        List available VM images to boot from.
-
-        :param location: The location at which to list images
-        (if None, use default location specified as 'region' in __init__)
-        :type location: :class:`.NodeLocation`
-
-        :param ex_publisher: Filter by publisher, or None to list
-        all publishers.
-        :type ex_publisher: ``str``
-
-        :param ex_offer: Filter by offer, or None to list all offers.
-        :type ex_offer: ``str``
-
-        :param ex_sku: Filter by sku, or None to list all skus.
-        :type ex_sku: ``str``
-
-        :param ex_version: Filter by version, or None to list all versions.
-        :type ex_version: ``str``
-
-        :return: list of node image objects.
-        :rtype: ``list`` of :class:`.AzureImage`
-        """
-
-        images = []
-
-        if location is None:
-            locations = [self.default_location]
-        else:
-            locations = [location]
-
-        for loc in locations:
-            if not ex_publisher:
-                publishers = self.ex_list_publishers(loc)
-            else:
-                publishers = [(
-                    "/subscriptions/%s/providers/Microsoft"
-                    ".Compute/locations/%s/publishers/%s" %
-                    (self.subscription_id, loc.id, ex_publisher),
-                    ex_publisher)]
-
-            for pub in publishers:
-                if not ex_offer:
-                    offers = self.ex_list_offers(pub[0])
-                else:
-                    offers = [("%s/artifacttypes/vmimage/offers/%s" % (
-                        pub[0], ex_offer), ex_offer)]
-
-                for off in offers:
-                    if not ex_sku:
-                        skus = self.ex_list_skus(off[0])
-                    else:
-                        skus = [("%s/skus/%s" % (off[0], ex_sku), ex_sku)]
-
-                    for sku in skus:
-                        if not ex_version:
-                            versions = self.ex_list_image_versions(sku[0])
-                        else:
-                            versions = [("%s/versions/%s" % (
-                                sku[0], ex_version), ex_version)]
-
-                        for v in versions:
-                            images.append(AzureImage(v[1], sku[1],
-                                                     off[1], pub[1],
-                                                     loc.id,
-                                                     self.connection.driver))
-        return images
-
-    def get_image(self, image_id, location=None):
-        """Returns a single node image from a provider.
-
-        :param image_id: Either an image urn in the form
-        `Publisher:Offer:Sku:Version` or a Azure blob store URI in the form
-        `http://storageaccount.blob.core.windows.net/container/image.vhd`
-        pointing to a VHD file.
-        :type image_id: ``str``
-
-        :param location: The location at which to search for the image
-        (if None, use default location specified as 'region' in __init__)
-        :type location: :class:`.NodeLocation`
-
-        :rtype :class:`.AzureImage`: or :class:`.AzureVhdImage`:
-        :return: AzureImage or AzureVhdImage instance on success.
-
-        """
-
-        if image_id.startswith("http"):
-            (storageAccount, blobContainer, blob) = _split_blob_uri(image_id)
-            return AzureVhdImage(storageAccount, blobContainer, blob, self)
-        else:
-            (ex_publisher, ex_offer, ex_sku, ex_version) = image_id.split(":")
-            i = self.list_images(location, ex_publisher,
-                                 ex_offer, ex_sku, ex_version)
-            return i[0] if i else None
-
-    def list_nodes(self, ex_resource_group=None, ex_fetch_nic=True):
-        """
-        List all nodes.
-
-        :param ex_resource_group: List nodes in a specific resource group.
-        :type ex_urn: ``str``
-
-        :param ex_fetch_nic: Fetch NIC resources in order to get
-        IP address information for nodes (requires extra API calls).
-        :type ex_urn: ``bool``
-
-        :return:  list of node objects
-        :rtype: ``list`` of :class:`.Node`
-        """
-
-        if ex_resource_group:
-            action = "/subscriptions/%s/resourceGroups/%s/" \
-                     "providers/Microsoft.Compute/virtualMachines" \
-                     % (self.subscription_id, ex_resource_group)
-        else:
-            action = "/subscriptions/%s/providers/Microsoft.Compute/" \
-                     "virtualMachines" \
-                     % (self.subscription_id)
-        r = self.connection.request(action,
-                                    params={"api-version": "2015-06-15"})
-        return [self._to_node(n, fetch_nic=ex_fetch_nic)
-                for n in r.object["value"]]
-
-    def create_node(self,
-                    name,
-                    size,
-                    image,
-                    auth,
-                    ex_resource_group,
-                    ex_storage_account,
-                    ex_blob_container="vhds",
-                    location=None,
-                    ex_user_name="azureuser",
-                    ex_network=None,
-                    ex_subnet=None,
-                    ex_nic=None,
-                    ex_tags={},
-                    ex_customdata=""):
-        """Create a new node instance. This instance will be started
-        automatically.
-
-        This driver supports the ``ssh_key`` feature flag for ``created_node``
-        so you can upload a public key into the new instance::
-
-            >>> from libcloud.compute.drivers.azure_arm import AzureNodeDriver
-            >>> driver = AzureNodeDriver(...)
-            >>> auth = NodeAuthSSHKey('pubkey data here')
-            >>> node = driver.create_node("test_node", auth=auth)
-
-        This driver also supports the ``password`` feature flag for
-        ``create_node``
-        so you can set a password::
-
-            >>> driver = AzureNodeDriver(...)
-            >>> auth = NodeAuthPassword('mysecretpassword')
-            >>> node = driver.create_node("test_node", auth=auth, ...)
-
-        If you don't provide the ``auth`` argument libcloud will assign
-        a password::
-
-            >>> driver = AzureNodeDriver(...)
-            >>> node = driver.create_node("test_node", ...)
-            >>> password = node.extra["properties"] \
-                           ["osProfile"]["adminPassword"]
-
-        :param name:   String with a name for this new node (required)
-        :type name:   ``str``
-
-        :param size:   The size of resources allocated to this node.
-                            (required)
-        :type size:   :class:`.NodeSize`
-
-        :param image:  OS Image to boot on node. (required)
-        :type image:  :class:`.AzureImage`
-
-        :param location: Which data center to create a node in.
-        (if None, use default location specified as 'region' in __init__)
-        :type location: :class:`.NodeLocation`
-
-        :param auth:   Initial authentication information for the node
-                            (optional)
-        :type auth:   :class:`.NodeAuthSSHKey` or :class:`NodeAuthPassword`
-
-        :param ex_resource_group:  The resource group in which to create the
-        node
-        :type ex_resource_group: ``str``
-
-        :param ex_storage_account:  The storage account id in which to store
-        the node's disk image.
-        Note: when booting from a user image (AzureVhdImage)
-        the source image and the node image must use the same storage account.
-        :type ex_storage_account: ``str``
-
-        :param ex_blob_container:  The name of the blob container on the
-        storage account in which to store the node's disk image (optional,
-        default "vhds")
-        :type ex_blob_container: ``str``
-
-        :param ex_user_name:  User name for the initial admin user
-        (optional, default "azureuser")
-        :type ex_user_name: ``str``
-
-        :param ex_network: The virtual network the node will be attached to.
-        Must provide either `ex_network` (to create a default NIC for the
-        node on the given network) or `ex_nic` (to supply the NIC explicitly).
-        :type ex_network: ``str``
-
-        :param ex_subnet: If ex_network is provided, the subnet of the
-        virtual network the node will be attached to.  Optional, default
-        is the "default" subnet.
-        :type ex_subnet: ``str``
-
-        :param ex_nic: A virtual NIC to attach to this Node, from
-        `ex_create_network_interface` or `ex_get_nic`.
-        Must provide either `ex_nic` (to supply the NIC explicitly) or
-        ex_network (to create a default NIC for the node on the
-        given network).
-        :type ex_nic: :class:`AzureNic`
-
-        :param ex_tags: Optional tags to associate with this node.
-        :type ex_tags: ``dict``
-
-        :param ex_customdata: Custom data that will
-            be placed in the file /var/lib/waagent/CustomData
-            https://azure.microsoft.com/en-us/documentation/ \
-            articles/virtual-machines-how-to-inject-custom-data/
-        :type ex_customdata: ``str``
-
-        :return: The newly created node.
-        :rtype: :class:`.Node`
-
-        """
-
-        if location is None:
-            location = self.default_location
-        if ex_nic is None:
-            if ex_network is None:
-                raise ValueError("Must provide either ex_network or ex_nic")
-            if ex_subnet is None:
-                ex_subnet = "default"
-
-            subnet_id = "/subscriptions/%s/resourceGroups/%s/providers" \
-                        "/Microsoft.Network/virtualnetworks/%s/subnets/%s" % \
-                        (self.subscription_id, ex_resource_group,
-                         ex_network, ex_subnet)
-            subnet = AzureSubnet(subnet_id, ex_subnet, {})
-            ex_nic = self.ex_create_network_interface(name + "-nic",
-                                                      subnet,
-                                                      ex_resource_group,
-                                                      location)
-
-        auth = self._get_and_check_auth(auth)
-
-        target = "/subscriptions/%s/resourceGroups/%s/providers" \
-                 "/Microsoft.Compute/virtualMachines/%s" % \
-                 (self.subscription_id, ex_resource_group, name)
-
-        n = 0
-        while True:
-            try:
-                instance_vhd = "https://%s.blob.core.windows.net" \
-                               "/%s/%s-os_%i.vhd" \
-                               % (ex_storage_account,
-                                  ex_blob_container,
-                                  name,
-                                  n)
-                self._ex_delete_old_vhd(ex_resource_group, instance_vhd)
-                break
-            except LibcloudError:
-                n += 1
-
-        if isinstance(image, AzureVhdImage):
-            storageProfile = {
-                "osDisk": {
-                    "name": "virtualmachine-osDisk",
-                    "osType": "linux",
-                    "caching": "ReadWrite",
-                    "createOption": "FromImage",
-                    "image": {
-                        "uri": image.id
-                    },
-                    "vhd": {
-                        "uri": instance_vhd
-                    }
-                }
-            }
-        elif isinstance(image, AzureImage):
-            storageProfile = {
-                "imageReference": {
-                    "publisher": image.publisher,
-                    "offer": image.offer,
-                    "sku": image.sku,
-                    "version": image.version
-                },
-                "osDisk": {
-                    "name": "virtualmachine-osDisk",
-                    "vhd": {
-                        "uri": instance_vhd
-                    },
-                    "caching": "ReadWrite",
-                    "createOption": "FromImage"
-                }
-            }
-        else:
-            raise LibcloudError(
-                "Unknown image type %s,"
-                "expected one of AzureImage, AzureVhdImage",
-                type(image))
-
-        data = {
-            "id": target,
-            "name": name,
-            "type": "Microsoft.Compute/virtualMachines",
-            "location": location.id,
-            "tags": ex_tags,
-            "properties": {
-                "hardwareProfile": {
-                    "vmSize": size.id
-                },
-                "storageProfile": storageProfile,
-                "osProfile": {
-                    "computerName": name
-                },
-                "networkProfile": {
-                    "networkInterfaces": [
-                        {
-                            "id": ex_nic.id
-                        }
-                    ]
-                }
-            }
-        }
-
-        if ex_customdata:
-            data["properties"]["osProfile"]["customData"] = \
-                base64.b64encode(ex_customdata)
-
-        data["properties"]["osProfile"]["adminUsername"] = ex_user_name
-
-        if isinstance(auth, NodeAuthSSHKey):
-            data["properties"]["osProfile"]["adminPassword"] = \
-                binascii.hexlify(os.urandom(20))
-            data["properties"]["osProfile"]["linuxConfiguration"] = {
-                "disablePasswordAuthentication": "true",
-                "ssh": {
-                    "publicKeys": [
-                        {
-                            "path": '/home/%s/.ssh/authorized_keys' % (
-                                ex_user_name),
-                            "keyData": auth.pubkey
-                        }
-                    ]
-                }
-            }
-        elif isinstance(auth, NodeAuthPassword):
-            data["properties"]["osProfile"]["linuxConfiguration"] = {
-                "disablePasswordAuthentication": "false"
-            }
-            data["properties"]["osProfile"]["adminPassword"] = auth.password
-        else:
-            raise ValueError(
-                "Must provide NodeAuthSSHKey or NodeAuthPassword in auth")
-
-        r = self.connection.request(target,
-                                    params={"api-version": "2015-06-15"},
-                                    data=data,
-                                    method="PUT")
-
-        node = self._to_node(r.object)
-        node.size = size
-        node.image = image
-        return node
-
-    def reboot_node(self, node):
-        """
-        Reboot a node.
-
-        :param node: The node to be rebooted
-        :type node: :class:`.Node`
-
-        :return: True if the reboot was successful, otherwise False
-        :rtype: ``bool``
-        """
-
-        target = "%s/restart" % node.id
-        try:
-            self.connection.request(target,
-                                    params={"api-version": "2015-06-15"},
-                                    method='POST')
-            return True
-        except BaseHTTPError as h:
-            if h.code == 202:
-                return True
-            else:
-                return False
-
-    def destroy_node(self, node, ex_destroy_nic=True, ex_destroy_vhd=True):
-        """
-        Destroy a node.
-
-        :param node: The node to be destroyed
-        :type node: :class:`.Node`
-
-        :param ex_destroy_nic: Destroy the NICs associated with
-        this node (default True).
-        :type node: ``bool``
-
-        :param ex_destroy_vhd: Destroy the OS disk blob associated with
-        this node (default True).
-        :type node: ``bool``
-
-        :return: True if the destroy was successful, False otherwise.
-        :rtype: ``bool``
-        """
-
-        # This returns a 202 (Accepted) which means that the delete happens
-        # asynchronously.
-        try:
-            self.connection.request(node.id,
-                                    params={"api-version": "2015-06-15"},
-                                    method='DELETE')
-        except BaseHTTPError as h:
-            if h.code == 202:
-                pass
-            else:
-                return False
-
-        # Need to poll until the node actually goes away.
-        while True:
-            try:
-                time.sleep(10)
-                self.connection.request(
-                    node.id,
-                    params={"api-version": "2015-06-15"})
-            except BaseHTTPError as h:
-                if h.code == 404:
-                    break
-                else:
-                    return False
-
-        # Optionally clean up the network
-        # interfaces that were attached to this node.
-        interfaces = \
-            node.extra["properties"]["networkProfile"]["networkInterfaces"]
-        if ex_destroy_nic:
-            for nic in interfaces:
-                while True:
-                    try:
-                        self.connection.request(nic["id"],
-                                                params={
-                                                    "api-version":
-                                                    "2015-06-15"},
-                                                method='DELETE')
-                        break
-                    except BaseHTTPError as h:
-                        if h.code == 202:
-                            break
-                        inuse = h.message.startswith("[NicInUse]")
-                        if h.code == 400 and inuse:
-                            time.sleep(10)
-                        else:
-                            return False
-
-        # Optionally clean up OS disk VHD.
-        vhd_uri = \
-            node.extra["properties"]["storageProfile"]["osDisk"]["vhd"]["uri"]
-        if ex_destroy_vhd:
-            while True:
-                try:
-                    resourceGroup = node.id.split("/")[4]
-                    self._ex_delete_old_vhd(
-                        resourceGroup,
-                        vhd_uri)
-                    break
-                except LibcloudError as e:
-                    if "LeaseIdMissing" in str(e):
-                        # Unfortunately lease errors
-                        # (which occur if the vhd blob
-                        # hasn't yet been released by the VM being destroyed)
-                        # get raised as plain
-                        # LibcloudError.  Wait a bit and try again.
-                        time.sleep(10)
-                    else:
-                        raise
-
-        return True
-
-    def ex_list_publishers(self, location=None):
-        """
-        List node image publishers.
-
-        :param location: The location at which to list publishers
-        (if None, use default location specified as 'region' in __init__)
-        :type location: :class:`.NodeLocation`
-
-        :return: A list of tuples in the form
-        ("publisher id", "publisher name")
-        :rtype: ``list``
-        """
-
-        if location is None and self.default_location:
-            location = self.default_location
-        else:
-            raise ValueError("location is required.")
-
-        action = "/subscriptions/%s/providers/Microsoft.Compute/" \
-                 "locations/%s/publishers" \
-                 % (self.subscription_id, location.id)
-        r = self.connection.request(action,
-                                    params={"api-version": "2015-06-15"})
-        return [(p["id"], p["name"]) for p in r.object]
-
-    def ex_list_offers(self, publisher):
-        """
-        List node image offers from a publisher.
-
-        :param publisher: The complete resource path to a publisher
-        (as returned by `ex_list_publishers`)
-        :type publisher: ``str``
-
-        :return: A list of tuples in the form
-        ("offer id", "offer name")
-        :rtype: ``list``
-        """
-
-        action = "%s/artifacttypes/vmimage/offers" % (publisher)
-        r = self.connection.request(action,
-                                    params={"api-version": "2015-06-15"})
-        return [(p["id"], p["name"]) for p in r.object]
-
-    def ex_list_skus(self, offer):
-        """
-        List node image skus in an offer.
-
-        :param offer: The complete resource path to an offer (as returned by
-        `ex_list_offers`)
-        :type publisher: ``str``
-
-        :return: A list of tuples in the form
-        ("sku id", "sku name")
-        :rtype: ``list``
-        """
-
-        action = "%s/skus" % (offer)
-        r = self.connection.request(action,
-                                    params={"api-version": "2015-06-15"})
-        return [(sku["id"], sku["name"]) for sku in r.object]
-
-    def ex_list_image_versions(self, sku):
-        """
-        List node image versions in a sku.
-
-        :param sku: The complete resource path to a sku (as returned by
-        `ex_list_skus`)
-        :type publisher: ``str``
-
-        :return: A list of tuples in the form
-        ("version id", "version name")
-        :rtype: ``list``
-        """
-
-        action = "%s/versions" % (sku)
-        r = self.connection.request(action,
-                                    params={"api-version": "2015-06-15"})
-        return [(img["id"], img["name"]) for img in r.object]
-
-    def ex_list_networks(self):
-        """
-        List virtual networks.
-
-        :return: A list of virtual networks.
-        :rtype: ``list`` of :class:`.AzureNetwork`
-        """
-
-        action = "/subscriptions/%s/providers/" \
-                 "Microsoft.Network/virtualnetworks" \
-                 % (self.subscription_id)
-        r = self.connection.request(action,
-                                    params={"api-version": "2015-06-15"})
-        return [AzureNetwork(net["id"], net["name"], net["location"],
-                             net["properties"]) for net in r.object["value"]]
-
-    def ex_list_subnets(self, network):
-        """
-        List subnets of a virtual network.
-
-        :param network: The virtual network containing the subnets.
-        :type network: :class:`.AzureNetwork`
-
-        :return: A list of subnets.
-        :rtype: ``list`` of :class:`.AzureSubnet`
-        """
-
-        action = "%s/subnets" % (network.id)
-        r = self.connection.request(action,
-                                    params={"api-version": "2015-06-15"})
-        return [AzureSubnet(net["id"], net["name"], net["properties"])
-                for net in r.object["value"]]
-
-    def ex_list_nics(self, resource_group):
-        """
-        List available virtual network interface controllers
-        in a resource group
-
-        :param resource_group: List NICS in a specific resource group
-        containing the NICs.
-        :type resource_group: ``str``
-
-        :return: A list of NICs.
-        :rtype: ``list`` of :class:`.AzureNic`
-        """
-
-        action = "/subscriptions/%s/providers/Microsoft.Network" \
-                 "/networkInterfaces" % \
-                 (self.subscription_id, resource_group)
-        r = self.connection.request(action,
-                                    params={"api-version": "2015-06-15"})
-        return [self._to_nic(net) for net in r.object["value"]]
-
-    def ex_get_nic(self, id):
-        """
-        Fetch information about a NIC.
-
-        :param id: The complete resource path to the NIC resource.
-        :type id: ``str``
-
-        :return: The NIC object
-        :rtype: :class:`.AzureNic`
-        """
-
-        r = self.connection.request(id, params={"api-version": "2015-06-15"})
-        return self._to_nic(r.object)
-
-    def ex_get_public_ip(self, id):
-        """
-        Fetch information about a public IP resource.
-
-        :param id: The complete resource path to the public IP resource.
-        :type id: ``str`
-
-        :return: The public ip object
-        :rtype: :class:`.AzureIPAddress`
-        """
-
-        r = self.connection.request(id, params={"api-version": "2015-06-15"})
-        return self._to_ip_address(r.object)
-
-    def ex_list_public_ips(self, resource_group):
-        """
-        List public IP resources.
-
-        :param resource_group: List public IPs in a specific resource group.
-        :type resource_group: ``str``
-
-        :return: List of public ip objects
-        :rtype: ``list`` of :class:`.AzureIPAddress`
-        """
-
-        action = "/subscriptions/%s/providers/Microsoft.Network" \
-                 "/publicIPAddresses" % (self.subscription_id, resource_group)
-        r = self.connection.request(action,
-                                    params={"api-version": "2015-06-15"})
-        return [self._to_ip_address(net) for net in r.object["value"]]
-
-    def ex_create_public_ip(self, name, resource_group, location=None):
-        """
-        Create a public IP resources.
-
-        :param name: Name of the public IP resource
-        :type name: ``str``
-
-        :param resource_group: The resource group to create the public IP
-        :type resource_group: ``str``
-
-        :param location: The location at which to create the public IP
-        (if None, use default location specified as 'region' in __init__)
-        :type location: :class:`.NodeLocation`
-
-        :return: The newly created public ip object
-        :rtype: :class:`.AzureIPAddress`
-        """
-
-        if location is None and self.default_location:
-            location = self.default_location
-        else:
-            raise ValueError("location is required.")
-
-        target = "/subscriptions/%s/resourceGroups/%s/" \
-                 "providers/Microsoft.Network/publicIPAddresses/%s" \
-                 % (self.subscription_id, resource_group, name)
-        data = {
-            "location": location.id,
-            "tags": {},
-            "properties": {
-                "publicIPAllocationMethod": "Dynamic"
-            }
-        }
-        r = self.connection.request(target,
-                                    params={"api-version": "2015-06-15"},
-                                    data=data,
-                                    method='PUT'
-                                    )
-        return self._to_ip_address(r.object)
-
-    def ex_create_network_interface(self, name, subnet, resource_group,
-                                    location=None, public_ip=None):
-        """
-        Create a virtual network interface (NIC).
-
-        :param name: Name of the NIC resource
-        :type name: ``str``
-
-        :param subnet: The subnet to attach the NIC
-        :type subnet: :class:`.AzureSubnet`
-
-        :param resource_group: The resource group to create the NIC
-        :type resource_group: ``str``
-
-        :param location: The location at which to create the NIC
-        (if None, use default location specified as 'region' in __init__)
-        :type location: :class:`.NodeLocation`
-
-        :param public_ip: Associate a public IP resource with this NIC
-        (optional).
-        :type public_ip: :class:`.AzureIPAddress`
-
-        :return: The newly created NIC
-        :rtype: :class:`.AzureNic`
-        """
-
-        if location is None:
-            if self.default_location:
-                location = self.default_location
-            else:
-                raise ValueError("location is required.")
-
-        target = "/subscriptions/%s/resourceGroups/%s/providers" \
-                 "/Microsoft.Network/networkInterfaces/%s" \
-                 % (self.subscription_id, resource_group, name)
-
-        data = {
-            "location": location.id,
-            "tags": {},
-            "properties": {
-                "ipConfigurations": [{
-                    "name": "myip1",
-                    "properties": {
-                        "subnet": {
-                            "id": subnet.id
-                        },
-                        "privateIPAllocationMethod": "Dynamic"
-                    }
-                }]
-            }
-        }
-
-        if public_ip:
-            data["properties"]["ipConfigurations"][0]["publicIPAddress"] = {
-                "id": public_ip.id
-            }
-
-        r = self.connection.request(target,
-                                    params={"api-version": "2015-06-15"},
-                                    data=data,
-                                    method='PUT'
-                                    )
-        return AzureNic(r.object["id"], r.object["name"], r.object["location"],
-                        r.object["properties"])
-
-    def ex_create_tags(self, resource, tags, replace=False):
-        """
-        Update tags on any resource supporting tags.
-
-        :param resource: The resource to update.
-        :type resource: ``str`` or Azure object with an ``id`` attribute.
-
-        :param tags: The tags to set.
-        :type tags: ``dict``
-
-        :param replace: If true, replace all tags with the new tags.
-        If false (default) add or update tags.
-        :type replace: ``bool``
-        """
-
-        if not isinstance(resource, basestring):
-            resource = resource.id
-        r = self.connection.request(
-            resource,
-            params={"api-version": "2015-06-15"})
-        if replace:
-            r.object["tags"] = tags
-        else:
-            r.object["tags"].update(tags)
-        r = self.connection.request(resource, data={"tags": r.object["tags"]},
-                                    params={"api-version": "2015-06-15"},
-                                    method="PATCH")
-
-    def ex_start_node(self, node):
-        """
-        Start a stopped node.
-
-        :param node: The node to be started
-        :type node: :class:`.Node`
-        """
-
-        target = "%s/start" % node.id
-        r = self.connection.request(target,
-                                    params={"api-version": "2015-06-15"},
-                                    method='POST')
-        return r.object
-
-    def ex_stop_node(self, node, deallocate=True):
-        """
-        Stop a running node.
-
-        :param node: The node to be stopped
-        :type node: :class:`.Node`
-
-        :param deallocate: If True (default) stop and then deallocate the node
-        (release the hardware allocated to run the node).  If False, stop the
-        node but maintain the hardware allocation.  If the node is not
-        deallocated, the subscription will continue to be billed as if it
-        were running.
-        :type deallocate: ``bool``
-        """
-
-        if deallocate:
-            target = "%s/deallocate" % node.id
-        else:
-            target = "%s/stop" % node.id
-        r = self.connection.request(target,
-                                    params={"api-version": "2015-06-15"},
-                                    method='POST')
-        return r.object
-
-    def ex_get_storage_account_keys(self, resource_group, storage_account):
-        """
-        Get account keys required to access to a storage account
-        (using AzureBlobsStorageDriver).
-
-        :param resource_group: The resource group
-            containing the storage account
-        :type resource_group: ``str``
-
-        :param storage_account: Storage account to access
-        :type storage_account: ``str``
-
-        :return: The account keys, in the form `{"key1": "XXX", "key2": "YYY"}`
-        :rtype: ``.dict``
-        """
-
-        action = "/subscriptions/%s/resourceGroups/%s/" \
-                 "providers/Microsoft.Storage/storageAccounts/%s/listKeys" \
-                 % (self.subscription_id,
-                    resource_group,
-                    storage_account)
-
-        r = self.connection.request(action,
-                                    params={
-                                        "api-version": "2015-05-01-preview"},
-                                    method="POST")
-        return r.object
-
-    def ex_run_command(self, node,
-                       command,
-                       filerefs=[],
-                       timestamp=0,
-                       storage_account_name=None,
-                       storage_account_key=None,
-                       location=None):
-        """
-        Run a command on the node as root.
-
-        Does not require ssh to log in,
-        uses Windows Azure Agent (waagent) running
-        on the node.
-
-        :param node: The node on which to run the command.
-        :type node: :class:``.Node``
-
-        :param command: The actual command to run.  Note this is parsed
-        into separate arguments according to shell quoting rules but is
-        executed directly as a subprocess, not a shell command.
-        :type command: ``str``
-
-        :param filerefs: Optional files to fetch by URI from Azure blob store
-        (must provide storage_account_name and storage_account_key),
-        or regular HTTP.
-        :type command: ``list`` of ``str``
-
-        :param location: The location of the virtual machine
-        (if None, use default location specified as 'region' in __init__)
-        :type location: :class:`.NodeLocation`
-
-        :param storage_account_name: The storage account
-            from which to fetch files in `filerefs`
-        :type storage_account_name: ``str``
-
-        :param storage_account_key: The storage key to
-            authorize to the blob store.
-        :type storage_account_key: ``str``
-
-        :type: ``list`` of :class:`.NodeLocation`
-
-        """
-
-        if location is None:
-            if self.default_location:
-                location = self.default_location
-            else:
-                raise ValueError("location is required.")
-
-        name = "init"
-
-        target = node.id + "/extensions/" + name
-
-        data = {
-            "location": location.id,
-            "name": name,
-            "properties": {
-                "publisher": "Microsoft.OSTCExtensions",
-                "type": "CustomScriptForLinux",
-                "typeHandlerVersion": "1.3",
-                "settings": {
-                    "fileUris": filerefs,
-                    "commandToExecute": command,
-                    "timestamp": timestamp
-                }
-            }
-        }
-
-        if storage_account_name and storage_account_key:
-            data["properties"]["protectedSettings"] = {
-                "storageAccountName": storage_account_name,
-                "storageAccountKey": storage_account_key}
-
-        r = self.connection.request(target,
-                                    params={"api-version": "2015-06-15"},
-                                    data=data,
-                                    method='PUT')
-        return r.object
-
-    def _ex_delete_old_vhd(self, resource_group, uri):
-        try:
-            (storageAccount, blobContainer, blob) = _split_blob_uri(uri)
-            keys = self.ex_get_storage_account_keys(resource_group,
-                                                    storageAccount)
-            blobdriver = AzureBlobsStorageDriver(storageAccount,
-                                                 keys["key1"])
-            blobdriver.delete_object(blobdriver.get_object(blobContainer,
-                                                           blob))
-            return True
-        except ObjectDoesNotExistError:
-            return True
-
-    def _ex_connection_class_kwargs(self):
-        kwargs = super(AzureNodeDriver, self)._ex_connection_class_kwargs()
-        kwargs['tenant_id'] = self.tenant_id
-        kwargs['subscription_id'] = self.subscription_id
-        return kwargs
-
-    def _to_node(self, data, fetch_nic=True):
-        private_ips = []
-        public_ips = []
-        nics = data["properties"]["networkProfile"]["networkInterfaces"]
-        if fetch_nic:
-            for nic in nics:
-                try:
-                    n = self.ex_get_nic(nic["id"])
-                    priv = n.extra["ipConfigurations"][0]["properties"] \
-                        .get("privateIPAddress")
-                    if priv:
-                        private_ips.append(priv)
-                    pub = n.extra["ipConfigurations"][0]["properties"].get(
-                        "publicIPAddress")
-                    if pub:
-                        pub_addr = self.ex_get_public_ip(pub["id"])
-                        addr = pub_addr.extra.get("ipAddress")
-                        if addr:
-                            public_ips.append(addr)
-                except BaseHTTPError:
-                    pass
-
-        state = NodeState.UNKNOWN
-        try:
-            action = "%s/InstanceView" % (data["id"])
-            r = self.connection.request(action,
-                                        params={"api-version": "2015-06-15"})
-            for status in r.object["statuses"]:
-                if status["code"] == "ProvisioningState/creating":
-                    state = NodeState.PENDING
-                    break
-                elif status["code"] == "ProvisioningState/deleting":
-                    state = NodeState.TERMINATED
-                    break
-                elif status["code"].startswith("ProvisioningState/failed"):
-                    state = NodeState.ERROR
-                    break
-                elif status["code"] == "ProvisioningState/succeeded":
-                    pass
-
-                if status["code"] == "PowerState/deallocated":
-                    state = NodeState.STOPPED
-                    break
-                elif status["code"] == "PowerState/deallocating":
-                    state = NodeState.PENDING
-                    break
-                elif status["code"] == "PowerState/running":
-                    state = NodeState.RUNNING
-        except BaseHTTPError:
-            pass
-
-        node = Node(data["id"],
-                    data["name"],
-                    state,
-                    public_ips,
-                    private_ips,
-                    driver=self.connection.driver,
-                    extra=data)
-
-        return node
-
-    def _to_node_size(self, data):
-        return NodeSize(id=data["name"],
-                        name=data["name"],
-                        ram=data["memoryInMB"],
-                        # convert to disk from MB to GB
-                        disk=data["resourceDiskSizeInMB"] / 1024,
-                        bandwidth=0,
-                        price=0,
-                        driver=self.connection.driver,
-                        extra={"numberOfCores": data["numberOfCores"],
-                               "osDiskSizeInMB": data["osDiskSizeInMB"],
-                               "maxDataDiskCount": data["maxDataDiskCount"]})
-
-    def _to_nic(self, data):
-        return AzureNic(data["id"], data["name"], data["location"],
-                        data["properties"])
-
-    def _to_ip_address(self, data):
-        return AzureIPAddress(data["id"], data["name"], data["properties"])
-
-    def _to_location(self, loc):
-        # XXX for some reason the API returns location names like
-        # "East US" instead of "eastus" which is what is actually needed
-        # for other API calls, so do a name->id fixup.
-        loc_id = loc.lower().replace(" ", "")
-        return NodeLocation(loc_id, loc, self._location_to_country.get(loc_id),
-                            self.connection.driver)
-
-
-def _split_blob_uri(uri):
-    uri = uri.split("/")
-    storageAccount = uri[2].split(".")[0]
-    blobContainer = uri[3]
-    blob = '/'.join(uri[4:])
-    return (storageAccount, blobContainer, blob)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/bluebox.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/bluebox.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/bluebox.py
deleted file mode 100644
index 204e0de..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/bluebox.py
+++ /dev/null
@@ -1,235 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-libcloud driver for the Blue Box Blocks API
-
-This driver implements all libcloud functionality for the Blue Box Blocks API.
-
-Blue Box home page            http://bluebox.net
-Blue Box API documentation    https://boxpanel.bluebox
-.net/public/the_vault/index.php/Blocks_API
-"""
-
-import copy
-import base64
-
-from libcloud.utils.py3 import urlencode
-from libcloud.utils.py3 import b
-
-from libcloud.common.base import JsonResponse, ConnectionUserAndKey
-from libcloud.compute.providers import Provider
-from libcloud.compute.types import NodeState, InvalidCredsError
-from libcloud.compute.base import Node, NodeDriver
-from libcloud.compute.base import NodeSize, NodeImage, NodeLocation
-from libcloud.compute.base import NodeAuthPassword, NodeAuthSSHKey
-
-# Current end point for Blue Box API.
-BLUEBOX_API_HOST = "boxpanel.bluebox.net"
-
-# The API doesn't currently expose all of the required values for libcloud,
-# so we simply list what's available right now, along with all of the various
-# attributes that are needed by libcloud.
-BLUEBOX_INSTANCE_TYPES = {
-    '1gb': {
-        'id': '94fd37a7-2606-47f7-84d5-9000deda52ae',
-        'name': 'Block 1GB Virtual Server',
-        'ram': 1024,
-        'disk': 20,
-        'cpu': 0.5
-    },
-    '2gb': {
-        'id': 'b412f354-5056-4bf0-a42f-6ddd998aa092',
-        'name': 'Block 2GB Virtual Server',
-        'ram': 2048,
-        'disk': 25,
-        'cpu': 1
-    },
-    '4gb': {
-        'id': '0cd183d3-0287-4b1a-8288-b3ea8302ed58',
-        'name': 'Block 4GB Virtual Server',
-        'ram': 4096,
-        'disk': 50,
-        'cpu': 2
-    },
-    '8gb': {
-        'id': 'b9b87a5b-2885-4a2e-b434-44a163ca6251',
-        'name': 'Block 8GB Virtual Server',
-        'ram': 8192,
-        'disk': 100,
-        'cpu': 4
-    }
-}
-
-RAM_PER_CPU = 2048
-
-NODE_STATE_MAP = {'queued': NodeState.PENDING,
-                  'building': NodeState.PENDING,
-                  'running': NodeState.RUNNING,
-                  'error': NodeState.TERMINATED,
-                  'unknown': NodeState.UNKNOWN}
-
-
-class BlueboxResponse(JsonResponse):
-    def parse_error(self):
-        if int(self.status) == 401:
-            if not self.body:
-                raise InvalidCredsError(str(self.status) + ': ' + self.error)
-            else:
-                raise InvalidCredsError(self.body)
-        return self.body
-
-
-class BlueboxNodeSize(NodeSize):
-    def __init__(self, id, name, cpu, ram, disk, price, driver):
-        self.id = id
-        self.name = name
-        self.cpu = cpu
-        self.ram = ram
-        self.disk = disk
-        self.price = price
-        self.driver = driver
-
-    def __repr__(self):
-        return ((
-                '<NodeSize: id=%s, name=%s, cpu=%s, ram=%s, disk=%s, '
-                'price=%s, driver=%s ...>')
-                % (self.id, self.name, self.cpu, self.ram, self.disk,
-                   self.price, self.driver.name))
-
-
-class BlueboxConnection(ConnectionUserAndKey):
-    """
-    Connection class for the Bluebox driver
-    """
-
-    host = BLUEBOX_API_HOST
-    secure = True
-    responseCls = BlueboxResponse
-
-    allow_insecure = False
-
-    def add_default_headers(self, headers):
-        user_b64 = base64.b64encode(b('%s:%s' % (self.user_id, self.key)))
-        headers['Authorization'] = 'Basic %s' % (user_b64)
-        return headers
-
-
-class BlueboxNodeDriver(NodeDriver):
-    """
-    Bluebox Blocks node driver
-    """
-
-    connectionCls = BlueboxConnection
-    type = Provider.BLUEBOX
-    api_name = 'bluebox'
-    name = 'Bluebox Blocks'
-    website = 'http://bluebox.net'
-    features = {'create_node': ['ssh_key', 'password']}
-
-    def list_nodes(self):
-        result = self.connection.request('/api/blocks.json')
-        return [self._to_node(i) for i in result.object]
-
-    def list_sizes(self, location=None):
-        sizes = []
-        for key, values in list(BLUEBOX_INSTANCE_TYPES.items()):
-            attributes = copy.deepcopy(values)
-            attributes.update({'price': self._get_size_price(size_id=key)})
-            sizes.append(BlueboxNodeSize(driver=self.connection.driver,
-                                         **attributes))
-
-        return sizes
-
-    def list_images(self, location=None):
-        result = self.connection.request('/api/block_templates.json')
-        images = []
-        for image in result.object:
-            images.extend([self._to_image(image)])
-
-        return images
-
-    def create_node(self, **kwargs):
-        headers = {'Content-Type': 'application/x-www-form-urlencoded'}
-        size = kwargs["size"]
-
-        name = kwargs['name']
-        image = kwargs['image']
-        size = kwargs['size']
-
-        auth = self._get_and_check_auth(kwargs.get('auth'))
-
-        data = {
-            'hostname': name,
-            'product': size.id,
-            'template': image.id
-        }
-
-        ssh = None
-        password = None
-
-        if isinstance(auth, NodeAuthSSHKey):
-            ssh = auth.pubkey
-            data.update(ssh_public_key=ssh)
-        elif isinstance(auth, NodeAuthPassword):
-            password = auth.password
-            data.update(password=password)
-
-        if "ex_username" in kwargs:
-            data.update(username=kwargs["ex_username"])
-
-        if not ssh and not password:
-            raise Exception("SSH public key or password required.")
-
-        params = urlencode(data)
-        result = self.connection.request('/api/blocks.json', headers=headers,
-                                         data=params, method='POST')
-        node = self._to_node(result.object)
-
-        if getattr(auth, "generated", False):
-            node.extra['password'] = auth.password
-
-        return node
-
-    def destroy_node(self, node):
-        url = '/api/blocks/%s.json' % (node.id)
-        result = self.connection.request(url, method='DELETE')
-
-        return result.status == 200
-
-    def list_locations(self):
-        return [NodeLocation(0, "Blue Box Seattle US", 'US', self)]
-
-    def reboot_node(self, node):
-        url = '/api/blocks/%s/reboot.json' % (node.id)
-        result = self.connection.request(url, method="PUT")
-        return result.status == 200
-
-    def _to_node(self, vm):
-        state = NODE_STATE_MAP[vm.get('status', NodeState.UNKNOWN)]
-        n = Node(id=vm['id'],
-                 name=vm['hostname'],
-                 state=state,
-                 public_ips=[ip['address'] for ip in vm['ips']],
-                 private_ips=[],
-                 extra={'storage': vm['storage'], 'cpu': vm['cpu']},
-                 driver=self.connection.driver)
-        return n
-
-    def _to_image(self, image):
-        image = NodeImage(id=image['id'],
-                          name=image['description'],
-                          driver=self.connection.driver)
-        return image

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/brightbox.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/brightbox.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/brightbox.py
deleted file mode 100644
index 8798332..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/brightbox.py
+++ /dev/null
@@ -1,306 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-Brightbox Driver
-"""
-
-from libcloud.utils.py3 import httplib
-from libcloud.utils.py3 import b
-
-from libcloud.common.brightbox import BrightboxConnection
-from libcloud.compute.types import Provider, NodeState
-from libcloud.compute.base import NodeDriver
-from libcloud.compute.base import Node, NodeImage, NodeSize, NodeLocation
-
-import base64
-
-
-API_VERSION = '1.0'
-
-
-def _extract(d, keys):
-    return dict((k, d[k]) for k in keys if k in d and d[k] is not None)
-
-
-class BrightboxNodeDriver(NodeDriver):
-    """
-    Brightbox node driver
-    """
-
-    connectionCls = BrightboxConnection
-
-    type = Provider.BRIGHTBOX
-    name = 'Brightbox'
-    website = 'http://www.brightbox.co.uk/'
-
-    NODE_STATE_MAP = {'creating': NodeState.PENDING,
-                      'active': NodeState.RUNNING,
-                      'inactive': NodeState.UNKNOWN,
-                      'deleting': NodeState.UNKNOWN,
-                      'deleted': NodeState.TERMINATED,
-                      'failed': NodeState.UNKNOWN,
-                      'unavailable': NodeState.UNKNOWN}
-
-    def __init__(self, key, secret=None, secure=True, host=None, port=None,
-                 api_version=API_VERSION, **kwargs):
-        super(BrightboxNodeDriver, self).__init__(key=key, secret=secret,
-                                                  secure=secure,
-                                                  host=host, port=port,
-                                                  api_version=api_version,
-                                                  **kwargs)
-
-    def _to_node(self, data):
-        extra_data = _extract(data, ['fqdn', 'user_data', 'status',
-                                     'interfaces', 'snapshots',
-                                     'server_groups', 'hostname',
-                                     'started_at', 'created_at',
-                                     'deleted_at'])
-        extra_data['zone'] = self._to_location(data['zone'])
-
-        ipv6_addresses = [interface['ipv6_address'] for interface
-                          in data['interfaces'] if 'ipv6_address' in interface]
-
-        private_ips = [interface['ipv4_address']
-                       for interface in data['interfaces']
-                       if 'ipv4_address' in interface]
-
-        public_ips = [cloud_ip['public_ip'] for cloud_ip in data['cloud_ips']]
-        public_ips += ipv6_addresses
-
-        return Node(
-            id=data['id'],
-            name=data['name'],
-            state=self.NODE_STATE_MAP[data['status']],
-            private_ips=private_ips,
-            public_ips=public_ips,
-            driver=self.connection.driver,
-            size=self._to_size(data['server_type']),
-            image=self._to_image(data['image']),
-            extra=extra_data
-        )
-
-    def _to_image(self, data):
-        extra_data = _extract(data, ['arch', 'compatibility_mode',
-                                     'created_at', 'description',
-                                     'disk_size', 'min_ram', 'official',
-                                     'owner', 'public', 'source',
-                                     'source_type', 'status', 'username',
-                                     'virtual_size', 'licence_name'])
-
-        if data.get('ancestor', None):
-            extra_data['ancestor'] = self._to_image(data['ancestor'])
-
-        return NodeImage(
-            id=data['id'],
-            name=data['name'],
-            driver=self,
-            extra=extra_data
-        )
-
-    def _to_size(self, data):
-        return NodeSize(
-            id=data['id'],
-            name=data['name'],
-            ram=data['ram'],
-            disk=data['disk_size'],
-            bandwidth=0,
-            price=0,
-            driver=self
-        )
-
-    def _to_location(self, data):
-        if data:
-            return NodeLocation(
-                id=data['id'],
-                name=data['handle'],
-                country='GB',
-                driver=self
-            )
-        else:
-            return None
-
-    def _post(self, path, data={}):
-        headers = {'Content-Type': 'application/json'}
-        return self.connection.request(path, data=data, headers=headers,
-                                       method='POST')
-
-    def _put(self, path, data={}):
-        headers = {'Content-Type': 'application/json'}
-        return self.connection.request(path, data=data, headers=headers,
-                                       method='PUT')
-
-    def create_node(self, **kwargs):
-        """Create a new Brightbox node
-
-        Reference: https://api.gb1.brightbox.com/1.0/#server_create_server
-
-        @inherits: :class:`NodeDriver.create_node`
-
-        :keyword    ex_userdata: User data
-        :type       ex_userdata: ``str``
-
-        :keyword    ex_servergroup: Name or list of server group ids to
-                                    add server to
-        :type       ex_servergroup: ``str`` or ``list`` of ``str``
-        """
-        data = {
-            'name': kwargs['name'],
-            'server_type': kwargs['size'].id,
-            'image': kwargs['image'].id,
-        }
-
-        if 'ex_userdata' in kwargs:
-            data['user_data'] = base64.b64encode(b(kwargs['ex_userdata'])) \
-                                      .decode('ascii')
-
-        if 'location' in kwargs:
-            data['zone'] = kwargs['location'].id
-
-        if 'ex_servergroup' in kwargs:
-            if not isinstance(kwargs['ex_servergroup'], list):
-                kwargs['ex_servergroup'] = [kwargs['ex_servergroup']]
-            data['server_groups'] = kwargs['ex_servergroup']
-
-        data = self._post('/%s/servers' % self.api_version, data).object
-        return self._to_node(data)
-
-    def destroy_node(self, node):
-        response = self.connection.request(
-            '/%s/servers/%s' % (self.api_version, node.id),
-            method='DELETE')
-        return response.status == httplib.ACCEPTED
-
-    def list_nodes(self):
-        data = self.connection.request('/%s/servers' % self.api_version).object
-        return list(map(self._to_node, data))
-
-    def list_images(self, location=None):
-        data = self.connection.request('/%s/images' % self.api_version).object
-        return list(map(self._to_image, data))
-
-    def list_sizes(self):
-        data = self.connection.request('/%s/server_types' % self.api_version) \
-                              .object
-        return list(map(self._to_size, data))
-
-    def list_locations(self):
-        data = self.connection.request('/%s/zones' % self.api_version).object
-        return list(map(self._to_location, data))
-
-    def ex_list_cloud_ips(self):
-        """
-        List Cloud IPs
-
-        @note: This is an API extension for use on Brightbox
-
-        :rtype: ``list`` of ``dict``
-        """
-        return self.connection.request('/%s/cloud_ips' % self.api_version) \
-                              .object
-
-    def ex_create_cloud_ip(self, reverse_dns=None):
-        """
-        Requests a new cloud IP address for the account
-
-        @note: This is an API extension for use on Brightbox
-
-        :param      reverse_dns: Reverse DNS hostname
-        :type       reverse_dns: ``str``
-
-        :rtype: ``dict``
-        """
-        params = {}
-
-        if reverse_dns:
-            params['reverse_dns'] = reverse_dns
-
-        return self._post('/%s/cloud_ips' % self.api_version, params).object
-
-    def ex_update_cloud_ip(self, cloud_ip_id, reverse_dns):
-        """
-        Update some details of the cloud IP address
-
-        @note: This is an API extension for use on Brightbox
-
-        :param  cloud_ip_id: The id of the cloud ip.
-        :type   cloud_ip_id: ``str``
-
-        :param      reverse_dns: Reverse DNS hostname
-        :type       reverse_dns: ``str``
-
-        :rtype: ``dict``
-        """
-        response = self._put('/%s/cloud_ips/%s' % (self.api_version,
-                                                   cloud_ip_id),
-                             {'reverse_dns': reverse_dns})
-        return response.status == httplib.OK
-
-    def ex_map_cloud_ip(self, cloud_ip_id, interface_id):
-        """
-        Maps (or points) a cloud IP address at a server's interface
-        or a load balancer to allow them to respond to public requests
-
-        @note: This is an API extension for use on Brightbox
-
-        :param  cloud_ip_id: The id of the cloud ip.
-        :type   cloud_ip_id: ``str``
-
-        :param  interface_id: The Interface ID or LoadBalancer ID to
-                              which this Cloud IP should be mapped to
-        :type   interface_id: ``str``
-
-        :return: True if the mapping was successful.
-        :rtype: ``bool``
-        """
-        response = self._post('/%s/cloud_ips/%s/map' % (self.api_version,
-                                                        cloud_ip_id),
-                              {'destination': interface_id})
-        return response.status == httplib.ACCEPTED
-
-    def ex_unmap_cloud_ip(self, cloud_ip_id):
-        """
-        Unmaps a cloud IP address from its current destination making
-        it available to remap. This remains in the account's pool
-        of addresses
-
-        @note: This is an API extension for use on Brightbox
-
-        :param  cloud_ip_id: The id of the cloud ip.
-        :type   cloud_ip_id: ``str``
-
-        :return: True if the unmap was successful.
-        :rtype: ``bool``
-        """
-        response = self._post('/%s/cloud_ips/%s/unmap' % (self.api_version,
-                                                          cloud_ip_id))
-        return response.status == httplib.ACCEPTED
-
-    def ex_destroy_cloud_ip(self, cloud_ip_id):
-        """
-        Release the cloud IP address from the account's ownership
-
-        @note: This is an API extension for use on Brightbox
-
-        :param  cloud_ip_id: The id of the cloud ip.
-        :type   cloud_ip_id: ``str``
-
-        :return: True if the unmap was successful.
-        :rtype: ``bool``
-        """
-        response = self.connection.request(
-            '/%s/cloud_ips/%s' % (self.api_version,
-                                  cloud_ip_id),
-            method='DELETE')
-        return response.status == httplib.OK

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/bsnl.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/bsnl.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/bsnl.py
deleted file mode 100644
index 6353671..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/bsnl.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from libcloud.compute.providers import Provider
-from libcloud.common.dimensiondata import (DimensionDataConnection,
-                                           API_ENDPOINTS)
-from libcloud.compute.drivers.dimensiondata import DimensionDataNodeDriver
-
-DEFAULT_REGION = 'bsnl-in'
-
-
-class BSNLNodeDriver(DimensionDataNodeDriver):
-    """
-    BSNL node driver, based on Dimension Data driver
-    """
-
-    selected_region = None
-    connectionCls = DimensionDataConnection
-    name = 'BSNL'
-    website = 'http://www.bsnlcloud.com/'
-    type = Provider.BSNL
-    features = {'create_node': ['password']}
-    api_version = 1.0
-
-    def __init__(self, key, secret=None, secure=True, host=None, port=None,
-                 api_version=None, region=DEFAULT_REGION, **kwargs):
-
-        if region not in API_ENDPOINTS:
-            raise ValueError('Invalid region: %s' % (region))
-
-        self.selected_region = API_ENDPOINTS[region]
-
-        super(BSNLNodeDriver, self).__init__(
-            key=key,
-            secret=secret,
-            secure=secure,
-            host=host,
-            port=port,
-            api_version=api_version,
-            region=region,
-            **kwargs)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/ciscoccs.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/ciscoccs.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/ciscoccs.py
deleted file mode 100644
index adc21f1..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/ciscoccs.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-Cisco CCS Driver
-"""
-
-from libcloud.compute.providers import Provider
-from libcloud.common.dimensiondata import (DimensionDataConnection,
-                                           API_ENDPOINTS)
-from libcloud.compute.drivers.dimensiondata import DimensionDataNodeDriver
-
-DEFAULT_REGION = 'cisco-na'
-
-
-class CiscoCCSNodeDriver(DimensionDataNodeDriver):
-    """
-    Cisco CCS node driver, based on Dimension Data driver
-    """
-
-    selected_region = None
-    connectionCls = DimensionDataConnection
-    name = 'CiscoCCS'
-    website = 'http://www.cisco.com/'
-    type = Provider.CISCOCCS
-    features = {'create_node': ['password']}
-    api_version = 1.0
-
-    def __init__(self, key, secret=None, secure=True, host=None, port=None,
-                 api_version=None, region=DEFAULT_REGION, **kwargs):
-
-        if region not in API_ENDPOINTS:
-            raise ValueError('Invalid region: %s' % (region))
-
-        self.selected_region = API_ENDPOINTS[region]
-
-        super(CiscoCCSNodeDriver, self).__init__(
-            key=key,
-            secret=secret,
-            secure=secure,
-            host=host,
-            port=port,
-            api_version=api_version,
-            region=region,
-            **kwargs)


[37/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/zonomi.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/zonomi.py b/apache-libcloud-1.0.0rc2/libcloud/common/zonomi.py
deleted file mode 100644
index 3ef913d..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/zonomi.py
+++ /dev/null
@@ -1,138 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from libcloud.common.base import XmlResponse
-from libcloud.common.base import ConnectionKey
-
-
-__all__ = [
-    'ZonomiException',
-    'ZonomiResponse',
-    'ZonomiConnection'
-]
-
-# Endpoint for Zonomi API.
-API_HOST = 'zonomi.com'
-
-SPECIAL_ERRORS = [
-    'Not found.',
-    'ERROR: This zone is already in your zone list.',
-    'Record not deleted.'
-]
-
-
-class ZonomiException(Exception):
-    def __init__(self, code, message):
-        self.code = code
-        self.message = message
-        self.args = (code, message)
-
-    def __str__(self):
-        return "%s %s" % (self.code, self.message)
-
-    def __repr__(self):
-        return "ZonomiException %s %s" % (self.code, self.message)
-
-
-class ZonomiResponse(XmlResponse):
-    errors = None
-    objects = None
-
-    def __init__(self, response, connection):
-        self.errors = []
-        super(ZonomiResponse, self).__init__(response=response,
-                                             connection=connection)
-        self.objects, self.errors = self.parse_body_and_errors()
-        if self.errors:
-            raise self._make_excp(self.errors[0])
-
-    def parse_body_and_errors(self):
-        error_dict = {}
-        actions = None
-        result_counts = None
-        action_childrens = None
-        data = []
-        errors = []
-        xml_body = super(ZonomiResponse, self).parse_body()
-        # Error handling
-        if xml_body.text is not None and xml_body.tag == 'error':
-            error_dict['ERRORCODE'] = self.status
-            if xml_body.text.startswith('ERROR: No zone found for'):
-                error_dict['ERRORCODE'] = '404'
-                error_dict['ERRORMESSAGE'] = 'Not found.'
-            else:
-                error_dict['ERRORMESSAGE'] = xml_body.text
-            errors.append(error_dict)
-
-        # Data handling
-        childrens = xml_body.getchildren()
-        if len(childrens) == 3:
-            result_counts = childrens[1]
-            actions = childrens[2]
-
-        if actions is not None:
-            actions_childrens = actions.getchildren()
-            action = actions_childrens[0]
-            action_childrens = action.getchildren()
-
-        if action_childrens is not None:
-            for child in action_childrens:
-                if child.tag == 'zone' or child.tag == 'record':
-                    data.append(child.attrib)
-
-        if result_counts is not None and \
-           result_counts.attrib.get('deleted') == '1':
-            data.append('DELETED')
-
-        if result_counts is not None and \
-           result_counts.attrib.get('deleted') == '0' and \
-           action.get('action') == 'DELETE':
-            error_dict['ERRORCODE'] = self.status
-            error_dict['ERRORMESSAGE'] = 'Record not deleted.'
-            errors.append(error_dict)
-
-        return (data, errors)
-
-    def success(self):
-        return (len(self.errors) == 0)
-
-    def _make_excp(self, error):
-        """
-        :param error: contains error code and error message
-        :type error: dict
-        """
-        return ZonomiException(error['ERRORCODE'], error['ERRORMESSAGE'])
-
-
-class ZonomiConnection(ConnectionKey):
-    host = API_HOST
-    responseCls = ZonomiResponse
-
-    def add_default_params(self, params):
-        """
-        Adds default parameters to perform a request,
-        such as api_key.
-        """
-        params['api_key'] = self.key
-
-        return params
-
-    def add_default_headers(self, headers):
-        """
-        Adds default headers needed to perform a successful
-        request such as Content-Type, User-Agent.
-        """
-        headers['Content-Type'] = 'text/xml;charset=UTF-8'
-
-        return headers

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/__init__.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/__init__.py b/apache-libcloud-1.0.0rc2/libcloud/compute/__init__.py
deleted file mode 100644
index 6d0970a..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-"""
-Module for working with Cloud Servers
-"""

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/base.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/base.py b/apache-libcloud-1.0.0rc2/libcloud/compute/base.py
deleted file mode 100644
index b64dd31..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/base.py
+++ /dev/null
@@ -1,1531 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-Provides base classes for working with drivers
-"""
-
-from __future__ import with_statement
-
-import sys
-import time
-import hashlib
-import os
-import socket
-import random
-import binascii
-
-from libcloud.utils.py3 import b
-
-import libcloud.compute.ssh
-from libcloud.pricing import get_size_price
-from libcloud.compute.types import NodeState, StorageVolumeState,\
-    DeploymentError
-from libcloud.compute.ssh import SSHClient
-from libcloud.common.base import ConnectionKey
-from libcloud.common.base import BaseDriver
-from libcloud.common.types import LibcloudError
-from libcloud.compute.ssh import have_paramiko
-
-from libcloud.utils.networking import is_private_subnet
-from libcloud.utils.networking import is_valid_ip_address
-
-if have_paramiko:
-    from paramiko.ssh_exception import SSHException
-    from paramiko.ssh_exception import AuthenticationException
-
-    SSH_TIMEOUT_EXCEPTION_CLASSES = (AuthenticationException, SSHException,
-                                     IOError, socket.gaierror, socket.error)
-else:
-    SSH_TIMEOUT_EXCEPTION_CLASSES = (IOError, socket.gaierror, socket.error)
-
-# How long to wait for the node to come online after creating it
-NODE_ONLINE_WAIT_TIMEOUT = 10 * 60
-
-# How long to try connecting to a remote SSH server when running a deployment
-# script.
-SSH_CONNECT_TIMEOUT = 5 * 60
-
-
-__all__ = [
-    'Node',
-    'NodeState',
-    'NodeSize',
-    'NodeImage',
-    'NodeLocation',
-    'NodeAuthSSHKey',
-    'NodeAuthPassword',
-    'NodeDriver',
-
-    'StorageVolume',
-    'StorageVolumeState',
-    'VolumeSnapshot',
-
-    # Deprecated, moved to libcloud.utils.networking
-    'is_private_subnet',
-    'is_valid_ip_address'
-]
-
-
-class UuidMixin(object):
-    """
-    Mixin class for get_uuid function.
-    """
-
-    def __init__(self):
-        self._uuid = None
-
-    def get_uuid(self):
-        """
-        Unique hash for a node, node image, or node size
-
-        The hash is a function of an SHA1 hash of the node, node image,
-        or node size's ID and its driver which means that it should be
-        unique between all objects of its type.
-        In some subclasses (e.g. GoGridNode) there is no ID
-        available so the public IP address is used.  This means that,
-        unlike a properly done system UUID, the same UUID may mean a
-        different system install at a different time
-
-        >>> from libcloud.compute.drivers.dummy import DummyNodeDriver
-        >>> driver = DummyNodeDriver(0)
-        >>> node = driver.create_node()
-        >>> node.get_uuid()
-        'd3748461511d8b9b0e0bfa0d4d3383a619a2bb9f'
-
-        Note, for example, that this example will always produce the
-        same UUID!
-
-        :rtype: ``str``
-        """
-        if not self._uuid:
-            self._uuid = hashlib.sha1(b('%s:%s' %
-                                      (self.id, self.driver.type))).hexdigest()
-
-        return self._uuid
-
-    @property
-    def uuid(self):
-        return self.get_uuid()
-
-
-class Node(UuidMixin):
-    """
-    Provide a common interface for handling nodes of all types.
-
-    The Node object provides the interface in libcloud through which
-    we can manipulate nodes in different cloud providers in the same
-    way.  Node objects don't actually do much directly themselves,
-    instead the node driver handles the connection to the node.
-
-    You don't normally create a node object yourself; instead you use
-    a driver and then have that create the node for you.
-
-    >>> from libcloud.compute.drivers.dummy import DummyNodeDriver
-    >>> driver = DummyNodeDriver(0)
-    >>> node = driver.create_node()
-    >>> node.public_ips[0]
-    '127.0.0.3'
-    >>> node.name
-    'dummy-3'
-
-    You can also get nodes from the driver's list_node function.
-
-    >>> node = driver.list_nodes()[0]
-    >>> node.name
-    'dummy-1'
-
-    The node keeps a reference to its own driver which means that we
-    can work on nodes from different providers without having to know
-    which is which.
-
-    >>> driver = DummyNodeDriver(72)
-    >>> node2 = driver.create_node()
-    >>> node.driver.creds
-    0
-    >>> node2.driver.creds
-    72
-
-    Although Node objects can be subclassed, this isn't normally
-    done.  Instead, any driver specific information is stored in the
-    "extra" attribute of the node.
-
-    >>> node.extra
-    {'foo': 'bar'}
-    """
-
-    def __init__(self, id, name, state, public_ips, private_ips,
-                 driver, size=None, image=None, extra=None, created_at=None):
-        """
-        :param id: Node ID.
-        :type id: ``str``
-
-        :param name: Node name.
-        :type name: ``str``
-
-        :param state: Node state.
-        :type state: :class:`libcloud.compute.types.NodeState`
-
-        :param public_ips: Public IP addresses associated with this node.
-        :type public_ips: ``list``
-
-        :param private_ips: Private IP addresses associated with this node.
-        :type private_ips: ``list``
-
-        :param driver: Driver this node belongs to.
-        :type driver: :class:`.NodeDriver`
-
-        :param size: Size of this node. (optional)
-        :type size: :class:`.NodeSize`
-
-        :param image: Image of this node. (optional)
-        :type size: :class:`.NodeImage`
-
-        :param created_at: The datetime this node was created (optional)
-        :type created_at: :class: `datetime.datetime`
-
-        :param extra: Optional provider specific attributes associated with
-                      this node.
-        :type extra: ``dict``
-
-        """
-        self.id = str(id) if id else None
-        self.name = name
-        self.state = state
-        self.public_ips = public_ips if public_ips else []
-        self.private_ips = private_ips if private_ips else []
-        self.driver = driver
-        self.size = size
-        self.created_at = created_at
-        self.image = image
-        self.extra = extra or {}
-        UuidMixin.__init__(self)
-
-    def reboot(self):
-        """
-        Reboot this node
-
-        :return: ``bool``
-
-        This calls the node's driver and reboots the node
-
-        >>> from libcloud.compute.drivers.dummy import DummyNodeDriver
-        >>> driver = DummyNodeDriver(0)
-        >>> node = driver.create_node()
-        >>> node.state == NodeState.RUNNING
-        True
-        >>> node.state == NodeState.REBOOTING
-        False
-        >>> node.reboot()
-        True
-        >>> node.state == NodeState.REBOOTING
-        True
-        """
-        return self.driver.reboot_node(self)
-
-    def destroy(self):
-        """
-        Destroy this node
-
-        :return: ``bool``
-
-        This calls the node's driver and destroys the node
-
-        >>> from libcloud.compute.drivers.dummy import DummyNodeDriver
-        >>> driver = DummyNodeDriver(0)
-        >>> from libcloud.compute.types import NodeState
-        >>> node = driver.create_node()
-        >>> node.state == NodeState.RUNNING
-        True
-        >>> node.destroy()
-        True
-        >>> node.state == NodeState.RUNNING
-        False
-
-        """
-        return self.driver.destroy_node(self)
-
-    def __repr__(self):
-        state = NodeState.tostring(self.state)
-
-        return (('<Node: uuid=%s, name=%s, state=%s, public_ips=%s, '
-                 'private_ips=%s, provider=%s ...>')
-                % (self.uuid, self.name, state, self.public_ips,
-                   self.private_ips, self.driver.name))
-
-
-class NodeSize(UuidMixin):
-    """
-    A Base NodeSize class to derive from.
-
-    NodeSizes are objects which are typically returned a driver's
-    list_sizes function.  They contain a number of different
-    parameters which define how big an image is.
-
-    The exact parameters available depends on the provider.
-
-    N.B. Where a parameter is "unlimited" (for example bandwidth in
-    Amazon) this will be given as 0.
-
-    >>> from libcloud.compute.drivers.dummy import DummyNodeDriver
-    >>> driver = DummyNodeDriver(0)
-    >>> size = driver.list_sizes()[0]
-    >>> size.ram
-    128
-    >>> size.bandwidth
-    500
-    >>> size.price
-    4
-    """
-
-    def __init__(self, id, name, ram, disk, bandwidth, price,
-                 driver, extra=None):
-        """
-        :param id: Size ID.
-        :type  id: ``str``
-
-        :param name: Size name.
-        :type  name: ``str``
-
-        :param ram: Amount of memory (in MB) provided by this size.
-        :type  ram: ``int``
-
-        :param disk: Amount of disk storage (in GB) provided by this image.
-        :type  disk: ``int``
-
-        :param bandwidth: Amount of bandiwdth included with this size.
-        :type  bandwidth: ``int``
-
-        :param price: Price (in US dollars) of running this node for an hour.
-        :type  price: ``float``
-
-        :param driver: Driver this size belongs to.
-        :type  driver: :class:`.NodeDriver`
-
-        :param extra: Optional provider specific attributes associated with
-                      this size.
-        :type  extra: ``dict``
-        """
-        self.id = str(id)
-        self.name = name
-        self.ram = ram
-        self.disk = disk
-        self.bandwidth = bandwidth
-        self.price = price
-        self.driver = driver
-        self.extra = extra or {}
-        UuidMixin.__init__(self)
-
-    def __repr__(self):
-        return (('<NodeSize: id=%s, name=%s, ram=%s disk=%s bandwidth=%s '
-                 'price=%s driver=%s ...>')
-                % (self.id, self.name, self.ram, self.disk, self.bandwidth,
-                   self.price, self.driver.name))
-
-
-class NodeImage(UuidMixin):
-    """
-    An operating system image.
-
-    NodeImage objects are typically returned by the driver for the
-    cloud provider in response to the list_images function
-
-    >>> from libcloud.compute.drivers.dummy import DummyNodeDriver
-    >>> driver = DummyNodeDriver(0)
-    >>> image = driver.list_images()[0]
-    >>> image.name
-    'Ubuntu 9.10'
-
-    Apart from name and id, there is no further standard information;
-    other parameters are stored in a driver specific "extra" variable
-
-    When creating a node, a node image should be given as an argument
-    to the create_node function to decide which OS image to use.
-
-    >>> node = driver.create_node(image=image)
-    """
-
-    def __init__(self, id, name, driver, extra=None):
-        """
-        :param id: Image ID.
-        :type id: ``str``
-
-        :param name: Image name.
-        :type name: ``str``
-
-        :param driver: Driver this image belongs to.
-        :type driver: :class:`.NodeDriver`
-
-        :param extra: Optional provided specific attributes associated with
-                      this image.
-        :type extra: ``dict``
-        """
-        self.id = str(id)
-        self.name = name
-        self.driver = driver
-        self.extra = extra or {}
-        UuidMixin.__init__(self)
-
-    def __repr__(self):
-        return (('<NodeImage: id=%s, name=%s, driver=%s  ...>')
-                % (self.id, self.name, self.driver.name))
-
-
-class NodeLocation(object):
-    """
-    A physical location where nodes can be.
-
-    >>> from libcloud.compute.drivers.dummy import DummyNodeDriver
-    >>> driver = DummyNodeDriver(0)
-    >>> location = driver.list_locations()[0]
-    >>> location.country
-    'US'
-    """
-
-    def __init__(self, id, name, country, driver):
-        """
-        :param id: Location ID.
-        :type id: ``str``
-
-        :param name: Location name.
-        :type name: ``str``
-
-        :param country: Location country.
-        :type country: ``str``
-
-        :param driver: Driver this location belongs to.
-        :type driver: :class:`.NodeDriver`
-        """
-        self.id = str(id)
-        self.name = name
-        self.country = country
-        self.driver = driver
-
-    def __repr__(self):
-        return (('<NodeLocation: id=%s, name=%s, country=%s, driver=%s>')
-                % (self.id, self.name, self.country, self.driver.name))
-
-
-class NodeAuthSSHKey(object):
-    """
-    An SSH key to be installed for authentication to a node.
-
-    This is the actual contents of the users ssh public key which will
-    normally be installed as root's public key on the node.
-
-    >>> pubkey = '...' # read from file
-    >>> from libcloud.compute.base import NodeAuthSSHKey
-    >>> k = NodeAuthSSHKey(pubkey)
-    >>> k
-    <NodeAuthSSHKey>
-    """
-
-    def __init__(self, pubkey):
-        """
-        :param pubkey: Public key matetiral.
-        :type pubkey: ``str``
-        """
-        self.pubkey = pubkey
-
-    def __repr__(self):
-        return '<NodeAuthSSHKey>'
-
-
-class NodeAuthPassword(object):
-    """
-    A password to be used for authentication to a node.
-    """
-    def __init__(self, password, generated=False):
-        """
-        :param password: Password.
-        :type password: ``str``
-
-        :type generated: ``True`` if this password was automatically generated,
-                         ``False`` otherwise.
-        """
-        self.password = password
-        self.generated = generated
-
-    def __repr__(self):
-        return '<NodeAuthPassword>'
-
-
-class StorageVolume(UuidMixin):
-    """
-    A base StorageVolume class to derive from.
-    """
-
-    def __init__(self, id, name, size, driver,
-                 state=None, extra=None):
-        """
-        :param id: Storage volume ID.
-        :type id: ``str``
-
-        :param name: Storage volume name.
-        :type name: ``str``
-
-        :param size: Size of this volume (in GB).
-        :type size: ``int``
-
-        :param driver: Driver this image belongs to.
-        :type driver: :class:`.NodeDriver`
-
-        :param state: Optional state of the StorageVolume. If not
-                      provided, will default to UNKNOWN.
-        :type state: :class:`.StorageVolumeState`
-
-        :param extra: Optional provider specific attributes.
-        :type extra: ``dict``
-        """
-        self.id = id
-        self.name = name
-        self.size = size
-        self.driver = driver
-        self.extra = extra
-        self.state = state
-        UuidMixin.__init__(self)
-
-    def list_snapshots(self):
-        """
-        :rtype: ``list`` of ``VolumeSnapshot``
-        """
-        return self.driver.list_volume_snapshots(volume=self)
-
-    def attach(self, node, device=None):
-        """
-        Attach this volume to a node.
-
-        :param node: Node to attach volume to
-        :type node: :class:`.Node`
-
-        :param device: Where the device is exposed,
-                            e.g. '/dev/sdb (optional)
-        :type device: ``str``
-
-        :return: ``True`` if attach was successful, ``False`` otherwise.
-        :rtype: ``bool``
-        """
-
-        return self.driver.attach_volume(node=node, volume=self, device=device)
-
-    def detach(self):
-        """
-        Detach this volume from its node
-
-        :return: ``True`` if detach was successful, ``False`` otherwise.
-        :rtype: ``bool``
-        """
-
-        return self.driver.detach_volume(volume=self)
-
-    def snapshot(self, name):
-        """
-        Creates a snapshot of this volume.
-
-        :return: Created snapshot.
-        :rtype: ``VolumeSnapshot``
-        """
-        return self.driver.create_volume_snapshot(volume=self, name=name)
-
-    def destroy(self):
-        """
-        Destroy this storage volume.
-
-        :return: ``True`` if destroy was successful, ``False`` otherwise.
-        :rtype: ``bool``
-        """
-
-        return self.driver.destroy_volume(volume=self)
-
-    def __repr__(self):
-        return '<StorageVolume id=%s size=%s driver=%s>' % (
-               self.id, self.size, self.driver.name)
-
-
-class VolumeSnapshot(object):
-    """
-    A base VolumeSnapshot class to derive from.
-    """
-    def __init__(self, id, driver, size=None, extra=None, created=None,
-                 state=None):
-        """
-        VolumeSnapshot constructor.
-
-        :param      id: Snapshot ID.
-        :type       id: ``str``
-
-        :param      driver: The driver that represents a connection to the
-                            provider
-        :type       driver: `NodeDriver`
-
-        :param      size: A snapshot size in GB.
-        :type       size: ``int``
-
-        :param      extra: Provider depends parameters for snapshot.
-        :type       extra: ``dict``
-
-        :param      created: A datetime object that represents when the
-                             snapshot was created
-        :type       created: ``datetime.datetime``
-
-        :param      state: A string representing the state the snapshot is
-                           in. See `libcloud.compute.types.StorageVolumeState`.
-        :type       state: ``str``
-        """
-        self.id = id
-        self.driver = driver
-        self.size = size
-        self.extra = extra or {}
-        self.created = created
-        self.state = state
-
-    def destroy(self):
-        """
-        Destroys this snapshot.
-
-        :rtype: ``bool``
-        """
-        return self.driver.destroy_volume_snapshot(snapshot=self)
-
-    def __repr__(self):
-        return ('<VolumeSnapshot id=%s size=%s driver=%s state=%s>' %
-                (self.id, self.size, self.driver.name, self.state))
-
-
-class KeyPair(object):
-    """
-    Represents a SSH key pair.
-    """
-
-    def __init__(self, name, public_key, fingerprint, driver, private_key=None,
-                 extra=None):
-        """
-        Constructor.
-
-        :keyword    name: Name of the key pair object.
-        :type       name: ``str``
-
-        :keyword    fingerprint: Key fingerprint.
-        :type       fingerprint: ``str``
-
-        :keyword    public_key: Public key in OpenSSH format.
-        :type       public_key: ``str``
-
-        :keyword    private_key: Private key in PEM format.
-        :type       private_key: ``str``
-
-        :keyword    extra: Provider specific attributes associated with this
-                           key pair. (optional)
-        :type       extra: ``dict``
-        """
-        self.name = name
-        self.fingerprint = fingerprint
-        self.public_key = public_key
-        self.private_key = private_key
-        self.driver = driver
-        self.extra = extra or {}
-
-    def __repr__(self):
-        return ('<KeyPair name=%s fingerprint=%s driver=%s>' %
-                (self.name, self.fingerprint, self.driver.name))
-
-
-class NodeDriver(BaseDriver):
-    """
-    A base NodeDriver class to derive from
-
-    This class is always subclassed by a specific driver.  For
-    examples of base behavior of most functions (except deploy node)
-    see the dummy driver.
-
-    """
-
-    connectionCls = ConnectionKey
-    name = None
-    type = None
-    port = None
-    features = {'create_node': []}
-
-    """
-    List of available features for a driver.
-        - :meth:`libcloud.compute.base.NodeDriver.create_node`
-            - ssh_key: Supports :class:`.NodeAuthSSHKey` as an authentication
-              method for nodes.
-            - password: Supports :class:`.NodeAuthPassword` as an
-              authentication
-              method for nodes.
-            - generates_password: Returns a password attribute on the Node
-              object returned from creation.
-    """
-
-    NODE_STATE_MAP = {}
-
-    def list_nodes(self):
-        """
-        List all nodes.
-
-        :return:  list of node objects
-        :rtype: ``list`` of :class:`.Node`
-        """
-        raise NotImplementedError(
-            'list_nodes not implemented for this driver')
-
-    def list_sizes(self, location=None):
-        """
-        List sizes on a provider
-
-        :param location: The location at which to list sizes
-        :type location: :class:`.NodeLocation`
-
-        :return: list of node size objects
-        :rtype: ``list`` of :class:`.NodeSize`
-        """
-        raise NotImplementedError(
-            'list_sizes not implemented for this driver')
-
-    def list_locations(self):
-        """
-        List data centers for a provider
-
-        :return: list of node location objects
-        :rtype: ``list`` of :class:`.NodeLocation`
-        """
-        raise NotImplementedError(
-            'list_locations not implemented for this driver')
-
-    def create_node(self, **kwargs):
-        """
-        Create a new node instance. This instance will be started
-        automatically.
-
-        Not all hosting API's are created equal and to allow libcloud to
-        support as many as possible there are some standard supported
-        variations of ``create_node``. These are declared using a
-        ``features`` API.
-        You can inspect ``driver.features['create_node']`` to see what
-        variation of the API you are dealing with:
-
-        ``ssh_key``
-            You can inject a public key into a new node allows key based SSH
-            authentication.
-        ``password``
-            You can inject a password into a new node for SSH authentication.
-            If no password is provided libcloud will generated a password.
-            The password will be available as
-            ``return_value.extra['password']``.
-        ``generates_password``
-            The hosting provider will generate a password. It will be returned
-            to you via ``return_value.extra['password']``.
-
-        Some drivers allow you to set how you will authenticate with the
-        instance that is created. You can inject this initial authentication
-        information via the ``auth`` parameter.
-
-        If a driver supports the ``ssh_key`` feature flag for ``created_node``
-        you can upload a public key into the new instance::
-
-            >>> from libcloud.compute.drivers.dummy import DummyNodeDriver
-            >>> driver = DummyNodeDriver(0)
-            >>> auth = NodeAuthSSHKey('pubkey data here')
-            >>> node = driver.create_node("test_node", auth=auth)
-
-        If a driver supports the ``password`` feature flag for ``create_node``
-        you can set a password::
-
-            >>> driver = DummyNodeDriver(0)
-            >>> auth = NodeAuthPassword('mysecretpassword')
-            >>> node = driver.create_node("test_node", auth=auth)
-
-        If a driver supports the ``password`` feature and you don't provide the
-        ``auth`` argument libcloud will assign a password::
-
-            >>> driver = DummyNodeDriver(0)
-            >>> node = driver.create_node("test_node")
-            >>> password = node.extra['password']
-
-        A password will also be returned in this way for drivers that declare
-        the ``generates_password`` feature, though in that case the password is
-        actually provided to the driver API by the hosting provider rather than
-        generated by libcloud.
-
-        You can only pass a :class:`.NodeAuthPassword` or
-        :class:`.NodeAuthSSHKey` to ``create_node`` via the auth parameter if
-        has the corresponding feature flag.
-
-        :param name:   String with a name for this new node (required)
-        :type name:   ``str``
-
-        :param size:   The size of resources allocated to this node.
-                            (required)
-        :type size:   :class:`.NodeSize`
-
-        :param image:  OS Image to boot on node. (required)
-        :type image:  :class:`.NodeImage`
-
-        :param location: Which data center to create a node in. If empty,
-                              undefined behavior will be selected. (optional)
-        :type location: :class:`.NodeLocation`
-
-        :param auth:   Initial authentication information for the node
-                            (optional)
-        :type auth:   :class:`.NodeAuthSSHKey` or :class:`NodeAuthPassword`
-
-        :return: The newly created node.
-        :rtype: :class:`.Node`
-        """
-        raise NotImplementedError(
-            'create_node not implemented for this driver')
-
-    def deploy_node(self, **kwargs):
-        """
-        Create a new node, and start deployment.
-
-        In order to be able to SSH into a created node access credentials are
-        required.
-
-        A user can pass either a :class:`.NodeAuthPassword` or
-        :class:`.NodeAuthSSHKey` to the ``auth`` argument. If the
-        ``create_node`` implementation supports that kind if credential (as
-        declared in ``self.features['create_node']``) then it is passed on to
-        ``create_node``. Otherwise it is not passed on to ``create_node`` and
-        it is only used for authentication.
-
-        If the ``auth`` parameter is not supplied but the driver declares it
-        supports ``generates_password`` then the password returned by
-        ``create_node`` will be used to SSH into the server.
-
-        Finally, if the ``ssh_key_file`` is supplied that key will be used to
-        SSH into the server.
-
-        This function may raise a :class:`DeploymentException`, if a
-        create_node call was successful, but there is a later error (like SSH
-        failing or timing out).  This exception includes a Node object which
-        you may want to destroy if incomplete deployments are not desirable.
-
-        >>> from libcloud.compute.drivers.dummy import DummyNodeDriver
-        >>> from libcloud.compute.deployment import ScriptDeployment
-        >>> from libcloud.compute.deployment import MultiStepDeployment
-        >>> from libcloud.compute.base import NodeAuthSSHKey
-        >>> driver = DummyNodeDriver(0)
-        >>> key = NodeAuthSSHKey('...') # read from file
-        >>> script = ScriptDeployment("yum -y install emacs strace tcpdump")
-        >>> msd = MultiStepDeployment([key, script])
-        >>> def d():
-        ...     try:
-        ...         driver.deploy_node(deploy=msd)
-        ...     except NotImplementedError:
-        ...         print ("not implemented for dummy driver")
-        >>> d()
-        not implemented for dummy driver
-
-        Deploy node is typically not overridden in subclasses.  The
-        existing implementation should be able to handle most such.
-
-        :param deploy: Deployment to run once machine is online and
-                            available to SSH.
-        :type deploy: :class:`Deployment`
-
-        :param ssh_username: Optional name of the account which is used
-                                  when connecting to
-                                  SSH server (default is root)
-        :type ssh_username: ``str``
-
-        :param ssh_alternate_usernames: Optional list of ssh usernames to
-                                             try to connect with if using the
-                                             default one fails
-        :type ssh_alternate_usernames: ``list``
-
-        :param ssh_port: Optional SSH server port (default is 22)
-        :type ssh_port: ``int``
-
-        :param ssh_timeout: Optional SSH connection timeout in seconds
-                                 (default is 10)
-        :type ssh_timeout: ``float``
-
-        :param auth:   Initial authentication information for the node
-                            (optional)
-        :type auth:   :class:`.NodeAuthSSHKey` or :class:`NodeAuthPassword`
-
-        :param ssh_key: A path (or paths) to an SSH private key with which
-                             to attempt to authenticate. (optional)
-        :type ssh_key: ``str`` or ``list`` of ``str``
-
-        :param timeout: How many seconds to wait before timing out.
-                             (default is 600)
-        :type timeout: ``int``
-
-        :param max_tries: How many times to retry if a deployment fails
-                               before giving up (default is 3)
-        :type max_tries: ``int``
-
-        :param ssh_interface: The interface to wait for. Default is
-                                   'public_ips', other option is 'private_ips'.
-        :type ssh_interface: ``str``
-        """
-        if not libcloud.compute.ssh.have_paramiko:
-            raise RuntimeError('paramiko is not installed. You can install ' +
-                               'it using pip: pip install paramiko')
-
-        if 'auth' in kwargs:
-            auth = kwargs['auth']
-            if not isinstance(auth, (NodeAuthSSHKey, NodeAuthPassword)):
-                raise NotImplementedError(
-                    'If providing auth, only NodeAuthSSHKey or'
-                    'NodeAuthPassword is supported')
-        elif 'ssh_key' in kwargs:
-            # If an ssh_key is provided we can try deploy_node
-            pass
-        elif 'create_node' in self.features:
-            f = self.features['create_node']
-            if 'generates_password' not in f and "password" not in f:
-                raise NotImplementedError(
-                    'deploy_node not implemented for this driver')
-        else:
-            raise NotImplementedError(
-                'deploy_node not implemented for this driver')
-
-        node = self.create_node(**kwargs)
-        max_tries = kwargs.get('max_tries', 3)
-
-        password = None
-        if 'auth' in kwargs:
-            if isinstance(kwargs['auth'], NodeAuthPassword):
-                password = kwargs['auth'].password
-        elif 'password' in node.extra:
-            password = node.extra['password']
-
-        ssh_interface = kwargs.get('ssh_interface', 'public_ips')
-
-        # Wait until node is up and running and has IP assigned
-        try:
-            node, ip_addresses = self.wait_until_running(
-                nodes=[node],
-                wait_period=3,
-                timeout=kwargs.get('timeout', NODE_ONLINE_WAIT_TIMEOUT),
-                ssh_interface=ssh_interface)[0]
-        except Exception:
-            e = sys.exc_info()[1]
-            raise DeploymentError(node=node, original_exception=e, driver=self)
-
-        ssh_username = kwargs.get('ssh_username', 'root')
-        ssh_alternate_usernames = kwargs.get('ssh_alternate_usernames', [])
-        ssh_port = kwargs.get('ssh_port', 22)
-        ssh_timeout = kwargs.get('ssh_timeout', 10)
-        ssh_key_file = kwargs.get('ssh_key', None)
-        timeout = kwargs.get('timeout', SSH_CONNECT_TIMEOUT)
-
-        deploy_error = None
-
-        for username in ([ssh_username] + ssh_alternate_usernames):
-            try:
-                self._connect_and_run_deployment_script(
-                    task=kwargs['deploy'], node=node,
-                    ssh_hostname=ip_addresses[0], ssh_port=ssh_port,
-                    ssh_username=username, ssh_password=password,
-                    ssh_key_file=ssh_key_file, ssh_timeout=ssh_timeout,
-                    timeout=timeout, max_tries=max_tries)
-            except Exception:
-                # Try alternate username
-                # Todo: Need to fix paramiko so we can catch a more specific
-                # exception
-                e = sys.exc_info()[1]
-                deploy_error = e
-            else:
-                # Script successfully executed, don't try alternate username
-                deploy_error = None
-                break
-
-        if deploy_error is not None:
-            raise DeploymentError(node=node, original_exception=deploy_error,
-                                  driver=self)
-
-        return node
-
-    def reboot_node(self, node):
-        """
-        Reboot a node.
-
-        :param node: The node to be rebooted
-        :type node: :class:`.Node`
-
-        :return: True if the reboot was successful, otherwise False
-        :rtype: ``bool``
-        """
-        raise NotImplementedError(
-            'reboot_node not implemented for this driver')
-
-    def destroy_node(self, node):
-        """
-        Destroy a node.
-
-        Depending upon the provider, this may destroy all data associated with
-        the node, including backups.
-
-        :param node: The node to be destroyed
-        :type node: :class:`.Node`
-
-        :return: True if the destroy was successful, False otherwise.
-        :rtype: ``bool``
-        """
-        raise NotImplementedError(
-            'destroy_node not implemented for this driver')
-
-    ##
-    # Volume and snapshot management methods
-    ##
-
-    def list_volumes(self):
-        """
-        List storage volumes.
-
-        :rtype: ``list`` of :class:`.StorageVolume`
-        """
-        raise NotImplementedError(
-            'list_volumes not implemented for this driver')
-
-    def list_volume_snapshots(self, volume):
-        """
-        List snapshots for a storage volume.
-
-        :rtype: ``list`` of :class:`VolumeSnapshot`
-        """
-        raise NotImplementedError(
-            'list_volume_snapshots not implemented for this driver')
-
-    def create_volume(self, size, name, location=None, snapshot=None):
-        """
-        Create a new volume.
-
-        :param size: Size of volume in gigabytes (required)
-        :type size: ``int``
-
-        :param name: Name of the volume to be created
-        :type name: ``str``
-
-        :param location: Which data center to create a volume in. If
-                               empty, undefined behavior will be selected.
-                               (optional)
-        :type location: :class:`.NodeLocation`
-
-        :param snapshot:  Snapshot from which to create the new
-                          volume.  (optional)
-        :type snapshot: :class:`.VolumeSnapshot`
-
-        :return: The newly created volume.
-        :rtype: :class:`StorageVolume`
-        """
-        raise NotImplementedError(
-            'create_volume not implemented for this driver')
-
-    def create_volume_snapshot(self, volume, name=None):
-        """
-        Creates a snapshot of the storage volume.
-
-        :param volume: The StorageVolume to create a VolumeSnapshot from
-        :type volume: :class:`.VolumeSnapshot`
-
-        :param name: Name of created snapshot (optional)
-        :type name: `str`
-
-        :rtype: :class:`VolumeSnapshot`
-        """
-        raise NotImplementedError(
-            'create_volume_snapshot not implemented for this driver')
-
-    def attach_volume(self, node, volume, device=None):
-        """
-        Attaches volume to node.
-
-        :param node: Node to attach volume to.
-        :type node: :class:`.Node`
-
-        :param volume: Volume to attach.
-        :type volume: :class:`.StorageVolume`
-
-        :param device: Where the device is exposed, e.g. '/dev/sdb'
-        :type device: ``str``
-
-        :rytpe: ``bool``
-        """
-        raise NotImplementedError('attach not implemented for this driver')
-
-    def detach_volume(self, volume):
-        """
-        Detaches a volume from a node.
-
-        :param volume: Volume to be detached
-        :type volume: :class:`.StorageVolume`
-
-        :rtype: ``bool``
-        """
-
-        raise NotImplementedError('detach not implemented for this driver')
-
-    def destroy_volume(self, volume):
-        """
-        Destroys a storage volume.
-
-        :param volume: Volume to be destroyed
-        :type volume: :class:`StorageVolume`
-
-        :rtype: ``bool``
-        """
-
-        raise NotImplementedError(
-            'destroy_volume not implemented for this driver')
-
-    def destroy_volume_snapshot(self, snapshot):
-        """
-        Destroys a snapshot.
-
-        :param snapshot: The snapshot to delete
-        :type snapshot: :class:`VolumeSnapshot`
-
-        :rtype: :class:`bool`
-        """
-        raise NotImplementedError(
-            'destroy_volume_snapshot not implemented for this driver')
-
-    ##
-    # Image management methods
-    ##
-
-    def list_images(self, location=None):
-        """
-        List images on a provider.
-
-        :param location: The location at which to list images.
-        :type location: :class:`.NodeLocation`
-
-        :return: list of node image objects.
-        :rtype: ``list`` of :class:`.NodeImage`
-        """
-        raise NotImplementedError(
-            'list_images not implemented for this driver')
-
-    def create_image(self, node, name, description=None):
-        """
-        Creates an image from a node object.
-
-        :param node: Node to run the task on.
-        :type node: :class:`.Node`
-
-        :param name: name for new image.
-        :type name: ``str``
-
-        :param description: description for new image.
-        :type name: ``description``
-
-        :rtype: :class:`.NodeImage`:
-        :return: NodeImage instance on success.
-
-        """
-        raise NotImplementedError(
-            'create_image not implemented for this driver')
-
-    def delete_image(self, node_image):
-        """
-        Deletes a node image from a provider.
-
-        :param node_image: Node image object.
-        :type node_image: :class:`.NodeImage`
-
-        :return: ``True`` if delete_image was successful, ``False`` otherwise.
-        :rtype: ``bool``
-        """
-
-        raise NotImplementedError(
-            'delete_image not implemented for this driver')
-
-    def get_image(self, image_id):
-        """
-        Returns a single node image from a provider.
-
-        :param image_id: Node to run the task on.
-        :type image_id: ``str``
-
-        :rtype :class:`.NodeImage`:
-        :return: NodeImage instance on success.
-        """
-        raise NotImplementedError(
-            'get_image not implemented for this driver')
-
-    def copy_image(self, source_region, node_image, name, description=None):
-        """
-        Copies an image from a source region to the current region.
-
-        :param source_region: Region to copy the node from.
-        :type source_region: ``str``
-
-        :param node_image: NodeImage to copy.
-        :type node_image: :class:`.NodeImage`:
-
-        :param name: name for new image.
-        :type name: ``str``
-
-        :param description: description for new image.
-        :type name: ``str``
-
-        :rtype: :class:`.NodeImage`:
-        :return: NodeImage instance on success.
-        """
-        raise NotImplementedError(
-            'copy_image not implemented for this driver')
-
-    ##
-    # SSH key pair management methods
-    ##
-
-    def list_key_pairs(self):
-        """
-        List all the available key pair objects.
-
-        :rtype: ``list`` of :class:`.KeyPair` objects
-        """
-        raise NotImplementedError(
-            'list_key_pairs not implemented for this driver')
-
-    def get_key_pair(self, name):
-        """
-        Retrieve a single key pair.
-
-        :param name: Name of the key pair to retrieve.
-        :type name: ``str``
-
-        :rtype: :class:`.KeyPair`
-        """
-        raise NotImplementedError(
-            'get_key_pair not implemented for this driver')
-
-    def create_key_pair(self, name):
-        """
-        Create a new key pair object.
-
-        :param name: Key pair name.
-        :type name: ``str``
-        """
-        raise NotImplementedError(
-            'create_key_pair not implemented for this driver')
-
-    def import_key_pair_from_string(self, name, key_material):
-        """
-        Import a new public key from string.
-
-        :param name: Key pair name.
-        :type name: ``str``
-
-        :param key_material: Public key material.
-        :type key_material: ``str``
-
-        :rtype: :class:`.KeyPair` object
-        """
-        raise NotImplementedError(
-            'import_key_pair_from_string not implemented for this driver')
-
-    def import_key_pair_from_file(self, name, key_file_path):
-        """
-        Import a new public key from string.
-
-        :param name: Key pair name.
-        :type name: ``str``
-
-        :param key_file_path: Path to the public key file.
-        :type key_file_path: ``str``
-
-        :rtype: :class:`.KeyPair` object
-        """
-        key_file_path = os.path.expanduser(key_file_path)
-
-        with open(key_file_path, 'r') as fp:
-            key_material = fp.read()
-
-        return self.import_key_pair_from_string(name=name,
-                                                key_material=key_material)
-
-    def delete_key_pair(self, key_pair):
-        """
-        Delete an existing key pair.
-
-        :param key_pair: Key pair object.
-        :type key_pair: :class:`.KeyPair`
-        """
-        raise NotImplementedError(
-            'delete_key_pair not implemented for this driver')
-
-    def wait_until_running(self, nodes, wait_period=3,
-                           timeout=600, ssh_interface='public_ips',
-                           force_ipv4=True, ex_list_nodes_kwargs=None):
-        """
-        Block until the provided nodes are considered running.
-
-        Node is considered running when it's state is "running" and when it has
-        at least one IP address assigned.
-
-        :param nodes: List of nodes to wait for.
-        :type nodes: ``list`` of :class:`.Node`
-
-        :param wait_period: How many seconds to wait between each loop
-                            iteration. (default is 3)
-        :type wait_period: ``int``
-
-        :param timeout: How many seconds to wait before giving up.
-                        (default is 600)
-        :type timeout: ``int``
-
-        :param ssh_interface: Which attribute on the node to use to obtain
-                              an IP address. Valid options: public_ips,
-                              private_ips. Default is public_ips.
-        :type ssh_interface: ``str``
-
-        :param force_ipv4: Ignore IPv6 addresses (default is True).
-        :type force_ipv4: ``bool``
-
-        :param ex_list_nodes_kwargs: Optional driver-specific keyword arguments
-                                     which are passed to the ``list_nodes``
-                                     method.
-        :type ex_list_nodes_kwargs: ``dict``
-
-        :return: ``[(Node, ip_addresses)]`` list of tuple of Node instance and
-                 list of ip_address on success.
-        :rtype: ``list`` of ``tuple``
-        """
-        ex_list_nodes_kwargs = ex_list_nodes_kwargs or {}
-
-        def is_supported(address):
-            """
-            Return True for supported address.
-            """
-            if force_ipv4 and not is_valid_ip_address(address=address,
-                                                      family=socket.AF_INET):
-                return False
-            return True
-
-        def filter_addresses(addresses):
-            """
-            Return list of supported addresses.
-            """
-            return [address for address in addresses if is_supported(address)]
-
-        if ssh_interface not in ['public_ips', 'private_ips']:
-            raise ValueError('ssh_interface argument must either be' +
-                             'public_ips or private_ips')
-
-        start = time.time()
-        end = start + timeout
-
-        uuids = set([node.uuid for node in nodes])
-
-        while time.time() < end:
-            all_nodes = self.list_nodes(**ex_list_nodes_kwargs)
-            matching_nodes = list([node for node in all_nodes
-                                   if node.uuid in uuids])
-
-            if len(matching_nodes) > len(uuids):
-                found_uuids = [node.uuid for node in matching_nodes]
-                msg = ('Unable to match specified uuids ' +
-                       '(%s) with existing nodes. Found ' % (uuids) +
-                       'multiple nodes with same uuid: (%s)' % (found_uuids))
-                raise LibcloudError(value=msg, driver=self)
-
-            running_nodes = [node for node in matching_nodes
-                             if node.state == NodeState.RUNNING]
-            addresses = [filter_addresses(getattr(node, ssh_interface))
-                         for node in running_nodes]
-
-            if len(running_nodes) == len(uuids) == len(addresses):
-                return list(zip(running_nodes, addresses))
-            else:
-                time.sleep(wait_period)
-                continue
-
-        raise LibcloudError(value='Timed out after %s seconds' % (timeout),
-                            driver=self)
-
-    def _get_and_check_auth(self, auth):
-        """
-        Helper function for providers supporting :class:`.NodeAuthPassword` or
-        :class:`.NodeAuthSSHKey`
-
-        Validates that only a supported object type is passed to the auth
-        parameter and raises an exception if it is not.
-
-        If no :class:`.NodeAuthPassword` object is provided but one is expected
-        then a password is automatically generated.
-        """
-
-        if isinstance(auth, NodeAuthPassword):
-            if 'password' in self.features['create_node']:
-                return auth
-            raise LibcloudError(
-                'Password provided as authentication information, but password'
-                'not supported', driver=self)
-
-        if isinstance(auth, NodeAuthSSHKey):
-            if 'ssh_key' in self.features['create_node']:
-                return auth
-            raise LibcloudError(
-                'SSH Key provided as authentication information, but SSH Key'
-                'not supported', driver=self)
-
-        if 'password' in self.features['create_node']:
-            value = os.urandom(16)
-            value = binascii.hexlify(value).decode('ascii')
-
-            # Some providers require password to also include uppercase
-            # characters so convert some characters to uppercase
-            password = ''
-            for char in value:
-                if not char.isdigit() and char.islower():
-                    if random.randint(0, 1) == 1:
-                        char = char.upper()
-
-                password += char
-
-            return NodeAuthPassword(password, generated=True)
-
-        if auth:
-            raise LibcloudError(
-                '"auth" argument provided, but it was not a NodeAuthPassword'
-                'or NodeAuthSSHKey object', driver=self)
-
-    def _wait_until_running(self, node, wait_period=3, timeout=600,
-                            ssh_interface='public_ips', force_ipv4=True):
-        # This is here for backward compatibility and will be removed in the
-        # next major release
-        return self.wait_until_running(nodes=[node], wait_period=wait_period,
-                                       timeout=timeout,
-                                       ssh_interface=ssh_interface,
-                                       force_ipv4=force_ipv4)
-
-    def _ssh_client_connect(self, ssh_client, wait_period=1.5, timeout=300):
-        """
-        Try to connect to the remote SSH server. If a connection times out or
-        is refused it is retried up to timeout number of seconds.
-
-        :param ssh_client: A configured SSHClient instance
-        :type ssh_client: ``SSHClient``
-
-        :param wait_period: How many seconds to wait between each loop
-                            iteration. (default is 1.5)
-        :type wait_period: ``int``
-
-        :param timeout: How many seconds to wait before giving up.
-                        (default is 300)
-        :type timeout: ``int``
-
-        :return: ``SSHClient`` on success
-        """
-        start = time.time()
-        end = start + timeout
-
-        while time.time() < end:
-            try:
-                ssh_client.connect()
-            except SSH_TIMEOUT_EXCEPTION_CLASSES:
-                e = sys.exc_info()[1]
-                message = str(e).lower()
-                expected_msg = 'no such file or directory'
-
-                if isinstance(e, IOError) and expected_msg in message:
-                    # Propagate (key) file doesn't exist errors
-                    raise e
-
-                # Retry if a connection is refused, timeout occurred,
-                # or the connection fails due to failed authentication.
-                ssh_client.close()
-                time.sleep(wait_period)
-                continue
-            else:
-                return ssh_client
-
-        raise LibcloudError(value='Could not connect to the remote SSH ' +
-                            'server. Giving up.', driver=self)
-
-    def _connect_and_run_deployment_script(self, task, node, ssh_hostname,
-                                           ssh_port, ssh_username,
-                                           ssh_password, ssh_key_file,
-                                           ssh_timeout, timeout, max_tries):
-        """
-        Establish an SSH connection to the node and run the provided deployment
-        task.
-
-        :rtype: :class:`.Node`:
-        :return: Node instance on success.
-        """
-        ssh_client = SSHClient(hostname=ssh_hostname,
-                               port=ssh_port, username=ssh_username,
-                               password=ssh_password,
-                               key_files=ssh_key_file,
-                               timeout=ssh_timeout)
-
-        ssh_client = self._ssh_client_connect(ssh_client=ssh_client,
-                                              timeout=timeout)
-
-        # Execute the deployment task
-        node = self._run_deployment_script(task=task, node=node,
-                                           ssh_client=ssh_client,
-                                           max_tries=max_tries)
-        return node
-
-    def _run_deployment_script(self, task, node, ssh_client, max_tries=3):
-        """
-        Run the deployment script on the provided node. At this point it is
-        assumed that SSH connection has already been established.
-
-        :param task: Deployment task to run.
-        :type task: :class:`Deployment`
-
-        :param node: Node to run the task on.
-        :type node: ``Node``
-
-        :param ssh_client: A configured and connected SSHClient instance.
-        :type ssh_client: :class:`SSHClient`
-
-        :param max_tries: How many times to retry if a deployment fails
-                          before giving up. (default is 3)
-        :type max_tries: ``int``
-
-        :rtype: :class:`.Node`
-        :return: ``Node`` Node instance on success.
-        """
-        tries = 0
-
-        while tries < max_tries:
-            try:
-                node = task.run(node, ssh_client)
-            except Exception:
-                tries += 1
-
-                if tries >= max_tries:
-                    e = sys.exc_info()[1]
-                    raise LibcloudError(value='Failed after %d tries: %s'
-                                        % (max_tries, str(e)), driver=self)
-            else:
-                # Deployment succeeded
-                ssh_client.close()
-                return node
-
-    def _get_size_price(self, size_id):
-        """
-        Return pricing information for the provided size id.
-        """
-        return get_size_price(driver_type='compute',
-                              driver_name=self.api_name,
-                              size_id=size_id)
-
-
-if __name__ == '__main__':
-    import doctest
-    doctest.testmod()

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/deployment.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/deployment.py b/apache-libcloud-1.0.0rc2/libcloud/compute/deployment.py
deleted file mode 100644
index d5f7eec..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/deployment.py
+++ /dev/null
@@ -1,263 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-Provides generic deployment steps for machines post boot.
-"""
-
-from __future__ import with_statement
-
-import os
-import binascii
-
-from libcloud.utils.py3 import basestring, PY3
-
-
-class Deployment(object):
-    """
-    Base class for deployment tasks.
-    """
-
-    def run(self, node, client):
-        """
-        Runs this deployment task on node using the client provided.
-
-        :type node: :class:`Node`
-        :keyword node: Node to operate one
-
-        :type client: :class:`BaseSSHClient`
-        :keyword client: Connected SSH client to use.
-
-        :return: :class:`Node`
-        """
-        raise NotImplementedError(
-            'run not implemented for this deployment')
-
-    def _get_string_value(self, argument_name, argument_value):
-        if not isinstance(argument_value, basestring) and \
-           not hasattr(argument_value, 'read'):
-            raise TypeError('%s argument must be a string or a file-like '
-                            'object' % (argument_name))
-
-        if hasattr(argument_value, 'read'):
-            argument_value = argument_value.read()
-
-        return argument_value
-
-
-class SSHKeyDeployment(Deployment):
-    """
-    Installs a public SSH Key onto a server.
-    """
-
-    def __init__(self, key):
-        """
-        :type key: ``str`` or :class:`File` object
-        :keyword key: Contents of the public key write or a file object which
-                      can be read.
-        """
-        self.key = self._get_string_value(argument_name='key',
-                                          argument_value=key)
-
-    def run(self, node, client):
-        """
-        Installs SSH key into ``.ssh/authorized_keys``
-
-        See also :class:`Deployment.run`
-        """
-        client.put(".ssh/authorized_keys", contents=self.key, mode='a')
-        return node
-
-
-class FileDeployment(Deployment):
-    """
-    Installs a file on the server.
-    """
-
-    def __init__(self, source, target):
-        """
-        :type source: ``str``
-        :keyword source: Local path of file to be installed
-
-        :type target: ``str``
-        :keyword target: Path to install file on node
-        """
-        self.source = source
-        self.target = target
-
-    def run(self, node, client):
-        """
-        Upload the file, retaining permissions.
-
-        See also :class:`Deployment.run`
-        """
-        perms = int(oct(os.stat(self.source).st_mode)[4:], 8)
-
-        with open(self.source, 'rb') as fp:
-            content = fp.read()
-
-        client.put(path=self.target, chmod=perms,
-                   contents=content)
-        return node
-
-
-class ScriptDeployment(Deployment):
-    """
-    Runs an arbitrary shell script on the server.
-
-    This step works by first writing the content of the shell script (script
-    argument) in a \*.sh file on a remote server and then running that file.
-
-    If you are running a non-shell script, make sure to put the appropriate
-    shebang to the top of the script. You are also advised to do that even if
-    you are running a plan shell script.
-    """
-
-    def __init__(self, script, args=None, name=None, delete=False):
-        """
-        :type script: ``str``
-        :keyword script: Contents of the script to run.
-
-        :type args: ``list``
-        :keyword args: Optional command line arguments which get passed to the
-                       deployment script file.
-
-        :type name: ``str``
-        :keyword name: Name of the script to upload it as, if not specified,
-                       a random name will be chosen.
-
-        :type delete: ``bool``
-        :keyword delete: Whether to delete the script on completion.
-        """
-        script = self._get_string_value(argument_name='script',
-                                        argument_value=script)
-
-        self.script = script
-        self.args = args or []
-        self.stdout = None
-        self.stderr = None
-        self.exit_status = None
-        self.delete = delete
-        self.name = name
-
-        if self.name is None:
-            # File is put under user's home directory
-            # (~/libcloud_deployment_<random_string>.sh)
-            random_string = binascii.hexlify(os.urandom(4))
-            random_string = random_string.decode('ascii')
-            self.name = 'libcloud_deployment_%s.sh' % (random_string)
-
-    def run(self, node, client):
-        """
-        Uploads the shell script and then executes it.
-
-        See also :class:`Deployment.run`
-        """
-        file_path = client.put(path=self.name, chmod=int('755', 8),
-                               contents=self.script)
-
-        # Pre-pend cwd if user specified a relative path
-        if self.name[0] != '/':
-            base_path = os.path.dirname(file_path)
-            name = os.path.join(base_path, self.name)
-        else:
-            name = self.name
-
-        cmd = name
-
-        if self.args:
-            # Append arguments to the command
-            cmd = '%s %s' % (name, ' '.join(self.args))
-        else:
-            cmd = name
-
-        self.stdout, self.stderr, self.exit_status = client.run(cmd)
-
-        if self.delete:
-            client.delete(self.name)
-
-        return node
-
-
-class ScriptFileDeployment(ScriptDeployment):
-    """
-    Runs an arbitrary shell script from a local file on the server. Same as
-    ScriptDeployment, except that you can pass in a path to the file instead of
-    the script content.
-    """
-
-    def __init__(self, script_file, args=None, name=None, delete=False):
-        """
-        :type script_file: ``str``
-        :keyword script_file: Path to a file containing the script to run.
-
-        :type args: ``list``
-        :keyword args: Optional command line arguments which get passed to the
-                       deployment script file.
-
-
-        :type name: ``str``
-        :keyword name: Name of the script to upload it as, if not specified,
-                       a random name will be chosen.
-
-        :type delete: ``bool``
-        :keyword delete: Whether to delete the script on completion.
-        """
-        with open(script_file, 'rb') as fp:
-            content = fp.read()
-
-        if PY3:
-            content = content.decode('utf-8')
-
-        super(ScriptFileDeployment, self).__init__(script=content,
-                                                   args=args,
-                                                   name=name,
-                                                   delete=delete)
-
-
-class MultiStepDeployment(Deployment):
-    """
-    Runs a chain of Deployment steps.
-    """
-    def __init__(self, add=None):
-        """
-        :type add: ``list``
-        :keyword add: Deployment steps to add.
-        """
-        self.steps = []
-        self.add(add)
-
-    def add(self, add):
-        """
-        Add a deployment to this chain.
-
-        :type add: Single :class:`Deployment` or a ``list`` of
-                   :class:`Deployment`
-        :keyword add: Adds this deployment to the others already in this
-                      object.
-        """
-        if add is not None:
-            add = add if isinstance(add, (list, tuple)) else [add]
-            self.steps.extend(add)
-
-    def run(self, node, client):
-        """
-        Run each deployment that has been added.
-
-        See also :class:`Deployment.run`
-        """
-        for s in self.steps:
-            node = s.run(node, client)
-        return node

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/deprecated.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/deprecated.py b/apache-libcloud-1.0.0rc2/libcloud/compute/deprecated.py
deleted file mode 100644
index d68e47f..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/deprecated.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-Database of deprecated drivers
-"""
-
-from libcloud.compute.types import Provider
-
-DEPRECATED_DRIVERS = {
-    Provider.OPSOURCE: {
-        'reason': 'OpSource cloud is now part of Dimension Data, '
-                  'use the DIMENSIONDATA provider instead.',
-        'url': 'http://www.ntt.co.jp/news2011/1107e/110701a.html'
-    },
-    Provider.NINEFOLD: {
-        'reason': 'We will shortly notify our customers that we '
-                  'will be sunsetting our Public Cloud Computing '
-                  '(Server) platform, the last day of operation '
-                  'being January 30, 2016',
-        'url': 'https://ninefold.com/news/'
-    },
-    Provider.IBM: {
-        'reason': 'IBM SmartCloud Enterprise has been deprecated '
-                  'in favour of IBM SoftLayer Public Cloud, please'
-                  ' use the SOFTLAYER provider.',
-        'url': 'http://www.ibm.com/midmarket/us/en/article_cloud6_1310.html'
-    },
-    Provider.HPCLOUD: {
-        'reason': 'HP Helion Public Cloud was shut down in January 2016.',
-        'url': 'http://libcloud.apache.org/blog/'
-               '2016/02/16/new-drivers-deprecated-drivers.html'
-    },
-    Provider.CLOUDFRAMES: {
-        'reason': 'The CloudFrames Provider is no longer supported',
-        'url': 'http://libcloud.apache.org/blog/2016/02/16/new-drivers-'
-               'deprecated-drivers.html'
-    }
-}

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/__init__.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/__init__.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/__init__.py
deleted file mode 100644
index d7c26ed..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/__init__.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-Drivers for working with different providers
-"""
-
-__all__ = [
-    'abiquo',
-    'brightbox',
-    'bluebox',
-    'dimensiondata',
-    'dummy',
-    'ec2',
-    'ecp',
-    'elasticstack',
-    'elastichosts',
-    'cloudsigma',
-    'gce',
-    'gogrid',
-    'hostvirtual',
-    'ibm_sce',
-    'linode',
-    'opennebula',
-    'rackspace',
-    'rimuhosting',
-    'softlayer',
-    'vcloud',
-    'voxel',
-    'vpsnet',
-    'onapp',
-]


[20/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/packet.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/packet.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/packet.py
deleted file mode 100644
index 2560145..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/packet.py
+++ /dev/null
@@ -1,258 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-Packet Driver
-"""
-
-from libcloud.utils.py3 import httplib
-
-from libcloud.common.base import ConnectionKey, JsonResponse
-from libcloud.compute.types import Provider, NodeState, InvalidCredsError
-from libcloud.compute.base import NodeDriver, Node
-from libcloud.compute.base import NodeImage, NodeSize, NodeLocation
-from libcloud.compute.base import KeyPair
-
-PACKET_ENDPOINT = "api.packet.net"
-
-
-class PacketResponse(JsonResponse):
-    valid_response_codes = [httplib.OK, httplib.ACCEPTED, httplib.CREATED,
-                            httplib.NO_CONTENT]
-
-    def parse_error(self):
-        if self.status == httplib.UNAUTHORIZED:
-            body = self.parse_body()
-            raise InvalidCredsError(body['message'])
-        else:
-            body = self.parse_body()
-            if 'message' in body:
-                error = '%s (code: %s)' % (body['message'], self.status)
-            else:
-                error = body
-            return error
-
-    def success(self):
-        return self.status in self.valid_response_codes
-
-
-class PacketConnection(ConnectionKey):
-    """
-    Connection class for the Packet driver.
-    """
-
-    host = PACKET_ENDPOINT
-    responseCls = PacketResponse
-
-    def add_default_headers(self, headers):
-        """
-        Add headers that are necessary for every request
-        """
-        headers['Content-Type'] = 'application/json'
-        headers['X-Auth-Token'] = self.key
-        headers['X-Consumer-Token'] = \
-            'kcrhMn7hwG8Ceo2hAhGFa2qpxLBvVHxEjS9ue8iqmsNkeeB2iQgMq4dNc1893pYu'
-        return headers
-
-
-class PacketNodeDriver(NodeDriver):
-    """
-    Packet NodeDriver
-    """
-
-    connectionCls = PacketConnection
-    type = Provider.PACKET
-    name = 'Packet'
-    website = 'http://www.packet.net/'
-
-    NODE_STATE_MAP = {'queued': NodeState.PENDING,
-                      'provisioning': NodeState.PENDING,
-                      'rebuilding': NodeState.PENDING,
-                      'powering_on': NodeState.REBOOTING,
-                      'powering_off': NodeState.REBOOTING,
-                      'rebooting': NodeState.REBOOTING,
-                      'inactive': NodeState.STOPPED,
-                      'deleted': NodeState.TERMINATED,
-                      'deprovisioning': NodeState.TERMINATED,
-                      'failed': NodeState.ERROR,
-                      'active': NodeState.RUNNING}
-
-    def list_nodes(self, ex_project_id):
-        data = self.connection.request('/projects/%s/devices' %
-                                       (ex_project_id),
-                                       params={'include': 'plan'}
-                                       ).object['devices']
-        return list(map(self._to_node, data))
-
-    def list_locations(self):
-        data = self.connection.request('/facilities')\
-            .object['facilities']
-        return list(map(self._to_location, data))
-
-    def list_images(self):
-        data = self.connection.request('/operating-systems')\
-            .object['operating_systems']
-        return list(map(self._to_image, data))
-
-    def list_sizes(self):
-        data = self.connection.request('/plans').object['plans']
-        return list(map(self._to_size, data))
-
-    def create_node(self, name, size, image, location, ex_project_id):
-        """
-        Create a node.
-
-        :return: The newly created node.
-        :rtype: :class:`Node`
-        """
-
-        params = {'hostname': name, 'plan': size.id,
-                  'operating_system': image.id, 'facility': location.id,
-                  'include': 'plan', 'billing_cycle': 'hourly'}
-
-        data = self.connection.request('/projects/%s/devices' %
-                                       (ex_project_id),
-                                       params=params, method='POST')
-
-        status = data.object.get('status', 'OK')
-        if status == 'ERROR':
-            message = data.object.get('message', None)
-            error_message = data.object.get('error_message', message)
-            raise ValueError('Failed to create node: %s' % (error_message))
-        return self._to_node(data=data.object)
-
-    def reboot_node(self, node):
-        params = {'type': 'reboot'}
-        res = self.connection.request('/devices/%s/actions' % (node.id),
-                                      params=params, method='POST')
-        return res.status == httplib.OK
-
-    def destroy_node(self, node):
-        res = self.connection.request('/devices/%s' % (node.id),
-                                      method='DELETE')
-        return res.status == httplib.OK
-
-    def list_key_pairs(self):
-        """
-        List all the available SSH keys.
-
-        :return: Available SSH keys.
-        :rtype: ``list`` of :class:`.KeyPair` objects
-        """
-        data = self.connection.request('/ssh-keys').object['ssh_keys']
-        return list(map(self._to_key_pairs, data))
-
-    def create_key_pair(self, name, public_key):
-        """
-        Create a new SSH key.
-
-        :param      name: Key name (required)
-        :type       name: ``str``
-
-        :param      public_key: Valid public key string (required)
-        :type       public_key: ``str``
-        """
-        params = {'label': name, 'key': public_key}
-        data = self.connection.request('/ssh-keys', method='POST',
-                                       params=params).object
-        return self._to_key_pairs(data)
-
-    def delete_key_pair(self, key):
-        """
-        Delete an existing SSH key.
-
-        :param      key: SSH key (required)
-        :type       key: :class:`KeyPair`
-        """
-        key_id = key.name
-        res = self.connection.request('/ssh-keys/%s' % (key_id),
-                                      method='DELETE')
-        return res.status == httplib.NO_CONTENT
-
-    def _to_node(self, data):
-        extra_keys = ['created_at', 'updated_at',
-                      'userdata', 'billing_cycle', 'locked']
-        if 'state' in data:
-            state = self.NODE_STATE_MAP.get(data['state'], NodeState.UNKNOWN)
-        else:
-            state = NodeState.UNKNOWN
-
-        if 'ip_addresses' in data and data['ip_addresses'] is not None:
-            ips = self._parse_ips(data['ip_addresses'])
-
-        if 'operating_system' in data and data['operating_system'] is not None:
-            image = self._to_image(data['operating_system'])
-
-        if 'plan' in data and data['plan'] is not None:
-            size = self._to_size(data['plan'])
-
-        extra = {}
-        for key in extra_keys:
-            if key in data:
-                extra[key] = data[key]
-
-        node = Node(id=data['id'], name=data['hostname'], state=state,
-                    image=image, size=size,
-                    public_ips=ips['public'], private_ips=ips['private'],
-                    extra=extra, driver=self)
-        return node
-
-    def _to_image(self, data):
-        extra = {'distro': data['distro'], 'version': data['version']}
-        return NodeImage(id=data['slug'], name=data['name'], extra=extra,
-                         driver=self)
-
-    def _to_location(self, data):
-        return NodeLocation(id=data['code'], name=data['name'], country=None,
-                            driver=self)
-
-    def _to_size(self, data):
-        extra = {'description': data['description'], 'line': data['line']}
-
-        ram = data['specs']['memory']['total'].lower()
-        if 'mb' in ram:
-            ram = int(ram.replace('mb', ''))
-        elif 'gb' in ram:
-            ram = int(ram.replace('gb', '')) * 1024
-
-        disk = 0
-        for disks in data['specs']['drives']:
-            disk += disks['count'] * int(disks['size'].replace('GB', ''))
-
-        price = data['pricing']['hourly']
-
-        return NodeSize(id=data['slug'], name=data['name'], ram=ram, disk=disk,
-                        bandwidth=0, price=price, extra=extra, driver=self)
-
-    def _to_key_pairs(self, data):
-        extra = {'label': data['label'],
-                 'created_at': data['created_at'],
-                 'updated_at': data['updated_at']}
-        return KeyPair(name=data['id'],
-                       fingerprint=data['fingerprint'],
-                       public_key=data['key'],
-                       private_key=None,
-                       driver=self,
-                       extra=extra)
-
-    def _parse_ips(self, data):
-        public_ips = []
-        private_ips = []
-        for address in data:
-            if 'address' in address and address['address'] is not None:
-                if 'public' in address and address['public'] is True:
-                    public_ips.append(address['address'])
-                else:
-                    private_ips.append(address['address'])
-        return {'public': public_ips, 'private': private_ips}

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/profitbricks.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/profitbricks.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/profitbricks.py
deleted file mode 100644
index 697b082..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/profitbricks.py
+++ /dev/null
@@ -1,1496 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""ProfitBricks Compute driver
-"""
-import base64
-
-import copy
-import time
-
-try:
-    from lxml import etree as ET
-except ImportError:
-    from xml.etree import ElementTree as ET
-
-from libcloud.utils.networking import is_private_subnet
-from libcloud.utils.py3 import b
-from libcloud.compute.providers import Provider
-from libcloud.common.base import ConnectionUserAndKey, XmlResponse
-from libcloud.compute.base import Node, NodeDriver, NodeLocation, NodeSize
-from libcloud.compute.base import NodeImage, StorageVolume
-from libcloud.compute.base import UuidMixin
-from libcloud.compute.types import NodeState
-from libcloud.common.types import LibcloudError, MalformedResponseError
-
-__all__ = [
-    'API_VERSION',
-    'API_HOST',
-    'ProfitBricksNodeDriver',
-    'Datacenter',
-    'ProfitBricksNetworkInterface',
-    'ProfitBricksAvailabilityZone'
-]
-
-API_HOST = 'api.profitbricks.com'
-API_VERSION = '/1.3/'
-
-
-class ProfitBricksResponse(XmlResponse):
-    """
-    ProfitBricks response parsing.
-    """
-    def parse_error(self):
-        try:
-            body = ET.XML(self.body)
-        except:
-            raise MalformedResponseError('Failed to parse XML',
-                                         body=self.body,
-                                         driver=ProfitBricksNodeDriver)
-
-        for e in body.findall('.//detail'):
-            if ET.iselement(e[0].find('httpCode')):
-                http_code = e[0].find('httpCode').text
-            else:
-                http_code = None
-            if ET.iselement(e[0].find('faultCode')):
-                fault_code = e[0].find('faultCode').text
-            else:
-                fault_code = None
-            if ET.iselement(e[0].find('message')):
-                message = e[0].find('message').text
-            else:
-                message = None
-
-        return LibcloudError('HTTP Code: %s, Fault Code: %s, Message: %s' %
-                             (http_code, fault_code, message), driver=self)
-
-
-class ProfitBricksConnection(ConnectionUserAndKey):
-    """
-    Represents a single connection to the ProfitBricks endpoint.
-    """
-    host = API_HOST
-    api_prefix = API_VERSION
-    responseCls = ProfitBricksResponse
-
-    def add_default_headers(self, headers):
-        headers['Content-Type'] = 'text/xml'
-        headers['Authorization'] = 'Basic %s' % (base64.b64encode(
-            b('%s:%s' % (self.user_id, self.key))).decode('utf-8'))
-
-        return headers
-
-    def encode_data(self, data):
-        soap_env = ET.Element('soapenv:Envelope', {
-            'xmlns:soapenv': 'http://schemas.xmlsoap.org/soap/envelope/',
-            'xmlns:ws': 'http://ws.api.profitbricks.com/'
-        })
-        ET.SubElement(soap_env, 'soapenv:Header')
-        soap_body = ET.SubElement(soap_env, 'soapenv:Body')
-        soap_req_body = ET.SubElement(soap_body, 'ws:%s' % (data['action']))
-
-        if 'request' in data.keys():
-            soap_req_body = ET.SubElement(soap_req_body, 'request')
-            for key, value in data.items():
-                if key not in ['action', 'request']:
-                    child = ET.SubElement(soap_req_body, key)
-                    child.text = value
-        else:
-            for key, value in data.items():
-                if key != 'action':
-                    child = ET.SubElement(soap_req_body, key)
-                    child.text = value
-
-        soap_post = ET.tostring(soap_env)
-
-        return soap_post
-
-    def request(self, action, params=None, data=None, headers=None,
-                method='POST', raw=False):
-        action = self.api_prefix + action
-
-        return super(ProfitBricksConnection, self).request(action=action,
-                                                           params=params,
-                                                           data=data,
-                                                           headers=headers,
-                                                           method=method,
-                                                           raw=raw)
-
-
-class Datacenter(UuidMixin):
-    """
-    Class which stores information about ProfitBricks datacenter
-    instances.
-
-    :param      id: The datacenter ID.
-    :type       id: ``str``
-
-    :param      name: The datacenter name.
-    :type       name: ``str``
-
-    :param version: Datacenter version.
-    :type version: ``str``
-
-
-    Note: This class is ProfitBricks specific.
-    """
-    def __init__(self, id, name, version, driver, extra=None):
-        self.id = str(id)
-        self.name = name
-        self.version = version
-        self.driver = driver
-        self.extra = extra or {}
-        UuidMixin.__init__(self)
-
-    def __repr__(self):
-        return ((
-            '<Datacenter: id=%s, name=%s, version=%s, driver=%s> ...>')
-            % (self.id, self.name, self.version,
-                self.driver.name))
-
-
-class ProfitBricksNetworkInterface(object):
-    """
-    Class which stores information about ProfitBricks network
-    interfaces.
-
-    :param      id: The network interface ID.
-    :type       id: ``str``
-
-    :param      name: The network interface name.
-    :type       name: ``str``
-
-    :param      state: The network interface name.
-    :type       state: ``int``
-
-    Note: This class is ProfitBricks specific.
-    """
-    def __init__(self, id, name, state, extra=None):
-        self.id = id
-        self.name = name
-        self.state = state
-        self.extra = extra or {}
-
-    def __repr__(self):
-        return (('<ProfitBricksNetworkInterface: id=%s, name=%s>')
-                % (self.id, self.name))
-
-
-class ProfitBricksAvailabilityZone(object):
-    """
-    Extension class which stores information about a ProfitBricks
-    availability zone.
-
-    Note: This class is ProfitBricks specific.
-    """
-
-    def __init__(self, name):
-        self.name = name
-
-    def __repr__(self):
-        return (('<ProfitBricksAvailabilityZone: name=%s>')
-                % (self.name))
-
-
-class ProfitBricksNodeDriver(NodeDriver):
-    """
-    Base ProfitBricks node driver.
-    """
-    connectionCls = ProfitBricksConnection
-    name = 'ProfitBricks'
-    website = 'http://www.profitbricks.com'
-    type = Provider.PROFIT_BRICKS
-
-    PROVISIONING_STATE = {
-        'INACTIVE': NodeState.PENDING,
-        'INPROCESS': NodeState.PENDING,
-        'AVAILABLE': NodeState.RUNNING,
-        'DELETED': NodeState.TERMINATED,
-    }
-
-    NODE_STATE_MAP = {
-        'NOSTATE': NodeState.UNKNOWN,
-        'RUNNING': NodeState.RUNNING,
-        'BLOCKED': NodeState.STOPPED,
-        'PAUSE': NodeState.STOPPED,
-        'SHUTDOWN': NodeState.PENDING,
-        'SHUTOFF': NodeState.STOPPED,
-        'CRASHED': NodeState.STOPPED,
-    }
-
-    REGIONS = {
-        '1': {'region': 'us/las', 'country': 'USA'},
-        '2': {'region': 'de/fra', 'country': 'DEU'},
-        '3': {'region': 'de/fkb', 'country': 'DEU'},
-    }
-
-    AVAILABILITY_ZONE = {
-        '1': {'name': 'AUTO'},
-        '2': {'name': 'ZONE_1'},
-        '3': {'name': 'ZONE_2'},
-    }
-
-    """
-    ProfitBricks is unique in that they allow the user to define all aspects
-    of the instance size, i.e. disk size, core size, and memory size.
-
-    These are instance types that match up with what other providers support.
-
-    You can configure disk size, core size, and memory size using the ``ex_``
-    parameters on the create_node method.
-    """
-
-    PROFIT_BRICKS_GENERIC_SIZES = {
-        '1': {
-            'id': '1',
-            'name': 'Micro',
-            'ram': 1024,
-            'disk': 50,
-            'cores': 1
-        },
-        '2': {
-            'id': '2',
-            'name': 'Small Instance',
-            'ram': 2048,
-            'disk': 50,
-            'cores': 1
-        },
-        '3': {
-            'id': '3',
-            'name': 'Medium Instance',
-            'ram': 4096,
-            'disk': 50,
-            'cores': 2
-        },
-        '4': {
-            'id': '4',
-            'name': 'Large Instance',
-            'ram': 7168,
-            'disk': 50,
-            'cores': 4
-        },
-        '5': {
-            'id': '5',
-            'name': 'ExtraLarge Instance',
-            'ram': 14336,
-            'disk': 50,
-            'cores': 8
-        },
-        '6': {
-            'id': '6',
-            'name': 'Memory Intensive Instance Medium',
-            'ram': 28672,
-            'disk': 50,
-            'cores': 4
-        },
-        '7': {
-            'id': '7',
-            'name': 'Memory Intensive Instance Large',
-            'ram': 57344,
-            'disk': 50,
-            'cores': 8
-        }
-    }
-
-    """
-    Core Functions
-    """
-
-    def list_sizes(self):
-        """
-        Lists all sizes
-
-        :rtype: ``list`` of :class:`NodeSize`
-        """
-        sizes = []
-
-        for key, values in self.PROFIT_BRICKS_GENERIC_SIZES.items():
-            node_size = self._to_node_size(values)
-            sizes.append(node_size)
-
-        return sizes
-
-    def list_images(self):
-        """
-        List all images.
-
-        :rtype: ``list`` of :class:`NodeImage`
-        """
-
-        action = 'getAllImages'
-        body = {'action': action}
-
-        return self._to_images(self.connection.request(action=action,
-                               data=body, method='POST').object)
-
-    def list_locations(self):
-        """
-        List all locations.
-        """
-        locations = []
-
-        for key, values in self.REGIONS.items():
-            location = self._to_location(values)
-            locations.append(location)
-
-        return locations
-
-    def list_nodes(self):
-        """
-        List all nodes.
-
-        :rtype: ``list`` of :class:`Node`
-        """
-        action = 'getAllServers'
-        body = {'action': action}
-
-        return self._to_nodes(self.connection.request(action=action,
-                              data=body, method='POST').object)
-
-    def reboot_node(self, node):
-        """
-        Reboots the node.
-
-        :rtype: ``bool``
-        """
-        action = 'resetServer'
-        body = {'action': action,
-                'serverId': node.id
-                }
-
-        self.connection.request(action=action,
-                                data=body, method='POST').object
-
-        return True
-
-    def create_node(self, name, image, size=None, location=None,
-                    volume=None, ex_datacenter=None, ex_internet_access=True,
-                    ex_availability_zone=None, ex_ram=None, ex_cores=None,
-                    ex_disk=None, **kwargs):
-        """
-        Creates a node.
-
-        image is optional as long as you pass ram, cores, and disk
-        to the method. ProfitBricks allows you to adjust compute
-        resources at a much more granular level.
-
-        :param volume: If the volume already exists then pass this in.
-        :type volume: :class:`StorageVolume`
-
-        :param location: The location of the new data center
-            if one is not supplied.
-        :type location: : :class:`NodeLocation`
-
-        :param ex_datacenter: If you've already created the DC then pass
-                           it in.
-        :type ex_datacenter: :class:`Datacenter`
-
-        :param ex_internet_access: Configure public Internet access.
-        :type ex_internet_access: : ``bool``
-
-        :param ex_availability_zone: The availability zone.
-        :type ex_availability_zone: class: `ProfitBricksAvailabilityZone`
-
-        :param ex_ram: The amount of ram required.
-        :type ex_ram: : ``int``
-
-        :param ex_cores: The number of cores required.
-        :type ex_cores: : ``int``
-
-        :param ex_disk: The amount of disk required.
-        :type ex_disk: : ``int``
-
-        :return:    Instance of class ``Node``
-        :rtype:     :class:`Node`
-        """
-        if not ex_datacenter:
-            '''
-            We generate a name from the server name passed into the function.
-            '''
-
-            'Creating a Datacenter for the node since one was not provided.'
-            new_datacenter = self._create_new_datacenter_for_node(
-                name=name,
-                location=location
-            )
-            datacenter_id = new_datacenter.id
-
-            'Waiting for the Datacenter create operation to finish.'
-            self._wait_for_datacenter_state(datacenter=new_datacenter)
-        else:
-            datacenter_id = ex_datacenter.id
-            new_datacenter = None
-
-        if not size:
-            if not ex_ram:
-                raise ValueError('You need to either pass a '
-                                 'NodeSize or specify ex_ram as '
-                                 'an extra parameter.')
-            if not ex_cores:
-                raise ValueError('You need to either pass a '
-                                 'NodeSize or specify ex_cores as '
-                                 'an extra parameter.')
-
-        if not volume:
-            if not size:
-                if not ex_disk:
-                    raise ValueError('You need to either pass a '
-                                     'StorageVolume, a NodeSize, or specify '
-                                     'ex_disk as an extra parameter.')
-
-        '''
-        You can override the suggested sizes by passing in unique
-        values for ram, cores, and disk allowing you to size it
-        for your specific use.
-        '''
-
-        if not ex_disk:
-            ex_disk = size.disk
-
-        if not ex_ram:
-            ex_ram = size.ram
-
-        if not ex_cores:
-            ex_cores = size.extra['cores']
-
-        '''
-        A pasword is automatically generated if it is
-        not provided. This is then sent via email to
-        the admin contact on record.
-        '''
-
-        if 'auth' in kwargs:
-            auth = self._get_and_check_auth(kwargs["auth"])
-            password = auth.password
-        else:
-            password = None
-
-        '''
-        Create a StorageVolume that can be attached to the
-        server when it is created.
-        '''
-        if not volume:
-            volume = self._create_node_volume(ex_disk=ex_disk,
-                                              image=image,
-                                              password=password,
-                                              name=name,
-                                              ex_datacenter=ex_datacenter,
-                                              new_datacenter=new_datacenter)
-
-            storage_id = volume.id
-
-            'Waiting on the storage volume to be created before provisioning '
-            'the instance.'
-            self._wait_for_storage_volume_state(volume)
-        else:
-            if ex_datacenter:
-                datacenter_id = ex_datacenter.id
-            else:
-                datacenter_id = volume.extra['datacenter_id']
-
-            storage_id = volume.id
-
-        action = 'createServer'
-        body = {'action': action,
-                'request': 'true',
-                'serverName': name,
-                'cores': str(ex_cores),
-                'ram': str(ex_ram),
-                'bootFromStorageId': storage_id,
-                'internetAccess': str(ex_internet_access).lower(),
-                'dataCenterId': datacenter_id
-                }
-
-        if ex_availability_zone:
-            body['availabilityZone'] = ex_availability_zone.name
-
-        data = self.connection.request(action=action,
-                                       data=body,
-                                       method='POST').object
-        nodes = self._to_nodes(data)
-        return nodes[0]
-
-    def destroy_node(self, node, ex_remove_attached_disks=False):
-        """
-        Destroys a node.
-
-        :param node: The node you wish to destroy.
-        :type volume: :class:`Node`
-
-        :param ex_remove_attached_disks: True to destroy all attached volumes.
-        :type ex_remove_attached_disks: : ``bool``
-
-        :rtype:     : ``bool``
-        """
-        action = 'deleteServer'
-        body = {'action': action,
-                'serverId': node.id
-                }
-
-        self.connection.request(action=action,
-                                data=body, method='POST').object
-
-        return True
-
-    """
-    Volume Functions
-    """
-
-    def list_volumes(self):
-        """
-        Lists all voumes.
-        """
-        action = 'getAllStorages'
-        body = {'action': action}
-
-        return self._to_volumes(self.connection.request(action=action,
-                                                        data=body,
-                                                        method='POST').object)
-
-    def attach_volume(self, node, volume, device=None, ex_bus_type=None):
-        """
-        Attaches a volume.
-
-        :param volume: The volume you're attaching.
-        :type volume: :class:`StorageVolume`
-
-        :param node: The node to which you're attaching the volume.
-        :type node: :class:`Node`
-
-        :param device: The device number order.
-        :type device: : ``int``
-
-        :param ex_bus_type: Bus type. Either IDE or VIRTIO (default).
-        :type ex_bus_type: ``str``
-
-        :return:    Instance of class ``StorageVolume``
-        :rtype:     :class:`StorageVolume`
-        """
-        action = 'connectStorageToServer'
-        body = {'action': action,
-                'request': 'true',
-                'storageId': volume.id,
-                'serverId': node.id,
-                'busType': ex_bus_type,
-                'deviceNumber': str(device)
-                }
-
-        self.connection.request(action=action,
-                                data=body, method='POST').object
-        return volume
-
-    def create_volume(self, size, name=None,
-                      ex_datacenter=None, ex_image=None, ex_password=None):
-        """
-        Creates a volume.
-
-        :param ex_datacenter: The datacenter you're placing
-                              the storage in. (req)
-        :type ex_datacenter: :class:`Datacenter`
-
-        :param ex_image: The OS image for the volume.
-        :type ex_image: :class:`NodeImage`
-
-        :param ex_password: Optional password for root.
-        :type ex_password: : ``str``
-
-        :return:    Instance of class ``StorageVolume``
-        :rtype:     :class:`StorageVolume`
-        """
-        action = 'createStorage'
-        body = {'action': action,
-                'request': 'true',
-                'size': str(size),
-                'storageName': name,
-                'mountImageId': ex_image.id
-                }
-
-        if ex_datacenter:
-            body['dataCenterId'] = ex_datacenter.id
-
-        if ex_password:
-            body['profitBricksImagePassword'] = ex_password
-
-        data = self.connection.request(action=action,
-                                       data=body,
-                                       method='POST').object
-        volumes = self._to_volumes(data)
-        return volumes[0]
-
-    def detach_volume(self, volume):
-        """
-        Detaches a volume.
-
-        :param volume: The volume you're detaching.
-        :type volume: :class:`StorageVolume`
-
-        :rtype:     :``bool``
-        """
-        node_id = volume.extra['server_id']
-
-        action = 'disconnectStorageFromServer'
-        body = {'action': action,
-                'storageId': volume.id,
-                'serverId': node_id
-                }
-
-        self.connection.request(action=action,
-                                data=body, method='POST').object
-
-        return True
-
-    def destroy_volume(self, volume):
-        """
-        Destroys a volume.
-
-        :param volume: The volume you're attaching.
-        :type volume: :class:`StorageVolume`
-
-        :rtype:     : ``bool``
-        """
-        action = 'deleteStorage'
-        body = {'action': action,
-                'storageId': volume.id}
-
-        self.connection.request(action=action,
-                                data=body, method='POST').object
-
-        return True
-
-    def ex_update_volume(self, volume, storage_name=None, size=None):
-        """
-        Updates a volume.
-
-        :param volume: The volume you're attaching..
-        :type volume: :class:`StorageVolume`
-
-        :param storage_name: The name of the volume.
-        :type storage_name: : ``str``
-
-        :param size: The desired size.
-        :type size: ``int``
-
-        :rtype:     : ``bool``
-        """
-        action = 'updateStorage'
-        body = {'action': action,
-                'request': 'true',
-                'storageId': volume.id
-                }
-
-        if storage_name:
-            body['storageName'] = storage_name
-        if size:
-            body['size'] = str(size)
-
-        self.connection.request(action=action,
-                                data=body, method='POST').object
-
-        return True
-
-    def ex_describe_volume(self, volume_id):
-        """
-        Describes a volume.
-
-        :param volume_id: The ID of the volume you're describing.
-        :type volume_id: :class:`StorageVolume`
-
-        :return:    Instance of class ``StorageVolume``
-        :rtype:     :class:`StorageVolume`
-        """
-        action = 'getStorage'
-        body = {'action': action,
-                'storageId': volume_id
-                }
-
-        data = self.connection.request(action=action,
-                                       data=body,
-                                       method='POST').object
-        volumes = self._to_volumes(data)
-        return volumes[0]
-
-    """
-    Extension Functions
-    """
-
-    ''' Server Extension Functions
-    '''
-    def ex_stop_node(self, node):
-        """
-        Stops a node.
-
-        This also deallocates the public IP space.
-
-        :param node: The node you wish to halt.
-        :type node: :class:`Node`
-
-        :rtype:     : ``bool``
-        """
-        action = 'stopServer'
-        body = {'action': action,
-                'serverId': node.id
-                }
-
-        self.connection.request(action=action,
-                                data=body, method='POST').object
-
-        return True
-
-    def ex_start_node(self, node):
-        """
-        Starts a volume.
-
-        :param node: The node you wish to start.
-        :type node: :class:`Node`
-
-        :rtype:     : ``bool``
-        """
-        action = 'startServer'
-        body = {'action': action,
-                'serverId': node.id
-                }
-
-        self.connection.request(action=action,
-                                data=body, method='POST').object
-
-        return True
-
-    def ex_list_availability_zones(self):
-        """
-        Returns a list of availability zones.
-        """
-
-        availability_zones = []
-
-        for key, values in self.AVAILABILITY_ZONE.items():
-            name = copy.deepcopy(values)["name"]
-
-            availability_zone = ProfitBricksAvailabilityZone(
-                name=name
-            )
-            availability_zones.append(availability_zone)
-
-        return availability_zones
-
-    def ex_describe_node(self, node):
-        """
-        Describes a node.
-
-        :param node: The node you wish to describe.
-        :type node: :class:`Node`
-
-        :return:    Instance of class ``Node``
-        :rtype:     :class:`Node`
-        """
-        action = 'getServer'
-        body = {'action': action,
-                'serverId': node.id
-                }
-
-        data = self.connection.request(action=action,
-                                       data=body,
-                                       method='POST').object
-        nodes = self._to_nodes(data)
-        return nodes[0]
-
-    def ex_update_node(self, node, name=None, cores=None,
-                       ram=None, availability_zone=None):
-        """
-        Updates a node.
-
-        :param cores: The number of CPUs the node should have.
-        :type device: : ``int``
-
-        :param ram: The amount of ram the machine should have.
-        :type ram: : ``int``
-
-        :param ex_availability_zone: Update the availability zone.
-        :type ex_availability_zone: :class:`ProfitBricksAvailabilityZone`
-
-        :rtype:     : ``bool``
-        """
-        action = 'updateServer'
-
-        body = {'action': action,
-                'request': 'true',
-                'serverId': node.id
-                }
-
-        if name:
-            body['serverName'] = name
-
-        if cores:
-            body['cores'] = str(cores)
-
-        if ram:
-            body['ram'] = str(ram)
-
-        if availability_zone:
-            body['availabilityZone'] = availability_zone.name
-
-        self.connection.request(action=action,
-                                data=body, method='POST').object
-
-        return True
-
-    '''
-    Datacenter Extension Functions
-    '''
-
-    def ex_create_datacenter(self, name, location):
-        """
-        Creates a datacenter.
-
-        ProfitBricks has a concept of datacenters.
-        These represent buckets into which you
-        can place various compute resources.
-
-        :param name: The DC name.
-        :type name: : ``str``
-
-        :param location: The DC region.
-        :type location: : ``str``
-
-        :return:    Instance of class ``Datacenter``
-        :rtype:     :class:`Datacenter`
-        """
-        action = 'createDataCenter'
-
-        body = {'action': action,
-                'request': 'true',
-                'dataCenterName': name,
-                'location': location.lower()
-                }
-        data = self.connection.request(action=action,
-                                       data=body,
-                                       method='POST').object
-        datacenters = self._to_datacenters(data)
-        return datacenters[0]
-
-    def ex_destroy_datacenter(self, datacenter):
-        """
-        Destroys a datacenter.
-
-        :param datacenter: The DC you're destroying.
-        :type datacenter: :class:`Datacenter`
-
-        :rtype:     : ``bool``
-        """
-        action = 'deleteDataCenter'
-        body = {'action': action,
-                'dataCenterId': datacenter.id
-                }
-
-        self.connection.request(action=action,
-                                data=body, method='POST').object
-
-        return True
-
-    def ex_describe_datacenter(self, datacenter_id):
-        """
-        Describes a datacenter.
-
-        :param datacenter_id: The DC you are describing.
-        :type datacenter_id: ``str``
-
-        :return:    Instance of class ``Datacenter``
-        :rtype:     :class:`Datacenter`
-        """
-
-        action = 'getDataCenter'
-        body = {'action': action,
-                'dataCenterId': datacenter_id
-                }
-
-        data = self.connection.request(action=action,
-                                       data=body,
-                                       method='POST').object
-        datacenters = self._to_datacenters(data)
-        return datacenters[0]
-
-    def ex_list_datacenters(self):
-        """
-        Lists all datacenters.
-
-        :return:    ``list`` of class ``Datacenter``
-        :rtype:     :class:`Datacenter`
-        """
-        action = 'getAllDataCenters'
-        body = {'action': action}
-
-        return self._to_datacenters(self.connection.request(
-                                    action=action,
-                                    data=body,
-                                    method='POST').object)
-
-    def ex_rename_datacenter(self, datacenter, name):
-        """
-        Update a datacenter.
-
-        :param datacenter: The DC you are renaming.
-        :type datacenter: :class:`Datacenter`
-
-        :param name: The DC name.
-        :type name: : ``str``
-
-        :rtype:     : ``bool``
-        """
-        action = 'updateDataCenter'
-        body = {'action': action,
-                'request': 'true',
-                'dataCenterId': datacenter.id,
-                'dataCenterName': name
-                }
-
-        self.connection.request(action=action,
-                                data=body,
-                                method='POST').object
-
-        return True
-
-    def ex_clear_datacenter(self, datacenter):
-        """
-        Clear a datacenter.
-
-        This removes all objects in a DC.
-
-        :param datacenter: The DC you're clearing.
-        :type datacenter: :class:`Datacenter`
-
-        :rtype:     : ``bool``
-        """
-        action = 'clearDataCenter'
-        body = {'action': action,
-                'dataCenterId': datacenter.id
-                }
-
-        self.connection.request(action=action,
-                                data=body, method='POST').object
-
-        return True
-
-    '''
-    Network Interface Extension Functions
-    '''
-
-    def ex_list_network_interfaces(self):
-        """
-        Lists all network interfaces.
-
-        :return:    ``list`` of class ``ProfitBricksNetworkInterface``
-        :rtype:     :class:`ProfitBricksNetworkInterface`
-        """
-        action = 'getAllNic'
-        body = {'action': action}
-
-        return self._to_interfaces(
-            self.connection.request(action=action,
-                                    data=body,
-                                    method='POST').object)
-
-    def ex_describe_network_interface(self, network_interface):
-        """
-        Describes a network interface.
-
-        :param network_interface: The NIC you wish to describe.
-        :type network_interface: :class:`ProfitBricksNetworkInterface`
-
-        :return:    Instance of class ``ProfitBricksNetworkInterface``
-        :rtype:     :class:`ProfitBricksNetworkInterface`
-        """
-        action = 'getNic'
-        body = {'action': action,
-                'nicId': network_interface.id
-                }
-
-        return self._to_interface(
-            self.connection.request(
-                action=action,
-                data=body,
-                method='POST').object.findall('.//return')[0])
-
-    def ex_create_network_interface(self, node,
-                                    lan_id=None, ip=None, nic_name=None,
-                                    dhcp_active=True):
-        """
-        Creates a network interface.
-
-        :param lan_id: The ID for the LAN.
-        :type lan_id: : ``int``
-
-        :param ip: The IP address for the NIC.
-        :type ip: ``str``
-
-        :param nic_name: The name of the NIC, e.g. PUBLIC.
-        :type nic_name: ``str``
-
-        :param dhcp_active: Set to false to disable.
-        :type dhcp_active: ``bool``
-
-        :return:    Instance of class ``ProfitBricksNetworkInterface``
-        :rtype:     :class:`ProfitBricksNetworkInterface`
-        """
-        action = 'createNic'
-        body = {'action': action,
-                'request': 'true',
-                'serverId': node.id,
-                'dhcpActive': str(dhcp_active)
-                }
-
-        if lan_id:
-            body['lanId'] = str(lan_id)
-        else:
-            body['lanId'] = str(1)
-
-        if ip:
-            body['ip'] = ip
-
-        if nic_name:
-            body['nicName'] = nic_name
-
-        data = self.connection.request(action=action,
-                                       data=body,
-                                       method='POST').object
-        interfaces = self._to_interfaces(data)
-        return interfaces[0]
-
-    def ex_update_network_interface(self, network_interface, name=None,
-                                    lan_id=None, ip=None,
-                                    dhcp_active=None):
-        """
-        Updates a network interface.
-
-        :param lan_id: The ID for the LAN.
-        :type lan_id: : ``int``
-
-        :param ip: The IP address for the NIC.
-        :type ip: ``str``
-
-        :param name: The name of the NIC, e.g. PUBLIC.
-        :type name: ``str``
-
-        :param dhcp_active: Set to false to disable.
-        :type dhcp_active: ``bool``
-
-        :rtype:     : ``bool``
-        """
-        action = 'updateNic'
-        body = {'action': action,
-                'request': 'true',
-                'nicId': network_interface.id
-                }
-
-        if name:
-            body['nicName'] = name
-
-        if lan_id:
-            body['lanId'] = str(lan_id)
-
-        if ip:
-            body['ip'] = ip
-
-        if dhcp_active is not None:
-            body['dhcpActive'] = str(dhcp_active).lower()
-
-        self.connection.request(action=action,
-                                data=body, method='POST').object
-
-        return True
-
-    def ex_destroy_network_interface(self, network_interface):
-        """
-        Destroy a network interface.
-
-        :param network_interface: The NIC you wish to describe.
-        :type network_interface: :class:`ProfitBricksNetworkInterface`
-
-        :rtype:     : ``bool``
-        """
-
-        action = 'deleteNic'
-        body = {'action': action,
-                'nicId': network_interface.id}
-
-        self.connection.request(action=action,
-                                data=body, method='POST').object
-
-        return True
-
-    def ex_set_inet_access(self, datacenter,
-                           network_interface, internet_access=True):
-
-        action = 'setInternetAccess'
-
-        body = {'action': action,
-                'dataCenterId': datacenter.id,
-                'lanId': network_interface.extra['lan_id'],
-                'internetAccess': str(internet_access).lower()
-                }
-
-        self.connection.request(action=action,
-                                data=body, method='POST').object
-
-        return True
-
-    """
-    Private Functions
-    """
-
-    def _to_datacenters(self, object):
-        return [self._to_datacenter(
-            datacenter) for datacenter in object.findall('.//return')]
-
-    def _to_datacenter(self, datacenter):
-        datacenter_id = datacenter.find('dataCenterId').text
-        if ET.iselement(datacenter.find('dataCenterName')):
-            datacenter_name = datacenter.find('dataCenterName').text
-        else:
-            datacenter_name = None
-        version = datacenter.find('dataCenterVersion').text
-        if ET.iselement(datacenter.find('provisioningState')):
-            provisioning_state = datacenter.find('provisioningState').text
-        else:
-            provisioning_state = None
-        if ET.iselement(datacenter.find('location')):
-            location = datacenter.find('location').text
-        else:
-            location = None
-
-        provisioning_state = self.PROVISIONING_STATE.get(provisioning_state,
-                                                         NodeState.UNKNOWN)
-
-        return Datacenter(id=datacenter_id,
-                          name=datacenter_name,
-                          version=version,
-                          driver=self.connection.driver,
-                          extra={'provisioning_state': provisioning_state,
-                                 'location': location})
-
-    def _to_images(self, object):
-        return [self._to_image(image) for image in object.findall('.//return')]
-
-    def _to_image(self, image):
-        image_id = image.find('imageId').text
-        image_name = image.find('imageName').text
-        image_size = image.find('imageSize').text
-        image_type = image.find('imageType').text
-        os_type = image.find('osType').text
-        public = image.find('public').text
-        writeable = image.find('writeable').text
-
-        if ET.iselement(image.find('cpuHotpluggable')):
-            cpu_hotpluggable = image.find('cpuHotpluggable').text
-        else:
-            cpu_hotpluggable = None
-
-        if ET.iselement(image.find('memoryHotpluggable')):
-            memory_hotpluggable = image.find('memoryHotpluggable').text
-        else:
-            memory_hotpluggable = None
-
-        if ET.iselement(image.find('location')):
-            if image.find('region'):
-                image_region = image.find('region').text
-            else:
-                image_region = None
-        else:
-            image_region = None
-
-        return NodeImage(id=image_id,
-                         name=image_name,
-                         driver=self.connection.driver,
-                         extra={'image_size': image_size,
-                                'image_type': image_type,
-                                'cpu_hotpluggable': cpu_hotpluggable,
-                                'memory_hotpluggable': memory_hotpluggable,
-                                'os_type': os_type,
-                                'public': public,
-                                'location': image_region,
-                                'writeable': writeable})
-
-    def _to_nodes(self, object):
-        return [self._to_node(n) for n in object.findall('.//return')]
-
-    def _to_node(self, node):
-        """
-        Convert the request into a node Node
-        """
-        ATTRIBUTE_NAME_MAP = {
-            'dataCenterId': 'datacenter_id',
-            'dataCenterVersion': 'datacenter_version',
-            'serverId': 'node_id',
-            'serverName': 'node_name',
-            'cores': 'cores',
-            'ram': 'ram',
-            'internetAccess': 'internet_access',
-            'provisioningState': 'provisioning_state',
-            'virtualMachineState': 'virtual_machine_state',
-            'creationTime': 'creation_time',
-            'lastModificationTime': 'last_modification_time',
-            'osType': 'os_type',
-            'availabilityZone': 'availability_zone',
-            'cpuHotPlug': 'cpu_hotpluggable',
-            'ramHotPlug': 'memory_hotpluggable',
-            'nicHotPlug': 'nic_hotpluggable',
-            'discVirtioHotPlug': 'disc_virtio_hotplug',
-            'discVirtioHotUnPlug': 'disc_virtio_hotunplug'
-        }
-
-        extra = {}
-        for attribute_name, extra_name in ATTRIBUTE_NAME_MAP.items():
-            elem = node.find(attribute_name)
-
-            if ET.iselement(elem):
-                value = elem.text
-            else:
-                value = None
-
-            extra[extra_name] = value
-
-        public_ips = []
-        private_ips = []
-
-        if ET.iselement(node.find('nics')):
-            for nic in node.findall('.//nics'):
-                n_elements = list(nic.findall('.//ips'))
-                if len(n_elements) > 0:
-                    ip = n_elements[0].text
-                    if is_private_subnet(ip):
-                        private_ips.append(ip)
-                    else:
-                        public_ips.append(ip)
-
-        extra['provisioning_state'] = self.PROVISIONING_STATE.get(
-            extra['provisioning_state'], NodeState.UNKNOWN)
-
-        node_id = extra['node_id']
-        node_name = extra['node_name']
-        state = self.NODE_STATE_MAP.get(extra['virtual_machine_state'],
-                                        NodeState.UNKNOWN)
-
-        return Node(
-            id=node_id,
-            name=node_name,
-            state=state,
-            public_ips=public_ips,
-            private_ips=private_ips,
-            driver=self.connection.driver,
-            extra=extra)
-
-    def _to_volumes(self, object):
-        return [self._to_volume(
-            volume) for volume in object.findall('.//return')]
-
-    def _to_volume(self, volume, node=None):
-        ATTRIBUTE_NAME_MAP = {
-            'dataCenterId': 'datacenter_id',
-            'storageId': 'storage_id',
-            'storageName': 'storage_name',
-            'serverIds': 'server_id',
-            'creationTime': 'creation_time',
-            'lastModificationTime': 'last_modification_time',
-            'provisioningState': 'provisioning_state',
-            'size': 'size',
-        }
-
-        extra = {}
-        for attribute_name, extra_name in ATTRIBUTE_NAME_MAP.items():
-            elem = volume.find(attribute_name)
-
-            if ET.iselement(elem):
-                value = elem.text
-            else:
-                value = None
-
-            extra[extra_name] = value
-
-        if ET.iselement(volume.find('mountImage')):
-            image_id = volume.find('mountImage')[0].text
-            image_name = volume.find('mountImage')[1].text
-        else:
-            image_id = None
-            image_name = None
-
-        extra['image_id'] = image_id
-        extra['image_name'] = image_name
-        extra['size'] = int(extra['size']) if extra['size'] else 0
-        extra['provisioning_state'] = \
-            self.PROVISIONING_STATE.get(extra['provisioning_state'],
-                                        NodeState.UNKNOWN)
-
-        storage_id = extra['storage_id']
-        storage_name = extra['storage_name']
-        size = extra['size']
-
-        return StorageVolume(
-            id=storage_id,
-            name=storage_name,
-            size=size,
-            driver=self.connection.driver,
-            extra=extra)
-
-    def _to_interfaces(self, object):
-        return [self._to_interface(
-            interface) for interface in object.findall('.//return')]
-
-    def _to_interface(self, interface):
-        ATTRIBUTE_NAME_MAP = {
-            'nicId': 'nic_id',
-            'nicName': 'nic_name',
-            'serverId': 'server_id',
-            'lanId': 'lan_id',
-            'internetAccess': 'internet_access',
-            'macAddress': 'mac_address',
-            'dhcpActive': 'dhcp_active',
-            'gatewayIp': 'gateway_ip',
-            'provisioningState': 'provisioning_state',
-            'dataCenterId': 'datacenter_id',
-            'dataCenterVersion': 'datacenter_version'
-        }
-
-        extra = {}
-        for attribute_name, extra_name in ATTRIBUTE_NAME_MAP.items():
-            elem = interface.find(attribute_name)
-
-            if ET.iselement(elem):
-                value = elem.text
-            else:
-                value = None
-
-            extra[extra_name] = value
-
-        ips = []
-
-        if ET.iselement(interface.find('ips')):
-            for ip in interface.findall('.//ips'):
-                ips.append(ip.text)
-
-        extra['ips'] = ips
-
-        nic_id = extra['nic_id']
-        nic_name = extra['nic_name']
-        state = self.PROVISIONING_STATE.get(extra['provisioning_state'],
-                                            NodeState.UNKNOWN)
-
-        return ProfitBricksNetworkInterface(
-            id=nic_id,
-            name=nic_name,
-            state=state,
-            extra=extra)
-
-    def _to_location(self, data):
-
-        return NodeLocation(id=data["region"],
-                            name=data["region"],
-                            country=data["country"],
-                            driver=self.connection.driver)
-
-    def _to_node_size(self, data):
-        """
-        Convert the PROFIT_BRICKS_GENERIC_SIZES into NodeSize
-        """
-        return NodeSize(id=data["id"],
-                        name=data["name"],
-                        ram=data["ram"],
-                        disk=data["disk"],
-                        bandwidth=None,
-                        price=None,
-                        driver=self.connection.driver,
-                        extra={
-                            'cores': data["cores"]})
-
-    def _wait_for_datacenter_state(self, datacenter, state=NodeState.RUNNING,
-                                   timeout=300, interval=5):
-        """
-        Private function that waits the datacenter to transition into the
-        specified state.
-
-        :return: Datacenter object on success.
-        :rtype: :class:`.Datacenter`
-        """
-        wait_time = 0
-        datacenter = self.ex_describe_datacenter(datacenter_id=datacenter.id)
-
-        while (datacenter.extra['provisioning_state'] != state):
-            datacenter = \
-                self.ex_describe_datacenter(datacenter_id=datacenter.id)
-            if datacenter.extra['provisioning_state'] == state:
-                break
-
-            if wait_time >= timeout:
-                raise Exception('Datacenter didn\'t transition to %s state '
-                                'in %s seconds' % (state, timeout))
-
-            wait_time += interval
-            time.sleep(interval)
-
-        return datacenter
-
-    def _create_new_datacenter_for_node(self, name, location):
-        """
-        Creates a Datacenter for a node.
-        """
-        dc_name = name + '-DC'
-
-        if not location:
-            loc = 'us/las'
-        else:
-            loc = location.id
-        return self.ex_create_datacenter(name=dc_name, location=loc)
-
-    def _wait_for_storage_volume_state(self, volume, state=NodeState.RUNNING,
-                                       timeout=300, interval=5):
-        """
-        Wait for volume to transition into the specified state.
-
-        :return: Volume object on success.
-        :rtype: :class:`Volume`
-        """
-        wait_time = 0
-        volume = self.ex_describe_volume(volume_id=volume.id)
-
-        while (volume.extra['provisioning_state'] != state):
-            volume = self.ex_describe_volume(volume_id=volume.id)
-            if volume.extra['provisioning_state'] == state:
-                break
-
-            if wait_time >= timeout:
-                raise Exception('Volume didn\'t transition to %s state '
-                                'in %s seconds' % (state, timeout))
-
-            wait_time += interval
-            time.sleep(interval)
-
-        return volume
-
-    def _create_node_volume(self, ex_disk, image, password,
-                            name, ex_datacenter=None, new_datacenter=None):
-
-        volume_name = name + '-volume'
-
-        if ex_datacenter:
-            volume = self.create_volume(size=ex_disk,
-                                        ex_datacenter=ex_datacenter,
-                                        ex_image=image,
-                                        ex_password=password,
-                                        name=volume_name)
-        else:
-            volume = self.create_volume(size=ex_disk,
-                                        ex_datacenter=new_datacenter,
-                                        ex_image=image,
-                                        ex_password=password,
-                                        name=volume_name)
-
-        return volume

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/rackspace.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/rackspace.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/rackspace.py
deleted file mode 100644
index 4aab926..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/rackspace.py
+++ /dev/null
@@ -1,253 +0,0 @@
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-Rackspace driver
-"""
-from libcloud.compute.types import Provider, LibcloudError, VolumeSnapshotState
-from libcloud.compute.base import NodeLocation, VolumeSnapshot
-from libcloud.compute.drivers.openstack import OpenStack_1_0_Connection,\
-    OpenStack_1_0_NodeDriver, OpenStack_1_0_Response
-from libcloud.compute.drivers.openstack import OpenStack_1_1_Connection,\
-    OpenStack_1_1_NodeDriver
-
-from libcloud.common.rackspace import AUTH_URL
-from libcloud.utils.iso8601 import parse_date
-
-SERVICE_TYPE = 'compute'
-SERVICE_NAME_GEN1 = 'cloudServers'
-SERVICE_NAME_GEN2 = 'cloudServersOpenStack'
-ENDPOINT_ARGS_MAP = {
-    'dfw': {'service_type': SERVICE_TYPE,
-            'name': SERVICE_NAME_GEN2,
-            'region': 'DFW'},
-    'ord': {'service_type': SERVICE_TYPE,
-            'name': SERVICE_NAME_GEN2,
-            'region': 'ORD'},
-    'iad': {'service_type': SERVICE_TYPE,
-            'name': SERVICE_NAME_GEN2,
-            'region': 'IAD'},
-    'lon': {'service_type': SERVICE_TYPE,
-            'name': SERVICE_NAME_GEN2,
-            'region': 'LON'},
-    'syd': {'service_type': SERVICE_TYPE,
-            'name': SERVICE_NAME_GEN2,
-            'region': 'SYD'},
-    'hkg': {'service_type': SERVICE_TYPE,
-            'name': SERVICE_NAME_GEN2,
-            'region': 'HKG'},
-
-}
-
-
-class RackspaceFirstGenConnection(OpenStack_1_0_Connection):
-    """
-    Connection class for the Rackspace first-gen driver.
-    """
-    responseCls = OpenStack_1_0_Response
-    XML_NAMESPACE = 'http://docs.rackspacecloud.com/servers/api/v1.0'
-    auth_url = AUTH_URL
-    _auth_version = '2.0'
-    cache_busting = True
-
-    def __init__(self, *args, **kwargs):
-        self.region = kwargs.pop('region', None)
-        super(RackspaceFirstGenConnection, self).__init__(*args, **kwargs)
-
-    def get_endpoint(self):
-        if '2.0' in self._auth_version:
-            ep = self.service_catalog.get_endpoint(service_type=SERVICE_TYPE,
-                                                   name=SERVICE_NAME_GEN1)
-        else:
-            raise LibcloudError(
-                'Auth version "%s" not supported' % (self._auth_version))
-
-        public_url = ep.url
-
-        if not public_url:
-            raise LibcloudError('Could not find specified endpoint')
-
-        # This is a nasty hack, but it's required because of how the
-        # auth system works.
-        # Old US accounts can access UK API endpoint, but they don't
-        # have this endpoint in the service catalog. Same goes for the
-        # old UK accounts and US endpoint.
-        if self.region == 'us':
-            # Old UK account, which only have uk endpoint in the catalog
-            public_url = public_url.replace('https://lon.servers.api',
-                                            'https://servers.api')
-        elif self.region == 'uk':
-            # Old US account, which only has us endpoints in the catalog
-            public_url = public_url.replace('https://servers.api',
-                                            'https://lon.servers.api')
-
-        return public_url
-
-    def get_service_name(self):
-        return SERVICE_NAME_GEN1
-
-
-class RackspaceFirstGenNodeDriver(OpenStack_1_0_NodeDriver):
-    name = 'Rackspace Cloud (First Gen)'
-    website = 'http://www.rackspace.com'
-    connectionCls = RackspaceFirstGenConnection
-    type = Provider.RACKSPACE_FIRST_GEN
-    api_name = 'rackspace'
-
-    def __init__(self, key, secret=None, secure=True, host=None, port=None,
-                 region='us', **kwargs):
-        """
-        @inherits:  :class:`NodeDriver.__init__`
-
-        :param region: Region ID which should be used
-        :type region: ``str``
-        """
-        if region not in ['us', 'uk']:
-            raise ValueError('Invalid region: %s' % (region))
-
-        super(RackspaceFirstGenNodeDriver, self).__init__(key=key,
-                                                          secret=secret,
-                                                          secure=secure,
-                                                          host=host,
-                                                          port=port,
-                                                          region=region,
-                                                          **kwargs)
-
-    def list_locations(self):
-        """
-        Lists available locations
-
-        Locations cannot be set or retrieved via the API, but currently
-        there are two locations, DFW and ORD.
-
-        @inherits: :class:`OpenStack_1_0_NodeDriver.list_locations`
-        """
-        if self.region == 'us':
-            locations = [NodeLocation(0, "Rackspace DFW1/ORD1", 'US', self)]
-        elif self.region == 'uk':
-            locations = [NodeLocation(0, 'Rackspace UK London', 'UK', self)]
-
-        return locations
-
-    def _ex_connection_class_kwargs(self):
-        kwargs = self.openstack_connection_kwargs()
-        kwargs['region'] = self.region
-        return kwargs
-
-
-class RackspaceConnection(OpenStack_1_1_Connection):
-    """
-    Connection class for the Rackspace next-gen OpenStack base driver.
-    """
-
-    auth_url = AUTH_URL
-    _auth_version = '2.0'
-
-    def __init__(self, *args, **kwargs):
-        self.region = kwargs.pop('region', None)
-        self.get_endpoint_args = kwargs.pop('get_endpoint_args', None)
-        super(RackspaceConnection, self).__init__(*args, **kwargs)
-
-    def get_service_name(self):
-        if not self.get_endpoint_args:
-            # if they used ex_force_base_url, assume the Rackspace default
-            return SERVICE_NAME_GEN2
-
-        return self.get_endpoint_args.get('name', SERVICE_NAME_GEN2)
-
-    def get_endpoint(self):
-        if not self.get_endpoint_args:
-            raise LibcloudError(
-                'RackspaceConnection must have get_endpoint_args set')
-
-        if '2.0' in self._auth_version:
-            ep = self.service_catalog.get_endpoint(**self.get_endpoint_args)
-        else:
-            raise LibcloudError(
-                'Auth version "%s" not supported' % (self._auth_version))
-
-        public_url = ep.url
-
-        if not public_url:
-            raise LibcloudError('Could not find specified endpoint')
-
-        return public_url
-
-
-class RackspaceNodeDriver(OpenStack_1_1_NodeDriver):
-    name = 'Rackspace Cloud (Next Gen)'
-    website = 'http://www.rackspace.com'
-    connectionCls = RackspaceConnection
-    type = Provider.RACKSPACE
-
-    _networks_url_prefix = '/os-networksv2'
-
-    def __init__(self, key, secret=None, secure=True, host=None, port=None,
-                 region='dfw', **kwargs):
-        """
-        @inherits:  :class:`NodeDriver.__init__`
-
-        :param region: ID of the region which should be used.
-        :type region: ``str``
-        """
-        valid_regions = ENDPOINT_ARGS_MAP.keys()
-
-        if region not in valid_regions:
-            raise ValueError('Invalid region: %s' % (region))
-
-        if region == 'lon':
-            self.api_name = 'rackspacenovalon'
-        elif region == 'syd':
-            self.api_name = 'rackspacenovasyd'
-        else:
-            self.api_name = 'rackspacenovaus'
-
-        super(RackspaceNodeDriver, self).__init__(key=key, secret=secret,
-                                                  secure=secure, host=host,
-                                                  port=port,
-                                                  region=region,
-                                                  **kwargs)
-
-    def _to_snapshot(self, api_node):
-        if 'snapshot' in api_node:
-            api_node = api_node['snapshot']
-
-        extra = {'volume_id': api_node['volumeId'],
-                 'name': api_node['displayName'],
-                 'created': api_node['createdAt'],
-                 'description': api_node['displayDescription'],
-                 'status': api_node['status']}
-
-        state = self.SNAPSHOT_STATE_MAP.get(
-            api_node['status'],
-            VolumeSnapshotState.UNKNOWN
-        )
-
-        try:
-            created_td = parse_date(api_node['createdAt'])
-        except ValueError:
-            created_td = None
-
-        snapshot = VolumeSnapshot(id=api_node['id'], driver=self,
-                                  size=api_node['size'],
-                                  extra=extra,
-                                  created=created_td,
-                                  state=state)
-        return snapshot
-
-    def _ex_connection_class_kwargs(self):
-        endpoint_args = ENDPOINT_ARGS_MAP[self.region]
-        kwargs = self.openstack_connection_kwargs()
-        kwargs['region'] = self.region
-        kwargs['get_endpoint_args'] = endpoint_args
-        return kwargs

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/rimuhosting.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/rimuhosting.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/rimuhosting.py
deleted file mode 100644
index 4cf8457..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/rimuhosting.py
+++ /dev/null
@@ -1,339 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-RimuHosting Driver
-"""
-try:
-    import simplejson as json
-except ImportError:
-    import json
-
-from libcloud.common.base import ConnectionKey, JsonResponse
-from libcloud.common.types import InvalidCredsError
-from libcloud.compute.types import Provider, NodeState
-from libcloud.compute.base import NodeDriver, NodeSize, Node, NodeLocation
-from libcloud.compute.base import NodeImage
-
-API_CONTEXT = '/r'
-API_HOST = 'rimuhosting.com'
-
-
-class RimuHostingException(Exception):
-    """
-    Exception class for RimuHosting driver
-    """
-
-    def __str__(self):
-        return self.args[0]
-
-    def __repr__(self):
-        return "<RimuHostingException '%s'>" % (self.args[0])
-
-
-class RimuHostingResponse(JsonResponse):
-    """
-    Response Class for RimuHosting driver
-    """
-    def success(self):
-        if self.status == 403:
-            raise InvalidCredsError()
-        return True
-
-    def parse_body(self):
-        try:
-            js = super(RimuHostingResponse, self).parse_body()
-            keys = list(js.keys())
-            if js[keys[0]]['response_type'] == "ERROR":
-                raise RimuHostingException(
-                    js[keys[0]]['human_readable_message']
-                )
-            return js[keys[0]]
-        except KeyError:
-            raise RimuHostingException('Could not parse body: %s'
-                                       % (self.body))
-
-
-class RimuHostingConnection(ConnectionKey):
-    """
-    Connection class for the RimuHosting driver
-    """
-
-    api_context = API_CONTEXT
-    host = API_HOST
-    port = 443
-    responseCls = RimuHostingResponse
-
-    def __init__(self, key, secure=True, retry_delay=None,
-                 backoff=None, timeout=None):
-        # override __init__ so that we can set secure of False for testing
-        ConnectionKey.__init__(self, key, secure, timeout=timeout,
-                               retry_delay=retry_delay, backoff=backoff)
-
-    def add_default_headers(self, headers):
-        # We want JSON back from the server. Could be application/xml
-        # (but JSON is better).
-        headers['Accept'] = 'application/json'
-        # Must encode all data as json, or override this header.
-        headers['Content-Type'] = 'application/json'
-
-        headers['Authorization'] = 'rimuhosting apikey=%s' % (self.key)
-        return headers
-
-    def request(self, action, params=None, data='', headers=None,
-                method='GET'):
-        if not headers:
-            headers = {}
-        if not params:
-            params = {}
-        # Override this method to prepend the api_context
-        return ConnectionKey.request(self, self.api_context + action,
-                                     params, data, headers, method)
-
-
-class RimuHostingNodeDriver(NodeDriver):
-    """
-    RimuHosting node driver
-    """
-
-    type = Provider.RIMUHOSTING
-    name = 'RimuHosting'
-    website = 'http://rimuhosting.com/'
-    connectionCls = RimuHostingConnection
-    features = {'create_node': ['password']}
-
-    def __init__(self, key, host=API_HOST, port=443,
-                 api_context=API_CONTEXT, secure=True):
-        """
-        :param    key: API key (required)
-        :type     key: ``str``
-
-        :param    host: hostname for connection
-        :type     host: ``str``
-
-        :param    port: Override port used for connections.
-        :type     port: ``int``
-
-        :param    api_context: Optional API context.
-        :type     api_context: ``str``
-
-        :param    secure: Weither to use HTTPS or HTTP.
-        :type     secure: ``bool``
-
-        :rtype: ``None``
-        """
-        # Pass in some extra vars so that
-        self.key = key
-        self.secure = secure
-        self.connection = self.connectionCls(key, secure)
-        self.connection.host = host
-        self.connection.api_context = api_context
-        self.connection.port = port
-        self.connection.driver = self
-        self.connection.connect()
-
-    def _order_uri(self, node, resource):
-        # Returns the order uri with its resourse appended.
-        return "/orders/%s/%s" % (node.id, resource)
-
-    # TODO: Get the node state.
-    def _to_node(self, order):
-        n = Node(id=order['slug'],
-                 name=order['domain_name'],
-                 state=NodeState.RUNNING,
-                 public_ips=(
-                     [order['allocated_ips']['primary_ip']] +
-                     order['allocated_ips']['secondary_ips']),
-                 private_ips=[],
-                 driver=self.connection.driver,
-                 extra={
-                     'order_oid': order['order_oid'],
-                     'monthly_recurring_fee': order.get(
-                         'billing_info').get('monthly_recurring_fee')})
-        return n
-
-    def _to_size(self, plan):
-        return NodeSize(
-            id=plan['pricing_plan_code'],
-            name=plan['pricing_plan_description'],
-            ram=plan['minimum_memory_mb'],
-            disk=plan['minimum_disk_gb'],
-            bandwidth=plan['minimum_data_transfer_allowance_gb'],
-            price=plan['monthly_recurring_amt']['amt_usd'],
-            driver=self.connection.driver
-        )
-
-    def _to_image(self, image):
-        return NodeImage(id=image['distro_code'],
-                         name=image['distro_description'],
-                         driver=self.connection.driver)
-
-    def list_sizes(self, location=None):
-        # Returns a list of sizes (aka plans)
-        # Get plans. Note this is really just for libcloud.
-        # We are happy with any size.
-        if location is None:
-            location = ''
-        else:
-            location = ";dc_location=%s" % (location.id)
-
-        res = self.connection.request(
-            '/pricing-plans;server-type=VPS%s' % (location)).object
-        return list(map(lambda x: self._to_size(x), res['pricing_plan_infos']))
-
-    def list_nodes(self):
-        # Returns a list of Nodes
-        # Will only include active ones.
-        res = self.connection.request('/orders;include_inactive=N').object
-        return list(map(lambda x: self._to_node(x), res['about_orders']))
-
-    def list_images(self, location=None):
-        # Get all base images.
-        # TODO: add other image sources. (Such as a backup of a VPS)
-        # All Images are available for use at all locations
-        res = self.connection.request('/distributions').object
-        return list(map(lambda x: self._to_image(x), res['distro_infos']))
-
-    def reboot_node(self, node):
-        # Reboot
-        # PUT the state of RESTARTING to restart a VPS.
-        # All data is encoded as JSON
-        data = {'reboot_request': {'running_state': 'RESTARTING'}}
-        uri = self._order_uri(node, 'vps/running-state')
-        self.connection.request(uri, data=json.dumps(data), method='PUT')
-        # XXX check that the response was actually successful
-        return True
-
-    def destroy_node(self, node):
-        # Shutdown a VPS.
-        uri = self._order_uri(node, 'vps')
-        self.connection.request(uri, method='DELETE')
-        # XXX check that the response was actually successful
-        return True
-
-    def create_node(self, **kwargs):
-        """Creates a RimuHosting instance
-
-        @inherits: :class:`NodeDriver.create_node`
-
-        :keyword    name: Must be a FQDN. e.g example.com.
-        :type       name: ``str``
-
-        :keyword    ex_billing_oid: If not set,
-                                    a billing method is automatically picked.
-        :type       ex_billing_oid: ``str``
-
-        :keyword    ex_host_server_oid: The host server to set the VPS up on.
-        :type       ex_host_server_oid: ``str``
-
-        :keyword    ex_vps_order_oid_to_clone: Clone another VPS to use as
-                                                the image for the new VPS.
-        :type       ex_vps_order_oid_to_clone: ``str``
-
-        :keyword    ex_num_ips: Number of IPs to allocate. Defaults to 1.
-        :type       ex_num_ips: ``int``
-
-        :keyword    ex_extra_ip_reason: Reason for needing the extra IPs.
-        :type       ex_extra_ip_reason: ``str``
-
-        :keyword    ex_memory_mb: Memory to allocate to the VPS.
-        :type       ex_memory_mb: ``int``
-
-        :keyword    ex_disk_space_mb: Diskspace to allocate to the VPS.
-            Defaults to 4096 (4GB).
-        :type       ex_disk_space_mb: ``int``
-
-        :keyword    ex_disk_space_2_mb: Secondary disk size allocation.
-                                        Disabled by default.
-        :type       ex_disk_space_2_mb: ``int``
-
-        :keyword    ex_control_panel: Control panel to install on the VPS.
-        :type       ex_control_panel: ``str``
-        """
-        # Note we don't do much error checking in this because we
-        # expect the API to error out if there is a problem.
-        name = kwargs['name']
-        image = kwargs['image']
-        size = kwargs['size']
-
-        data = {
-            'instantiation_options': {
-                'domain_name': name,
-                'distro': image.id
-            },
-            'pricing_plan_code': size.id,
-            'vps_parameters': {}
-        }
-
-        if 'ex_control_panel' in kwargs:
-            data['instantiation_options']['control_panel'] = \
-                kwargs['ex_control_panel']
-
-        auth = self._get_and_check_auth(kwargs.get('auth'))
-        data['instantiation_options']['password'] = auth.password
-
-        if 'ex_billing_oid' in kwargs:
-            # TODO check for valid oid.
-            data['billing_oid'] = kwargs['ex_billing_oid']
-
-        if 'ex_host_server_oid' in kwargs:
-            data['host_server_oid'] = kwargs['ex_host_server_oid']
-
-        if 'ex_vps_order_oid_to_clone' in kwargs:
-            data['vps_order_oid_to_clone'] = \
-                kwargs['ex_vps_order_oid_to_clone']
-
-        if 'ex_num_ips' in kwargs and int(kwargs['ex_num_ips']) > 1:
-            if 'ex_extra_ip_reason' not in kwargs:
-                raise RimuHostingException(
-                    'Need an reason for having an extra IP')
-            else:
-                if 'ip_request' not in data:
-                    data['ip_request'] = {}
-                data['ip_request']['num_ips'] = int(kwargs['ex_num_ips'])
-                data['ip_request']['extra_ip_reason'] = \
-                    kwargs['ex_extra_ip_reason']
-
-        if 'ex_memory_mb' in kwargs:
-            data['vps_parameters']['memory_mb'] = kwargs['ex_memory_mb']
-
-        if 'ex_disk_space_mb' in kwargs:
-            data['vps_parameters']['disk_space_mb'] = \
-                kwargs['ex_disk_space_mb']
-
-        if 'ex_disk_space_2_mb' in kwargs:
-            data['vps_parameters']['disk_space_2_mb'] =\
-                kwargs['ex_disk_space_2_mb']
-
-        # Don't send empty 'vps_parameters' attribute
-        if not data['vps_parameters']:
-            del data['vps_parameters']
-
-        res = self.connection.request(
-            '/orders/new-vps',
-            method='POST',
-            data=json.dumps({"new-vps": data})
-        ).object
-        node = self._to_node(res['about_order'])
-        node.extra['password'] = \
-            res['new_order_request']['instantiation_options']['password']
-        return node
-
-    def list_locations(self):
-        return [
-            NodeLocation('DCAUCKLAND', "RimuHosting Auckland", 'NZ', self),
-            NodeLocation('DCDALLAS', "RimuHosting Dallas", 'US', self),
-            NodeLocation('DCLONDON', "RimuHosting London", 'GB', self),
-            NodeLocation('DCSYDNEY', "RimuHosting Sydney", 'AU', self),
-        ]


[50/56] [abbrv] libcloud git commit: merge conflicts

Posted by an...@apache.org.
merge conflicts


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/363b024a
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/363b024a
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/363b024a

Branch: refs/heads/trunk
Commit: 363b024a60441e62d678de5ace85713aa8486233
Parents: c674922 908aa5b
Author: Anthony Shaw <an...@apache.org>
Authored: Thu Sep 22 19:41:53 2016 +1000
Committer: Anthony Shaw <an...@apache.org>
Committed: Thu Sep 22 19:41:53 2016 +1000

----------------------------------------------------------------------
 CHANGES.rst                                     |    2 +-
 docs/compute/drivers/azure.rst                  |   14 +-
 docs/compute/drivers/azure_arm.rst              |   54 +
 docs/examples/compute/azure_arm/instantiate.py  |    7 +
 libcloud/common/azure_arm.py                    |  124 ++
 libcloud/compute/drivers/azure_arm.py           | 1281 ++++++++++++++++++
 libcloud/compute/providers.py                   |    2 +
 libcloud/compute/types.py                       |    5 +-
 ...777_7777_7777_777777777777_oauth2_token.json |    1 +
 ...99999999999_providers_Microsoft_Compute.json |  200 +++
 ...rosoft_Compute_locations_eastus_vmSizes.json |   28 +
 libcloud/test/compute/test_azure_arm.py         |   69 +
 12 files changed, 1782 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/363b024a/CHANGES.rst
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/libcloud/blob/363b024a/libcloud/compute/types.py
----------------------------------------------------------------------
diff --cc libcloud/compute/types.py
index 740b688,9e96575..4fd25c5
--- a/libcloud/compute/types.py
+++ b/libcloud/compute/types.py
@@@ -59,111 -59,114 +59,114 @@@ class Provider(Type)
      """
      Defines for each of the supported providers
  
 +    Non-Dummy drivers are sorted in alphabetical order. Please preserve this
 +    ordering when adding new drivers.
 +
      :cvar DUMMY: Example provider
 -    :cvar EC2_US_EAST: Amazon AWS US N. Virgina
 -    :cvar EC2_US_WEST: Amazon AWS US N. California
 -    :cvar EC2_EU_WEST: Amazon AWS EU Ireland
 -    :cvar RACKSPACE: Rackspace next-gen OpenStack based Cloud Servers
 -    :cvar RACKSPACE_FIRST_GEN: Rackspace First Gen Cloud Servers
 +    :cvar ABIQUO: Abiquo driver
 +    :cvar ALIYUN_ECS: Aliyun ECS driver.
 +    :cvar AURORACOMPUTE: Aurora Compute driver.
-     :cvar AZURE: Azure driver.
++    :cvar AZURE: Azure (classic) driver.
++    :cvar AZURE_ARM: Azure Resource Manager (modern) driver.
 +    :cvar BLUEBOX: Bluebox
 +    :cvar CLOUDSIGMA: CloudSigma
 +    :cvar CLOUDSTACK: CloudStack
 +    :cvar DIMENSIONDATA: Dimension Data Cloud
 +    :cvar EC2: Amazon AWS.
 +    :cvar ECP: Enomaly
 +    :cvar ELASTICHOSTS: ElasticHosts.com
 +    :cvar EXOSCALE: Exoscale driver.
      :cvar GCE: Google Compute Engine
      :cvar GOGRID: GoGrid
 -    :cvar VPSNET: VPS.net
 -    :cvar LINODE: Linode.com
 -    :cvar VCLOUD: vmware vCloud
 -    :cvar RIMUHOSTING: RimuHosting.com
 -    :cvar ECP: Enomaly
 +    :cvar GRIDSPOT: Gridspot driver
      :cvar IBM: IBM Developer Cloud
 -    :cvar OPENNEBULA: OpenNebula.org
 -    :cvar ELASTICHOSTS: ElasticHosts.com
 -    :cvar CLOUDSIGMA: CloudSigma
 -    :cvar NIMBUS: Nimbus
 -    :cvar BLUEBOX: Bluebox
 -    :cvar OPSOURCE: Opsource Cloud
 -    :cvar DIMENSIONDATA: Dimension Data Cloud
 -    :cvar NINEFOLD: Ninefold
 -    :cvar TERREMARK: Terremark
 -    :cvar EC2_US_WEST_OREGON: Amazon AWS US West 2 (Oregon)
 -    :cvar CLOUDSTACK: CloudStack
 -    :cvar CLOUDSIGMA_US: CloudSigma US Las Vegas
 -    :cvar LIBVIRT: Libvirt driver
 +    :cvar IKOULA: Ikoula driver.
      :cvar JOYENT: Joyent driver
 -    :cvar VCL: VCL driver
      :cvar KTUCLOUD: kt ucloud driver
 -    :cvar GRIDSPOT: Gridspot driver
 -    :cvar ABIQUO: Abiquo driver
 +    :cvar LIBVIRT: Libvirt driver
 +    :cvar LINODE: Linode.com
      :cvar NEPHOSCALE: NephoScale driver
 -    :cvar EXOSCALE: Exoscale driver.
 -    :cvar IKOULA: Ikoula driver.
 -    :cvar OUTSCALE_SAS: Outscale SAS driver.
 +    :cvar NIMBUS: Nimbus
 +    :cvar NINEFOLD: Ninefold
 +    :cvar OPENNEBULA: OpenNebula.org
 +    :cvar OPSOURCE: Opsource Cloud
      :cvar OUTSCALE_INC: Outscale INC driver.
 +    :cvar OUTSCALE_SAS: Outscale SAS driver.
      :cvar PROFIT_BRICKS: ProfitBricks driver.
 +    :cvar RACKSPACE: Rackspace next-gen OpenStack based Cloud Servers
 +    :cvar RACKSPACE_FIRST_GEN: Rackspace First Gen Cloud Servers
 +    :cvar RIMUHOSTING: RimuHosting.com
 +    :cvar TERREMARK: Terremark
 +    :cvar VCL: VCL driver
 +    :cvar VCLOUD: vmware vCloud
 +    :cvar VPSNET: VPS.net
      :cvar VULTR: vultr driver.
 -    :cvar AZURE: Azure Service Manager (classic) driver.
 -    :cvar AZURE_ARM: Azure Resource Manager (modern) driver.
 -    :cvar AURORACOMPUTE: Aurora Compute driver.
 -    :cvar ALIYUN_ECS: Aliyun ECS driver.
      """
+     AZURE = 'azure'
+     AZURE_ARM = 'azure_arm'
      DUMMY = 'dummy'
 +    ABIQUO = 'abiquo'
 +    ALIYUN_ECS = 'aliyun_ecs'
 +    AURORACOMPUTE = 'aurora_compute'
 +    AZURE = 'azure'
 +    BLUEBOX = 'bluebox'
 +    BRIGHTBOX = 'brightbox'
 +    BSNL = 'bsnl'
 +    CISCOCCS = 'ciscoccs'
 +    CLOUDFRAMES = 'cloudframes'
 +    CLOUDSIGMA = 'cloudsigma'
 +    CLOUDSTACK = 'cloudstack'
 +    CLOUDWATT = 'cloudwatt'
 +    DIGITAL_OCEAN = 'digitalocean'
 +    DIMENSIONDATA = 'dimensiondata'
      EC2 = 'ec2'
 -    RACKSPACE = 'rackspace'
 +    ECP = 'ecp'
 +    ELASTICHOSTS = 'elastichosts'
 +    EUCALYPTUS = 'eucalyptus'
 +    EXOSCALE = 'exoscale'
 +    GANDI = 'gandi'
      GCE = 'gce'
      GOGRID = 'gogrid'
 -    VPSNET = 'vpsnet'
 -    LINODE = 'linode'
 -    VCLOUD = 'vcloud'
 -    RIMUHOSTING = 'rimuhosting'
 -    VOXEL = 'voxel'
 -    SOFTLAYER = 'softlayer'
 -    EUCALYPTUS = 'eucalyptus'
 -    ECP = 'ecp'
 +    GRIDSPOT = 'gridspot'
 +    HOSTVIRTUAL = 'hostvirtual'
      IBM = 'ibm'
 -    OPENNEBULA = 'opennebula'
 -    ELASTICHOSTS = 'elastichosts'
 -    BRIGHTBOX = 'brightbox'
 -    CLOUDSIGMA = 'cloudsigma'
 +    IKOULA = 'ikoula'
 +    INDOSAT = 'indosat'
 +    INTERNETSOLUTIONS = 'internetsolutions'
 +    JOYENT = 'joyent'
 +    KTUCLOUD = 'ktucloud'
 +    LIBVIRT = 'libvirt'
 +    LINODE = 'linode'
 +    MEDONE = 'medone'
 +    NEPHOSCALE = 'nephoscale'
      NIMBUS = 'nimbus'
 -    BLUEBOX = 'bluebox'
 -    GANDI = 'gandi'
 -    OPSOURCE = 'opsource'
 -    DIMENSIONDATA = 'dimensiondata'
 +    NINEFOLD = 'ninefold'
 +    NTTA = 'ntta'
 +    OPENNEBULA = 'opennebula'
      OPENSTACK = 'openstack'
 -    SKALICLOUD = 'skalicloud'
 +    OPSOURCE = 'opsource'
 +    OUTSCALE_INC = 'outscale_inc'
 +    OUTSCALE_SAS = 'outscale_sas'
 +    PACKET = 'packet'
 +    PROFIT_BRICKS = 'profitbricks'
 +    RACKSPACE = 'rackspace'
 +    RACKSPACE_FIRST_GEN = 'rackspace_first_gen'
 +    RIMUHOSTING = 'rimuhosting'
 +    RUNABOVE = 'runabove'
      SERVERLOVE = 'serverlove'
 -    NINEFOLD = 'ninefold'
 +    SKALICLOUD = 'skalicloud'
 +    SOFTLAYER = 'softlayer'
      TERREMARK = 'terremark'
 -    CLOUDSTACK = 'cloudstack'
 -    LIBVIRT = 'libvirt'
 -    JOYENT = 'joyent'
      VCL = 'vcl'
 -    KTUCLOUD = 'ktucloud'
 -    GRIDSPOT = 'gridspot'
 -    RACKSPACE_FIRST_GEN = 'rackspace_first_gen'
 -    HOSTVIRTUAL = 'hostvirtual'
 -    ABIQUO = 'abiquo'
 -    DIGITAL_OCEAN = 'digitalocean'
 -    NEPHOSCALE = 'nephoscale'
 -    CLOUDFRAMES = 'cloudframes'
 -    EXOSCALE = 'exoscale'
 -    IKOULA = 'ikoula'
 -    OUTSCALE_SAS = 'outscale_sas'
 -    OUTSCALE_INC = 'outscale_inc'
 +    VCLOUD = 'vcloud'
 +    VOXEL = 'voxel'
 +    VPSNET = 'vpsnet'
      VSPHERE = 'vsphere'
 -    PROFIT_BRICKS = 'profitbricks'
      VULTR = 'vultr'
 -    AURORACOMPUTE = 'aurora_compute'
 -    CLOUDWATT = 'cloudwatt'
 -    PACKET = 'packet'
 -    RUNABOVE = 'runabove'
 -    INTERNETSOLUTIONS = 'internetsolutions'
 -    INDOSAT = 'indosat'
 -    BSNL = 'bsnl'
 -    NTTA = 'ntta'
 -    MEDONE = 'medone'
 -    CISCOCCS = 'ciscoccs'
 -    ALIYUN_ECS = 'aliyun_ecs'
  
      # OpenStack based providers
 -    HPCLOUD = 'hpcloud'
      CLOUDWATT = 'cloudwatt'
 +    HPCLOUD = 'hpcloud'
      KILI = 'kili'
      ONAPP = 'onapp'
  


[05/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/backblaze_b2.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/backblaze_b2.py b/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/backblaze_b2.py
deleted file mode 100644
index fe2f335..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/backblaze_b2.py
+++ /dev/null
@@ -1,525 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-Driver for Backblaze B2 service.
-"""
-
-import base64
-import hashlib
-
-try:
-    import simplejson as json
-except ImportError:
-    import json
-
-from libcloud.utils.py3 import b
-from libcloud.utils.py3 import httplib
-from libcloud.utils.py3 import urlparse
-from libcloud.utils.py3 import next
-from libcloud.utils.files import read_in_chunks
-from libcloud.utils.files import exhaust_iterator
-from libcloud.utils.escape import sanitize_object_name
-
-from libcloud.common.base import ConnectionUserAndKey
-from libcloud.common.base import JsonResponse
-from libcloud.common.types import InvalidCredsError
-from libcloud.common.types import LibcloudError
-from libcloud.storage.providers import Provider
-from libcloud.storage.base import Object, Container, StorageDriver
-from libcloud.storage.types import ContainerDoesNotExistError
-from libcloud.storage.types import ObjectDoesNotExistError
-
-__all__ = [
-    'BackblazeB2StorageDriver',
-
-    'BackblazeB2Connection',
-    'BackblazeB2AuthConnection'
-]
-
-AUTH_API_HOST = 'api.backblaze.com'
-API_PATH = '/b2api/v1/'
-
-
-class BackblazeB2Response(JsonResponse):
-    def success(self):
-        return self.status in [httplib.OK, httplib.CREATED, httplib.ACCEPTED]
-
-    def parse_error(self):
-        status = int(self.status)
-        body = self.parse_body()
-
-        if status == httplib.UNAUTHORIZED:
-            raise InvalidCredsError(body['message'])
-
-        return self.body
-
-
-class BackblazeB2AuthConnection(ConnectionUserAndKey):
-    host = AUTH_API_HOST
-    secure = True
-    responseCls = BackblazeB2Response
-
-    def __init__(self, *args, **kwargs):
-        super(BackblazeB2AuthConnection, self).__init__(*args, **kwargs)
-
-        # Those attributes are populated after authentication
-        self.account_id = None
-        self.api_url = None
-        self.api_host = None
-        self.download_url = None
-        self.download_host = None
-        self.auth_token = None
-
-    def authenticate(self, force=False):
-        """
-        :param force: Force authentication if if we have already obtained the
-                      token.
-        :type force: ``bool``
-        """
-        if not self._is_authentication_needed(force=force):
-            return self
-
-        headers = {}
-        action = 'b2_authorize_account'
-        auth_b64 = base64.b64encode(b('%s:%s' % (self.user_id, self.key)))
-        headers['Authorization'] = 'Basic %s' % (auth_b64.decode('utf-8'))
-
-        action = API_PATH + 'b2_authorize_account'
-        resp = self.request(action=action, headers=headers, method='GET')
-
-        if resp.status == httplib.OK:
-            self._parse_and_set_auth_info(data=resp.object)
-        else:
-            raise Exception('Failed to authenticate: %s' % (str(resp.object)))
-
-        return self
-
-    def _parse_and_set_auth_info(self, data):
-        result = {}
-        self.account_id = data['accountId']
-        self.api_url = data['apiUrl']
-        self.download_url = data['downloadUrl']
-        self.auth_token = data['authorizationToken']
-
-        parsed_api_url = urlparse.urlparse(self.api_url)
-        self.api_host = parsed_api_url.netloc
-
-        parsed_download_url = urlparse.urlparse(self.download_url)
-        self.download_host = parsed_download_url.netloc
-
-        return result
-
-    def _is_authentication_needed(self, force=False):
-        if not self.auth_token or force:
-            return True
-
-        return False
-
-
-class BackblazeB2Connection(ConnectionUserAndKey):
-    host = None  # Note: host is set after authentication
-    secure = True
-    responseCls = BackblazeB2Response
-    authCls = BackblazeB2AuthConnection
-
-    def __init__(self, *args, **kwargs):
-        super(BackblazeB2Connection, self).__init__(*args, **kwargs)
-
-        # Stores info retrieved after authentication (auth token, api url,
-        # dowload url).
-        self._auth_conn = self.authCls(*args, **kwargs)
-
-    def download_request(self, action, params=None):
-        # Lazily perform authentication
-        auth_conn = self._auth_conn.authenticate()
-
-        # Set host to the download server
-        self.host = auth_conn.download_host
-
-        action = '/file/' + action
-        method = 'GET'
-        raw = True
-        response = self._request(auth_conn=auth_conn, action=action,
-                                 params=params, method=method,
-                                 raw=raw)
-        return response
-
-    def upload_request(self, action, headers, upload_host, auth_token, data):
-        # Lazily perform authentication
-        auth_conn = self._auth_conn.authenticate()
-
-        # Upload host is dynamically retrieved for each upload request
-        self.host = upload_host
-
-        method = 'POST'
-        raw = False
-        response = self._request(auth_conn=auth_conn, action=action,
-                                 params=None, data=data,
-                                 headers=headers, method=method,
-                                 raw=raw, auth_token=auth_token)
-        return response
-
-    def request(self, action, params=None, data=None, headers=None,
-                method='GET', raw=False, include_account_id=False):
-        params = params or {}
-        headers = headers or {}
-
-        # Lazily perform authentication
-        auth_conn = self._auth_conn.authenticate()
-
-        # Set host
-        self.host = auth_conn.api_host
-
-        # Include Content-Type
-        if not raw and data:
-            headers['Content-Type'] = 'application/json'
-
-        # Include account id
-        if include_account_id:
-            if method == 'GET':
-                params['accountId'] = auth_conn.account_id
-            elif method == 'POST':
-                data = data or {}
-                data['accountId'] = auth_conn.account_id
-
-        action = API_PATH + action
-        if data:
-            data = json.dumps(data)
-
-        response = self._request(auth_conn=self._auth_conn, action=action,
-                                 params=params, data=data,
-                                 method=method, headers=headers, raw=raw)
-        return response
-
-    def _request(self, auth_conn, action, params=None, data=None, headers=None,
-                 method='GET', raw=False, auth_token=None):
-        params = params or {}
-        headers = headers or {}
-
-        if not auth_token:
-            # If auth token is not explicitly provided, use the default one
-            auth_token = self._auth_conn.auth_token
-
-        # Include auth token
-        headers['Authorization'] = '%s' % (auth_token)
-        response = super(BackblazeB2Connection, self).request(action=action,
-                                                              params=params,
-                                                              data=data,
-                                                              method=method,
-                                                              headers=headers,
-                                                              raw=raw)
-        return response
-
-
-class BackblazeB2StorageDriver(StorageDriver):
-    connectionCls = BackblazeB2Connection
-    name = 'Backblaze B2'
-    website = 'https://www.backblaze.com/b2/'
-    type = Provider.BACKBLAZE_B2
-    hash_type = 'sha1'
-    supports_chunked_encoding = False
-
-    def iterate_containers(self):
-        resp = self.connection.request(action='b2_list_buckets',
-                                       method='GET',
-                                       include_account_id=True)
-        containers = self._to_containers(data=resp.object)
-        return containers
-
-    def iterate_container_objects(self, container):
-        # TODO: Support pagination
-        params = {'bucketId': container.extra['id']}
-        resp = self.connection.request(action='b2_list_file_names',
-                                       method='GET',
-                                       params=params)
-        objects = self._to_objects(data=resp.object, container=container)
-        return objects
-
-    def get_container(self, container_name):
-        containers = self.iterate_containers()
-        container = next((c for c in containers if c.name == container_name),
-                         None)
-        if container:
-            return container
-        else:
-            raise ContainerDoesNotExistError(value=None, driver=self,
-                                             container_name=container_name)
-
-    def get_object(self, container_name, object_name):
-        container = self.get_container(container_name=container_name)
-        objects = self.iterate_container_objects(container=container)
-
-        obj = next((obj for obj in objects if obj.name == object_name), None)
-
-        if obj is not None:
-            return obj
-        else:
-            raise ObjectDoesNotExistError(value=None, driver=self,
-                                          object_name=object_name)
-
-    def create_container(self, container_name, ex_type='allPrivate'):
-        data = {}
-        data['bucketName'] = container_name
-        data['bucketType'] = ex_type
-        resp = self.connection.request(action='b2_create_bucket',
-                                       data=data, method='POST',
-                                       include_account_id=True)
-        container = self._to_container(item=resp.object)
-        return container
-
-    def delete_container(self, container):
-        data = {}
-        data['bucketId'] = container.extra['id']
-        resp = self.connection.request(action='b2_delete_bucket',
-                                       data=data, method='POST',
-                                       include_account_id=True)
-        return resp.status == httplib.OK
-
-    def download_object(self, obj, destination_path, overwrite_existing=False,
-                        delete_on_failure=True):
-        action = self._get_object_download_path(container=obj.container,
-                                                obj=obj)
-        response = self.connection.download_request(action=action)
-
-        # TODO: Include metadata from response headers
-        return self._get_object(obj=obj, callback=self._save_object,
-                                response=response,
-                                callback_kwargs={
-                                    'obj': obj,
-                                    'response': response.response,
-                                    'destination_path': destination_path,
-                                    'overwrite_existing': overwrite_existing,
-                                    'delete_on_failure': delete_on_failure
-                                },
-                                success_status_code=httplib.OK)
-
-    def download_object_as_stream(self, obj, chunk_size=None):
-        action = self._get_object_download_path(container=obj.container,
-                                                obj=obj)
-        response = self.connection.download_request(action=action)
-
-        return self._get_object(obj=obj, callback=read_in_chunks,
-                                response=response,
-                                callback_kwargs={'iterator': response.response,
-                                                 'chunk_size': chunk_size},
-                                success_status_code=httplib.OK)
-
-    def upload_object(self, file_path, container, object_name, extra=None,
-                      verify_hash=True, headers=None):
-        """
-        Upload an object.
-
-        Note: This will override file with a same name if it already exists.
-        """
-        # Note: We don't use any of the base driver functions since Backblaze
-        # API requires you to provide SHA1 has upfront and the base methods
-        # don't support that
-
-        with open(file_path, 'rb') as fp:
-            iterator = iter(fp)
-            iterator = read_in_chunks(iterator=iterator)
-            data = exhaust_iterator(iterator=iterator)
-
-        obj = self._perform_upload(data=data, container=container,
-                                   object_name=object_name,
-                                   extra=extra,
-                                   verify_hash=verify_hash,
-                                   headers=headers)
-
-        return obj
-
-    def upload_object_via_stream(self, iterator, container, object_name,
-                                 extra=None, headers=None):
-        """
-        Upload an object.
-
-        Note: Backblaze does not yet support uploading via stream,
-        so this calls upload_object internally requiring the object data
-        to be loaded into memory at once
-        """
-
-        iterator = read_in_chunks(iterator=iterator)
-        data = exhaust_iterator(iterator=iterator)
-
-        obj = self._perform_upload(data=data, container=container,
-                                   object_name=object_name,
-                                   extra=extra,
-                                   headers=headers)
-
-        return obj
-
-    def delete_object(self, obj):
-        data = {}
-        data['fileName'] = obj.name
-        data['fileId'] = obj.extra['fileId']
-        resp = self.connection.request(action='b2_delete_file_version',
-                                       data=data, method='POST')
-        return resp.status == httplib.OK
-
-    def ex_get_object(self, object_id):
-        params = {}
-        params['fileId'] = object_id
-        resp = self.connection.request(action='b2_get_file_info',
-                                       method='GET',
-                                       params=params)
-        obj = self._to_object(item=resp.object, container=None)
-        return obj
-
-    def ex_hide_object(self, container_id, object_name):
-        data = {}
-        data['bucketId'] = container_id
-        data['fileName'] = object_name
-        resp = self.connection.request(action='b2_hide_file',
-                                       data=data, method='POST')
-        obj = self._to_object(item=resp.object, container=None)
-        return obj
-
-    def ex_list_object_versions(self, container_id, ex_start_file_name=None,
-                                ex_start_file_id=None, ex_max_file_count=None):
-        params = {}
-        params['bucketId'] = container_id
-
-        if ex_start_file_name:
-            params['startFileName'] = ex_start_file_name
-
-        if ex_start_file_id:
-            params['startFileId'] = ex_start_file_id
-
-        if ex_max_file_count:
-            params['maxFileCount'] = ex_max_file_count
-
-        resp = self.connection.request(action='b2_list_file_versions',
-                                       params=params, method='GET')
-        objects = self._to_objects(data=resp.object, container=None)
-        return objects
-
-    def ex_get_upload_data(self, container_id):
-        """
-        Retrieve information used for uploading files (upload url, auth token,
-        etc).
-
-        :rype: ``dict``
-        """
-        # TODO: This is static (AFAIK) so it could be cached
-        params = {}
-        params['bucketId'] = container_id
-        response = self.connection.request(action='b2_get_upload_url',
-                                           method='GET',
-                                           params=params)
-        return response.object
-
-    def ex_get_upload_url(self, container_id):
-        """
-        Retrieve URL used for file uploads.
-
-        :rtype: ``str``
-        """
-        result = self.ex_get_upload_data(container_id=container_id)
-        upload_url = result['uploadUrl']
-        return upload_url
-
-    def _to_containers(self, data):
-        result = []
-        for item in data['buckets']:
-            container = self._to_container(item=item)
-            result.append(container)
-
-        return result
-
-    def _to_container(self, item):
-        extra = {}
-        extra['id'] = item['bucketId']
-        extra['bucketType'] = item['bucketType']
-        container = Container(name=item['bucketName'], extra=extra,
-                              driver=self)
-        return container
-
-    def _to_objects(self, data, container):
-        result = []
-        for item in data['files']:
-            obj = self._to_object(item=item, container=container)
-            result.append(obj)
-
-        return result
-
-    def _to_object(self, item, container=None):
-        extra = {}
-        extra['fileId'] = item['fileId']
-        extra['uploadTimestamp'] = item.get('uploadTimestamp', None)
-        size = item.get('size', item.get('contentLength', None))
-        hash = item.get('contentSha1', None)
-        meta_data = item.get('fileInfo', {})
-        obj = Object(name=item['fileName'], size=size, hash=hash, extra=extra,
-                     meta_data=meta_data, container=container, driver=self)
-        return obj
-
-    def _get_object_download_path(self, container, obj):
-        """
-        Return a path used in the download requests.
-
-        :rtype: ``str``
-        """
-        path = container.name + '/' + obj.name
-        return path
-
-    def _perform_upload(self, data, container, object_name, extra=None,
-                        verify_hash=True, headers=None):
-
-        if isinstance(data, str):
-            data = bytearray(data)
-
-        object_name = sanitize_object_name(object_name)
-
-        extra = extra or {}
-        content_type = extra.get('content_type', 'b2/x-auto')
-        meta_data = extra.get('meta_data', {})
-
-        # Note: Backblaze API doesn't support chunked encoding and we need to
-        # provide Content-Length up front (this is one inside _upload_object):/
-        headers = headers or {}
-        headers['X-Bz-File-Name'] = object_name
-        headers['Content-Type'] = content_type
-
-        sha1 = hashlib.sha1()
-        sha1.update(b(data))
-        headers['X-Bz-Content-Sha1'] = sha1.hexdigest()
-
-        # Include optional meta-data (up to 10 items)
-        for key, value in meta_data:
-            # TODO: Encode / escape key
-            headers['X-Bz-Info-%s' % (key)] = value
-
-        upload_data = self.ex_get_upload_data(
-            container_id=container.extra['id'])
-        upload_token = upload_data['authorizationToken']
-        parsed_url = urlparse.urlparse(upload_data['uploadUrl'])
-
-        upload_host = parsed_url.netloc
-        request_path = parsed_url.path
-
-        response = self.connection.upload_request(action=request_path,
-                                                  headers=headers,
-                                                  upload_host=upload_host,
-                                                  auth_token=upload_token,
-                                                  data=data)
-
-        if response.status == httplib.OK:
-            obj = self._to_object(item=response.object, container=container)
-            return obj
-        else:
-            body = response.response.read()
-            raise LibcloudError('Upload failed. status_code=%s, body=%s' %
-                                (response.status, body), driver=self)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/cloudfiles.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/cloudfiles.py b/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/cloudfiles.py
deleted file mode 100644
index 2502d42..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/cloudfiles.py
+++ /dev/null
@@ -1,972 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from hashlib import sha1
-import hmac
-import os
-from time import time
-
-from libcloud.utils.py3 import httplib
-from libcloud.utils.py3 import urlencode
-
-try:
-    import simplejson as json
-except ImportError:
-    import json
-
-from libcloud.utils.py3 import PY3
-from libcloud.utils.py3 import b
-from libcloud.utils.py3 import urlquote
-
-if PY3:
-    from io import FileIO as file
-
-from libcloud.utils.files import read_in_chunks
-from libcloud.common.types import MalformedResponseError, LibcloudError
-from libcloud.common.base import Response, RawResponse
-
-from libcloud.storage.providers import Provider
-from libcloud.storage.base import Object, Container, StorageDriver
-from libcloud.storage.types import ContainerAlreadyExistsError
-from libcloud.storage.types import ContainerDoesNotExistError
-from libcloud.storage.types import ContainerIsNotEmptyError
-from libcloud.storage.types import ObjectDoesNotExistError
-from libcloud.storage.types import ObjectHashMismatchError
-from libcloud.storage.types import InvalidContainerNameError
-from libcloud.common.openstack import OpenStackBaseConnection
-from libcloud.common.openstack import OpenStackDriverMixin
-
-from libcloud.common.rackspace import AUTH_URL
-
-CDN_HOST = 'cdn.clouddrive.com'
-API_VERSION = 'v1.0'
-
-# Keys which are used to select a correct endpoint from the service catalog.
-INTERNAL_ENDPOINT_KEY = 'internalURL'
-PUBLIC_ENDPOINT_KEY = 'publicURL'
-
-
-class CloudFilesResponse(Response):
-    valid_response_codes = [httplib.NOT_FOUND, httplib.CONFLICT]
-
-    def success(self):
-        i = int(self.status)
-        return i >= 200 and i <= 299 or i in self.valid_response_codes
-
-    def parse_body(self):
-        if not self.body:
-            return None
-
-        if 'content-type' in self.headers:
-            key = 'content-type'
-        elif 'Content-Type' in self.headers:
-            key = 'Content-Type'
-        else:
-            raise LibcloudError('Missing content-type header')
-
-        content_type = self.headers[key]
-        if content_type.find(';') != -1:
-            content_type = content_type.split(';')[0]
-
-        if content_type == 'application/json':
-            try:
-                data = json.loads(self.body)
-            except:
-                raise MalformedResponseError('Failed to parse JSON',
-                                             body=self.body,
-                                             driver=CloudFilesStorageDriver)
-        elif content_type == 'text/plain':
-            data = self.body
-        else:
-            data = self.body
-
-        return data
-
-
-class CloudFilesRawResponse(CloudFilesResponse, RawResponse):
-    pass
-
-
-class OpenStackSwiftConnection(OpenStackBaseConnection):
-    """
-    Connection class for the OpenStack Swift endpoint.
-    """
-
-    responseCls = CloudFilesResponse
-    rawResponseCls = CloudFilesRawResponse
-
-    auth_url = AUTH_URL
-    _auth_version = '1.0'
-
-    # TODO: Reverse the relationship - Swift -> CloudFiles
-    def __init__(self, user_id, key, secure=True, **kwargs):
-        # Ignore this for now
-        kwargs.pop('use_internal_url', None)
-        super(OpenStackSwiftConnection, self).__init__(user_id, key,
-                                                       secure=secure,
-                                                       **kwargs)
-        self.api_version = API_VERSION
-        self.accept_format = 'application/json'
-
-        self._service_type = self._ex_force_service_type or 'object-store'
-        self._service_name = self._ex_force_service_name or 'swift'
-
-        if self._ex_force_service_region:
-            self._service_region = self._ex_force_service_region
-        else:
-            self._service_region = None
-
-    def get_endpoint(self, *args, **kwargs):
-        if '2.0' in self._auth_version:
-            endpoint = self.service_catalog.get_endpoint(
-                service_type=self._service_type,
-                name=self._service_name,
-                region=self._service_region)
-        elif ('1.1' in self._auth_version) or ('1.0' in self._auth_version):
-            endpoint = self.service_catalog.get_endpoint(
-                name=self._service_name, region=self._service_region)
-
-        if endpoint:
-            return endpoint.url
-        else:
-            raise LibcloudError('Could not find specified endpoint')
-
-    def request(self, action, params=None, data='', headers=None, method='GET',
-                raw=False, cdn_request=False):
-        if not headers:
-            headers = {}
-        if not params:
-            params = {}
-
-        self.cdn_request = cdn_request
-        params['format'] = 'json'
-
-        if method in ['POST', 'PUT'] and 'Content-Type' not in headers:
-            headers.update({'Content-Type': 'application/json; charset=UTF-8'})
-
-        return super(OpenStackSwiftConnection, self).request(
-            action=action,
-            params=params, data=data,
-            method=method, headers=headers,
-            raw=raw)
-
-
-class CloudFilesConnection(OpenStackSwiftConnection):
-    """
-    Base connection class for the Cloudfiles driver.
-    """
-
-    responseCls = CloudFilesResponse
-    rawResponseCls = CloudFilesRawResponse
-
-    auth_url = AUTH_URL
-    _auth_version = '2.0'
-
-    def __init__(self, user_id, key, secure=True,
-                 use_internal_url=False, **kwargs):
-        super(CloudFilesConnection, self).__init__(user_id, key, secure=secure,
-                                                   **kwargs)
-        self.api_version = API_VERSION
-        self.accept_format = 'application/json'
-        self.cdn_request = False
-        self.use_internal_url = use_internal_url
-
-    def get_endpoint(self):
-        region = self._ex_force_service_region.upper()
-
-        if self.use_internal_url:
-            endpoint_type = 'internal'
-        else:
-            endpoint_type = 'external'
-
-        if '2.0' in self._auth_version:
-            ep = self.service_catalog.get_endpoint(
-                service_type='object-store',
-                name='cloudFiles',
-                region=region,
-                endpoint_type=endpoint_type)
-            cdn_ep = self.service_catalog.get_endpoint(
-                service_type='rax:object-cdn',
-                name='cloudFilesCDN',
-                region=region,
-                endpoint_type=endpoint_type)
-        else:
-            raise LibcloudError(
-                'Auth version "%s" not supported' % (self._auth_version))
-
-        # if this is a CDN request, return the cdn url instead
-        if self.cdn_request:
-            ep = cdn_ep
-
-        if not ep or not ep.url:
-            raise LibcloudError('Could not find specified endpoint')
-
-        return ep.url
-
-    def request(self, action, params=None, data='', headers=None, method='GET',
-                raw=False, cdn_request=False):
-        if not headers:
-            headers = {}
-        if not params:
-            params = {}
-
-        self.cdn_request = cdn_request
-        params['format'] = 'json'
-
-        if method in ['POST', 'PUT'] and 'Content-Type' not in headers:
-            headers.update({'Content-Type': 'application/json; charset=UTF-8'})
-
-        return super(CloudFilesConnection, self).request(
-            action=action,
-            params=params, data=data,
-            method=method, headers=headers,
-            raw=raw, cdn_request=cdn_request)
-
-
-class CloudFilesStorageDriver(StorageDriver, OpenStackDriverMixin):
-    """
-    CloudFiles driver.
-    """
-    name = 'CloudFiles'
-    website = 'http://www.rackspace.com/'
-
-    connectionCls = CloudFilesConnection
-    hash_type = 'md5'
-    supports_chunked_encoding = True
-
-    def __init__(self, key, secret=None, secure=True, host=None, port=None,
-                 region='ord', use_internal_url=False, **kwargs):
-        """
-        @inherits:  :class:`StorageDriver.__init__`
-
-        :param region: ID of the region which should be used.
-        :type region: ``str``
-        """
-        # This is here for backard compatibility
-        if 'ex_force_service_region' in kwargs:
-            region = kwargs['ex_force_service_region']
-
-        self.use_internal_url = use_internal_url
-        OpenStackDriverMixin.__init__(self, (), **kwargs)
-        super(CloudFilesStorageDriver, self).__init__(key=key, secret=secret,
-                                                      secure=secure, host=host,
-                                                      port=port, region=region,
-                                                      **kwargs)
-
-    @classmethod
-    def list_regions(cls):
-        return ['ord', 'dfw', 'iad', 'lon', 'hkg', 'syd']
-
-    def iterate_containers(self):
-        response = self.connection.request('')
-
-        if response.status == httplib.NO_CONTENT:
-            return []
-        elif response.status == httplib.OK:
-            return self._to_container_list(json.loads(response.body))
-
-        raise LibcloudError('Unexpected status code: %s' % (response.status))
-
-    def get_container(self, container_name):
-        container_name_encoded = self._encode_container_name(container_name)
-        response = self.connection.request('/%s' % (container_name_encoded),
-                                           method='HEAD')
-
-        if response.status == httplib.NO_CONTENT:
-            container = self._headers_to_container(
-                container_name, response.headers)
-            return container
-        elif response.status == httplib.NOT_FOUND:
-            raise ContainerDoesNotExistError(None, self, container_name)
-
-        raise LibcloudError('Unexpected status code: %s' % (response.status))
-
-    def get_object(self, container_name, object_name):
-        container = self.get_container(container_name)
-        container_name_encoded = self._encode_container_name(container_name)
-        object_name_encoded = self._encode_object_name(object_name)
-
-        response = self.connection.request('/%s/%s' % (container_name_encoded,
-                                                       object_name_encoded),
-                                           method='HEAD')
-        if response.status in [httplib.OK, httplib.NO_CONTENT]:
-            obj = self._headers_to_object(
-                object_name, container, response.headers)
-            return obj
-        elif response.status == httplib.NOT_FOUND:
-            raise ObjectDoesNotExistError(None, self, object_name)
-
-        raise LibcloudError('Unexpected status code: %s' % (response.status))
-
-    def get_container_cdn_url(self, container):
-        # pylint: disable=unexpected-keyword-arg
-        container_name_encoded = self._encode_container_name(container.name)
-        response = self.connection.request('/%s' % (container_name_encoded),
-                                           method='HEAD',
-                                           cdn_request=True)
-
-        if response.status == httplib.NO_CONTENT:
-            cdn_url = response.headers['x-cdn-uri']
-            return cdn_url
-        elif response.status == httplib.NOT_FOUND:
-            raise ContainerDoesNotExistError(value='',
-                                             container_name=container.name,
-                                             driver=self)
-
-        raise LibcloudError('Unexpected status code: %s' % (response.status))
-
-    def get_object_cdn_url(self, obj):
-        container_cdn_url = self.get_container_cdn_url(container=obj.container)
-        return '%s/%s' % (container_cdn_url, obj.name)
-
-    def enable_container_cdn(self, container, ex_ttl=None):
-        """
-        @inherits: :class:`StorageDriver.enable_container_cdn`
-
-        :param ex_ttl: cache time to live
-        :type ex_ttl: ``int``
-        """
-        container_name = self._encode_container_name(container.name)
-        headers = {'X-CDN-Enabled': 'True'}
-
-        if ex_ttl:
-            headers['X-TTL'] = ex_ttl
-
-        # pylint: disable=unexpected-keyword-arg
-        response = self.connection.request('/%s' % (container_name),
-                                           method='PUT',
-                                           headers=headers,
-                                           cdn_request=True)
-
-        return response.status in [httplib.CREATED, httplib.ACCEPTED]
-
-    def create_container(self, container_name):
-        container_name_encoded = self._encode_container_name(container_name)
-        response = self.connection.request(
-            '/%s' % (container_name_encoded), method='PUT')
-
-        if response.status == httplib.CREATED:
-            # Accepted mean that container is not yet created but it will be
-            # eventually
-            extra = {'object_count': 0}
-            container = Container(name=container_name,
-                                  extra=extra, driver=self)
-
-            return container
-        elif response.status == httplib.ACCEPTED:
-            error = ContainerAlreadyExistsError(None, self, container_name)
-            raise error
-
-        raise LibcloudError('Unexpected status code: %s' % (response.status))
-
-    def delete_container(self, container):
-        name = self._encode_container_name(container.name)
-
-        # Only empty container can be deleted
-        response = self.connection.request('/%s' % (name), method='DELETE')
-
-        if response.status == httplib.NO_CONTENT:
-            return True
-        elif response.status == httplib.NOT_FOUND:
-            raise ContainerDoesNotExistError(value='',
-                                             container_name=name, driver=self)
-        elif response.status == httplib.CONFLICT:
-            # @TODO: Add "delete_all_objects" parameter?
-            raise ContainerIsNotEmptyError(value='',
-                                           container_name=name, driver=self)
-
-    def download_object(self, obj, destination_path, overwrite_existing=False,
-                        delete_on_failure=True):
-        container_name = obj.container.name
-        object_name = obj.name
-        response = self.connection.request('/%s/%s' % (container_name,
-                                                       object_name),
-                                           method='GET', raw=True)
-
-        return self._get_object(
-            obj=obj, callback=self._save_object, response=response,
-            callback_kwargs={'obj': obj,
-                             'response': response.response,
-                             'destination_path': destination_path,
-                             'overwrite_existing': overwrite_existing,
-                             'delete_on_failure': delete_on_failure},
-            success_status_code=httplib.OK)
-
-    def download_object_as_stream(self, obj, chunk_size=None):
-        container_name = obj.container.name
-        object_name = obj.name
-        response = self.connection.request('/%s/%s' % (container_name,
-                                                       object_name),
-                                           method='GET', raw=True)
-
-        return self._get_object(obj=obj, callback=read_in_chunks,
-                                response=response,
-                                callback_kwargs={'iterator': response.response,
-                                                 'chunk_size': chunk_size},
-                                success_status_code=httplib.OK)
-
-    def upload_object(self, file_path, container, object_name, extra=None,
-                      verify_hash=True, headers=None):
-        """
-        Upload an object.
-
-        Note: This will override file with a same name if it already exists.
-        """
-        upload_func = self._upload_file
-        upload_func_kwargs = {'file_path': file_path}
-
-        return self._put_object(container=container, object_name=object_name,
-                                upload_func=upload_func,
-                                upload_func_kwargs=upload_func_kwargs,
-                                extra=extra, file_path=file_path,
-                                verify_hash=verify_hash, headers=headers)
-
-    def upload_object_via_stream(self, iterator,
-                                 container, object_name, extra=None,
-                                 headers=None):
-        if isinstance(iterator, file):
-            iterator = iter(iterator)
-
-        upload_func = self._stream_data
-        upload_func_kwargs = {'iterator': iterator}
-
-        return self._put_object(container=container, object_name=object_name,
-                                upload_func=upload_func,
-                                upload_func_kwargs=upload_func_kwargs,
-                                extra=extra, iterator=iterator,
-                                headers=headers)
-
-    def delete_object(self, obj):
-        container_name = self._encode_container_name(obj.container.name)
-        object_name = self._encode_object_name(obj.name)
-
-        response = self.connection.request(
-            '/%s/%s' % (container_name, object_name), method='DELETE')
-
-        if response.status == httplib.NO_CONTENT:
-            return True
-        elif response.status == httplib.NOT_FOUND:
-            raise ObjectDoesNotExistError(value='', object_name=object_name,
-                                          driver=self)
-
-        raise LibcloudError('Unexpected status code: %s' % (response.status))
-
-    def ex_purge_object_from_cdn(self, obj, email=None):
-        """
-        Purge edge cache for the specified object.
-
-        :param email: Email where a notification will be sent when the job
-        completes. (optional)
-        :type email: ``str``
-        """
-        container_name = self._encode_container_name(obj.container.name)
-        object_name = self._encode_object_name(obj.name)
-        headers = {'X-Purge-Email': email} if email else {}
-
-        # pylint: disable=unexpected-keyword-arg
-        response = self.connection.request('/%s/%s' % (container_name,
-                                                       object_name),
-                                           method='DELETE',
-                                           headers=headers,
-                                           cdn_request=True)
-
-        return response.status == httplib.NO_CONTENT
-
-    def ex_get_meta_data(self):
-        """
-        Get meta data
-
-        :rtype: ``dict``
-        """
-        response = self.connection.request('', method='HEAD')
-
-        if response.status == httplib.NO_CONTENT:
-            container_count = response.headers.get(
-                'x-account-container-count', 'unknown')
-            object_count = response.headers.get(
-                'x-account-object-count', 'unknown')
-            bytes_used = response.headers.get(
-                'x-account-bytes-used', 'unknown')
-            temp_url_key = response.headers.get(
-                'x-account-meta-temp-url-key', None)
-
-            return {'container_count': int(container_count),
-                    'object_count': int(object_count),
-                    'bytes_used': int(bytes_used),
-                    'temp_url_key': temp_url_key}
-
-        raise LibcloudError('Unexpected status code: %s' % (response.status))
-
-    def ex_multipart_upload_object(self, file_path, container, object_name,
-                                   chunk_size=33554432, extra=None,
-                                   verify_hash=True):
-        object_size = os.path.getsize(file_path)
-        if object_size < chunk_size:
-            return self.upload_object(file_path, container, object_name,
-                                      extra=extra, verify_hash=verify_hash)
-
-        iter_chunk_reader = FileChunkReader(file_path, chunk_size)
-
-        for index, iterator in enumerate(iter_chunk_reader):
-            self._upload_object_part(container=container,
-                                     object_name=object_name,
-                                     part_number=index,
-                                     iterator=iterator,
-                                     verify_hash=verify_hash)
-
-        return self._upload_object_manifest(container=container,
-                                            object_name=object_name,
-                                            extra=extra,
-                                            verify_hash=verify_hash)
-
-    def ex_enable_static_website(self, container, index_file='index.html'):
-        """
-        Enable serving a static website.
-
-        :param container: Container instance
-        :type container: :class:`Container`
-
-        :param index_file: Name of the object which becomes an index page for
-        every sub-directory in this container.
-        :type index_file: ``str``
-
-        :rtype: ``bool``
-        """
-        container_name = container.name
-        headers = {'X-Container-Meta-Web-Index': index_file}
-
-        # pylint: disable=unexpected-keyword-arg
-        response = self.connection.request('/%s' % (container_name),
-                                           method='POST',
-                                           headers=headers,
-                                           cdn_request=False)
-
-        return response.status in [httplib.CREATED, httplib.ACCEPTED]
-
-    def ex_set_error_page(self, container, file_name='error.html'):
-        """
-        Set a custom error page which is displayed if file is not found and
-        serving of a static website is enabled.
-
-        :param container: Container instance
-        :type container: :class:`Container`
-
-        :param file_name: Name of the object which becomes the error page.
-        :type file_name: ``str``
-
-        :rtype: ``bool``
-        """
-        container_name = container.name
-        headers = {'X-Container-Meta-Web-Error': file_name}
-
-        # pylint: disable=unexpected-keyword-arg
-        response = self.connection.request('/%s' % (container_name),
-                                           method='POST',
-                                           headers=headers,
-                                           cdn_request=False)
-
-        return response.status in [httplib.CREATED, httplib.ACCEPTED]
-
-    def ex_set_account_metadata_temp_url_key(self, key):
-        """
-        Set the metadata header X-Account-Meta-Temp-URL-Key on your Cloud
-        Files account.
-
-        :param key: X-Account-Meta-Temp-URL-Key
-        :type key: ``str``
-
-        :rtype: ``bool``
-        """
-        headers = {'X-Account-Meta-Temp-URL-Key': key}
-
-        # pylint: disable=unexpected-keyword-arg
-        response = self.connection.request('',
-                                           method='POST',
-                                           headers=headers,
-                                           cdn_request=False)
-
-        return response.status in [httplib.OK, httplib.NO_CONTENT,
-                                   httplib.CREATED, httplib.ACCEPTED]
-
-    def ex_get_object_temp_url(self, obj, method='GET', timeout=60):
-        """
-        Create a temporary URL to allow others to retrieve or put objects
-        in your Cloud Files account for as long or as short a time as you
-        wish.  This method is specifically for allowing users to retrieve
-        or update an object.
-
-        :param obj: The object that you wish to make temporarily public
-        :type obj: :class:`Object`
-
-        :param method: Which method you would like to allow, 'PUT' or 'GET'
-        :type method: ``str``
-
-        :param timeout: Time (in seconds) after which you want the TempURL
-        to expire.
-        :type timeout: ``int``
-
-        :rtype: ``bool``
-        """
-        # pylint: disable=no-member
-        self.connection._populate_hosts_and_request_paths()
-        expires = int(time() + timeout)
-        path = '%s/%s/%s' % (self.connection.request_path,
-                             obj.container.name, obj.name)
-        try:
-            key = self.ex_get_meta_data()['temp_url_key']
-            assert key is not None
-        except Exception:
-            raise KeyError('You must first set the ' +
-                           'X-Account-Meta-Temp-URL-Key header on your ' +
-                           'Cloud Files account using ' +
-                           'ex_set_account_metadata_temp_url_key before ' +
-                           'you can use this method.')
-        hmac_body = '%s\n%s\n%s' % (method, expires, path)
-        sig = hmac.new(b(key), b(hmac_body), sha1).hexdigest()
-        params = urlencode({'temp_url_sig': sig,
-                            'temp_url_expires': expires})
-
-        temp_url = 'https://%s/%s/%s?%s' %\
-                   (self.connection.host + self.connection.request_path,
-                    obj.container.name, obj.name, params)
-
-        return temp_url
-
-    def _upload_object_part(self, container, object_name, part_number,
-                            iterator, verify_hash=True):
-        upload_func = self._stream_data
-        upload_func_kwargs = {'iterator': iterator}
-        part_name = object_name + '/%08d' % part_number
-        extra = {'content_type': 'application/octet-stream'}
-
-        self._put_object(container=container,
-                         object_name=part_name,
-                         upload_func=upload_func,
-                         upload_func_kwargs=upload_func_kwargs,
-                         extra=extra, iterator=iterator,
-                         verify_hash=verify_hash)
-
-    def _upload_object_manifest(self, container, object_name, extra=None,
-                                verify_hash=True):
-        extra = extra or {}
-        meta_data = extra.get('meta_data')
-
-        container_name_encoded = self._encode_container_name(container.name)
-        object_name_encoded = self._encode_object_name(object_name)
-        request_path = '/%s/%s' % (container_name_encoded, object_name_encoded)
-
-        # pylint: disable=no-member
-        headers = {'X-Auth-Token': self.connection.auth_token,
-                   'X-Object-Manifest': '%s/%s/' %
-                                        (container_name_encoded,
-                                         object_name_encoded)}
-
-        data = ''
-        response = self.connection.request(request_path,
-                                           method='PUT', data=data,
-                                           headers=headers, raw=True)
-
-        object_hash = None
-
-        if verify_hash:
-            hash_function = self._get_hash_function()
-            hash_function.update(b(data))
-            data_hash = hash_function.hexdigest()
-            object_hash = response.headers.get('etag')
-
-            if object_hash != data_hash:
-                raise ObjectHashMismatchError(
-                    value=('MD5 hash checksum does not match (expected=%s, ' +
-                           'actual=%s)') %
-                          (data_hash, object_hash),
-                    object_name=object_name, driver=self)
-
-        obj = Object(name=object_name, size=0, hash=object_hash, extra=None,
-                     meta_data=meta_data, container=container, driver=self)
-
-        return obj
-
-    def list_container_objects(self, container, ex_prefix=None):
-        """
-        Return a list of objects for the given container.
-
-        :param container: Container instance.
-        :type container: :class:`Container`
-
-        :param ex_prefix: Only get objects with names starting with ex_prefix
-        :type ex_prefix: ``str``
-
-        :return: A list of Object instances.
-        :rtype: ``list`` of :class:`Object`
-        """
-        return list(self.iterate_container_objects(container,
-                                                   ex_prefix=ex_prefix))
-
-    def iterate_container_objects(self, container, ex_prefix=None):
-        """
-        Return a generator of objects for the given container.
-
-        :param container: Container instance
-        :type container: :class:`Container`
-
-        :param ex_prefix: Only get objects with names starting with ex_prefix
-        :type ex_prefix: ``str``
-
-        :return: A generator of Object instances.
-        :rtype: ``generator`` of :class:`Object`
-        """
-        params = {}
-        if ex_prefix:
-            params['prefix'] = ex_prefix
-
-        while True:
-            container_name_encoded = \
-                self._encode_container_name(container.name)
-            response = self.connection.request('/%s' %
-                                               (container_name_encoded),
-                                               params=params)
-
-            if response.status == httplib.NO_CONTENT:
-                # Empty or non-existent container
-                break
-            elif response.status == httplib.OK:
-                objects = self._to_object_list(json.loads(response.body),
-                                               container)
-
-                if len(objects) == 0:
-                    break
-
-                for obj in objects:
-                    yield obj
-                params['marker'] = obj.name
-
-            else:
-                raise LibcloudError('Unexpected status code: %s' %
-                                    (response.status))
-
-    def _put_object(self, container, object_name, upload_func,
-                    upload_func_kwargs, extra=None, file_path=None,
-                    iterator=None, verify_hash=True, headers=None):
-        extra = extra or {}
-        container_name_encoded = self._encode_container_name(container.name)
-        object_name_encoded = self._encode_object_name(object_name)
-        content_type = extra.get('content_type', None)
-        meta_data = extra.get('meta_data', None)
-        content_disposition = extra.get('content_disposition', None)
-
-        headers = headers or {}
-        if meta_data:
-            for key, value in list(meta_data.items()):
-                key = 'X-Object-Meta-%s' % (key)
-                headers[key] = value
-
-        if content_disposition is not None:
-            headers['Content-Disposition'] = content_disposition
-
-        request_path = '/%s/%s' % (container_name_encoded, object_name_encoded)
-        result_dict = self._upload_object(
-            object_name=object_name, content_type=content_type,
-            upload_func=upload_func, upload_func_kwargs=upload_func_kwargs,
-            request_path=request_path, request_method='PUT',
-            headers=headers, file_path=file_path, iterator=iterator)
-
-        response = result_dict['response'].response
-        bytes_transferred = result_dict['bytes_transferred']
-        server_hash = result_dict['response'].headers.get('etag', None)
-
-        if response.status == httplib.EXPECTATION_FAILED:
-            raise LibcloudError(value='Missing content-type header',
-                                driver=self)
-        elif verify_hash and not server_hash:
-            raise LibcloudError(value='Server didn\'t return etag',
-                                driver=self)
-        elif (verify_hash and result_dict['data_hash'] != server_hash):
-            raise ObjectHashMismatchError(
-                value=('MD5 hash checksum does not match (expected=%s, ' +
-                       'actual=%s)') % (result_dict['data_hash'], server_hash),
-                object_name=object_name, driver=self)
-        elif response.status == httplib.CREATED:
-            obj = Object(
-                name=object_name, size=bytes_transferred, hash=server_hash,
-                extra=None, meta_data=meta_data, container=container,
-                driver=self)
-
-            return obj
-        else:
-            # @TODO: Add test case for this condition (probably 411)
-            raise LibcloudError('status_code=%s' % (response.status),
-                                driver=self)
-
-    def _encode_container_name(self, name):
-        """
-        Encode container name so it can be used as part of the HTTP request.
-        """
-        if name.startswith('/'):
-            name = name[1:]
-        name = urlquote(name)
-
-        if name.find('/') != -1:
-            raise InvalidContainerNameError(value='Container name cannot'
-                                                  ' contain slashes',
-                                            container_name=name, driver=self)
-
-        if len(name) > 256:
-            raise InvalidContainerNameError(
-                value='Container name cannot be longer than 256 bytes',
-                container_name=name, driver=self)
-
-        return name
-
-    def _encode_object_name(self, name):
-        name = urlquote(name)
-        return name
-
-    def _to_container_list(self, response):
-        # @TODO: Handle more than 10k containers - use "lazy list"?
-        for container in response:
-            extra = {'object_count': int(container['count']),
-                     'size': int(container['bytes'])}
-            yield Container(name=container['name'], extra=extra, driver=self)
-
-    def _to_object_list(self, response, container):
-        objects = []
-
-        for obj in response:
-            name = obj['name']
-            size = int(obj['bytes'])
-            hash = obj['hash']
-            extra = {'content_type': obj['content_type'],
-                     'last_modified': obj['last_modified']}
-            objects.append(Object(
-                name=name, size=size, hash=hash, extra=extra,
-                meta_data=None, container=container, driver=self))
-
-        return objects
-
-    def _headers_to_container(self, name, headers):
-        size = int(headers.get('x-container-bytes-used', 0))
-        object_count = int(headers.get('x-container-object-count', 0))
-
-        extra = {'object_count': object_count,
-                 'size': size}
-        container = Container(name=name, extra=extra, driver=self)
-        return container
-
-    def _headers_to_object(self, name, container, headers):
-        size = int(headers.pop('content-length', 0))
-        last_modified = headers.pop('last-modified', None)
-        etag = headers.pop('etag', None)
-        content_type = headers.pop('content-type', None)
-
-        meta_data = {}
-        for key, value in list(headers.items()):
-            if key.find('x-object-meta-') != -1:
-                key = key.replace('x-object-meta-', '')
-                meta_data[key] = value
-
-        extra = {'content_type': content_type, 'last_modified': last_modified}
-
-        obj = Object(name=name, size=size, hash=etag, extra=extra,
-                     meta_data=meta_data, container=container, driver=self)
-        return obj
-
-    def _ex_connection_class_kwargs(self):
-        kwargs = self.openstack_connection_kwargs()
-        kwargs['ex_force_service_region'] = self.region
-        kwargs['use_internal_url'] = self.use_internal_url
-        return kwargs
-
-
-class OpenStackSwiftStorageDriver(CloudFilesStorageDriver):
-    """
-    Storage driver for the OpenStack Swift.
-    """
-    type = Provider.CLOUDFILES_SWIFT
-    name = 'OpenStack Swift'
-    connectionCls = OpenStackSwiftConnection
-
-    # TODO: Reverse the relationship - Swift -> CloudFiles
-
-    def __init__(self, key, secret=None, secure=True, host=None, port=None,
-                 region=None, **kwargs):
-        super(OpenStackSwiftStorageDriver, self).__init__(key=key,
-                                                          secret=secret,
-                                                          secure=secure,
-                                                          host=host,
-                                                          port=port,
-                                                          region=region,
-                                                          **kwargs)
-
-
-class FileChunkReader(object):
-    def __init__(self, file_path, chunk_size):
-        self.file_path = file_path
-        self.total = os.path.getsize(file_path)
-        self.chunk_size = chunk_size
-        self.bytes_read = 0
-        self.stop_iteration = False
-
-    def __iter__(self):
-        return self
-
-    def next(self):
-        if self.stop_iteration:
-            raise StopIteration
-
-        start_block = self.bytes_read
-        end_block = start_block + self.chunk_size
-        if end_block >= self.total:
-            end_block = self.total
-            self.stop_iteration = True
-        self.bytes_read += end_block - start_block
-        return ChunkStreamReader(file_path=self.file_path,
-                                 start_block=start_block,
-                                 end_block=end_block,
-                                 chunk_size=8192)
-
-    def __next__(self):
-        return self.next()
-
-
-class ChunkStreamReader(object):
-    def __init__(self, file_path, start_block, end_block, chunk_size):
-        self.fd = open(file_path, 'rb')
-        self.fd.seek(start_block)
-        self.start_block = start_block
-        self.end_block = end_block
-        self.chunk_size = chunk_size
-        self.bytes_read = 0
-        self.stop_iteration = False
-
-    def __iter__(self):
-        return self
-
-    def next(self):
-        if self.stop_iteration:
-            self.fd.close()
-            raise StopIteration
-
-        block_size = self.chunk_size
-        if self.bytes_read + block_size > \
-                self.end_block - self.start_block:
-            block_size = self.end_block - self.start_block - self.bytes_read
-            self.stop_iteration = True
-
-        block = self.fd.read(block_size)
-        self.bytes_read += block_size
-        return block
-
-    def __next__(self):
-        return self.next()

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/dummy.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/dummy.py b/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/dummy.py
deleted file mode 100644
index affd265..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/dummy.py
+++ /dev/null
@@ -1,490 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 os.path
-import random
-import hashlib
-
-from libcloud.utils.py3 import PY3
-from libcloud.utils.py3 import b
-
-if PY3:
-    from io import FileIO as file
-
-from libcloud.common.types import LibcloudError
-
-from libcloud.storage.base import Object, Container, StorageDriver
-from libcloud.storage.types import ContainerAlreadyExistsError
-from libcloud.storage.types import ContainerDoesNotExistError
-from libcloud.storage.types import ContainerIsNotEmptyError
-from libcloud.storage.types import ObjectDoesNotExistError
-
-
-class DummyFileObject(file):
-    def __init__(self, yield_count=5, chunk_len=10):
-        self._yield_count = yield_count
-        self._chunk_len = chunk_len
-
-    def read(self, size):
-        i = 0
-
-        while i < self._yield_count:
-            yield self._get_chunk(self._chunk_len)
-            i += 1
-
-        raise StopIteration
-
-    def _get_chunk(self, chunk_len):
-        chunk = [str(x) for x in random.randint(97, 120)]
-        return chunk
-
-    def __len__(self):
-        return self._yield_count * self._chunk_len
-
-
-class DummyIterator(object):
-    def __init__(self, data=None):
-        self.hash = hashlib.md5()
-        self._data = data or []
-        self._current_item = 0
-
-    def get_md5_hash(self):
-        return self.hash.hexdigest()
-
-    def next(self):
-        if self._current_item == len(self._data):
-            raise StopIteration
-
-        value = self._data[self._current_item]
-        self.hash.update(b(value))
-        self._current_item += 1
-        return value
-
-    def __next__(self):
-        return self.next()
-
-
-class DummyStorageDriver(StorageDriver):
-    """
-    Dummy Storage driver.
-
-    >>> from libcloud.storage.drivers.dummy import DummyStorageDriver
-    >>> driver = DummyStorageDriver('key', 'secret')
-    >>> container = driver.create_container(container_name='test container')
-    >>> container
-    <Container: name=test container, provider=Dummy Storage Provider>
-    >>> container.name
-    'test container'
-    >>> container.extra['object_count']
-    0
-    """
-
-    name = 'Dummy Storage Provider'
-    website = 'http://example.com'
-
-    def __init__(self, api_key, api_secret):
-        """
-        :param    api_key:    API key or username to used (required)
-        :type     api_key:    ``str``
-        :param    api_secret: Secret password to be used (required)
-        :type     api_secret: ``str``
-        :rtype: ``None``
-        """
-        self._containers = {}
-
-    def get_meta_data(self):
-        """
-        >>> driver = DummyStorageDriver('key', 'secret')
-        >>> driver.get_meta_data()['object_count']
-        0
-        >>> driver.get_meta_data()['container_count']
-        0
-        >>> driver.get_meta_data()['bytes_used']
-        0
-        >>> container_name = 'test container 1'
-        >>> container = driver.create_container(container_name=container_name)
-        >>> container_name = 'test container 2'
-        >>> container = driver.create_container(container_name=container_name)
-        >>> obj = container.upload_object_via_stream(
-        ...  object_name='test object', iterator=DummyFileObject(5, 10),
-        ...  extra={})
-        >>> driver.get_meta_data()['object_count']
-        1
-        >>> driver.get_meta_data()['container_count']
-        2
-        >>> driver.get_meta_data()['bytes_used']
-        50
-
-        :rtype: ``dict``
-        """
-
-        container_count = len(self._containers)
-        object_count = sum([len(self._containers[container]['objects']) for
-                            container in self._containers])
-
-        bytes_used = 0
-        for container in self._containers:
-            objects = self._containers[container]['objects']
-            for _, obj in objects.items():
-                bytes_used += obj.size
-
-        return {'container_count': int(container_count),
-                'object_count': int(object_count),
-                'bytes_used': int(bytes_used)}
-
-    def iterate_containers(self):
-        """
-        >>> driver = DummyStorageDriver('key', 'secret')
-        >>> list(driver.iterate_containers())
-        []
-        >>> container_name = 'test container 1'
-        >>> container = driver.create_container(container_name=container_name)
-        >>> container
-        <Container: name=test container 1, provider=Dummy Storage Provider>
-        >>> container.name
-        'test container 1'
-        >>> container_name = 'test container 2'
-        >>> container = driver.create_container(container_name=container_name)
-        >>> container
-        <Container: name=test container 2, provider=Dummy Storage Provider>
-        >>> container = driver.create_container(
-        ...  container_name='test container 2')
-        ... #doctest: +IGNORE_EXCEPTION_DETAIL
-        Traceback (most recent call last):
-        ContainerAlreadyExistsError:
-        >>> container_list=list(driver.iterate_containers())
-        >>> sorted([c.name for c in container_list])
-        ['test container 1', 'test container 2']
-
-        @inherits: :class:`StorageDriver.iterate_containers`
-        """
-
-        for container in list(self._containers.values()):
-            yield container['container']
-
-    def list_container_objects(self, container):
-        container = self.get_container(container.name)
-
-        return container.objects
-
-    def get_container(self, container_name):
-        """
-        >>> driver = DummyStorageDriver('key', 'secret')
-        >>> driver.get_container('unknown') #doctest: +IGNORE_EXCEPTION_DETAIL
-        Traceback (most recent call last):
-        ContainerDoesNotExistError:
-        >>> container_name = 'test container 1'
-        >>> container = driver.create_container(container_name=container_name)
-        >>> container
-        <Container: name=test container 1, provider=Dummy Storage Provider>
-        >>> container.name
-        'test container 1'
-        >>> driver.get_container('test container 1')
-        <Container: name=test container 1, provider=Dummy Storage Provider>
-
-        @inherits: :class:`StorageDriver.get_container`
-        """
-
-        if container_name not in self._containers:
-            raise ContainerDoesNotExistError(driver=self, value=None,
-                                             container_name=container_name)
-
-        return self._containers[container_name]['container']
-
-    def get_container_cdn_url(self, container):
-        """
-        >>> driver = DummyStorageDriver('key', 'secret')
-        >>> driver.get_container('unknown') #doctest: +IGNORE_EXCEPTION_DETAIL
-        Traceback (most recent call last):
-        ContainerDoesNotExistError:
-        >>> container_name = 'test container 1'
-        >>> container = driver.create_container(container_name=container_name)
-        >>> container
-        <Container: name=test container 1, provider=Dummy Storage Provider>
-        >>> container.name
-        'test container 1'
-        >>> container.get_cdn_url()
-        'http://www.test.com/container/test_container_1'
-
-        @inherits: :class:`StorageDriver.get_container_cdn_url`
-        """
-
-        if container.name not in self._containers:
-            raise ContainerDoesNotExistError(driver=self, value=None,
-                                             container_name=container.name)
-
-        return self._containers[container.name]['cdn_url']
-
-    def get_object(self, container_name, object_name):
-        """
-        >>> driver = DummyStorageDriver('key', 'secret')
-        >>> driver.get_object('unknown', 'unknown')
-        ... #doctest: +IGNORE_EXCEPTION_DETAIL
-        Traceback (most recent call last):
-        ContainerDoesNotExistError:
-        >>> container_name = 'test container 1'
-        >>> container = driver.create_container(container_name=container_name)
-        >>> container
-        <Container: name=test container 1, provider=Dummy Storage Provider>
-        >>> driver.get_object(
-        ...  'test container 1', 'unknown') #doctest: +IGNORE_EXCEPTION_DETAIL
-        Traceback (most recent call last):
-        ObjectDoesNotExistError:
-        >>> obj = container.upload_object_via_stream(object_name='test object',
-        ...      iterator=DummyFileObject(5, 10), extra={})
-        >>> obj.name
-        'test object'
-        >>> obj.size
-        50
-
-        @inherits: :class:`StorageDriver.get_object`
-        """
-
-        self.get_container(container_name)
-        container_objects = self._containers[container_name]['objects']
-        if object_name not in container_objects:
-            raise ObjectDoesNotExistError(object_name=object_name, value=None,
-                                          driver=self)
-
-        return container_objects[object_name]
-
-    def get_object_cdn_url(self, obj):
-        """
-        >>> driver = DummyStorageDriver('key', 'secret')
-        >>> container_name = 'test container 1'
-        >>> container = driver.create_container(container_name=container_name)
-        >>> container
-        <Container: name=test container 1, provider=Dummy Storage Provider>
-        >>> obj = container.upload_object_via_stream(
-        ...      object_name='test object 5',
-        ...      iterator=DummyFileObject(5, 10), extra={})
-        >>> obj.name
-        'test object 5'
-        >>> obj.get_cdn_url()
-        'http://www.test.com/object/test_object_5'
-
-        @inherits: :class:`StorageDriver.get_object_cdn_url`
-        """
-
-        container_name = obj.container.name
-        container_objects = self._containers[container_name]['objects']
-        if obj.name not in container_objects:
-            raise ObjectDoesNotExistError(object_name=obj.name, value=None,
-                                          driver=self)
-
-        return container_objects[obj.name].meta_data['cdn_url']
-
-    def create_container(self, container_name):
-        """
-        >>> driver = DummyStorageDriver('key', 'secret')
-        >>> container_name = 'test container 1'
-        >>> container = driver.create_container(container_name=container_name)
-        >>> container
-        <Container: name=test container 1, provider=Dummy Storage Provider>
-        >>> container = driver.create_container(
-        ...    container_name='test container 1')
-        ... #doctest: +IGNORE_EXCEPTION_DETAIL
-        Traceback (most recent call last):
-        ContainerAlreadyExistsError:
-
-        @inherits: :class:`StorageDriver.create_container`
-        """
-
-        if container_name in self._containers:
-            raise ContainerAlreadyExistsError(container_name=container_name,
-                                              value=None, driver=self)
-
-        extra = {'object_count': 0}
-        container = Container(name=container_name, extra=extra, driver=self)
-
-        self._containers[container_name] = {'container': container,
-                                            'objects': {},
-                                            'cdn_url':
-                                            'http://www.test.com/container/%s'
-                                            %
-                                            (container_name.replace(' ', '_'))
-                                            }
-        return container
-
-    def delete_container(self, container):
-        """
-        >>> driver = DummyStorageDriver('key', 'secret')
-        >>> container = Container(name = 'test container',
-        ...    extra={'object_count': 0}, driver=driver)
-        >>> driver.delete_container(container=container)
-        ... #doctest: +IGNORE_EXCEPTION_DETAIL
-        Traceback (most recent call last):
-        ContainerDoesNotExistError:
-        >>> container = driver.create_container(
-        ...      container_name='test container 1')
-        ... #doctest: +IGNORE_EXCEPTION_DETAIL
-        >>> len(driver._containers)
-        1
-        >>> driver.delete_container(container=container)
-        True
-        >>> len(driver._containers)
-        0
-        >>> container = driver.create_container(
-        ...    container_name='test container 1')
-        ... #doctest: +IGNORE_EXCEPTION_DETAIL
-        >>> obj = container.upload_object_via_stream(
-        ...   object_name='test object', iterator=DummyFileObject(5, 10),
-        ...   extra={})
-        >>> driver.delete_container(container=container)
-        ... #doctest: +IGNORE_EXCEPTION_DETAIL
-        Traceback (most recent call last):
-        ContainerIsNotEmptyError:
-
-        @inherits: :class:`StorageDriver.delete_container`
-        """
-
-        container_name = container.name
-        if container_name not in self._containers:
-            raise ContainerDoesNotExistError(container_name=container_name,
-                                             value=None, driver=self)
-
-        container = self._containers[container_name]
-        if len(container['objects']) > 0:
-            raise ContainerIsNotEmptyError(container_name=container_name,
-                                           value=None, driver=self)
-
-        del self._containers[container_name]
-        return True
-
-    def download_object(self, obj, destination_path, overwrite_existing=False,
-                        delete_on_failure=True):
-        kwargs_dict = {'obj': obj,
-                       'response': DummyFileObject(),
-                       'destination_path': destination_path,
-                       'overwrite_existing': overwrite_existing,
-                       'delete_on_failure': delete_on_failure}
-
-        return self._save_object(**kwargs_dict)
-
-    def download_object_as_stream(self, obj, chunk_size=None):
-        """
-        >>> driver = DummyStorageDriver('key', 'secret')
-        >>> container = driver.create_container(
-        ...   container_name='test container 1')
-        ... #doctest: +IGNORE_EXCEPTION_DETAIL
-        >>> obj = container.upload_object_via_stream(object_name='test object',
-        ...    iterator=DummyFileObject(5, 10), extra={})
-        >>> stream = container.download_object_as_stream(obj)
-        >>> stream #doctest: +ELLIPSIS
-        <...closed...>
-
-        @inherits: :class:`StorageDriver.download_object_as_stream`
-        """
-
-        return DummyFileObject()
-
-    def upload_object(self, file_path, container, object_name, extra=None,
-                      file_hash=None):
-        """
-        >>> driver = DummyStorageDriver('key', 'secret')
-        >>> container_name = 'test container 1'
-        >>> container = driver.create_container(container_name=container_name)
-        >>> container.upload_object(file_path='/tmp/inexistent.file',
-        ...     object_name='test') #doctest: +IGNORE_EXCEPTION_DETAIL
-        Traceback (most recent call last):
-        LibcloudError:
-        >>> file_path = path = os.path.abspath(__file__)
-        >>> file_size = os.path.getsize(file_path)
-        >>> obj = container.upload_object(file_path=file_path,
-        ...                               object_name='test')
-        >>> obj #doctest: +ELLIPSIS
-        <Object: name=test, size=...>
-        >>> obj.size == file_size
-        True
-
-        @inherits: :class:`StorageDriver.upload_object`
-        :param file_hash: File hash
-        :type file_hash: ``str``
-        """
-
-        if not os.path.exists(file_path):
-            raise LibcloudError(value='File %s does not exist' % (file_path),
-                                driver=self)
-
-        size = os.path.getsize(file_path)
-        return self._add_object(container=container, object_name=object_name,
-                                size=size, extra=extra)
-
-    def upload_object_via_stream(self, iterator, container,
-                                 object_name, extra=None):
-        """
-        >>> driver = DummyStorageDriver('key', 'secret')
-        >>> container = driver.create_container(
-        ...    container_name='test container 1')
-        ... #doctest: +IGNORE_EXCEPTION_DETAIL
-        >>> obj = container.upload_object_via_stream(
-        ...   object_name='test object', iterator=DummyFileObject(5, 10),
-        ...   extra={})
-        >>> obj #doctest: +ELLIPSIS
-        <Object: name=test object, size=50, ...>
-
-        @inherits: :class:`StorageDriver.upload_object_via_stream`
-        """
-
-        size = len(iterator)
-        return self._add_object(container=container, object_name=object_name,
-                                size=size, extra=extra)
-
-    def delete_object(self, obj):
-        """
-        >>> driver = DummyStorageDriver('key', 'secret')
-        >>> container = driver.create_container(
-        ...   container_name='test container 1')
-        ... #doctest: +IGNORE_EXCEPTION_DETAIL
-        >>> obj = container.upload_object_via_stream(object_name='test object',
-        ...   iterator=DummyFileObject(5, 10), extra={})
-        >>> obj #doctest: +ELLIPSIS
-        <Object: name=test object, size=50, ...>
-        >>> container.delete_object(obj=obj)
-        True
-        >>> obj = Object(name='test object 2',
-        ...    size=1000, hash=None, extra=None,
-        ...    meta_data=None, container=container,driver=None)
-        >>> container.delete_object(obj=obj) #doctest: +IGNORE_EXCEPTION_DETAIL
-        Traceback (most recent call last):
-        ObjectDoesNotExistError:
-
-        @inherits: :class:`StorageDriver.delete_object`
-        """
-
-        container_name = obj.container.name
-        object_name = obj.name
-        obj = self.get_object(container_name=container_name,
-                              object_name=object_name)
-
-        del self._containers[container_name]['objects'][object_name]
-        return True
-
-    def _add_object(self, container, object_name, size, extra=None):
-        container = self.get_container(container.name)
-
-        extra = extra or {}
-        meta_data = extra.get('meta_data', {})
-        meta_data.update({'cdn_url': 'http://www.test.com/object/%s' %
-                          (object_name.replace(' ', '_'))})
-        obj = Object(name=object_name, size=size, extra=extra, hash=None,
-                     meta_data=meta_data, container=container, driver=self)
-
-        self._containers[container.name]['objects'][object_name] = obj
-        return obj
-
-if __name__ == "__main__":
-    import doctest
-    doctest.testmod()

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/google_storage.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/google_storage.py b/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/google_storage.py
deleted file mode 100644
index 580a29c..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/google_storage.py
+++ /dev/null
@@ -1,145 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 copy
-
-import email.utils
-
-from libcloud.common.base import ConnectionUserAndKey
-from libcloud.common.google import GoogleAuthType
-from libcloud.common.google import GoogleOAuth2Credential
-from libcloud.storage.drivers.s3 import BaseS3Connection
-from libcloud.storage.drivers.s3 import BaseS3StorageDriver
-from libcloud.storage.drivers.s3 import S3RawResponse
-from libcloud.storage.drivers.s3 import S3Response
-
-# Docs are a lie. Actual namespace returned is different that the one listed
-# in the docs.
-SIGNATURE_IDENTIFIER = 'GOOG1'
-API_VERSION = '2006-03-01'
-NAMESPACE = 'http://doc.s3.amazonaws.com/%s' % (API_VERSION)
-
-
-class GoogleStorageConnection(ConnectionUserAndKey):
-    """
-    Represents a single connection to the Google storage API endpoint.
-
-    This can either authenticate via the Google OAuth2 methods or via
-    the S3 HMAC interoperability method.
-    """
-
-    host = 'storage.googleapis.com'
-    responseCls = S3Response
-    rawResponseCls = S3RawResponse
-    PROJECT_ID_HEADER = 'x-goog-project-id'
-
-    def __init__(self, user_id, key, secure, auth_type=None,
-                 credential_file=None, **kwargs):
-        self.auth_type = auth_type or GoogleAuthType.guess_type(user_id)
-        if GoogleAuthType.is_oauth2(self.auth_type):
-            self.oauth2_credential = GoogleOAuth2Credential(
-                user_id, key, self.auth_type, credential_file, **kwargs)
-        else:
-            self.oauth2_credential = None
-        super(GoogleStorageConnection, self).__init__(user_id, key, secure,
-                                                      **kwargs)
-
-    def add_default_headers(self, headers):
-        date = email.utils.formatdate(usegmt=True)
-        headers['Date'] = date
-        project = self.get_project()
-        if project:
-            headers[self.PROJECT_ID_HEADER] = project
-        return headers
-
-    def get_project(self):
-        return getattr(self.driver, 'project')
-
-    def pre_connect_hook(self, params, headers):
-        if self.auth_type == GoogleAuthType.GCS_S3:
-            signature = self._get_s3_auth_signature(params, headers)
-            headers['Authorization'] = '%s %s:%s' % (SIGNATURE_IDENTIFIER,
-                                                     self.user_id, signature)
-        else:
-            headers['Authorization'] = ('Bearer ' +
-                                        self.oauth2_credential.access_token)
-        return params, headers
-
-    def _get_s3_auth_signature(self, params, headers):
-        """Hacky wrapper to work with S3's get_auth_signature."""
-        headers_copy = {}
-        params_copy = copy.deepcopy(params)
-
-        # Lowercase all headers except 'date' and Google header values
-        for k, v in headers.items():
-            k_lower = k.lower()
-            if (k_lower == 'date' or k_lower.startswith(
-                    GoogleStorageDriver.http_vendor_prefix) or
-                    not isinstance(v, str)):
-                headers_copy[k_lower] = v
-            else:
-                headers_copy[k_lower] = v.lower()
-
-        return BaseS3Connection.get_auth_signature(
-            method=self.method,
-            headers=headers_copy,
-            params=params_copy,
-            expires=None,
-            secret_key=self.key,
-            path=self.action,
-            vendor_prefix=GoogleStorageDriver.http_vendor_prefix)
-
-
-class GoogleStorageDriver(BaseS3StorageDriver):
-    """
-    Driver for Google Cloud Storage.
-
-    Can authenticate via standard Google Cloud methods (Service Accounts,
-    Installed App credentials, and GCE instance service accounts)
-
-    Examples:
-
-    Service Accounts::
-
-        driver = GoogleStorageDriver(key=client_email, secret=private_key, ...)
-
-    Installed Application::
-
-        driver = GoogleStorageDriver(key=client_id, secret=client_secret, ...)
-
-    From GCE instance::
-
-        driver = GoogleStorageDriver(key=foo , secret=bar, ...)
-
-    Can also authenticate via Google Cloud Storage's S3 HMAC interoperability
-    API. S3 user keys are 20 alphanumeric characters, starting with GOOG.
-
-    Example::
-
-        driver = GoogleStorageDriver(key='GOOG0123456789ABCXYZ',
-                                     secret=key_secret)
-    """
-    name = 'Google Storage'
-    website = 'http://cloud.google.com/'
-    connectionCls = GoogleStorageConnection
-    hash_type = 'md5'
-    namespace = NAMESPACE
-    supports_chunked_encoding = False
-    supports_s3_multipart_upload = False
-    http_vendor_prefix = 'x-goog'
-
-    def __init__(self, key, secret=None, project=None, **kwargs):
-        self.project = project
-        super(GoogleStorageDriver, self).__init__(key, secret, **kwargs)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/ktucloud.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/ktucloud.py b/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/ktucloud.py
deleted file mode 100644
index 385d445..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/storage/drivers/ktucloud.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from libcloud.common.types import LibcloudError
-from libcloud.storage.providers import Provider
-
-from libcloud.storage.drivers.cloudfiles import CloudFilesConnection
-from libcloud.storage.drivers.cloudfiles import CloudFilesStorageDriver
-
-KTUCLOUDSTORAGE_AUTH_URL = "https://ssproxy.ucloudbiz.olleh.com/auth/v1.0"
-KTUCLOUDSTORAGE_API_VERSION = "1.0"
-
-
-class KTUCloudStorageConnection(CloudFilesConnection):
-    """
-    Connection class for the KT UCloud Storage endpoint.
-    """
-
-    auth_url = KTUCLOUDSTORAGE_AUTH_URL
-    _auth_version = KTUCLOUDSTORAGE_API_VERSION
-
-    def get_endpoint(self):
-        eps = self.service_catalog.get_endpoints(name='cloudFiles')
-
-        if len(eps) == 0:
-            raise LibcloudError('Could not find specified endpoint')
-
-        ep = eps[0]
-        public_url = ep.url
-
-        if not public_url:
-            raise LibcloudError('Could not find specified endpoint')
-
-        return public_url
-
-
-class KTUCloudStorageDriver(CloudFilesStorageDriver):
-    """
-    Cloudfiles storage driver for the UK endpoint.
-    """
-
-    type = Provider.KTUCLOUD
-    name = 'KTUCloud Storage'
-    connectionCls = KTUCloudStorageConnection


[46/56] [abbrv] libcloud git commit: Fix lint in example script

Posted by an...@apache.org.
Fix lint in example script


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/c705fcf1
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/c705fcf1
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/c705fcf1

Branch: refs/heads/trunk
Commit: c705fcf1771466ac2445a8058334c27cd1040e81
Parents: 8afcda9
Author: anthony-shaw <an...@apache.org>
Authored: Thu Apr 14 21:44:01 2016 +1000
Committer: anthony-shaw <an...@apache.org>
Committed: Thu Apr 14 21:44:01 2016 +1000

----------------------------------------------------------------------
 docs/examples/compute/azure_arm/instantiate.py | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/c705fcf1/docs/examples/compute/azure_arm/instantiate.py
----------------------------------------------------------------------
diff --git a/docs/examples/compute/azure_arm/instantiate.py b/docs/examples/compute/azure_arm/instantiate.py
index 0448ae1..c9d0801 100644
--- a/docs/examples/compute/azure_arm/instantiate.py
+++ b/docs/examples/compute/azure_arm/instantiate.py
@@ -2,4 +2,6 @@ from libcloud.compute.types import Provider
 from libcloud.compute.providers import get_driver
 
 cls = get_driver(Provider.AZURE_ARM)
-driver = cls(tenant_id='tenant_id', subscription_id='subscription_id', key='application_id', secret='password')
+driver = cls(tenant_id='tenant_id',
+             subscription_id='subscription_id',
+             key='application_id', secret='password')


[30/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/dimensiondata.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/dimensiondata.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/dimensiondata.py
deleted file mode 100644
index 19a3856..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/dimensiondata.py
+++ /dev/null
@@ -1,2311 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-Dimension Data Driver
-"""
-
-try:
-    from lxml import etree as ET
-except ImportError:
-    from xml.etree import ElementTree as ET
-
-from libcloud.compute.base import NodeDriver, Node, NodeAuthPassword
-from libcloud.compute.base import NodeSize, NodeImage, NodeLocation
-from libcloud.common.dimensiondata import dd_object_to_id
-from libcloud.common.dimensiondata import DimensionDataAPIException
-from libcloud.common.dimensiondata import (DimensionDataConnection,
-                                           DimensionDataStatus)
-from libcloud.common.dimensiondata import DimensionDataNetwork
-from libcloud.common.dimensiondata import DimensionDataNetworkDomain
-from libcloud.common.dimensiondata import DimensionDataVlan
-from libcloud.common.dimensiondata import DimensionDataServerCpuSpecification
-from libcloud.common.dimensiondata import DimensionDataServerDisk
-from libcloud.common.dimensiondata import DimensionDataServerVMWareTools
-from libcloud.common.dimensiondata import DimensionDataPublicIpBlock
-from libcloud.common.dimensiondata import DimensionDataFirewallRule
-from libcloud.common.dimensiondata import DimensionDataFirewallAddress
-from libcloud.common.dimensiondata import DimensionDataNatRule
-from libcloud.common.dimensiondata import DimensionDataAntiAffinityRule
-from libcloud.common.dimensiondata import NetworkDomainServicePlan
-from libcloud.common.dimensiondata import API_ENDPOINTS, DEFAULT_REGION
-from libcloud.common.dimensiondata import TYPES_URN
-from libcloud.common.dimensiondata import SERVER_NS, NETWORK_NS, GENERAL_NS
-from libcloud.utils.py3 import urlencode
-from libcloud.utils.xml import fixxpath, findtext, findall
-from libcloud.utils.py3 import basestring
-from libcloud.compute.types import NodeState, Provider
-
-# Node state map is a dictionary with the keys as tuples
-# These tuples represent:
-# (<state_of_node_from_didata>, <is node started?>, <action happening>)
-NODE_STATE_MAP = {
-    ('NORMAL', 'true', None):
-        NodeState.RUNNING,
-    ('NORMAL', 'false', None):
-        NodeState.STOPPED,
-    ('PENDING_CHANGE', 'true', 'START_SERVER'):
-        NodeState.STARTING,
-    ('PENDING_ADD', 'true', 'DEPLOY_SERVER'):
-        NodeState.STARTING,
-    ('PENDING_ADD', 'true', 'DEPLOY_SERVER_WITH_DISK_SPEED'):
-        NodeState.STARTING,
-    ('PENDING_CHANGE', 'true', 'SHUTDOWN_SERVER'):
-        NodeState.STOPPING,
-    ('PENDING_CHANGE', 'true', 'POWER_OFF_SERVER'):
-        NodeState.STOPPING,
-    ('PENDING_CHANGE', 'true', 'REBOOT_SERVER'):
-        NodeState.REBOOTING,
-    ('PENDING_CHANGE', 'true', 'RESET_SERVER'):
-        NodeState.REBOOTING,
-    ('PENDING_CHANGE', 'true', 'RECONFIGURE_SERVER'):
-        NodeState.RECONFIGURING,
-}
-
-
-class DimensionDataNodeDriver(NodeDriver):
-    """
-    DimensionData node driver.
-    """
-
-    selected_region = None
-    connectionCls = DimensionDataConnection
-    name = 'DimensionData'
-    website = 'http://www.dimensiondata.com/'
-    type = Provider.DIMENSIONDATA
-    features = {'create_node': ['password']}
-    api_version = 1.0
-
-    def __init__(self, key, secret=None, secure=True, host=None, port=None,
-                 api_version=None, region=DEFAULT_REGION, **kwargs):
-
-        if region not in API_ENDPOINTS:
-            raise ValueError('Invalid region: %s' % (region))
-
-        self.selected_region = API_ENDPOINTS[region]
-
-        super(DimensionDataNodeDriver, self).__init__(key=key, secret=secret,
-                                                      secure=secure, host=host,
-                                                      port=port,
-                                                      api_version=api_version,
-                                                      region=region,
-                                                      **kwargs)
-
-    def _ex_connection_class_kwargs(self):
-        """
-            Add the region to the kwargs before the connection is instantiated
-        """
-
-        kwargs = super(DimensionDataNodeDriver,
-                       self)._ex_connection_class_kwargs()
-        kwargs['region'] = self.selected_region
-        return kwargs
-
-    def create_node(self, name, image, auth, ex_description,
-                    ex_network=None, ex_network_domain=None,
-                    ex_vlan=None, ex_primary_ipv4=None,
-                    ex_memory_gb=None,
-                    ex_cpu_specification=None,
-                    ex_is_started=True, ex_additional_nics_vlan=None,
-                    ex_additional_nics_ipv4=None, **kwargs):
-        """
-        Create a new DimensionData node
-
-        :keyword    name:   String with a name for this new node (required)
-        :type       name:   ``str``
-
-        :keyword    image:  OS Image to boot on node. (required)
-        :type       image:  :class:`NodeImage` or ``str``
-
-        :keyword    auth:   Initial authentication information for the
-                            node. (If this is a customer LINUX
-                            image auth will be ignored)
-        :type       auth:   :class:`NodeAuthPassword` or ``str`` or ``None``
-
-        :keyword    ex_description:  description for this node (required)
-        :type       ex_description:  ``str``
-
-        :keyword    ex_network:  Network to create the node within
-                                 (required unless using ex_network_domain
-                                 or ex_primary_ipv4)
-
-        :type       ex_network: :class:`DimensionDataNetwork` or ``str``
-
-        :keyword    ex_network_domain:  Network Domain to create the node
-                                        (required unless using network
-                                        or ex_primary_ipv4)
-        :type       ex_network_domain: :class:`DimensionDataNetworkDomain`
-                                        or ``str``
-
-        :keyword    ex_primary_ipv4: Primary nics IPv4 Address
-                                     MCP1: (required unless ex_network)
-                                     MCP2: (required unless ex_vlan)
-        :type       ex_primary_ipv4: ``str``
-
-        :keyword    ex_vlan:  VLAN to create the node within
-                              (required unless using network)
-        :type       ex_vlan: :class:`DimensionDataVlan` or ``str``
-
-        :keyword    ex_memory_gb:  The amount of memory in GB for the server
-        :type       ex_memory_gb: ``int``
-
-        :keyword    ex_cpu_specification: The spec of CPU to deploy (optional)
-        :type       ex_cpu_specification:
-            :class:`DimensionDataServerCpuSpecification`
-
-        :keyword    ex_is_started:  Start server after creation? default
-                                   true (required)
-        :type       ex_is_started:  ``bool``
-
-        :keyword    ex_additional_nics_vlan: (MCP2 Only) List of additional
-                                              nics to add by vlan
-        :type       ex_additional_nics_vlan: ``list`` of
-            :class:`DimensionDataVlan` or ``list`` of ``str``
-
-        :keyword    ex_additional_nics_ipv4: (MCP2 Only) List of additional
-                                              nics to add by ipv4 address
-        :type       ex_additional_nics_ipv4: ``list`` of ``str``
-
-        :return: The newly created :class:`Node`.
-        :rtype: :class:`Node`
-        """
-        password = None
-        image_needs_auth = self._image_needs_auth(image)
-        if image_needs_auth:
-            if isinstance(auth, basestring):
-                auth_obj = NodeAuthPassword(password=auth)
-                password = auth
-            else:
-                auth_obj = self._get_and_check_auth(auth)
-                password = auth_obj.password
-
-        if (ex_network_domain is None and
-                ex_network is None and
-                ex_primary_ipv4 is None):
-            raise ValueError("One of ex_network_domain, ex_network, "
-                             "or ex_ipv6_primary must be specified")
-
-        server_elm = ET.Element('deployServer', {'xmlns': TYPES_URN})
-        ET.SubElement(server_elm, "name").text = name
-        ET.SubElement(server_elm, "description").text = ex_description
-        image_id = self._image_to_image_id(image)
-        ET.SubElement(server_elm, "imageId").text = image_id
-        ET.SubElement(server_elm, "start").text = str(ex_is_started).lower()
-        if password is not None:
-            ET.SubElement(server_elm, "administratorPassword").text = password
-
-        if ex_cpu_specification is not None:
-            cpu = ET.SubElement(server_elm, "cpu")
-            cpu.set('speed', ex_cpu_specification.performance)
-            cpu.set('count', str(ex_cpu_specification.cpu_count))
-            cpu.set('coresPerSocket',
-                    str(ex_cpu_specification.cores_per_socket))
-
-        if ex_memory_gb is not None:
-            ET.SubElement(server_elm, "memoryGb").text = str(ex_memory_gb)
-
-        if ex_network is not None:
-            network_elm = ET.SubElement(server_elm, "network")
-            network_id = self._network_to_network_id(ex_network)
-            ET.SubElement(network_elm, "networkId").text = network_id
-        elif ex_network_domain is None and ex_primary_ipv4 is not None:
-            network_elm = ET.SubElement(server_elm, "network")
-            ET.SubElement(network_elm, "privateIpv4").text = ex_primary_ipv4
-        elif ex_network_domain is not None:
-            net_domain_id = self._network_domain_to_network_domain_id(
-                ex_network_domain)
-            network_inf_elm = ET.SubElement(
-                server_elm, "networkInfo",
-                {'networkDomainId': net_domain_id}
-            )
-
-            if ex_vlan is not None:
-                vlan_id = self._vlan_to_vlan_id(ex_vlan)
-                pri_nic = ET.SubElement(network_inf_elm, "primaryNic")
-                ET.SubElement(pri_nic, "vlanId").text = vlan_id
-            elif ex_primary_ipv4 is not None:
-                pri_nic = ET.SubElement(network_inf_elm, "primaryNic")
-                ET.SubElement(pri_nic, "privateIpv4").text = ex_primary_ipv4
-            else:
-                raise ValueError("One of ex_vlan or ex_primary_ipv4 "
-                                 "must be specified")
-
-            if isinstance(ex_additional_nics_ipv4, (list, tuple)):
-                for ipv4_nic in ex_additional_nics_ipv4:
-                    add_nic = ET.SubElement(network_inf_elm, "additionalNic")
-                    ET.SubElement(add_nic, "privateIpv4").text = ipv4_nic
-            elif ex_additional_nics_ipv4 is not None:
-                raise TypeError("ex_additional_nics_ipv4 must "
-                                "be None or a tuple/list")
-
-            if isinstance(ex_additional_nics_vlan, (list, tuple)):
-                for vlan_nic in ex_additional_nics_vlan:
-                    add_nic = ET.SubElement(network_inf_elm, "additionalNic")
-                    ET.SubElement(add_nic, "vlanId").text = vlan_nic
-            elif ex_additional_nics_vlan is not None:
-                raise TypeError("ex_additional_nics_vlan"
-                                "must be None or tuple/list")
-
-        response = self.connection.request_with_orgId_api_2(
-            'server/deployServer',
-            method='POST',
-            data=ET.tostring(server_elm)).object
-
-        node_id = None
-        for info in findall(response, 'info', TYPES_URN):
-            if info.get('name') == 'serverId':
-                node_id = info.get('value')
-
-        node = self.ex_get_node_by_id(node_id)
-
-        if image_needs_auth:
-            if getattr(auth_obj, "generated", False):
-                node.extra['password'] = auth_obj.password
-
-        return node
-
-    def destroy_node(self, node):
-        """
-        Deletes a node, node must be stopped before deletion
-
-
-        :keyword node: The node to delete
-        :type    node: :class:`Node`
-
-        :rtype: ``bool``
-        """
-        request_elm = ET.Element('deleteServer',
-                                 {'xmlns': TYPES_URN, 'id': node.id})
-        body = self.connection.request_with_orgId_api_2(
-            'server/deleteServer',
-            method='POST',
-            data=ET.tostring(request_elm)).object
-        response_code = findtext(body, 'responseCode', TYPES_URN)
-        return response_code in ['IN_PROGRESS', 'OK']
-
-    def reboot_node(self, node):
-        """
-        Reboots a node by requesting the OS restart via the hypervisor
-
-
-        :keyword node: The node to reboot
-        :type    node: :class:`Node`
-
-        :rtype: ``bool``
-        """
-        request_elm = ET.Element('rebootServer',
-                                 {'xmlns': TYPES_URN, 'id': node.id})
-        body = self.connection.request_with_orgId_api_2(
-            'server/rebootServer',
-            method='POST',
-            data=ET.tostring(request_elm)).object
-        response_code = findtext(body, 'responseCode', TYPES_URN)
-        return response_code in ['IN_PROGRESS', 'OK']
-
-    def list_nodes(self, ex_location=None, ex_name=None,
-                   ex_ipv6=None, ex_ipv4=None, ex_vlan=None,
-                   ex_image=None, ex_deployed=None,
-                   ex_started=None, ex_state=None,
-                   ex_network=None, ex_network_domain=None):
-        """
-        List nodes deployed for your organization.
-
-        :keyword ex_location: Filters the node list to nodes that are
-                              located in this location
-        :type    ex_location: :class:`NodeLocation` or ``str``
-
-        :keyword ex_name: Filters the node list to nodes that have this name
-        :type    ex_name ``str``
-
-        :keyword ex_ipv6: Filters the node list to nodes that have this
-                          ipv6 address
-        :type    ex_ipv6: ``str``
-
-        :keyword ex_ipv4: Filters the node list to nodes that have this
-                          ipv4 address
-        :type    ex_ipv4: ``str``
-
-        :keyword ex_vlan: Filters the node list to nodes that are in this VLAN
-        :type    ex_vlan: :class:`DimensionDataVlan` or ``str``
-
-        :keyword ex_image: Filters the node list to nodes that have this image
-        :type    ex_image: :class:`NodeImage` or ``str``
-
-        :keyword ex_deployed: Filters the node list to nodes that are
-                              deployed or not
-        :type    ex_deployed: ``bool``
-
-        :keyword ex_started: Filters the node list to nodes that are
-                             started or not
-        :type    ex_started: ``bool``
-
-        :keyword ex_state: Filters the node list by nodes that are in
-                           this state
-        :type    ex_state: ``str``
-
-        :keyword ex_network: Filters the node list to nodes in this network
-        :type    ex_network: :class:`DimensionDataNetwork` or ``str``
-
-        :keyword ex_network_domain: Filters the node list to nodes in this
-                                    network domain
-        :type    ex_network_domain: :class:`DimensionDataNetworkDomain`
-                                    or ``str``
-
-        :return: a list of `Node` objects
-        :rtype: ``list`` of :class:`Node`
-        """
-        node_list = []
-        for nodes in self.ex_list_nodes_paginated(
-                location=ex_location,
-                name=ex_name, ipv6=ex_ipv6,
-                ipv4=ex_ipv4, vlan=ex_vlan,
-                image=ex_image, deployed=ex_deployed,
-                started=ex_started, state=ex_state,
-                network=ex_network,
-                network_domain=ex_network_domain):
-            node_list.extend(nodes)
-
-        return node_list
-
-    def list_images(self, location=None):
-        """
-        List images available
-
-        Note:  Currently only returns the default 'base OS images'
-               provided by DimensionData. Customer images (snapshots)
-               are not yet supported.
-
-        :keyword ex_location: Filters the node list to nodes that are
-                              located in this location
-        :type    ex_location: :class:`NodeLocation` or ``str``
-
-        :return: List of images available
-        :rtype: ``list`` of :class:`NodeImage`
-        """
-        params = {}
-        if location is not None:
-            params['datacenterId'] = self._location_to_location_id(location)
-
-        return self._to_images(
-            self.connection.request_with_orgId_api_2(
-                'image/osImage',
-                params=params)
-            .object)
-
-    def list_sizes(self, location=None):
-        """
-        return a list of available sizes
-            Currently, the size of the node is dictated by the chosen OS base
-            image, they cannot be set explicitly.
-
-        @inherits: :class:`NodeDriver.list_sizes`
-        """
-        return [
-            NodeSize(id=1,
-                     name="default",
-                     ram=0,
-                     disk=0,
-                     bandwidth=0,
-                     price=0,
-                     driver=self.connection.driver),
-        ]
-
-    def list_locations(self, ex_id=None):
-        """
-        List locations (datacenters) available for instantiating servers and
-        networks.
-
-        :keyword ex_id: Filters the location list to this id
-        :type    ex_id: ``str``
-
-        :return:  List of locations
-        :rtype:  ``list`` of :class:`NodeLocation`
-        """
-        params = {}
-        if ex_id is not None:
-            params['id'] = ex_id
-
-        return self._to_locations(
-            self.connection
-            .request_with_orgId_api_2(
-                'infrastructure/datacenter',
-                params=params
-            ).object
-        )
-
-    def list_networks(self, location=None):
-        """
-        List networks deployed across all data center locations for your
-        organization.  The response includes the location of each network.
-
-
-        :keyword location: The location
-        :type    location: :class:`NodeLocation` or ``str``
-
-        :return: a list of DimensionDataNetwork objects
-        :rtype: ``list`` of :class:`DimensionDataNetwork`
-        """
-        url_ext = ''
-        if location is not None:
-            url_ext = '/' + self._location_to_location_id(location)
-
-        return self._to_networks(
-            self.connection
-            .request_with_orgId_api_1('networkWithLocation%s' % url_ext)
-            .object)
-
-    def ex_list_nodes_paginated(self, name=None, location=None,
-                                ipv6=None, ipv4=None, vlan=None,
-                                image=None, deployed=None, started=None,
-                                state=None, network=None, network_domain=None):
-        """
-        Return a generator which yields node lists in pages
-
-        :keyword location: Filters the node list to nodes that are
-                           located in this location
-        :type    location: :class:`NodeLocation` or ``str``
-
-        :keyword name: Filters the node list to nodes that have this name
-        :type    name ``str``
-
-        :keyword ipv6: Filters the node list to nodes that have this
-                       ipv6 address
-        :type    ipv6: ``str``
-
-        :keyword ipv4: Filters the node list to nodes that have this
-                       ipv4 address
-        :type    ipv4: ``str``
-
-        :keyword vlan: Filters the node list to nodes that are in this VLAN
-        :type    vlan: :class:`DimensionDataVlan` or ``str``
-
-        :keyword image: Filters the node list to nodes that have this image
-        :type    image: :class:`NodeImage` or ``str``
-
-        :keyword deployed: Filters the node list to nodes that are
-                           deployed or not
-        :type    deployed: ``bool``
-
-        :keyword started: Filters the node list to nodes that are
-                          started or not
-        :type    started: ``bool``
-
-        :keyword state: Filters the node list to nodes that are in
-                        this state
-        :type    state: ``str``
-
-        :keyword network: Filters the node list to nodes in this network
-        :type    network: :class:`DimensionDataNetwork` or ``str``
-
-        :keyword network_domain: Filters the node list to nodes in this
-                                 network domain
-        :type    network_domain: :class:`DimensionDataNetworkDomain`
-                                 or ``str``
-
-        :return: a list of `Node` objects
-        :rtype: ``generator`` of `list` of :class:`Node`
-        """
-
-        params = {}
-        if location is not None:
-            params['datacenterId'] = self._location_to_location_id(location)
-        if ipv6 is not None:
-            params['ipv6'] = ipv6
-        if ipv4 is not None:
-            params['privateIpv4'] = ipv4
-        if state is not None:
-            params['state'] = state
-        if started is not None:
-            params['started'] = started
-        if deployed is not None:
-            params['deployed'] = deployed
-        if name is not None:
-            params['name'] = name
-        if network_domain is not None:
-            params['networkDomainId'] = \
-                self._network_domain_to_network_domain_id(network_domain)
-        if network is not None:
-            params['networkId'] = self._network_to_network_id(network)
-        if vlan is not None:
-            params['vlanId'] = self._vlan_to_vlan_id(vlan)
-        if image is not None:
-            params['sourceImageId'] = self._image_to_image_id(image)
-
-        nodes_obj = self._list_nodes_single_page(params)
-        yield self._to_nodes(nodes_obj)
-
-        while nodes_obj.get('pageCount') >= nodes_obj.get('pageSize'):
-            params['pageNumber'] = int(nodes_obj.get('pageNumber')) + 1
-            nodes_obj = self._list_nodes_single_page(params)
-            yield self._to_nodes(nodes_obj)
-
-    def ex_start_node(self, node):
-        """
-        Powers on an existing deployed server
-
-        :param      node: Node which should be used
-        :type       node: :class:`Node`
-
-        :rtype: ``bool``
-        """
-        request_elm = ET.Element('startServer',
-                                 {'xmlns': TYPES_URN, 'id': node.id})
-        body = self.connection.request_with_orgId_api_2(
-            'server/startServer',
-            method='POST',
-            data=ET.tostring(request_elm)).object
-        response_code = findtext(body, 'responseCode', TYPES_URN)
-        return response_code in ['IN_PROGRESS', 'OK']
-
-    def ex_shutdown_graceful(self, node):
-        """
-        This function will attempt to "gracefully" stop a server by
-        initiating a shutdown sequence within the guest operating system.
-        A successful response on this function means the system has
-        successfully passed the request into the operating system.
-
-        :param      node: Node which should be used
-        :type       node: :class:`Node`
-
-        :rtype: ``bool``
-        """
-        request_elm = ET.Element('shutdownServer',
-                                 {'xmlns': TYPES_URN, 'id': node.id})
-        body = self.connection.request_with_orgId_api_2(
-            'server/shutdownServer',
-            method='POST',
-            data=ET.tostring(request_elm)).object
-        response_code = findtext(body, 'responseCode', TYPES_URN)
-        return response_code in ['IN_PROGRESS', 'OK']
-
-    def ex_power_off(self, node):
-        """
-        This function will abruptly power-off a server.  Unlike
-        ex_shutdown_graceful, success ensures the node will stop but some OS
-        and application configurations may be adversely affected by the
-        equivalent of pulling the power plug out of the machine.
-
-        :param      node: Node which should be used
-        :type       node: :class:`Node`
-
-        :rtype: ``bool``
-        """
-        request_elm = ET.Element('powerOffServer',
-                                 {'xmlns': TYPES_URN, 'id': node.id})
-        body = self.connection.request_with_orgId_api_2(
-            'server/powerOffServer',
-            method='POST',
-            data=ET.tostring(request_elm)).object
-        response_code = findtext(body, 'responseCode', TYPES_URN)
-        return response_code in ['IN_PROGRESS', 'OK']
-
-    def ex_reset(self, node):
-        """
-        This function will abruptly reset a server.  Unlike
-        reboot_node, success ensures the node will restart but some OS
-        and application configurations may be adversely affected by the
-        equivalent of pulling the power plug out of the machine.
-
-        :param      node: Node which should be used
-        :type       node: :class:`Node`
-
-        :rtype: ``bool``
-        """
-        request_elm = ET.Element('resetServer',
-                                 {'xmlns': TYPES_URN, 'id': node.id})
-        body = self.connection.request_with_orgId_api_2(
-            'server/resetServer',
-            method='POST',
-            data=ET.tostring(request_elm)).object
-        response_code = findtext(body, 'responseCode', TYPES_URN)
-        return response_code in ['IN_PROGRESS', 'OK']
-
-    def ex_update_vm_tools(self, node):
-        """
-        This function triggers an update of the VMware Tools
-        software running on the guest OS of a Server.
-
-        :param      node: Node which should be used
-        :type       node: :class:`Node`
-
-        :rtype: ``bool``
-        """
-        request_elm = ET.Element('updateVmwareTools',
-                                 {'xmlns': TYPES_URN, 'id': node.id})
-        body = self.connection.request_with_orgId_api_2(
-            'server/updateVmwareTools',
-            method='POST',
-            data=ET.tostring(request_elm)).object
-        response_code = findtext(body, 'responseCode', TYPES_URN)
-        return response_code in ['IN_PROGRESS', 'OK']
-
-    def ex_update_node(self, node, name=None, description=None,
-                       cpu_count=None, ram_mb=None):
-        """
-        Update the node, the name, CPU or RAM
-
-        :param      node: Node which should be used
-        :type       node: :class:`Node`
-
-        :param      name: The new name (optional)
-        :type       name: ``str``
-
-        :param      description: The new description (optional)
-        :type       description: ``str``
-
-        :param      cpu_count: The new CPU count (optional)
-        :type       cpu_count: ``int``
-
-        :param      ram_mb: The new Memory in MB (optional)
-        :type       ram_mb: ``int``
-
-        :rtype: ``bool``
-        """
-        data = {}
-        if name is not None:
-            data['name'] = name
-        if description is not None:
-            data['description'] = description
-        if cpu_count is not None:
-            data['cpuCount'] = str(cpu_count)
-        if ram_mb is not None:
-            data['memory'] = str(ram_mb)
-        body = self.connection.request_with_orgId_api_1(
-            'server/%s' % (node.id),
-            method='POST',
-            data=urlencode(data, True)).object
-        response_code = findtext(body, 'result', GENERAL_NS)
-        return response_code in ['IN_PROGRESS', 'SUCCESS']
-
-    def ex_create_anti_affinity_rule(self, node_list):
-        """
-        Create an anti affinity rule given a list of nodes
-        Anti affinity rules ensure that servers will not reside
-        on the same VMware ESX host
-
-        :param node_list: The list of nodes to create a rule for
-        :type  node_list: ``list`` of :class:`Node` or
-                          ``list`` of ``str``
-
-        :rtype: ``bool``
-        """
-        if not isinstance(node_list, (list, tuple)):
-            raise TypeError("Node list must be a list or a tuple.")
-        anti_affinity_xml_request = ET.Element('NewAntiAffinityRule',
-                                               {'xmlns': SERVER_NS})
-        for node in node_list:
-            ET.SubElement(anti_affinity_xml_request, 'serverId').text = \
-                self._node_to_node_id(node)
-        result = self.connection.request_with_orgId_api_1(
-            'antiAffinityRule',
-            method='POST',
-            data=ET.tostring(anti_affinity_xml_request)).object
-        response_code = findtext(result, 'result', GENERAL_NS)
-        return response_code in ['IN_PROGRESS', 'SUCCESS']
-
-    def ex_delete_anti_affinity_rule(self, anti_affinity_rule):
-        """
-        Remove anti affinity rule
-
-        :param anti_affinity_rule: The anti affinity rule to delete
-        :type  anti_affinity_rule: :class:`DimensionDataAntiAffinityRule` or
-                                   ``str``
-
-        :rtype: ``bool``
-        """
-        rule_id = self._anti_affinity_rule_to_anti_affinity_rule_id(
-            anti_affinity_rule)
-        result = self.connection.request_with_orgId_api_1(
-            'antiAffinityRule/%s?delete' % (rule_id),
-            method='GET').object
-        response_code = findtext(result, 'result', GENERAL_NS)
-        return response_code in ['IN_PROGRESS', 'SUCCESS']
-
-    def ex_list_anti_affinity_rules(self, network=None, network_domain=None,
-                                    node=None, filter_id=None,
-                                    filter_state=None):
-        """
-        List anti affinity rules for a network, network domain, or node
-
-        :param network: The network to list anti affinity rules for
-                        One of network, network_domain, or node is required
-        :type  network: :class:`DimensionDataNetwork` or ``str``
-
-        :param network_domain: The network domain to list anti affinity rules
-                               One of network, network_domain,
-                               or node is required
-        :type  network_domain: :class:`DimensionDataNetworkDomain` or ``str``
-
-        :param node: The node to list anti affinity rules for
-                     One of network, netwok_domain, or node is required
-        :type  node: :class:`Node` or ``str``
-
-        :param filter_id: This will allow you to filter the rules
-                          by this node id
-        :type  filter_id: ``str``
-
-        :type  filter_state: This will allow you to filter rules by
-                             node state (i.e. NORMAL)
-        :type  filter_state: ``str``
-
-        :rtype: ``list`` of :class:`DimensionDataAntiAffinityRule`
-        """
-        not_none_arguments = [key
-                              for key in (network, network_domain, node)
-                              if key is not None]
-        if len(not_none_arguments) != 1:
-            raise ValueError("One and ONLY one of network, "
-                             "network_domain, or node must be set")
-
-        params = {}
-        if network_domain is not None:
-            params['networkDomainId'] = \
-                self._network_domain_to_network_domain_id(network_domain)
-        if network is not None:
-            params['networkId'] = \
-                self._network_to_network_id(network)
-        if node is not None:
-            params['serverId'] = \
-                self._node_to_node_id(node)
-        if filter_id is not None:
-            params['id'] = filter_id
-        if filter_state is not None:
-            params['state'] = filter_state
-
-        paged_result = self.connection.paginated_request_with_orgId_api_2(
-            'server/antiAffinityRule',
-            method='GET',
-            params=params
-        )
-
-        rules = []
-        for result in paged_result:
-            rules.extend(self._to_anti_affinity_rules(result))
-        return rules
-
-    def ex_attach_node_to_vlan(self, node, vlan=None, private_ipv4=None):
-        """
-        Attach a node to a VLAN by adding an additional NIC to
-        the node on the target VLAN. The IP will be automatically
-        assigned based on the VLAN IP network space. Alternatively, provide
-        a private IPv4 address instead of VLAN information, and this will
-        be assigned to the node on corresponding NIC.
-
-        :param      node: Node which should be used
-        :type       node: :class:`Node`
-
-        :param      vlan: VLAN to attach the node to
-                          (required unless private_ipv4)
-        :type       vlan: :class:`DimensionDataVlan`
-
-        :keyword    private_ipv4: Private nic IPv4 Address
-                                  (required unless vlan)
-        :type       private_ipv4: ``str``
-
-        :rtype: ``bool``
-        """
-        request = ET.Element('addNic',
-                             {'xmlns': TYPES_URN})
-        ET.SubElement(request, 'serverId').text = node.id
-        nic = ET.SubElement(request, 'nic')
-
-        if vlan is not None:
-            ET.SubElement(nic, 'vlanId').text = vlan.id
-        elif private_ipv4 is not None:
-            ET.SubElement(nic, 'privateIpv4').text = private_ipv4
-        else:
-            raise ValueError("One of vlan or primary_ipv4 "
-                             "must be specified")
-
-        response = self.connection.request_with_orgId_api_2(
-            'server/addNic',
-            method='POST',
-            data=ET.tostring(request)).object
-        response_code = findtext(response, 'responseCode', TYPES_URN)
-        return response_code in ['IN_PROGRESS', 'OK']
-
-    def ex_destroy_nic(self, nic_id):
-        """
-        Remove a NIC on a node, removing the node from a VLAN
-
-        :param      nic_id: The identifier of the NIC to remove
-        :type       nic_id: ``str``
-
-        :rtype: ``bool``
-        """
-        request = ET.Element('removeNic',
-                             {'xmlns': TYPES_URN,
-                              'id': nic_id})
-
-        response = self.connection.request_with_orgId_api_2(
-            'server/removeNic',
-            method='POST',
-            data=ET.tostring(request)).object
-        response_code = findtext(response, 'responseCode', TYPES_URN)
-        return response_code in ['IN_PROGRESS', 'OK']
-
-    def ex_list_networks(self, location=None):
-        """
-        List networks deployed across all data center locations for your
-        organization.  The response includes the location of each network.
-
-        :param location: The target location
-        :type  location: :class:`NodeLocation` or ``str``
-
-        :return: a list of DimensionDataNetwork objects
-        :rtype: ``list`` of :class:`DimensionDataNetwork`
-        """
-        return self.list_networks(location=location)
-
-    def ex_create_network(self, location, name, description=None):
-        """
-        Create a new network in an MCP 1.0 location
-
-        :param   location: The target location (MCP1)
-        :type    location: :class:`NodeLocation` or ``str``
-
-        :param   name: The name of the network
-        :type    name: ``str``
-
-        :param   description: Additional description of the network
-        :type    description: ``str``
-
-        :return: A new instance of `DimensionDataNetwork`
-        :rtype:  Instance of :class:`DimensionDataNetwork`
-        """
-        network_location = self._location_to_location_id(location)
-
-        create_node = ET.Element('NewNetworkWithLocation',
-                                 {'xmlns': NETWORK_NS})
-        ET.SubElement(create_node, "name").text = name
-        if description is not None:
-            ET.SubElement(create_node, "description").text = description
-        ET.SubElement(create_node, "location").text = network_location
-
-        self.connection.request_with_orgId_api_1(
-            'networkWithLocation',
-            method='POST',
-            data=ET.tostring(create_node))
-
-        # MCP1 API does not return the ID, but name is unique for location
-        network = list(
-            filter(lambda x: x.name == name,
-                   self.ex_list_networks(location)))[0]
-
-        return network
-
-    def ex_delete_network(self, network):
-        """
-        Delete a network from an MCP 1 data center
-
-        :param  network: The network to delete
-        :type   network: :class:`DimensionDataNetwork`
-
-        :rtype: ``bool``
-        """
-        response = self.connection.request_with_orgId_api_1(
-            'network/%s?delete' % network.id,
-            method='GET').object
-        response_code = findtext(response, 'result', GENERAL_NS)
-        return response_code == "SUCCESS"
-
-    def ex_rename_network(self, network, new_name):
-        """
-        Rename a network in MCP 1 data center
-
-        :param  network: The network to rename
-        :type   network: :class:`DimensionDataNetwork`
-
-        :param  new_name: The new name of the network
-        :type   new_name: ``str``
-
-        :rtype: ``bool``
-        """
-        response = self.connection.request_with_orgId_api_1(
-            'network/%s' % network.id,
-            method='POST',
-            data='name=%s' % new_name).object
-        response_code = findtext(response, 'result', GENERAL_NS)
-        return response_code == "SUCCESS"
-
-    def ex_get_network_domain(self, network_domain_id):
-        """
-        Get an individual Network Domain, by identifier
-
-        :param      network_domain_id: The identifier of the network domain
-        :type       network_domain_id: ``str``
-
-        :rtype: :class:`DimensionDataNetworkDomain`
-        """
-        locations = self.list_locations()
-        net = self.connection.request_with_orgId_api_2(
-            'network/networkDomain/%s' % network_domain_id).object
-        return self._to_network_domain(net, locations)
-
-    def ex_list_network_domains(self, location=None, name=None,
-                                service_plan=None, state=None):
-        """
-        List networks domains deployed across all data center locations
-        for your organization.
-        The response includes the location of each network domain.
-
-        :param      location: Only network domains in the location (optional)
-        :type       location: :class:`NodeLocation` or ``str``
-
-        :param      name: Only network domains of this name (optional)
-        :type       name: ``str``
-
-        :param      service_plan: Only network domains of this type (optional)
-        :type       service_plan: ``str``
-
-        :param      state: Only network domains in this state (optional)
-        :type       state: ``str``
-
-        :return: a list of `DimensionDataNetwork` objects
-        :rtype: ``list`` of :class:`DimensionDataNetwork`
-        """
-        params = {}
-        if location is not None:
-            params['datacenterId'] = self._location_to_location_id(location)
-        if name is not None:
-            params['name'] = name
-        if service_plan is not None:
-            params['type'] = service_plan
-        if state is not None:
-            params['state'] = state
-
-        response = self.connection \
-            .request_with_orgId_api_2('network/networkDomain',
-                                      params=params).object
-        return self._to_network_domains(response)
-
-    def ex_create_network_domain(self, location, name, service_plan,
-                                 description=None):
-        """
-        Deploy a new network domain to a data center
-
-        :param      location: The data center to list
-        :type       location: :class:`NodeLocation` or ``str``
-
-        :param      name: The name of the network domain to create
-        :type       name: ``str``
-
-        :param      service_plan: The service plan, either "ESSENTIALS"
-            or "ADVANCED"
-        :type       service_plan: ``str``
-
-        :param      description: An additional description of
-                                 the network domain
-        :type       description: ``str``
-
-        :return: an instance of `DimensionDataNetworkDomain`
-        :rtype: :class:`DimensionDataNetworkDomain`
-        """
-        create_node = ET.Element('deployNetworkDomain', {'xmlns': TYPES_URN})
-        ET.SubElement(
-            create_node,
-            "datacenterId"
-        ).text = self._location_to_location_id(location)
-
-        ET.SubElement(create_node, "name").text = name
-        if description is not None:
-            ET.SubElement(create_node, "description").text = description
-        ET.SubElement(create_node, "type").text = service_plan
-
-        response = self.connection.request_with_orgId_api_2(
-            'network/deployNetworkDomain',
-            method='POST',
-            data=ET.tostring(create_node)).object
-
-        network_domain_id = None
-
-        for info in findall(response, 'info', TYPES_URN):
-            if info.get('name') == 'networkDomainId':
-                network_domain_id = info.get('value')
-
-        return DimensionDataNetworkDomain(
-            id=network_domain_id,
-            name=name,
-            description=description,
-            location=location,
-            status=NodeState.RUNNING,
-            plan=service_plan
-        )
-
-    def ex_update_network_domain(self, network_domain):
-        """
-        Update the properties of a network domain
-
-        :param      network_domain: The network domain with updated properties
-        :type       network_domain: :class:`DimensionDataNetworkDomain`
-
-        :return: an instance of `DimensionDataNetworkDomain`
-        :rtype: :class:`DimensionDataNetworkDomain`
-        """
-        edit_node = ET.Element('editNetworkDomain', {'xmlns': TYPES_URN})
-        edit_node.set('id', network_domain.id)
-        ET.SubElement(edit_node, "name").text = network_domain.name
-        if network_domain.description is not None:
-            ET.SubElement(edit_node, "description").text \
-                = network_domain.description
-        ET.SubElement(edit_node, "type").text = network_domain.plan
-
-        self.connection.request_with_orgId_api_2(
-            'network/editNetworkDomain',
-            method='POST',
-            data=ET.tostring(edit_node)).object
-
-        return network_domain
-
-    def ex_delete_network_domain(self, network_domain):
-        """
-        Delete a network domain
-
-        :param      network_domain: The network domain to delete
-        :type       network_domain: :class:`DimensionDataNetworkDomain`
-
-        :rtype: ``bool``
-        """
-        delete_node = ET.Element('deleteNetworkDomain', {'xmlns': TYPES_URN})
-        delete_node.set('id', network_domain.id)
-        result = self.connection.request_with_orgId_api_2(
-            'network/deleteNetworkDomain',
-            method='POST',
-            data=ET.tostring(delete_node)).object
-
-        response_code = findtext(result, 'responseCode', TYPES_URN)
-        return response_code in ['IN_PROGRESS', 'OK']
-
-    def ex_create_vlan(self,
-                       network_domain,
-                       name,
-                       private_ipv4_base_address,
-                       description=None,
-                       private_ipv4_prefix_size=24):
-        """
-        Deploy a new VLAN to a network domain
-
-        :param      network_domain: The network domain to add the VLAN to
-        :type       network_domain: :class:`DimensionDataNetworkDomain`
-
-        :param      name: The name of the VLAN to create
-        :type       name: ``str``
-
-        :param      private_ipv4_base_address: The base IPv4 address
-            e.g. 192.168.1.0
-        :type       private_ipv4_base_address: ``str``
-
-        :param      description: An additional description of the VLAN
-        :type       description: ``str``
-
-        :param      private_ipv4_prefix_size: The size of the IPv4
-            address space, e.g 24
-        :type       private_ipv4_prefix_size: ``int``
-
-        :return: an instance of `DimensionDataVlan`
-        :rtype: :class:`DimensionDataVlan`
-        """
-        create_node = ET.Element('deployVlan', {'xmlns': TYPES_URN})
-        ET.SubElement(create_node, "networkDomainId").text = network_domain.id
-        ET.SubElement(create_node, "name").text = name
-        if description is not None:
-            ET.SubElement(create_node, "description").text = description
-        ET.SubElement(create_node, "privateIpv4BaseAddress").text = \
-            private_ipv4_base_address
-        ET.SubElement(create_node, "privateIpv4PrefixSize").text = \
-            str(private_ipv4_prefix_size)
-
-        response = self.connection.request_with_orgId_api_2(
-            'network/deployVlan',
-            method='POST',
-            data=ET.tostring(create_node)).object
-
-        vlan_id = None
-
-        for info in findall(response, 'info', TYPES_URN):
-            if info.get('name') == 'vlanId':
-                vlan_id = info.get('value')
-
-        return self.ex_get_vlan(vlan_id)
-
-    def ex_get_vlan(self, vlan_id):
-        """
-        Get a single VLAN, by it's identifier
-
-        :param   vlan_id: The identifier of the VLAN
-        :type    vlan_id: ``str``
-
-        :return: an instance of `DimensionDataVlan`
-        :rtype: :class:`DimensionDataVlan`
-        """
-        locations = self.list_locations()
-        vlan = self.connection.request_with_orgId_api_2(
-            'network/vlan/%s' % vlan_id).object
-        return self._to_vlan(vlan, locations)
-
-    def ex_update_vlan(self, vlan):
-        """
-        Updates the properties of the given VLAN
-        Only name and description are updated
-
-        :param      vlan: The VLAN to update
-        :type       vlan: :class:`DimensionDataNetworkDomain`
-
-        :return: an instance of `DimensionDataVlan`
-        :rtype: :class:`DimensionDataVlan`
-        """
-        edit_node = ET.Element('editVlan', {'xmlns': TYPES_URN})
-        edit_node.set('id', vlan.id)
-        ET.SubElement(edit_node, "name").text = vlan.name
-        if vlan.description is not None:
-            ET.SubElement(edit_node, "description").text \
-                = vlan.description
-
-        self.connection.request_with_orgId_api_2(
-            'network/editVlan',
-            method='POST',
-            data=ET.tostring(edit_node)).object
-
-        return vlan
-
-    def ex_expand_vlan(self, vlan):
-        """
-        Expands the VLAN to the prefix size in private_ipv4_range_size
-        The expansion will
-        not be permitted if the proposed IP space overlaps with an
-        already deployed VLANs IP space.
-
-        :param      vlan: The VLAN to update
-        :type       vlan: :class:`DimensionDataNetworkDomain`
-
-        :return: an instance of `DimensionDataVlan`
-        :rtype: :class:`DimensionDataVlan`
-        """
-        edit_node = ET.Element('expandVlan', {'xmlns': TYPES_URN})
-        edit_node.set('id', vlan.id)
-        ET.SubElement(edit_node, "privateIpv4PrefixSize").text =\
-            vlan.private_ipv4_range_size
-
-        self.connection.request_with_orgId_api_2(
-            'network/expandVlan',
-            method='POST',
-            data=ET.tostring(edit_node)).object
-
-        return vlan
-
-    def ex_delete_vlan(self, vlan):
-        """
-        Deletes an existing VLAN
-
-        :param      vlan: The VLAN to delete
-        :type       vlan: :class:`DimensionDataNetworkDomain`
-
-        :rtype: ``bool``
-        """
-        delete_node = ET.Element('deleteVlan', {'xmlns': TYPES_URN})
-        delete_node.set('id', vlan.id)
-        result = self.connection.request_with_orgId_api_2(
-            'network/deleteVlan',
-            method='POST',
-            data=ET.tostring(delete_node)).object
-
-        response_code = findtext(result, 'responseCode', TYPES_URN)
-        return response_code in ['IN_PROGRESS', 'OK']
-
-    def ex_list_vlans(self, location=None, network_domain=None, name=None,
-                      ipv4_address=None, ipv6_address=None, state=None):
-        """
-        List VLANs available, can filter by location and/or network domain
-
-        :param      location: Only VLANs in this location (optional)
-        :type       location: :class:`NodeLocation` or ``str``
-
-        :param      network_domain: Only VLANs in this domain (optional)
-        :type       network_domain: :class:`DimensionDataNetworkDomain`
-
-        :param      name: Only VLANs with this name (optional)
-        :type       name: ``str``
-
-        :param      ipv4_address: Only VLANs with this ipv4 address (optional)
-        :type       ipv4_address: ``str``
-
-        :param      ipv6_address: Only VLANs with this ipv6 address  (optional)
-        :type       ipv6_address: ``str``
-
-        :param      state: Only VLANs with this state (optional)
-        :type       state: ``str``
-
-        :return: a list of DimensionDataVlan objects
-        :rtype: ``list`` of :class:`DimensionDataVlan`
-        """
-        params = {}
-        if location is not None:
-            params['datacenterId'] = self._location_to_location_id(location)
-        if network_domain is not None:
-            params['networkDomainId'] = \
-                self._network_domain_to_network_domain_id(network_domain)
-        if name is not None:
-            params['name'] = name
-        if ipv4_address is not None:
-            params['privateIpv4Address'] = ipv4_address
-        if ipv6_address is not None:
-            params['ipv6Address'] = ipv6_address
-        if state is not None:
-            params['state'] = state
-        response = self.connection.request_with_orgId_api_2('network/vlan',
-                                                            params=params) \
-                                  .object
-        return self._to_vlans(response)
-
-    def ex_add_public_ip_block_to_network_domain(self, network_domain):
-        add_node = ET.Element('addPublicIpBlock', {'xmlns': TYPES_URN})
-        ET.SubElement(add_node, "networkDomainId").text =\
-            network_domain.id
-
-        response = self.connection.request_with_orgId_api_2(
-            'network/addPublicIpBlock',
-            method='POST',
-            data=ET.tostring(add_node)).object
-
-        block_id = None
-
-        for info in findall(response, 'info', TYPES_URN):
-            if info.get('name') == 'ipBlockId':
-                block_id = info.get('value')
-        return self.ex_get_public_ip_block(block_id)
-
-    def ex_list_public_ip_blocks(self, network_domain):
-        params = {}
-        params['networkDomainId'] = network_domain.id
-
-        response = self.connection \
-            .request_with_orgId_api_2('network/publicIpBlock',
-                                      params=params).object
-        return self._to_ip_blocks(response)
-
-    def ex_get_public_ip_block(self, block_id):
-        locations = self.list_locations()
-        block = self.connection.request_with_orgId_api_2(
-            'network/publicIpBlock/%s' % block_id).object
-        return self._to_ip_block(block, locations)
-
-    def ex_delete_public_ip_block(self, block):
-        delete_node = ET.Element('removePublicIpBlock', {'xmlns': TYPES_URN})
-        delete_node.set('id', block.id)
-        result = self.connection.request_with_orgId_api_2(
-            'network/removePublicIpBlock',
-            method='POST',
-            data=ET.tostring(delete_node)).object
-
-        response_code = findtext(result, 'responseCode', TYPES_URN)
-        return response_code in ['IN_PROGRESS', 'OK']
-
-    def ex_get_node_by_id(self, id):
-        node = self.connection.request_with_orgId_api_2(
-            'server/server/%s' % id).object
-        return self._to_node(node)
-
-    def ex_list_firewall_rules(self, network_domain, page_size=50,
-                               page_number=1):
-        params = {'pageSize': page_size, 'pageNumber': page_number}
-        params['networkDomainId'] = self._network_domain_to_network_domain_id(
-            network_domain)
-
-        response = self.connection \
-            .request_with_orgId_api_2('network/firewallRule',
-                                      params=params).object
-        return self._to_firewall_rules(response, network_domain)
-
-    def ex_create_firewall_rule(self, network_domain, rule, position,
-                                position_relative_to_rule=None):
-        """
-        Creates a firewall rule
-
-        :param network_domain: The network domain in which to create
-                                the firewall rule
-        :type  network_domain: :class:`DimensionDataNetworkDomain` or ``str``
-
-        :param rule: The rule in which to create
-        :type  rule: :class:`DimensionDataFirewallRule`
-
-        :param position: The position in which to create the rule
-                         There are two types of positions
-                         with position_relative_to_rule arg and without it
-                         With: 'BEFORE' or 'AFTER'
-                         Without: 'FIRST' or 'LAST'
-        :type  position: ``str``
-
-        :param position_relative_to_rule: The rule or rule name in
-                                          which to decide positioning by
-        :type  position_relative_to_rule:
-            :class:`DimensionDataFirewallRule` or ``str``
-
-        :rtype: ``bool``
-        """
-        positions_without_rule = ('FIRST', 'LAST')
-        positions_with_rule = ('BEFORE', 'AFTER')
-
-        create_node = ET.Element('createFirewallRule', {'xmlns': TYPES_URN})
-        ET.SubElement(create_node, "networkDomainId").text = \
-            self._network_domain_to_network_domain_id(network_domain)
-        ET.SubElement(create_node, "name").text = rule.name
-        ET.SubElement(create_node, "action").text = rule.action
-        ET.SubElement(create_node, "ipVersion").text = rule.ip_version
-        ET.SubElement(create_node, "protocol").text = rule.protocol
-        # Setup source port rule
-        source = ET.SubElement(create_node, "source")
-        source_ip = ET.SubElement(source, 'ip')
-        if rule.source.any_ip:
-            source_ip.set('address', 'ANY')
-        else:
-            source_ip.set('address', rule.source.ip_address)
-            if rule.source.ip_prefix_size is not None:
-                source_ip.set('prefixSize', str(rule.source.ip_prefix_size))
-            if rule.source.port_begin is not None:
-                source_port = ET.SubElement(source, 'port')
-                source_port.set('begin', rule.source.port_begin)
-            if rule.source.port_end is not None:
-                source_port.set('end', rule.source.port_end)
-        # Setup destination port rule
-        dest = ET.SubElement(create_node, "destination")
-        dest_ip = ET.SubElement(dest, 'ip')
-        if rule.destination.any_ip:
-            dest_ip.set('address', 'ANY')
-        else:
-            dest_ip.set('address', rule.destination.ip_address)
-            if rule.destination.ip_prefix_size is not None:
-                dest_ip.set('prefixSize', rule.destination.ip_prefix_size)
-            if rule.destination.port_begin is not None:
-                dest_port = ET.SubElement(dest, 'port')
-                dest_port.set('begin', rule.destination.port_begin)
-            if rule.destination.port_end is not None:
-                dest_port.set('end', rule.destination.port_end)
-        # Set up positioning of rule
-        ET.SubElement(create_node, "enabled").text = str(rule.enabled).lower()
-        placement = ET.SubElement(create_node, "placement")
-        if position_relative_to_rule is not None:
-            if position not in positions_with_rule:
-                raise ValueError("When position_relative_to_rule is specified"
-                                 " position must be %s"
-                                 % ', '.join(positions_with_rule))
-            if isinstance(position_relative_to_rule,
-                          DimensionDataFirewallRule):
-                rule_name = position_relative_to_rule.name
-            else:
-                rule_name = position_relative_to_rule
-            placement.set('relativeToRule', rule_name)
-        else:
-            if position not in positions_without_rule:
-                raise ValueError("When position_relative_to_rule is not"
-                                 " specified position must be %s"
-                                 % ', '.join(positions_without_rule))
-        placement.set('position', position)
-
-        response = self.connection.request_with_orgId_api_2(
-            'network/createFirewallRule',
-            method='POST',
-            data=ET.tostring(create_node)).object
-
-        rule_id = None
-        for info in findall(response, 'info', TYPES_URN):
-            if info.get('name') == 'firewallRuleId':
-                rule_id = info.get('value')
-        rule.id = rule_id
-        return rule
-
-    def ex_get_firewall_rule(self, network_domain, rule_id):
-        locations = self.list_locations()
-        rule = self.connection.request_with_orgId_api_2(
-            'network/firewallRule/%s' % rule_id).object
-        return self._to_firewall_rule(rule, locations, network_domain)
-
-    def ex_set_firewall_rule_state(self, rule, state):
-        """
-        Change the state (enabled or disabled) of a rule
-
-        :param rule: The rule to delete
-        :type  rule: :class:`DimensionDataFirewallRule`
-
-        :param state: The desired state enabled (True) or disabled (False)
-        :type  state: ``bool``
-
-        :rtype: ``bool``
-        """
-        update_node = ET.Element('editFirewallRule', {'xmlns': TYPES_URN})
-        update_node.set('id', rule.id)
-        ET.SubElement(update_node, 'enabled').text = str(state).lower()
-        result = self.connection.request_with_orgId_api_2(
-            'network/editFirewallRule',
-            method='POST',
-            data=ET.tostring(update_node)).object
-
-        response_code = findtext(result, 'responseCode', TYPES_URN)
-        return response_code in ['IN_PROGRESS', 'OK']
-
-    def ex_delete_firewall_rule(self, rule):
-        """
-        Delete a firewall rule
-
-        :param rule: The rule to delete
-        :type  rule: :class:`DimensionDataFirewallRule`
-
-        :rtype: ``bool``
-        """
-        update_node = ET.Element('deleteFirewallRule', {'xmlns': TYPES_URN})
-        update_node.set('id', rule.id)
-        result = self.connection.request_with_orgId_api_2(
-            'network/deleteFirewallRule',
-            method='POST',
-            data=ET.tostring(update_node)).object
-
-        response_code = findtext(result, 'responseCode', TYPES_URN)
-        return response_code in ['IN_PROGRESS', 'OK']
-
-    def ex_create_nat_rule(self, network_domain, internal_ip, external_ip):
-        """
-        Create a NAT rule
-
-        :param  network_domain: The network domain the rule belongs to
-        :type   network_domain: :class:`DimensionDataNetworkDomain`
-
-        :param  internal_ip: The IPv4 address internally
-        :type   internal_ip: ``str``
-
-        :param  external_ip: The IPv4 address externally
-        :type   external_ip: ``str``
-
-        :rtype: :class:`DimensionDataNatRule`
-        """
-        create_node = ET.Element('createNatRule', {'xmlns': TYPES_URN})
-        ET.SubElement(create_node, 'networkDomainId').text = network_domain.id
-        ET.SubElement(create_node, 'internalIp').text = internal_ip
-        ET.SubElement(create_node, 'externalIp').text = external_ip
-        result = self.connection.request_with_orgId_api_2(
-            'network/createNatRule',
-            method='POST',
-            data=ET.tostring(create_node)).object
-
-        rule_id = None
-        for info in findall(result, 'info', TYPES_URN):
-            if info.get('name') == 'natRuleId':
-                rule_id = info.get('value')
-
-        return DimensionDataNatRule(
-            id=rule_id,
-            network_domain=network_domain,
-            internal_ip=internal_ip,
-            external_ip=external_ip,
-            status=NodeState.RUNNING
-        )
-
-    def ex_list_nat_rules(self, network_domain):
-        """
-        Get NAT rules for the network domain
-
-        :param  network_domain: The network domain the rules belongs to
-        :type   network_domain: :class:`DimensionDataNetworkDomain`
-
-        :rtype: ``list`` of :class:`DimensionDataNatRule`
-        """
-        params = {}
-        params['networkDomainId'] = network_domain.id
-
-        response = self.connection \
-            .request_with_orgId_api_2('network/natRule',
-                                      params=params).object
-        return self._to_nat_rules(response, network_domain)
-
-    def ex_get_nat_rule(self, network_domain, rule_id):
-        """
-        Get a NAT rule by ID
-
-        :param  network_domain: The network domain the rule belongs to
-        :type   network_domain: :class:`DimensionDataNetworkDomain`
-
-        :param  rule_id: The ID of the NAT rule to fetch
-        :type   rule_id: ``str``
-
-        :rtype: :class:`DimensionDataNatRule`
-        """
-        rule = self.connection.request_with_orgId_api_2(
-            'network/natRule/%s' % rule_id).object
-        return self._to_nat_rule(rule, network_domain)
-
-    def ex_delete_nat_rule(self, rule):
-        """
-        Delete an existing NAT rule
-
-        :param  rule: The rule to delete
-        :type   rule: :class:`DimensionDataNatRule`
-
-        :rtype: ``bool``
-        """
-        update_node = ET.Element('deleteNatRule', {'xmlns': TYPES_URN})
-        update_node.set('id', rule.id)
-        result = self.connection.request_with_orgId_api_2(
-            'network/deleteNatRule',
-            method='POST',
-            data=ET.tostring(update_node)).object
-
-        response_code = findtext(result, 'responseCode', TYPES_URN)
-        return response_code in ['IN_PROGRESS', 'OK']
-
-    def ex_get_location_by_id(self, id):
-        """
-        Get location by ID.
-
-        :param  id: ID of the node location which should be used
-        :type   id: ``str``
-
-        :rtype: :class:`NodeLocation`
-        """
-        location = None
-        if id is not None:
-            location = self.list_locations(ex_id=id)[0]
-        return location
-
-    def ex_wait_for_state(self, state, func, poll_interval=2,
-                          timeout=60, *args, **kwargs):
-        """
-        Wait for the function which returns a instance
-        with field status to match
-
-        Keep polling func until one of the desired states is matched
-
-        :param state: Either the desired state (`str`) or a `list` of states
-        :type  state: ``str`` or ``list``
-
-        :param  func: The function to call, e.g. ex_get_vlan
-        :type   func: ``function``
-
-        :param  poll_interval: The number of seconds to wait between checks
-        :type   poll_interval: `int`
-
-        :param  timeout: The total number of seconds to wait to reach a state
-        :type   timeout: `int`
-
-        :param  args: The arguments for func
-        :type   args: Positional arguments
-
-        :param  kwargs: The arguments for func
-        :type   kwargs: Keyword arguments
-        """
-        return self.connection.wait_for_state(state, func, poll_interval,
-                                              timeout, *args, **kwargs)
-
-    def ex_enable_monitoring(self, node, service_plan="ESSENTIALS"):
-        """
-        Enables cloud monitoring on a node
-
-        :param   node: The node to monitor
-        :type    node: :class:`Node`
-
-        :param   service_plan: The service plan, one of ESSENTIALS or
-                               ADVANCED
-        :type    service_plan: ``str``
-
-        :rtype: ``bool``
-        """
-        update_node = ET.Element('enableServerMonitoring',
-                                 {'xmlns': TYPES_URN})
-        update_node.set('id', node.id)
-        ET.SubElement(update_node, 'servicePlan').text = service_plan
-        result = self.connection.request_with_orgId_api_2(
-            'server/enableServerMonitoring',
-            method='POST',
-            data=ET.tostring(update_node)).object
-
-        response_code = findtext(result, 'responseCode', TYPES_URN)
-        return response_code in ['IN_PROGRESS', 'OK']
-
-    def ex_update_monitoring_plan(self, node, service_plan="ESSENTIALS"):
-        """
-        Updates the service plan on a node with monitoring
-
-        :param   node: The node to monitor
-        :type    node: :class:`Node`
-
-        :param   service_plan: The service plan, one of ESSENTIALS or
-                               ADVANCED
-        :type    service_plan: ``str``
-
-        :rtype: ``bool``
-        """
-        update_node = ET.Element('changeServerMonitoringPlan',
-                                 {'xmlns': TYPES_URN})
-        update_node.set('id', node.id)
-        ET.SubElement(update_node, 'servicePlan').text = service_plan
-        result = self.connection.request_with_orgId_api_2(
-            'server/changeServerMonitoringPlan',
-            method='POST',
-            data=ET.tostring(update_node)).object
-
-        response_code = findtext(result, 'responseCode', TYPES_URN)
-        return response_code in ['IN_PROGRESS', 'OK']
-
-    def ex_disable_monitoring(self, node):
-        """
-        Disables cloud monitoring for a node
-
-        :param   node: The node to stop monitoring
-        :type    node: :class:`Node`
-
-        :rtype: ``bool``
-        """
-        update_node = ET.Element('disableServerMonitoring',
-                                 {'xmlns': TYPES_URN})
-        update_node.set('id', node.id)
-        result = self.connection.request_with_orgId_api_2(
-            'server/disableServerMonitoring',
-            method='POST',
-            data=ET.tostring(update_node)).object
-
-        response_code = findtext(result, 'responseCode', TYPES_URN)
-        return response_code in ['IN_PROGRESS', 'OK']
-
-    def ex_add_storage_to_node(self, node, amount, speed='STANDARD'):
-        """
-        Add storage to the node
-
-        :param  node: The server to add storage to
-        :type   node: :class:`Node`
-
-        :param  amount: The amount of storage to add, in GB
-        :type   amount: ``int``
-
-        :param  speed: The disk speed type
-        :type   speed: ``str``
-
-        :rtype: ``bool``
-        """
-        result = self.connection.request_with_orgId_api_1(
-            'server/%s?addLocalStorage&amount=%s&speed=%s' %
-            (node.id, amount, speed)).object
-        response_code = findtext(result, 'result', GENERAL_NS)
-        return response_code in ['IN_PROGRESS', 'SUCCESS']
-
-    def ex_remove_storage_from_node(self, node, disk_id):
-        """
-        Remove storage from a node
-
-        :param  node: The server to add storage to
-        :type   node: :class:`Node`
-
-        :param  disk_id: The ID of the disk to remove
-        :type   disk_id: ``str``
-
-        :rtype: ``bool``
-        """
-        result = self.connection.request_with_orgId_api_1(
-            'server/%s/disk/%s?delete' %
-            (node.id, disk_id)).object
-        response_code = findtext(result, 'result', GENERAL_NS)
-        return response_code in ['IN_PROGRESS', 'SUCCESS']
-
-    def ex_change_storage_speed(self, node, disk_id, speed):
-        """
-        Change the speed (disk tier) of a disk
-
-        :param  node: The server to change the disk speed of
-        :type   node: :class:`Node`
-
-        :param  disk_id: The ID of the disk to change
-        :type   disk_id: ``str``
-
-        :param  speed: The disk speed type e.g. STANDARD
-        :type   speed: ``str``
-
-        :rtype: ``bool``
-        """
-        create_node = ET.Element('ChangeDiskSpeed', {'xmlns': SERVER_NS})
-        ET.SubElement(create_node, 'speed').text = speed
-        result = self.connection.request_with_orgId_api_1(
-            'server/%s/disk/%s/changeSpeed' %
-            (node.id, disk_id),
-            method='POST',
-            data=ET.tostring(create_node)).object
-        response_code = findtext(result, 'result', GENERAL_NS)
-        return response_code in ['IN_PROGRESS', 'SUCCESS']
-
-    def ex_change_storage_size(self, node, disk_id, size):
-        """
-        Change the size of a disk
-
-        :param  node: The server to change the disk of
-        :type   node: :class:`Node`
-
-        :param  disk_id: The ID of the disk to resize
-        :type   disk_id: ``str``
-
-        :param  size: The disk size in GB
-        :type   size: ``int``
-
-        :rtype: ``bool``
-        """
-        create_node = ET.Element('ChangeDiskSize', {'xmlns': SERVER_NS})
-        ET.SubElement(create_node, 'newSizeGb').text = str(size)
-        result = self.connection.request_with_orgId_api_1(
-            'server/%s/disk/%s/changeSize' %
-            (node.id, disk_id),
-            method='POST',
-            data=ET.tostring(create_node)).object
-        response_code = findtext(result, 'result', GENERAL_NS)
-        return response_code in ['IN_PROGRESS', 'SUCCESS']
-
-    def ex_reconfigure_node(self, node, memory_gb, cpu_count, cores_per_socket,
-                            cpu_performance):
-        """
-        Reconfigure the virtual hardware specification of a node
-
-        :param  node: The server to change
-        :type   node: :class:`Node`
-
-        :param  memory_gb: The amount of memory in GB (optional)
-        :type   memory_gb: ``int``
-
-        :param  cpu_count: The number of CPU (optional)
-        :type   cpu_count: ``int``
-
-        :param  cores_per_socket: Number of CPU cores per socket (optional)
-        :type   cores_per_socket: ``int``
-
-        :param  cpu_performance: CPU Performance type (optional)
-        :type   cpu_performance: ``str``
-
-        :rtype: ``bool``
-        """
-        update = ET.Element('reconfigureServer', {'xmlns': TYPES_URN})
-        update.set('id', node.id)
-        if memory_gb is not None:
-            ET.SubElement(update, 'memoryGb').text = str(memory_gb)
-        if cpu_count is not None:
-            ET.SubElement(update, 'cpuCount').text = str(cpu_count)
-        if cpu_performance is not None:
-            ET.SubElement(update, 'cpuSpeed').text = cpu_performance
-        if cores_per_socket is not None:
-            ET.SubElement(update, 'coresPerSocket').text = \
-                str(cores_per_socket)
-        result = self.connection.request_with_orgId_api_2(
-            'server/reconfigureServer',
-            method='POST',
-            data=ET.tostring(update)).object
-        response_code = findtext(result, 'responseCode', TYPES_URN)
-        return response_code in ['IN_PROGRESS', 'OK']
-
-    def ex_clone_node_to_image(self, node, image_name, image_description=None):
-        """
-        Clone a server into a customer image.
-
-        :param  node: The server to clone
-        :type   node: :class:`Node`
-
-        :param  image_name: The name of the clone image
-        :type   image_name: ``str``
-
-        :param  description: The description of the image
-        :type   description: ``str``
-
-        :rtype: ``bool``
-        """
-        if image_description is None:
-            image_description = ''
-        result = self.connection.request_with_orgId_api_1(
-            'server/%s?clone=%s&desc=%s' %
-            (node.id, image_name, image_description)).object
-        response_code = findtext(result, 'result', GENERAL_NS)
-        return response_code in ['IN_PROGRESS', 'SUCCESS']
-
-    def ex_list_customer_images(self, location=None):
-        """
-        Return a list of customer imported images
-
-        :param location: The target location
-        :type  location: :class:`NodeLocation` or ``str``
-
-        :rtype: ``list`` of :class:`NodeImage`
-        """
-        params = {}
-        if location is not None:
-            params['datacenterId'] = self._location_to_location_id(location)
-
-        return self._to_images(
-            self.connection.request_with_orgId_api_2(
-                'image/customerImage',
-                params=params)
-            .object, 'customerImage')
-
-    def ex_get_base_image_by_id(self, id):
-        """
-        Gets a Base image in the Dimension Data Cloud given the id
-
-        :param id: The id of the image
-        :type  id: ``str``
-
-        :rtype: :class:`NodeImage`
-        """
-        image = self.connection.request_with_orgId_api_2(
-            'image/osImage/%s' % id).object
-        return self._to_image(image)
-
-    def ex_get_customer_image_by_id(self, id):
-        """
-        Gets a Customer image in the Dimension Data Cloud given the id
-
-        :param id: The id of the image
-        :type  id: ``str``
-
-        :rtype: :class:`NodeImage`
-        """
-        image = self.connection.request_with_orgId_api_2(
-            'image/customerImage/%s' % id).object
-        return self._to_image(image)
-
-    def ex_get_image_by_id(self, id):
-        """
-        Gets a Base/Customer image in the Dimension Data Cloud given the id
-
-        Note: This first checks the base image
-              If it is not a base image we check if it is a customer image
-              If it is not in either of these a DimensionDataAPIException
-              is thrown
-
-        :param id: The id of the image
-        :type  id: ``str``
-
-        :rtype: :class:`NodeImage`
-        """
-        try:
-            return self.ex_get_base_image_by_id(id)
-        except DimensionDataAPIException as e:
-            if e.code != 'RESOURCE_NOT_FOUND':
-                raise e
-        return self.ex_get_customer_image_by_id(id)
-
-    def _list_nodes_single_page(self, params={}):
-        return self.connection.request_with_orgId_api_2(
-            'server/server', params=params).object
-
-    def _to_images(self, object, el_name='osImage'):
-        images = []
-        locations = self.list_locations()
-
-        for element in object.findall(fixxpath(el_name, TYPES_URN)):
-            images.append(self._to_image(element, locations))
-
-        return images
-
-    def _to_image(self, element, locations=None):
-        location_id = element.get('datacenterId')
-        if locations is None:
-            locations = self.list_locations(location_id)
-        location = list(filter(lambda x: x.id == location_id,
-                               locations))[0]
-        cpu_spec = self._to_cpu_spec(element.find(fixxpath('cpu', TYPES_URN)))
-        os_el = element.find(fixxpath('operatingSystem', TYPES_URN))
-        if element.tag.endswith('customerImage'):
-            is_customer_image = True
-        else:
-            is_customer_image = False
-        extra = {
-            'description': findtext(element, 'description', TYPES_URN),
-            'OS_type': os_el.get('family'),
-            'OS_displayName': os_el.get('displayName'),
-            'cpu': cpu_spec,
-            'memoryGb': findtext(element, 'memoryGb', TYPES_URN),
-            'osImageKey': findtext(element, 'osImageKey', TYPES_URN),
-            'created': findtext(element, 'createTime', TYPES_URN),
-            'location': location,
-            'isCustomerImage': is_customer_image
-        }
-
-        return NodeImage(id=element.get('id'),
-                         name=str(findtext(element, 'name', TYPES_URN)),
-                         extra=extra,
-                         driver=self.connection.driver)
-
-    def _to_nat_rules(self, object, network_domain):
-        rules = []
-        for element in findall(object, 'natRule', TYPES_URN):
-            rules.append(
-                self._to_nat_rule(element, network_domain))
-
-        return rules
-
-    def _to_nat_rule(self, element, network_domain):
-        return DimensionDataNatRule(
-            id=element.get('id'),
-            network_domain=network_domain,
-            internal_ip=findtext(element, 'internalIp', TYPES_URN),
-            external_ip=findtext(element, 'externalIp', TYPES_URN),
-            status=findtext(element, 'state', TYPES_URN))
-
-    def _to_anti_affinity_rules(self, object):
-        rules = []
-        for element in findall(object, 'antiAffinityRule', TYPES_URN):
-            rules.append(
-                self._to_anti_affinity_rule(element))
-        return rules
-
-    def _to_anti_affinity_rule(self, element):
-        node_list = []
-        for node in findall(element, 'serverSummary', TYPES_URN):
-            node_list.append(node.get('id'))
-        return DimensionDataAntiAffinityRule(
-            id=element.get('id'),
-            node_list=node_list
-        )
-
-    def _to_firewall_rules(self, object, network_domain):
-        rules = []
-        locations = self.list_locations()
-        for element in findall(object, 'firewallRule', TYPES_URN):
-            rules.append(
-                self._to_firewall_rule(element, locations, network_domain))
-
-        return rules
-
-    def _to_firewall_rule(self, element, locations, network_domain):
-        location_id = element.get('datacenterId')
-        location = list(filter(lambda x: x.id == location_id,
-                               locations))[0]
-
-        return DimensionDataFirewallRule(
-            id=element.get('id'),
-            network_domain=network_domain,
-            name=findtext(element, 'name', TYPES_URN),
-            action=findtext(element, 'action', TYPES_URN),
-            ip_version=findtext(element, 'ipVersion', TYPES_URN),
-            protocol=findtext(element, 'protocol', TYPES_URN),
-            enabled=findtext(element, 'enabled', TYPES_URN),
-            source=self._to_firewall_address(
-                element.find(fixxpath('source', TYPES_URN))),
-            destination=self._to_firewall_address(
-                element.find(fixxpath('destination', TYPES_URN))),
-            location=location,
-            status=findtext(element, 'state', TYPES_URN))
-
-    def _to_firewall_address(self, element):
-        ip = element.find(fixxpath('ip', TYPES_URN))
-        port = element.find(fixxpath('port', TYPES_URN))
-        return DimensionDataFirewallAddress(
-            any_ip=ip.get('address') == 'ANY',
-            ip_address=ip.get('address'),
-            ip_prefix_size=ip.get('prefixSize'),
-            port_begin=port.get('begin') if port is not None else None,
-            port_end=port.get('end') if port is not None else None
-        )
-
-    def _to_ip_blocks(self, object):
-        blocks = []
-        locations = self.list_locations()
-        for element in findall(object, 'publicIpBlock', TYPES_URN):
-            blocks.append(self._to_ip_block(element, locations))
-
-        return blocks
-
-    def _to_ip_block(self, element, locations):
-        location_id = element.get('datacenterId')
-        location = list(filter(lambda x: x.id == location_id,
-                               locations))[0]
-
-        return DimensionDataPublicIpBlock(
-            id=element.get('id'),
-            network_domain=self.ex_get_network_domain(
-                findtext(element, 'networkDomainId', TYPES_URN)
-            ),
-            base_ip=findtext(element, 'baseIp', TYPES_URN),
-            size=findtext(element, 'size', TYPES_URN),
-            location=location,
-            status=findtext(element, 'state', TYPES_URN))
-
-    def _to_networks(self, object):
-        networks = []
-        locations = self.list_locations()
-        for element in findall(object, 'network', NETWORK_NS):
-            networks.append(self._to_network(element, locations))
-
-        return networks
-
-    def _to_network(self, element, locations):
-        multicast = False
-        if findtext(element, 'multicast', NETWORK_NS) == 'true':
-            multicast = True
-
-        status = self._to_status(element.find(fixxpath('status', NETWORK_NS)))
-
-        location_id = findtext(element, 'location', NETWORK_NS)
-        location = list(filter(lambda x: x.id == location_id,
-                               locations))[0]
-
-        return DimensionDataNetwork(
-            id=findtext(element, 'id', NETWORK_NS),
-            name=findtext(element, 'name', NETWORK_NS),
-            description=findtext(element, 'description',
-                                 NETWORK_NS),
-            location=location,
-            private_net=findtext(element, 'privateNet',
-                                 NETWORK_NS),
-            multicast=multicast,
-            status=status)
-
-    def _to_network_domains(self, object):
-        network_domains = []
-        locations = self.list_locations()
-        for element in findall(object, 'networkDomain', TYPES_URN):
-            network_domains.append(self._to_network_domain(element, locations))
-
-        return network_domains
-
-    def _to_network_domain(self, element, locations):
-        location_id = element.get('datacenterId')
-        location = list(filter(lambda x: x.id == location_id,
-                               locations))[0]
-        plan = findtext(element, 'type', TYPES_URN)
-        if plan is 'ESSENTIALS':
-            plan_type = NetworkDomainServicePlan.ESSENTIALS
-        else:
-            plan_type = NetworkDomainServicePlan.ADVANCED
-        return DimensionDataNetworkDomain(
-            id=element.get('id'),
-            name=findtext(element, 'name', TYPES_URN),
-            description=findtext(element, 'description', TYPES_URN),
-            plan=plan_type,
-            location=location,
-            status=findtext(element, 'state', TYPES_URN))
-
-    def _to_vlans(self, object):
-        vlans = []
-        locations = self.list_locations()
-        for element in findall(object, 'vlan', TYPES_URN):
-            vlans.append(self._to_vlan(element, locations=locations))
-
-        return vlans
-
-    def _to_vlan(self, element, locations):
-        location_id = element.get('datacenterId')
-        location = list(filter(lambda x: x.id == location_id,
-                               locations))[0]
-        ip_range = element.find(fixxpath('privateIpv4Range', TYPES_URN))
-        ip6_range = element.find(fixxpath('ipv6Range', TYPES_URN))
-        network_domain_el = element.find(
-            fixxpath('networkDomain', TYPES_URN))
-        network_domain = self.ex_get_network_domain(
-            network_domain_el.get('id'))
-        return DimensionDataVlan(
-            id=element.get('id'),
-            name=findtext(element, 'name', TYPES_URN),
-            description=findtext(element, 'description',
-                                 TYPES_URN),
-            network_domain=network_domain,
-            private_ipv4_range_address=ip_range.get('address'),
-            private_ipv4_range_size=int(ip_range.get('prefixSize')),
-            ipv6_range_address=ip6_range.get('address'),
-            ipv6_range_size=int(ip6_range.get('prefixSize')),
-            ipv4_gateway=findtext(
-                element,
-                'ipv4GatewayAddress',
-                TYPES_URN),
-            ipv6_gateway=findtext(
-                element,
-                'ipv6GatewayAddress',
-                TYPES_URN),
-            location=location,
-            status=findtext(element, 'state', TYPES_URN))
-
-    def _to_locations(self, object):
-        locations = []
-        for element in object.findall(fixxpath('datacenter', TYPES_URN)):
-            locations.append(self._to_location(element))
-
-        return locations
-
-    def _to_location(self, element):
-        l = NodeLocation(id=element.get('id'),
-                         name=findtext(element, 'displayName', TYPES_URN),
-                         country=findtext(element, 'country', TYPES_URN),
-                         driver=self)
-        return l
-
-    def _to_cpu_spec(self, element):
-        return DimensionDataServerCpuSpecification(
-            cpu_count=int(element.get('count')),
-            cores_per_socket=int(element.get('coresPerSocket')),
-            performance=element.get('speed'))
-
-    def _to_vmware_tools(self, element):
-        return DimensionDataServerVMWareTools(
-            status=element.get('runningStatus'),
-            version_status=element.get('versionStatus'),
-            api_version=element.get('apiVersion'))
-
-    def _to_disks(self, object):
-        disk_elements = object.findall(fixxpath('disk', TYPES_URN))
-        return [self._to_disk(el) for el in disk_elements]
-
-    def _to_disk(self, element):
-        return DimensionDataServerDisk(
-            id=element.get('id'),
-            scsi_id=int(element.get('scsiId')),
-            size_gb=int(element.get('sizeGb')),
-            speed=element.get('speed'),
-            state=element.get('state')
-        )
-
-    def _to_nodes(self, object):
-        node_elements = object.findall(fixxpath('server', TYPES_URN))
-        return [self._to_node(el) for el in node_elements]
-
-    def _to_node(self, element):
-        started = findtext(element, 'started', TYPES_URN)
-        status = self._to_status(element.find(fixxpath('progress', TYPES_URN)))
-        dd_state = findtext(element, 'state', TYPES_URN)
-
-        node_state = self._get_node_state(dd_state, started, status.action)
-
-        has_network_info \
-            = element.find(fixxpath('networkInfo', TYPES_URN)) is not None
-        cpu_spec = self._to_cpu_spec(element.find(fixxpath('cpu', TYPES_URN)))
-        disks = self._to_disks(element)
-        vmware_tools = self._to_vmware_tools(
-            element.find(fixxpath('vmwareTools', TYPES_URN)))
-        extra = {
-            'description': findtext(element, 'description', TYPES_URN),
-            'sourceImageId': findtext(element, 'sourceImageId', TYPES_URN),
-            'networkId': findtext(element, 'networkId', TYPES_URN),
-            'networkDomainId':
-                element.find(fixxpath('networkInfo', TYPES_URN))
-                .get('networkDomainId')
-                if has_network_info else None,
-            'datacenterId': element.get('datacenterId'),
-            'deployedTime': findtext(element, 'createTime', TYPES_URN),
-            'cpu': cpu_spec,
-            'memoryMb': int(findtext(
-                element,
-                'memoryGb',
-                TYPES_URN)) * 1024,
-            'OS_id': element.find(fixxpath(
-                'operatingSystem',
-                TYPES_URN)).get('id'),
-            'OS_type': element.find(fixxpath(
-                'operatingSystem',
-                TYPES_URN)).get('family'),
-            'OS_displayName': element.find(fixxpath(
-                'operatingSystem',
-                TYPES_URN)).get('displayName'),
-            'status': status,
-            'disks': disks,
-            'vmWareTools': vmware_tools
-        }
-
-        public_ip = findtext(element, 'publicIpAddress', TYPES_URN)
-
-        private_ip = element.find(
-            fixxpath('networkInfo/primaryNic', TYPES_URN)) \
-            .get('privateIpv4') \
-            if has_network_info else \
-            element.find(fixxpath('nic', TYPES_URN)).get('privateIpv4')
-
-        extra['ipv6'] = element.find(
-            fixxpath('networkInfo/primaryNic', TYPES_URN)) \
-            .get('ipv6') \
-            if has_network_info else \
-            element.find(fixxpath('nic', TYPES_URN)).get('ipv6')
-
-        n = Node(id=element.get('id'),
-                 name=findtext(element, 'name', TYPES_URN),
-                 state=node_state,
-                 public_ips=[public_ip] if public_ip is not None else [],
-                 private_ips=[private_ip] if private_ip is not None else [],
-                 driver=self.connection.d

<TRUNCATED>

[45/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
Removed sdist


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/8afcda91
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/8afcda91
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/8afcda91

Branch: refs/heads/trunk
Commit: 8afcda914b6ba5adc042caba00a17c09da6ebd34
Parents: d728af2
Author: anthony-shaw <an...@apache.org>
Authored: Thu Apr 14 21:42:42 2016 +1000
Committer: anthony-shaw <an...@apache.org>
Committed: Thu Apr 14 21:42:42 2016 +1000

----------------------------------------------------------------------
 apache-libcloud-1.0.0rc2/CHANGES.rst            | 4205 -----------
 apache-libcloud-1.0.0rc2/LICENSE                |  202 -
 apache-libcloud-1.0.0rc2/MANIFEST.in            |   24 -
 apache-libcloud-1.0.0rc2/NOTICE                 |    8 -
 apache-libcloud-1.0.0rc2/README.rst             |   70 -
 apache-libcloud-1.0.0rc2/demos/compute_demo.py  |  118 -
 apache-libcloud-1.0.0rc2/demos/gce_demo.py      |  706 --
 apache-libcloud-1.0.0rc2/demos/secrets.py-dist  |   38 -
 apache-libcloud-1.0.0rc2/example_aliyun_ecs.py  |   79 -
 apache-libcloud-1.0.0rc2/example_aliyun_oss.py  |   82 -
 apache-libcloud-1.0.0rc2/example_aliyun_slb.py  |   55 -
 apache-libcloud-1.0.0rc2/example_compute.py     |   35 -
 apache-libcloud-1.0.0rc2/example_dns.py         |   29 -
 .../example_loadbalancer.py                     |   71 -
 apache-libcloud-1.0.0rc2/example_storage.py     |   29 -
 apache-libcloud-1.0.0rc2/libcloud/__init__.py   |   77 -
 .../libcloud/backup/__init__.py                 |    0
 .../libcloud/backup/base.py                     |  489 --
 .../libcloud/backup/drivers/__init__.py         |    0
 .../libcloud/backup/drivers/dimensiondata.py    |  688 --
 .../libcloud/backup/drivers/dummy.py            |   41 -
 .../libcloud/backup/drivers/ebs.py              |  413 --
 .../libcloud/backup/drivers/gce.py              |  478 --
 .../libcloud/backup/providers.py                |   38 -
 .../libcloud/backup/types.py                    |   63 -
 .../libcloud/common/__init__.py                 |    0
 .../libcloud/common/abiquo.py                   |  274 -
 .../libcloud/common/aliyun.py                   |  239 -
 apache-libcloud-1.0.0rc2/libcloud/common/aws.py |  426 --
 .../libcloud/common/azure.py                    |  294 -
 .../libcloud/common/azure_arm.py                |  124 -
 .../libcloud/common/base.py                     | 1179 ---
 .../libcloud/common/brightbox.py                |  101 -
 .../libcloud/common/buddyns.py                  |   77 -
 .../libcloud/common/cloudsigma.py               |  165 -
 .../libcloud/common/cloudstack.py               |  199 -
 .../libcloud/common/digitalocean.py             |  250 -
 .../libcloud/common/dimensiondata.py            | 1406 ----
 .../libcloud/common/dnsimple.py                 |   53 -
 .../libcloud/common/durabledns.py               |  285 -
 .../libcloud/common/exceptions.py               |   75 -
 .../libcloud/common/gandi.py                    |  194 -
 .../libcloud/common/gogrid.py                   |  183 -
 .../libcloud/common/google.py                   |  828 ---
 .../libcloud/common/hostvirtual.py              |   77 -
 .../libcloud/common/linode.py                   |  186 -
 .../libcloud/common/liquidweb.py                |  229 -
 .../libcloud/common/luadns.py                   |   69 -
 .../libcloud/common/nfsn.py                     |  114 -
 .../libcloud/common/nsone.py                    |   62 -
 .../libcloud/common/onapp.py                    |   49 -
 .../libcloud/common/openstack.py                |  430 --
 .../libcloud/common/openstack_identity.py       | 1394 ----
 .../libcloud/common/pointdns.py                 |   55 -
 .../libcloud/common/providers.py                |  107 -
 .../libcloud/common/rackspace.py                |   24 -
 .../libcloud/common/runabove.py                 |  164 -
 .../libcloud/common/softlayer.py                |   88 -
 .../libcloud/common/types.py                    |  143 -
 .../libcloud/common/vultr.py                    |  121 -
 .../libcloud/common/worldwidedns.py             |  195 -
 .../libcloud/common/xmlrpc.py                   |  108 -
 .../libcloud/common/zonomi.py                   |  138 -
 .../libcloud/compute/__init__.py                |    3 -
 .../libcloud/compute/base.py                    | 1531 ----
 .../libcloud/compute/deployment.py              |  263 -
 .../libcloud/compute/deprecated.py              |   50 -
 .../libcloud/compute/drivers/__init__.py        |   44 -
 .../libcloud/compute/drivers/abiquo.py          |  795 --
 .../libcloud/compute/drivers/auroracompute.py   |   57 -
 .../libcloud/compute/drivers/azure.py           | 3591 ----------
 .../libcloud/compute/drivers/azure_arm.py       | 1281 ----
 .../libcloud/compute/drivers/bluebox.py         |  235 -
 .../libcloud/compute/drivers/brightbox.py       |  306 -
 .../libcloud/compute/drivers/bsnl.py            |   53 -
 .../libcloud/compute/drivers/ciscoccs.py        |   56 -
 .../libcloud/compute/drivers/cloudsigma.py      | 2096 ------
 .../libcloud/compute/drivers/cloudstack.py      | 4754 ------------
 .../libcloud/compute/drivers/cloudwatt.py       |  154 -
 .../libcloud/compute/drivers/digitalocean.py    |  592 --
 .../libcloud/compute/drivers/dimensiondata.py   | 2311 ------
 .../libcloud/compute/drivers/dummy.py           |  349 -
 .../libcloud/compute/drivers/ec2.py             | 6773 ------------------
 .../libcloud/compute/drivers/ecp.py             |  385 -
 .../libcloud/compute/drivers/ecs.py             | 1533 ----
 .../libcloud/compute/drivers/elastichosts.py    |  236 -
 .../libcloud/compute/drivers/elasticstack.py    |  495 --
 .../libcloud/compute/drivers/exoscale.py        |   31 -
 .../libcloud/compute/drivers/gandi.py           |  825 ---
 .../libcloud/compute/drivers/gce.py             | 5860 ---------------
 .../libcloud/compute/drivers/gogrid.py          |  464 --
 .../libcloud/compute/drivers/gridspot.py        |  127 -
 .../libcloud/compute/drivers/hostvirtual.py     |  449 --
 .../libcloud/compute/drivers/ikoula.py          |   31 -
 .../libcloud/compute/drivers/indosat.py         |   56 -
 .../compute/drivers/internetsolutions.py        |   56 -
 .../libcloud/compute/drivers/joyent.py          |  240 -
 .../libcloud/compute/drivers/kili.py            |   87 -
 .../libcloud/compute/drivers/ktucloud.py        |  103 -
 .../libcloud/compute/drivers/libvirt_driver.py  |  335 -
 .../libcloud/compute/drivers/linode.py          |  683 --
 .../libcloud/compute/drivers/medone.py          |   56 -
 .../libcloud/compute/drivers/nephoscale.py      |  448 --
 .../libcloud/compute/drivers/ntta.py            |   56 -
 .../libcloud/compute/drivers/onapp.py           |  406 --
 .../libcloud/compute/drivers/opennebula.py      | 1264 ----
 .../libcloud/compute/drivers/openstack.py       | 2528 -------
 .../libcloud/compute/drivers/packet.py          |  258 -
 .../libcloud/compute/drivers/profitbricks.py    | 1496 ----
 .../libcloud/compute/drivers/rackspace.py       |  253 -
 .../libcloud/compute/drivers/rimuhosting.py     |  339 -
 .../libcloud/compute/drivers/runabove.py        |  453 --
 .../libcloud/compute/drivers/serverlove.py      |   83 -
 .../libcloud/compute/drivers/skalicloud.py      |   83 -
 .../libcloud/compute/drivers/softlayer.py       |  505 --
 .../libcloud/compute/drivers/vcl.py             |  302 -
 .../libcloud/compute/drivers/vcloud.py          | 2226 ------
 .../libcloud/compute/drivers/voxel.py           |  307 -
 .../libcloud/compute/drivers/vpsnet.py          |  193 -
 .../libcloud/compute/drivers/vsphere.py         |  552 --
 .../libcloud/compute/drivers/vultr.py           |  210 -
 .../libcloud/compute/providers.py               |  158 -
 .../libcloud/compute/ssh.py                     |  568 --
 .../libcloud/compute/types.py                   |  358 -
 .../libcloud/container/__init__.py              |    0
 .../libcloud/container/base.py                  |  416 --
 .../libcloud/container/drivers/__init__.py      |    0
 .../libcloud/container/drivers/docker.py        |  656 --
 .../libcloud/container/drivers/dummy.py         |   46 -
 .../libcloud/container/drivers/ecs.py           |  627 --
 .../libcloud/container/drivers/joyent.py        |   73 -
 .../libcloud/container/drivers/kubernetes.py    |  405 --
 .../libcloud/container/providers.py             |   40 -
 .../libcloud/container/types.py                 |   76 -
 .../libcloud/container/utils/__init__.py        |    0
 .../libcloud/container/utils/docker.py          |  177 -
 .../libcloud/data/pricing.json                  | 1038 ---
 .../libcloud/dns/__init__.py                    |    0
 apache-libcloud-1.0.0rc2/libcloud/dns/base.py   |  495 --
 .../libcloud/dns/drivers/__init__.py            |    0
 .../libcloud/dns/drivers/auroradns.py           |  609 --
 .../libcloud/dns/drivers/buddyns.py             |  153 -
 .../libcloud/dns/drivers/cloudflare.py          |  429 --
 .../libcloud/dns/drivers/digitalocean.py        |  292 -
 .../libcloud/dns/drivers/dnsimple.py            |  294 -
 .../libcloud/dns/drivers/dummy.py               |  218 -
 .../libcloud/dns/drivers/durabledns.py          |  660 --
 .../libcloud/dns/drivers/gandi.py               |  279 -
 .../libcloud/dns/drivers/godaddy.py             |  502 --
 .../libcloud/dns/drivers/google.py              |  383 -
 .../libcloud/dns/drivers/hostvirtual.py         |  257 -
 .../libcloud/dns/drivers/linode.py              |  273 -
 .../libcloud/dns/drivers/liquidweb.py           |  388 -
 .../libcloud/dns/drivers/luadns.py              |  293 -
 .../libcloud/dns/drivers/nfsn.py                |  198 -
 .../libcloud/dns/drivers/nsone.py               |  344 -
 .../libcloud/dns/drivers/pointdns.py            |  791 --
 .../libcloud/dns/drivers/rackspace.py           |  662 --
 .../libcloud/dns/drivers/route53.py             |  548 --
 .../libcloud/dns/drivers/softlayer.py           |  214 -
 .../libcloud/dns/drivers/vultr.py               |  388 -
 .../libcloud/dns/drivers/worldwidedns.py        |  536 --
 .../libcloud/dns/drivers/zerigo.py              |  484 --
 .../libcloud/dns/drivers/zonomi.py              |  351 -
 .../libcloud/dns/providers.py                   |   93 -
 apache-libcloud-1.0.0rc2/libcloud/dns/types.py  |  141 -
 .../libcloud/httplib_ssl.py                     |  344 -
 .../libcloud/loadbalancer/__init__.py           |   25 -
 .../libcloud/loadbalancer/base.py               |  349 -
 .../libcloud/loadbalancer/drivers/__init__.py   |   19 -
 .../libcloud/loadbalancer/drivers/brightbox.py  |  138 -
 .../libcloud/loadbalancer/drivers/cloudstack.py |  209 -
 .../loadbalancer/drivers/dimensiondata.py       | 1126 ---
 .../libcloud/loadbalancer/drivers/elb.py        |  351 -
 .../libcloud/loadbalancer/drivers/gce.py        |  369 -
 .../libcloud/loadbalancer/drivers/gogrid.py     |  239 -
 .../libcloud/loadbalancer/drivers/ninefold.py   |   29 -
 .../libcloud/loadbalancer/drivers/rackspace.py  | 1531 ----
 .../libcloud/loadbalancer/drivers/slb.py        |  831 ---
 .../libcloud/loadbalancer/drivers/softlayer.py  |  435 --
 .../libcloud/loadbalancer/providers.py          |   59 -
 .../libcloud/loadbalancer/types.py              |   84 -
 apache-libcloud-1.0.0rc2/libcloud/pricing.py    |  224 -
 apache-libcloud-1.0.0rc2/libcloud/security.py   |   89 -
 .../libcloud/storage/__init__.py                |    3 -
 .../libcloud/storage/base.py                    |  831 ---
 .../libcloud/storage/drivers/__init__.py        |   23 -
 .../libcloud/storage/drivers/atmos.py           |  472 --
 .../libcloud/storage/drivers/auroraobjects.py   |   52 -
 .../libcloud/storage/drivers/azure_blobs.py     |  986 ---
 .../libcloud/storage/drivers/backblaze_b2.py    |  525 --
 .../libcloud/storage/drivers/cloudfiles.py      |  972 ---
 .../libcloud/storage/drivers/dummy.py           |  490 --
 .../libcloud/storage/drivers/google_storage.py  |  145 -
 .../libcloud/storage/drivers/ktucloud.py        |   56 -
 .../libcloud/storage/drivers/local.py           |  593 --
 .../libcloud/storage/drivers/nimbus.py          |  114 -
 .../libcloud/storage/drivers/ninefold.py        |   26 -
 .../libcloud/storage/drivers/oss.py             | 1069 ---
 .../libcloud/storage/drivers/s3.py              | 1037 ---
 .../libcloud/storage/providers.py               |   77 -
 .../libcloud/storage/types.py                   |  141 -
 .../libcloud/test/__init__.py                   |  353 -
 .../libcloud/test/backup/__init__.py            |   36 -
 .../dimensiondata/_remove_backup_client.xml     |    7 -
 .../_remove_backup_client_FAIL.xml              |    7 -
 ...745_4d8a_9cbc_8dabe5a7d0e4_server_server.xml |   49 -
 ...ver_e75ead52_692f_4314_8725_c8a4f4d13a87.xml |   27 -
 ...ad52_692f_4314_8725_c8a4f4d13a87_DEFAULT.xml |   27 -
 ...2f_4314_8725_c8a4f4d13a87_backup_DISABLE.xml |    7 -
 ...92f_4314_8725_c8a4f4d13a87_backup_ENABLE.xml |   18 -
 ...92f_4314_8725_c8a4f4d13a87_backup_EXISTS.xml |    7 -
 ..._692f_4314_8725_c8a4f4d13a87_backup_INFO.xml |   16 -
 ...4_8725_c8a4f4d13a87_backup_INFO_DISABLED.xml |    7 -
 ...4_8725_c8a4f4d13a87_backup_INFO_NOCLIENT.xml |    2 -
 ...4314_8725_c8a4f4d13a87_backup_INFO_NOJOB.xml |   11 -
 .../libcloud/test/backup/test_base.py           |   29 -
 .../libcloud/test/backup/test_dimensiondata.py  |  490 --
 .../libcloud/test/file_fixtures.py              |   97 -
 .../libcloud/test/pricing_test.json             |   10 -
 .../libcloud/test/secrets.py-dist               |   94 -
 .../libcloud/test/test_connection.py            |  334 -
 .../libcloud/test/test_file_fixtures.py         |   32 -
 .../libcloud/test/test_httplib_ssl.py           |  157 -
 .../libcloud/test/test_init.py                  |   61 -
 .../libcloud/test/test_pricing.py               |  106 -
 .../libcloud/test/test_response_classes.py      |  151 -
 .../libcloud/test/test_types.py                 |  112 -
 .../libcloud/test/test_utils.py                 |  385 -
 apache-libcloud-1.0.0rc2/requirements-tests.txt |    3 -
 apache-libcloud-1.0.0rc2/setup.cfg              |    5 -
 apache-libcloud-1.0.0rc2/setup.py               |  306 -
 apache-libcloud-1.0.0rc2/tox.ini                |   62 -
 233 files changed, 99435 deletions(-)
----------------------------------------------------------------------



[38/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/openstack_identity.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/openstack_identity.py b/apache-libcloud-1.0.0rc2/libcloud/common/openstack_identity.py
deleted file mode 100644
index e8cc6a8..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/openstack_identity.py
+++ /dev/null
@@ -1,1394 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-Common / shared code for handling authentication against OpenStack identity
-service (Keystone).
-"""
-
-import sys
-import datetime
-
-from libcloud.utils.py3 import httplib
-from libcloud.utils.iso8601 import parse_date
-
-from libcloud.common.base import ConnectionUserAndKey, Response
-from libcloud.compute.types import (LibcloudError, InvalidCredsError,
-                                    MalformedResponseError)
-
-try:
-    import simplejson as json
-except ImportError:
-    import json
-
-AUTH_API_VERSION = '1.1'
-
-# Auth versions which contain token expiration information.
-AUTH_VERSIONS_WITH_EXPIRES = [
-    '1.1',
-    '2.0',
-    '2.0_apikey',
-    '2.0_password',
-    '3.0',
-    '3.x_password'
-]
-
-# How many seconds to subtract from the auth token expiration time before
-# testing if the token is still valid.
-# The time is subtracted to account for the HTTP request latency and prevent
-# user from getting "InvalidCredsError" if token is about to expire.
-AUTH_TOKEN_EXPIRES_GRACE_SECONDS = 5
-
-
-__all__ = [
-    'OpenStackIdentityVersion',
-    'OpenStackIdentityDomain',
-    'OpenStackIdentityProject',
-    'OpenStackIdentityUser',
-    'OpenStackIdentityRole',
-
-    'OpenStackServiceCatalog',
-    'OpenStackServiceCatalogEntry',
-    'OpenStackServiceCatalogEntryEndpoint',
-    'OpenStackIdentityEndpointType',
-
-    'OpenStackIdentityConnection',
-    'OpenStackIdentity_1_0_Connection',
-    'OpenStackIdentity_1_1_Connection',
-    'OpenStackIdentity_2_0_Connection',
-    'OpenStackIdentity_3_0_Connection',
-
-    'get_class_for_auth_version'
-]
-
-
-class OpenStackIdentityEndpointType(object):
-    """
-    Enum class for openstack identity endpoint type.
-    """
-    INTERNAL = 'internal'
-    EXTERNAL = 'external'
-    ADMIN = 'admin'
-
-
-class OpenStackIdentityTokenScope(object):
-    """
-    Enum class for openstack identity token scope.
-    """
-    PROJECT = 'project'
-    DOMAIN = 'domain'
-    UNSCOPED = 'unscoped'
-
-
-class OpenStackIdentityVersion(object):
-    def __init__(self, version, status, updated, url):
-        self.version = version
-        self.status = status
-        self.updated = updated
-        self.url = url
-
-    def __repr__(self):
-        return (('<OpenStackIdentityVersion version=%s, status=%s, '
-                 'updated=%s, url=%s>' %
-                 (self.version, self.status, self.updated, self.url)))
-
-
-class OpenStackIdentityDomain(object):
-    def __init__(self, id, name, enabled):
-        self.id = id
-        self.name = name
-        self.enabled = enabled
-
-    def __repr__(self):
-        return (('<OpenStackIdentityDomain id=%s, name=%s, enabled=%s>' %
-                 (self.id, self.name, self.enabled)))
-
-
-class OpenStackIdentityProject(object):
-    def __init__(self, id, name, description, enabled, domain_id=None):
-        self.id = id
-        self.name = name
-        self.description = description
-        self.enabled = enabled
-        self.domain_id = domain_id
-
-    def __repr__(self):
-        return (('<OpenStackIdentityProject id=%s, domain_id=%s, name=%s, '
-                 'enabled=%s>' %
-                 (self.id, self.domain_id, self.name, self.enabled)))
-
-
-class OpenStackIdentityRole(object):
-    def __init__(self, id, name, description, enabled):
-        self.id = id
-        self.name = name
-        self.description = description
-        self.enabled = enabled
-
-    def __repr__(self):
-        return (('<OpenStackIdentityRole id=%s, name=%s, description=%s, '
-                 'enabled=%s>' % (self.id, self.name, self.description,
-                                  self.enabled)))
-
-
-class OpenStackIdentityUser(object):
-    def __init__(self, id, domain_id, name, email, description, enabled):
-        self.id = id
-        self.domain_id = domain_id
-        self.name = name
-        self.email = email
-        self.description = description
-        self.enabled = enabled
-
-    def __repr__(self):
-        return (('<OpenStackIdentityUser id=%s, domain_id=%s, name=%s, '
-                 'email=%s, enabled=%s>' % (self.id, self.domain_id, self.name,
-                                            self.email, self.enabled)))
-
-
-class OpenStackServiceCatalog(object):
-    """
-    http://docs.openstack.org/api/openstack-identity-service/2.0/content/
-
-    This class should be instantiated with the contents of the
-    'serviceCatalog' in the auth response. This will do the work of figuring
-    out which services actually exist in the catalog as well as split them up
-    by type, name, and region if available
-    """
-
-    _auth_version = None
-    _service_catalog = None
-
-    def __init__(self, service_catalog, auth_version=AUTH_API_VERSION):
-        self._auth_version = auth_version
-
-        # Check this way because there are a couple of different 2.0_*
-        # auth types.
-        if '3.x' in self._auth_version:
-            entries = self._parse_service_catalog_auth_v3(
-                service_catalog=service_catalog)
-        elif '2.0' in self._auth_version:
-            entries = self._parse_service_catalog_auth_v2(
-                service_catalog=service_catalog)
-        elif ('1.1' in self._auth_version) or ('1.0' in self._auth_version):
-            entries = self._parse_service_catalog_auth_v1(
-                service_catalog=service_catalog)
-        else:
-            raise LibcloudError('auth version "%s" not supported'
-                                % (self._auth_version))
-
-        # Force consistent ordering by sorting the entries
-        entries = sorted(entries,
-                         key=lambda x: x.service_type + (x.service_name or ''))
-        self._entries = entries  # stories all the service catalog entries
-
-    def get_entries(self):
-        """
-        Return all the entries for this service catalog.
-
-        :rtype: ``list`` of :class:`.OpenStackServiceCatalogEntry`
-        """
-        return self._entries
-
-    def get_catalog(self):
-        """
-        Deprecated in the favor of ``get_entries`` method.
-        """
-        return self.get_entries()
-
-    def get_public_urls(self, service_type=None, name=None):
-        """
-        Retrieve all the available public (external) URLs for the provided
-        service type and name.
-        """
-        endpoints = self.get_endpoints(service_type=service_type,
-                                       name=name)
-
-        result = []
-        for endpoint in endpoints:
-            endpoint_type = endpoint.endpoint_type
-            if endpoint_type == OpenStackIdentityEndpointType.EXTERNAL:
-                result.append(endpoint.url)
-
-        return result
-
-    def get_endpoints(self, service_type=None, name=None):
-        """
-        Retrieve all the endpoints for the provided service type and name.
-
-        :rtype: ``list`` of :class:`.OpenStackServiceCatalogEntryEndpoint`
-        """
-        endpoints = []
-
-        for entry in self._entries:
-            # Note: "if XXX and YYY != XXX" comparison is used to support
-            # partial lookups.
-            # This allows user to pass in only one argument to the method (only
-            # service_type or name), both of them or neither.
-            if service_type and entry.service_type != service_type:
-                continue
-
-            if name and entry.service_name != name:
-                continue
-
-            for endpoint in entry.endpoints:
-                endpoints.append(endpoint)
-
-        return endpoints
-
-    def get_endpoint(self, service_type=None, name=None, region=None,
-                     endpoint_type=OpenStackIdentityEndpointType.EXTERNAL):
-        """
-        Retrieve a single endpoint using the provided criteria.
-
-        Note: If no or more than one matching endpoint is found, an exception
-        is thrown.
-        """
-        endpoints = []
-
-        for entry in self._entries:
-            if service_type and entry.service_type != service_type:
-                continue
-
-            if name and entry.service_name != name:
-                continue
-
-            for endpoint in entry.endpoints:
-                if region and endpoint.region != region:
-                    continue
-
-                if endpoint_type and endpoint.endpoint_type != endpoint_type:
-                    continue
-
-                endpoints.append(endpoint)
-
-        if len(endpoints) == 1:
-            return endpoints[0]
-        elif len(endpoints) > 1:
-            raise ValueError('Found more than 1 matching endpoint')
-        else:
-            raise LibcloudError('Could not find specified endpoint')
-
-    def get_regions(self, service_type=None):
-        """
-        Retrieve a list of all the available regions.
-
-        :param service_type: If specified, only return regions for this
-                             service type.
-        :type service_type: ``str``
-
-        :rtype: ``list`` of ``str``
-        """
-        regions = set()
-
-        for entry in self._entries:
-            if service_type and entry.service_type != service_type:
-                continue
-
-            for endpoint in entry.endpoints:
-                if endpoint.region:
-                    regions.add(endpoint.region)
-
-        return sorted(list(regions))
-
-    def get_service_types(self, region=None):
-        """
-        Retrieve all the available service types.
-
-        :param region: Optional region to retrieve service types for.
-        :type region: ``str``
-
-        :rtype: ``list`` of ``str``
-        """
-        service_types = set()
-
-        for entry in self._entries:
-            include = True
-
-            for endpoint in entry.endpoints:
-                if region and endpoint.region != region:
-                    include = False
-                    break
-
-            if include:
-                service_types.add(entry.service_type)
-
-        return sorted(list(service_types))
-
-    def get_service_names(self, service_type=None, region=None):
-        """
-        Retrieve list of service names that match service type and region.
-
-        :type service_type: ``str``
-        :type region: ``str``
-
-        :rtype: ``list`` of ``str``
-        """
-        names = set()
-
-        if '2.0' not in self._auth_version:
-            raise ValueError('Unsupported version: %s' % (self._auth_version))
-
-        for entry in self._entries:
-            if service_type and entry.service_type != service_type:
-                continue
-
-            include = True
-            for endpoint in entry.endpoints:
-                if region and endpoint.region != region:
-                    include = False
-                    break
-
-            if include and entry.service_name:
-                names.add(entry.service_name)
-
-        return sorted(list(names))
-
-    def _parse_service_catalog_auth_v1(self, service_catalog):
-        entries = []
-
-        for service, endpoints in service_catalog.items():
-            entry_endpoints = []
-            for endpoint in endpoints:
-                region = endpoint.get('region', None)
-
-                public_url = endpoint.get('publicURL', None)
-                private_url = endpoint.get('internalURL', None)
-
-                if public_url:
-                    entry_endpoint = OpenStackServiceCatalogEntryEndpoint(
-                        region=region, url=public_url,
-                        endpoint_type=OpenStackIdentityEndpointType.EXTERNAL)
-                    entry_endpoints.append(entry_endpoint)
-
-                if private_url:
-                    entry_endpoint = OpenStackServiceCatalogEntryEndpoint(
-                        region=region, url=private_url,
-                        endpoint_type=OpenStackIdentityEndpointType.INTERNAL)
-                    entry_endpoints.append(entry_endpoint)
-
-            entry = OpenStackServiceCatalogEntry(service_type=service,
-                                                 endpoints=entry_endpoints)
-            entries.append(entry)
-
-        return entries
-
-    def _parse_service_catalog_auth_v2(self, service_catalog):
-        entries = []
-
-        for service in service_catalog:
-            service_type = service['type']
-            service_name = service.get('name', None)
-
-            entry_endpoints = []
-            for endpoint in service.get('endpoints', []):
-                region = endpoint.get('region', None)
-
-                public_url = endpoint.get('publicURL', None)
-                private_url = endpoint.get('internalURL', None)
-
-                if public_url:
-                    entry_endpoint = OpenStackServiceCatalogEntryEndpoint(
-                        region=region, url=public_url,
-                        endpoint_type=OpenStackIdentityEndpointType.EXTERNAL)
-                    entry_endpoints.append(entry_endpoint)
-
-                if private_url:
-                    entry_endpoint = OpenStackServiceCatalogEntryEndpoint(
-                        region=region, url=private_url,
-                        endpoint_type=OpenStackIdentityEndpointType.INTERNAL)
-                    entry_endpoints.append(entry_endpoint)
-
-            entry = OpenStackServiceCatalogEntry(service_type=service_type,
-                                                 endpoints=entry_endpoints,
-                                                 service_name=service_name)
-            entries.append(entry)
-
-        return entries
-
-    def _parse_service_catalog_auth_v3(self, service_catalog):
-        entries = []
-
-        for item in service_catalog:
-            service_type = item['type']
-            service_name = item.get('name', None)
-
-            entry_endpoints = []
-            for endpoint in item['endpoints']:
-                region = endpoint.get('region', None)
-                url = endpoint['url']
-                endpoint_type = endpoint['interface']
-
-                if endpoint_type == 'internal':
-                    endpoint_type = OpenStackIdentityEndpointType.INTERNAL
-                elif endpoint_type == 'public':
-                    endpoint_type = OpenStackIdentityEndpointType.EXTERNAL
-                elif endpoint_type == 'admin':
-                    endpoint_type = OpenStackIdentityEndpointType.ADMIN
-
-                entry_endpoint = OpenStackServiceCatalogEntryEndpoint(
-                    region=region, url=url, endpoint_type=endpoint_type)
-                entry_endpoints.append(entry_endpoint)
-
-            entry = OpenStackServiceCatalogEntry(service_type=service_type,
-                                                 service_name=service_name,
-                                                 endpoints=entry_endpoints)
-            entries.append(entry)
-
-        return entries
-
-
-class OpenStackServiceCatalogEntry(object):
-    def __init__(self, service_type, endpoints=None, service_name=None):
-        """
-        :param service_type: Service type.
-        :type service_type: ``str``
-
-        :param endpoints: Endpoints belonging to this entry.
-        :type endpoints: ``list``
-
-        :param service_name: Optional service name.
-        :type service_name: ``str``
-        """
-        self.service_type = service_type
-        self.endpoints = endpoints or []
-        self.service_name = service_name
-
-        # For consistency, sort the endpoints
-        self.endpoints = sorted(self.endpoints, key=lambda x: x.url or '')
-
-    def __eq__(self, other):
-        return (self.service_type == other.service_type and
-                self.endpoints == other.endpoints and
-                other.service_name == self.service_name)
-
-    def __ne__(self, other):
-        return not self.__eq__(other=other)
-
-    def __repr__(self):
-        return (('<OpenStackServiceCatalogEntry service_type=%s, '
-                 'service_name=%s, endpoints=%s' %
-                 (self.service_type, self.service_name, repr(self.endpoints))))
-
-
-class OpenStackServiceCatalogEntryEndpoint(object):
-    VALID_ENDPOINT_TYPES = [
-        OpenStackIdentityEndpointType.INTERNAL,
-        OpenStackIdentityEndpointType.EXTERNAL,
-        OpenStackIdentityEndpointType.ADMIN,
-    ]
-
-    def __init__(self, region, url, endpoint_type='external'):
-        """
-        :param region: Endpoint region.
-        :type region: ``str``
-
-        :param url: Endpoint URL.
-        :type url: ``str``
-
-        :param endpoint_type: Endpoint type (external / internal / admin).
-        :type endpoint_type: ``str``
-        """
-        if endpoint_type not in self.VALID_ENDPOINT_TYPES:
-            raise ValueError('Invalid type: %s' % (endpoint_type))
-
-        # TODO: Normalize / lowercase all the region names
-        self.region = region
-        self.url = url
-        self.endpoint_type = endpoint_type
-
-    def __eq__(self, other):
-        return (self.region == other.region and self.url == other.url and
-                self.endpoint_type == other.endpoint_type)
-
-    def __ne__(self, other):
-        return not self.__eq__(other=other)
-
-    def __repr__(self):
-        return (('<OpenStackServiceCatalogEntryEndpoint region=%s, url=%s, '
-                 'type=%s' % (self.region, self.url, self.endpoint_type)))
-
-
-class OpenStackAuthResponse(Response):
-    def success(self):
-        return self.status in [httplib.OK, httplib.CREATED,
-                               httplib.ACCEPTED, httplib.NO_CONTENT,
-                               httplib.MULTIPLE_CHOICES,
-                               httplib.UNAUTHORIZED,
-                               httplib.INTERNAL_SERVER_ERROR]
-
-    def parse_body(self):
-        if not self.body:
-            return None
-
-        if 'content-type' in self.headers:
-            key = 'content-type'
-        elif 'Content-Type' in self.headers:
-            key = 'Content-Type'
-        else:
-            raise LibcloudError('Missing content-type header',
-                                driver=OpenStackIdentityConnection)
-
-        content_type = self.headers[key]
-        if content_type.find(';') != -1:
-            content_type = content_type.split(';')[0]
-
-        if content_type == 'application/json':
-            try:
-                data = json.loads(self.body)
-            except:
-                driver = OpenStackIdentityConnection
-                raise MalformedResponseError('Failed to parse JSON',
-                                             body=self.body,
-                                             driver=driver)
-        elif content_type == 'text/plain':
-            data = self.body
-        else:
-            data = self.body
-
-        return data
-
-
-class OpenStackIdentityConnection(ConnectionUserAndKey):
-    """
-    Base identity connection class which contains common / shared logic.
-
-    Note: This class shouldn't be instantiated directly.
-    """
-    responseCls = OpenStackAuthResponse
-    timeout = None
-
-    def __init__(self, auth_url, user_id, key, tenant_name=None,
-                 timeout=None, parent_conn=None):
-        super(OpenStackIdentityConnection, self).__init__(user_id=user_id,
-                                                          key=key,
-                                                          url=auth_url,
-                                                          timeout=timeout)
-
-        self.auth_url = auth_url
-        self.tenant_name = tenant_name
-        self.parent_conn = parent_conn
-
-        # enable tests to use the same mock connection classes.
-        if parent_conn:
-            self.conn_classes = parent_conn.conn_classes
-            self.driver = parent_conn.driver
-        else:
-            self.driver = None
-
-        self.auth_url = auth_url
-        self.tenant_name = tenant_name
-        self.timeout = timeout
-
-        self.urls = {}
-        self.auth_token = None
-        self.auth_token_expires = None
-        self.auth_user_info = None
-
-    def authenticated_request(self, action, params=None, data=None,
-                              headers=None, method='GET', raw=False):
-        """
-        Perform an authenticated request against the identity API.
-        """
-        if not self.auth_token:
-            raise ValueError('Not to be authenticated to perform this request')
-
-        headers = headers or {}
-        headers['X-Auth-Token'] = self.auth_token
-
-        return self.request(action=action, params=params, data=data,
-                            headers=headers, method=method, raw=raw)
-
-    def morph_action_hook(self, action):
-        (_, _, _, request_path) = self._tuple_from_url(self.auth_url)
-
-        if request_path == '':
-            # No path is provided in the auth_url, use action passed to this
-            # method.
-            return action
-
-        return request_path
-
-    def add_default_headers(self, headers):
-        headers['Accept'] = 'application/json'
-        headers['Content-Type'] = 'application/json; charset=UTF-8'
-        return headers
-
-    def is_token_valid(self):
-        """
-        Return True if the current auth token is already cached and hasn't
-        expired yet.
-
-        :return: ``True`` if the token is still valid, ``False`` otherwise.
-        :rtype: ``bool``
-        """
-        if not self.auth_token:
-            return False
-
-        if not self.auth_token_expires:
-            return False
-
-        expires = self.auth_token_expires - \
-            datetime.timedelta(seconds=AUTH_TOKEN_EXPIRES_GRACE_SECONDS)
-
-        time_tuple_expires = expires.utctimetuple()
-        time_tuple_now = datetime.datetime.utcnow().utctimetuple()
-
-        if time_tuple_now < time_tuple_expires:
-            return True
-
-        return False
-
-    def authenticate(self, force=False):
-        """
-        Authenticate against the identity API.
-
-        :param force: Forcefully update the token even if it's already cached
-                      and still valid.
-        :type force: ``bool``
-        """
-        raise NotImplementedError('authenticate not implemented')
-
-    def list_supported_versions(self):
-        """
-        Retrieve a list of all the identity versions which are supported by
-        this installation.
-
-        :rtype: ``list`` of :class:`.OpenStackIdentityVersion`
-        """
-        response = self.request('/', method='GET')
-        result = self._to_versions(data=response.object['versions']['values'])
-        result = sorted(result, key=lambda x: x.version)
-        return result
-
-    def _to_versions(self, data):
-        result = []
-        for item in data:
-            version = self._to_version(data=item)
-            result.append(version)
-
-        return result
-
-    def _to_version(self, data):
-        try:
-            updated = parse_date(data['updated'])
-        except Exception:
-            updated = None
-
-        try:
-            url = data['links'][0]['href']
-        except IndexError:
-            url = None
-
-        version = OpenStackIdentityVersion(version=data['id'],
-                                           status=data['status'],
-                                           updated=updated,
-                                           url=url)
-        return version
-
-    def _is_authentication_needed(self, force=False):
-        """
-        Determine if the authentication is needed or if the existing token (if
-        any exists) is still valid.
-        """
-        if force:
-            return True
-
-        if self.auth_version not in AUTH_VERSIONS_WITH_EXPIRES:
-            return True
-
-        if self.is_token_valid():
-            return False
-
-        return True
-
-    def _to_projects(self, data):
-        result = []
-        for item in data:
-            project = self._to_project(data=item)
-            result.append(project)
-
-        return result
-
-    def _to_project(self, data):
-        project = OpenStackIdentityProject(id=data['id'],
-                                           name=data['name'],
-                                           description=data['description'],
-                                           enabled=data['enabled'],
-                                           domain_id=data.get('domain_id',
-                                                              None))
-        return project
-
-
-class OpenStackIdentity_1_0_Connection(OpenStackIdentityConnection):
-    """
-    Connection class for Keystone API v1.0.
-    """
-
-    responseCls = OpenStackAuthResponse
-    name = 'OpenStack Identity API v1.0'
-    auth_version = '1.0'
-
-    def authenticate(self, force=False):
-        if not self._is_authentication_needed(force=force):
-            return self
-
-        headers = {
-            'X-Auth-User': self.user_id,
-            'X-Auth-Key': self.key,
-        }
-
-        resp = self.request('/v1.0', headers=headers, method='GET')
-
-        if resp.status == httplib.UNAUTHORIZED:
-            # HTTP UNAUTHORIZED (401): auth failed
-            raise InvalidCredsError()
-        elif resp.status not in [httplib.NO_CONTENT, httplib.OK]:
-            body = 'code: %s body:%s headers:%s' % (resp.status,
-                                                    resp.body,
-                                                    resp.headers)
-            raise MalformedResponseError('Malformed response', body=body,
-                                         driver=self.driver)
-        else:
-            headers = resp.headers
-            # emulate the auth 1.1 URL list
-            self.urls = {}
-            self.urls['cloudServers'] = \
-                [{'publicURL': headers.get('x-server-management-url', None)}]
-            self.urls['cloudFilesCDN'] = \
-                [{'publicURL': headers.get('x-cdn-management-url', None)}]
-            self.urls['cloudFiles'] = \
-                [{'publicURL': headers.get('x-storage-url', None)}]
-            self.auth_token = headers.get('x-auth-token', None)
-            self.auth_user_info = None
-
-            if not self.auth_token:
-                raise MalformedResponseError('Missing X-Auth-Token in \
-                                              response headers')
-
-        return self
-
-
-class OpenStackIdentity_1_1_Connection(OpenStackIdentityConnection):
-    """
-    Connection class for Keystone API v1.1.
-    """
-
-    responseCls = OpenStackAuthResponse
-    name = 'OpenStack Identity API v1.1'
-    auth_version = '1.1'
-
-    def authenticate(self, force=False):
-        if not self._is_authentication_needed(force=force):
-            return self
-
-        reqbody = json.dumps({'credentials': {'username': self.user_id,
-                                              'key': self.key}})
-        resp = self.request('/v1.1/auth', data=reqbody, headers={},
-                            method='POST')
-
-        if resp.status == httplib.UNAUTHORIZED:
-            # HTTP UNAUTHORIZED (401): auth failed
-            raise InvalidCredsError()
-        elif resp.status != httplib.OK:
-            body = 'code: %s body:%s' % (resp.status, resp.body)
-            raise MalformedResponseError('Malformed response', body=body,
-                                         driver=self.driver)
-        else:
-            try:
-                body = json.loads(resp.body)
-            except Exception:
-                e = sys.exc_info()[1]
-                raise MalformedResponseError('Failed to parse JSON', e)
-
-            try:
-                expires = body['auth']['token']['expires']
-
-                self.auth_token = body['auth']['token']['id']
-                self.auth_token_expires = parse_date(expires)
-                self.urls = body['auth']['serviceCatalog']
-                self.auth_user_info = None
-            except KeyError:
-                e = sys.exc_info()[1]
-                raise MalformedResponseError('Auth JSON response is \
-                                             missing required elements', e)
-
-        return self
-
-
-class OpenStackIdentity_2_0_Connection(OpenStackIdentityConnection):
-    """
-    Connection class for Keystone API v2.0.
-    """
-
-    responseCls = OpenStackAuthResponse
-    name = 'OpenStack Identity API v1.0'
-    auth_version = '2.0'
-
-    def authenticate(self, auth_type='api_key', force=False):
-        if not self._is_authentication_needed(force=force):
-            return self
-
-        if auth_type == 'api_key':
-            return self._authenticate_2_0_with_api_key()
-        elif auth_type == 'password':
-            return self._authenticate_2_0_with_password()
-        else:
-            raise ValueError('Invalid value for auth_type argument')
-
-    def _authenticate_2_0_with_api_key(self):
-        # API Key based authentication uses the RAX-KSKEY extension.
-        # http://s.apache.org/oAi
-        data = {'auth':
-                {'RAX-KSKEY:apiKeyCredentials':
-                 {'username': self.user_id, 'apiKey': self.key}}}
-        if self.tenant_name:
-            data['auth']['tenantName'] = self.tenant_name
-        reqbody = json.dumps(data)
-        return self._authenticate_2_0_with_body(reqbody)
-
-    def _authenticate_2_0_with_password(self):
-        # Password based authentication is the only 'core' authentication
-        # method in Keystone at this time.
-        # 'keystone' - http://s.apache.org/e8h
-        data = {'auth':
-                {'passwordCredentials':
-                 {'username': self.user_id, 'password': self.key}}}
-        if self.tenant_name:
-            data['auth']['tenantName'] = self.tenant_name
-        reqbody = json.dumps(data)
-        return self._authenticate_2_0_with_body(reqbody)
-
-    def _authenticate_2_0_with_body(self, reqbody):
-        resp = self.request('/v2.0/tokens', data=reqbody,
-                            headers={'Content-Type': 'application/json'},
-                            method='POST')
-
-        if resp.status == httplib.UNAUTHORIZED:
-            raise InvalidCredsError()
-        elif resp.status not in [httplib.OK,
-                                 httplib.NON_AUTHORITATIVE_INFORMATION]:
-            body = 'code: %s body: %s' % (resp.status, resp.body)
-            raise MalformedResponseError('Malformed response', body=body,
-                                         driver=self.driver)
-        else:
-            body = resp.object
-
-            try:
-                access = body['access']
-                expires = access['token']['expires']
-
-                self.auth_token = access['token']['id']
-                self.auth_token_expires = parse_date(expires)
-                self.urls = access['serviceCatalog']
-                self.auth_user_info = access.get('user', {})
-            except KeyError:
-                e = sys.exc_info()[1]
-                raise MalformedResponseError('Auth JSON response is \
-                                             missing required elements', e)
-
-        return self
-
-    def list_projects(self):
-        response = self.authenticated_request('/v2.0/tenants', method='GET')
-        result = self._to_projects(data=response.object['tenants'])
-        return result
-
-    def list_tenants(self):
-        return self.list_projects()
-
-
-class OpenStackIdentity_3_0_Connection(OpenStackIdentityConnection):
-    """
-    Connection class for Keystone API v3.x.
-    """
-
-    responseCls = OpenStackAuthResponse
-    name = 'OpenStack Identity API v3.x'
-    auth_version = '3.0'
-
-    VALID_TOKEN_SCOPES = [
-        OpenStackIdentityTokenScope.PROJECT,
-        OpenStackIdentityTokenScope.DOMAIN,
-        OpenStackIdentityTokenScope.UNSCOPED
-    ]
-
-    def __init__(self, auth_url, user_id, key, tenant_name=None,
-                 domain_name='Default',
-                 token_scope=OpenStackIdentityTokenScope.PROJECT,
-                 timeout=None, parent_conn=None):
-        """
-        :param tenant_name: Name of the project this user belongs to. Note:
-                            When token_scope is set to project, this argument
-                            control to which project to scope the token to.
-        :type tenant_name: ``str``
-
-        :param domain_name: Domain the user belongs to. Note: Then token_scope
-                            is set to token, this argument controls to which
-                            domain to scope the token to.
-        :type domain_name: ``str``
-
-        :param token_scope: Whether to scope a token to a "project" or a
-                         "domain"
-        :type token_scope: ``str``
-        """
-        super(OpenStackIdentity_3_0_Connection,
-              self).__init__(auth_url=auth_url,
-                             user_id=user_id,
-                             key=key,
-                             tenant_name=tenant_name,
-                             timeout=timeout,
-                             parent_conn=parent_conn)
-        if token_scope not in self.VALID_TOKEN_SCOPES:
-            raise ValueError('Invalid value for "token_scope" argument: %s' %
-                             (token_scope))
-
-        if (token_scope == OpenStackIdentityTokenScope.PROJECT and
-                (not tenant_name or not domain_name)):
-            raise ValueError('Must provide tenant_name and domain_name '
-                             'argument')
-        elif (token_scope == OpenStackIdentityTokenScope.DOMAIN and
-                not domain_name):
-            raise ValueError('Must provide domain_name argument')
-
-        self.tenant_name = tenant_name
-        self.domain_name = domain_name
-        self.token_scope = token_scope
-        self.auth_user_roles = None
-
-    def authenticate(self, force=False):
-        """
-        Perform authentication.
-        """
-        if not self._is_authentication_needed(force=force):
-            return self
-
-        data = {
-            'auth': {
-                'identity': {
-                    'methods': ['password'],
-                    'password': {
-                        'user': {
-                            'domain': {
-                                'name': self.domain_name
-                            },
-                            'name': self.user_id,
-                            'password': self.key
-                        }
-                    }
-                }
-            }
-        }
-
-        if self.token_scope == OpenStackIdentityTokenScope.PROJECT:
-            # Scope token to project (tenant)
-            data['auth']['scope'] = {
-                'project': {
-                    'domain': {
-                        'name': self.domain_name
-                    },
-                    'name': self.tenant_name
-                }
-            }
-        elif self.token_scope == OpenStackIdentityTokenScope.DOMAIN:
-            # Scope token to domain
-            data['auth']['scope'] = {
-                'domain': {
-                    'name': self.domain_name
-                }
-            }
-        elif self.token_scope == OpenStackIdentityTokenScope.UNSCOPED:
-            pass
-        else:
-            raise ValueError('Token needs to be scoped either to project or '
-                             'a domain')
-
-        data = json.dumps(data)
-        response = self.request('/v3/auth/tokens', data=data,
-                                headers={'Content-Type': 'application/json'},
-                                method='POST')
-
-        if response.status == httplib.UNAUTHORIZED:
-            # Invalid credentials
-            raise InvalidCredsError()
-        elif response.status in [httplib.OK, httplib.CREATED]:
-            headers = response.headers
-
-            try:
-                body = json.loads(response.body)
-            except Exception:
-                e = sys.exc_info()[1]
-                raise MalformedResponseError('Failed to parse JSON', e)
-
-            try:
-                roles = self._to_roles(body['token']['roles'])
-            except Exception:
-                e = sys.exc_info()[1]
-                roles = []
-
-            try:
-                expires = body['token']['expires_at']
-
-                self.auth_token = headers['x-subject-token']
-                self.auth_token_expires = parse_date(expires)
-                # Note: catalog is not returned for unscoped tokens
-                self.urls = body['token'].get('catalog', None)
-                self.auth_user_info = None
-                self.auth_user_roles = roles
-            except KeyError:
-                e = sys.exc_info()[1]
-                raise MalformedResponseError('Auth JSON response is \
-                                             missing required elements', e)
-            body = 'code: %s body:%s' % (response.status, response.body)
-        else:
-            raise MalformedResponseError('Malformed response', body=body,
-                                         driver=self.driver)
-
-        return self
-
-    def list_domains(self):
-        """
-        List the available domains.
-
-        :rtype: ``list`` of :class:`OpenStackIdentityDomain`
-        """
-        response = self.authenticated_request('/v3/domains', method='GET')
-        result = self._to_domains(data=response.object['domains'])
-        return result
-
-    def list_projects(self):
-        """
-        List the available projects.
-
-        Note: To perform this action, user you are currently authenticated with
-        needs to be an admin.
-
-        :rtype: ``list`` of :class:`OpenStackIdentityProject`
-        """
-        response = self.authenticated_request('/v3/projects', method='GET')
-        result = self._to_projects(data=response.object['projects'])
-        return result
-
-    def list_users(self):
-        """
-        List the available users.
-
-        :rtype: ``list`` of :class:`.OpenStackIdentityUser`
-        """
-        response = self.authenticated_request('/v3/users', method='GET')
-        result = self._to_users(data=response.object['users'])
-        return result
-
-    def list_roles(self):
-        """
-        List the available roles.
-
-        :rtype: ``list`` of :class:`.OpenStackIdentityRole`
-        """
-        response = self.authenticated_request('/v3/roles', method='GET')
-        result = self._to_roles(data=response.object['roles'])
-        return result
-
-    def get_domain(self, domain_id):
-        """
-        Retrieve information about a single domain.
-
-        :param domain_id: ID of domain to retrieve information for.
-        :type domain_id: ``str``
-
-        :rtype: :class:`.OpenStackIdentityDomain`
-        """
-        response = self.authenticated_request('/v3/domains/%s' % (domain_id),
-                                              method='GET')
-        result = self._to_domain(data=response.object['domain'])
-        return result
-
-    def list_user_projects(self, user):
-        """
-        Retrieve all the projects user belongs to.
-
-        :rtype: ``list`` of :class:`.OpenStackIdentityProject`
-        """
-        path = '/v3/users/%s/projects' % (user.id)
-        response = self.authenticated_request(path, method='GET')
-        result = self._to_projects(data=response.object['projects'])
-        return result
-
-    def list_user_domain_roles(self, domain, user):
-        """
-        Retrieve all the roles for a particular user on a domain.
-
-        :rtype: ``list`` of :class:`.OpenStackIdentityRole`
-        """
-        # TODO: Also add "get users roles" and "get assginements" which are
-        # available in 3.1 and 3.3
-        path = '/v3/domains/%s/users/%s/roles' % (domain.id, user.id)
-        response = self.authenticated_request(path, method='GET')
-        result = self._to_roles(data=response.object['roles'])
-        return result
-
-    def grant_domain_role_to_user(self, domain, role, user):
-        """
-        Grant domain role to a user.
-
-        Note: This function appears to be idempotent.
-
-        :param domain: Domain to grant the role to.
-        :type domain: :class:`.OpenStackIdentityDomain`
-
-        :param role: Role to grant.
-        :type role: :class:`.OpenStackIdentityRole`
-
-        :param user: User to grant the role to.
-        :type user: :class:`.OpenStackIdentityUser`
-
-        :return: ``True`` on success.
-        :rtype: ``bool``
-        """
-        path = ('/v3/domains/%s/users/%s/roles/%s' %
-                (domain.id, user.id, role.id))
-        response = self.authenticated_request(path, method='PUT')
-        return response.status == httplib.NO_CONTENT
-
-    def revoke_domain_role_from_user(self, domain, user, role):
-        """
-        Revoke domain role from a user.
-
-        :param domain: Domain to revoke the role from.
-        :type domain: :class:`.OpenStackIdentityDomain`
-
-        :param role: Role to revoke.
-        :type role: :class:`.OpenStackIdentityRole`
-
-        :param user: User to revoke the role from.
-        :type user: :class:`.OpenStackIdentityUser`
-
-        :return: ``True`` on success.
-        :rtype: ``bool``
-        """
-        path = ('/v3/domains/%s/users/%s/roles/%s' %
-                (domain.id, user.id, role.id))
-        response = self.authenticated_request(path, method='DELETE')
-        return response.status == httplib.NO_CONTENT
-
-    def grant_project_role_to_user(self, project, role, user):
-        """
-        Grant project role to a user.
-
-        Note: This function appears to be idempotent.
-
-        :param project: Project to grant the role to.
-        :type project: :class:`.OpenStackIdentityDomain`
-
-        :param role: Role to grant.
-        :type role: :class:`.OpenStackIdentityRole`
-
-        :param user: User to grant the role to.
-        :type user: :class:`.OpenStackIdentityUser`
-
-        :return: ``True`` on success.
-        :rtype: ``bool``
-        """
-        path = ('/v3/projects/%s/users/%s/roles/%s' %
-                (project.id, user.id, role.id))
-        response = self.authenticated_request(path, method='PUT')
-        return response.status == httplib.NO_CONTENT
-
-    def revoke_project_role_from_user(self, project, role, user):
-        """
-        Revoke project role from a user.
-
-        :param project: Project to revoke the role from.
-        :type project: :class:`.OpenStackIdentityDomain`
-
-        :param role: Role to revoke.
-        :type role: :class:`.OpenStackIdentityRole`
-
-        :param user: User to revoke the role from.
-        :type user: :class:`.OpenStackIdentityUser`
-
-        :return: ``True`` on success.
-        :rtype: ``bool``
-        """
-        path = ('/v3/projects/%s/users/%s/roles/%s' %
-                (project.id, user.id, role.id))
-        response = self.authenticated_request(path, method='DELETE')
-        return response.status == httplib.NO_CONTENT
-
-    def create_user(self, email, password, name, description=None,
-                    domain_id=None, default_project_id=None, enabled=True):
-        """
-        Create a new user account.
-
-        :param email: User's mail address.
-        :type email: ``str``
-
-        :param password: User's password.
-        :type password: ``str``
-
-        :param name: User's name.
-        :type name: ``str``
-
-        :param description: Optional description.
-        :type description: ``str``
-
-        :param domain_id: ID of the domain to add the user to (optional).
-        :type domain_id: ``str``
-
-        :param default_project_id: ID of the default user project (optional).
-        :type default_project_id: ``str``
-
-        :param enabled: True to enable user after creation.
-        :type enabled: ``bool``
-
-        :return: Created user.
-        :rtype: :class:`.OpenStackIdentityUser`
-        """
-        data = {
-            'email': email,
-            'password': password,
-            'name': name,
-            'enabled': enabled
-        }
-
-        if description:
-            data['description'] = description
-
-        if domain_id:
-            data['domain_id'] = domain_id
-
-        if default_project_id:
-            data['default_project_id'] = default_project_id
-
-        data = json.dumps({'user': data})
-        response = self.authenticated_request('/v3/users', data=data,
-                                              method='POST')
-
-        user = self._to_user(data=response.object['user'])
-        return user
-
-    def enable_user(self, user):
-        """
-        Enable user account.
-
-        Note: This operation appears to be idempotent.
-
-        :param user: User to enable.
-        :type user: :class:`.OpenStackIdentityUser`
-
-        :return: User account which has been enabled.
-        :rtype: :class:`.OpenStackIdentityUser`
-        """
-        data = {
-            'enabled': True
-        }
-        data = json.dumps({'user': data})
-        response = self.authenticated_request('/v3/users/%s' % (user.id),
-                                              data=data,
-                                              method='PATCH')
-
-        user = self._to_user(data=response.object['user'])
-        return user
-
-    def disable_user(self, user):
-        """
-        Disable user account.
-
-        Note: This operation appears to be idempotent.
-
-        :param user: User to disable.
-        :type user: :class:`.OpenStackIdentityUser`
-
-        :return: User account which has been disabled.
-        :rtype: :class:`.OpenStackIdentityUser`
-        """
-        data = {
-            'enabled': False
-        }
-        data = json.dumps({'user': data})
-        response = self.authenticated_request('/v3/users/%s' % (user.id),
-                                              data=data,
-                                              method='PATCH')
-
-        user = self._to_user(data=response.object['user'])
-        return user
-
-    def _to_domains(self, data):
-        result = []
-        for item in data:
-            domain = self._to_domain(data=item)
-            result.append(domain)
-
-        return result
-
-    def _to_domain(self, data):
-        domain = OpenStackIdentityDomain(id=data['id'],
-                                         name=data['name'],
-                                         enabled=data['enabled'])
-        return domain
-
-    def _to_users(self, data):
-        result = []
-        for item in data:
-            user = self._to_user(data=item)
-            result.append(user)
-
-        return result
-
-    def _to_user(self, data):
-        user = OpenStackIdentityUser(id=data['id'],
-                                     domain_id=data['domain_id'],
-                                     name=data['name'],
-                                     email=data['email'],
-                                     description=data.get('description',
-                                                          None),
-                                     enabled=data['enabled'])
-        return user
-
-    def _to_roles(self, data):
-        result = []
-        for item in data:
-            user = self._to_role(data=item)
-            result.append(user)
-
-        return result
-
-    def _to_role(self, data):
-        role = OpenStackIdentityRole(id=data['id'],
-                                     name=data['name'],
-                                     description=data.get('description',
-                                                          None),
-                                     enabled=data.get('enabled', True))
-        return role
-
-
-def get_class_for_auth_version(auth_version):
-    """
-    Retrieve class for the provided auth version.
-    """
-    if auth_version == '1.0':
-        cls = OpenStackIdentity_1_0_Connection
-    elif auth_version == '1.1':
-        cls = OpenStackIdentity_1_1_Connection
-    elif auth_version == '2.0' or auth_version == '2.0_apikey':
-        cls = OpenStackIdentity_2_0_Connection
-    elif auth_version == '2.0_password':
-        cls = OpenStackIdentity_2_0_Connection
-    elif auth_version == '3.x_password':
-        cls = OpenStackIdentity_3_0_Connection
-    else:
-        raise LibcloudError('Unsupported Auth Version requested')
-
-    return cls

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/pointdns.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/pointdns.py b/apache-libcloud-1.0.0rc2/libcloud/common/pointdns.py
deleted file mode 100644
index cfb911f..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/pointdns.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 base64
-from libcloud.utils.py3 import b
-from libcloud.utils.py3 import httplib
-
-from libcloud.common.base import ConnectionUserAndKey
-from libcloud.common.base import JsonResponse
-
-
-class PointDNSDNSResponse(JsonResponse):
-
-    def success(self):
-        """
-        Determine if our request was successful.
-
-        The meaning of this can be arbitrary; did we receive OK status? Did
-        the node get created? Were we authenticated?
-
-        :rtype: ``bool``
-        :return: ``True`` or ``False``
-        """
-        # response.success() only checks for 200 and 201 codes. Should we
-        # add 202?
-        return self.status in [httplib.OK, httplib.CREATED, httplib.ACCEPTED]
-
-
-class PointDNSConnection(ConnectionUserAndKey):
-    host = 'pointhq.com'
-    responseCls = PointDNSDNSResponse
-
-    def add_default_headers(self, headers):
-        """
-        Add headers that are necessary for every request
-
-        This method adds ``token`` to the request.
-        """
-        b64string = b('%s:%s' % (self.user_id, self.key))
-        token = base64.b64encode(b64string)
-        headers['Authorization'] = 'Basic %s' % token
-        headers['Accept'] = 'application/json'
-        headers['Content-Type'] = 'application/json'
-        return headers

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/providers.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/providers.py b/apache-libcloud-1.0.0rc2/libcloud/common/providers.py
deleted file mode 100644
index b8ad271..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/providers.py
+++ /dev/null
@@ -1,107 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-Common methods for obtaining a reference to the provider driver class.
-"""
-
-import sys
-
-__all__ = [
-    'get_driver',
-    'set_driver'
-]
-
-
-def get_driver(drivers, provider, deprecated_providers=None,
-               deprecated_constants=None):
-    """
-    Get a driver.
-
-    :param drivers: Dictionary containing valid providers.
-    :type drivers: ``dict``
-
-    :param provider: Id (constant) of provider to get the driver for.
-    :type provider: :class:`libcloud.types.Provider`
-
-    :param: deprecated_providers: Dictionary with information about the
-            deprecated drivers.
-    :type deprecated_providers: ``dict``
-
-    :param: deprecated_constants: Dictionary with information about the
-            deprecated provider constants.
-    :type deprecated_constants: ``dict``
-    """
-    # Those providers have been shut down or similar.
-    deprecated_providers = deprecated_providers or {}
-    if provider in deprecated_providers:
-        url = deprecated_providers[provider]['url']
-        reason = deprecated_providers[provider]['reason']
-        msg = ('Provider no longer supported: %s, please visit: %s' %
-               (url, reason))
-        raise Exception(msg)
-
-    # Those drivers have moved to "region" constructor argument model
-    deprecated_constants = deprecated_constants or {}
-    if provider in deprecated_constants:
-        old_name = provider.upper()
-        new_name = deprecated_constants[provider].upper()
-
-        url = 'https://s.apache.org/lc0140un'
-        msg = ('Provider constant "%s" has been removed. New constant '
-               'is now called "%s".\n'
-               'For more information on this change and how to modify your '
-               'code to work with it, please visit: %s' %
-               (old_name, new_name, url))
-        raise Exception(msg)
-
-    if provider in drivers:
-        mod_name, driver_name = drivers[provider]
-        _mod = __import__(mod_name, globals(), locals(), [driver_name])
-        return getattr(_mod, driver_name)
-
-    raise AttributeError('Provider %s does not exist' % (provider))
-
-
-def set_driver(drivers, provider, module, klass):
-    """
-    Sets a driver.
-
-    :param drivers: Dictionary to store providers.
-    :param provider: Id of provider to set driver for
-
-    :type provider: :class:`libcloud.types.Provider`
-    :param module: The module which contains the driver
-
-    :type module: L
-    :param klass: The driver class name
-
-    :type klass:
-    """
-
-    if provider in drivers:
-        raise AttributeError('Provider %s already registered' % (provider))
-
-    drivers[provider] = (module, klass)
-
-    # Check if this driver is valid
-    try:
-        driver = get_driver(drivers, provider)
-    except (ImportError, AttributeError):
-        exp = sys.exc_info()[1]
-        drivers.pop(provider)
-        raise exp
-
-    return driver

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/rackspace.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/rackspace.py b/apache-libcloud-1.0.0rc2/libcloud/common/rackspace.py
deleted file mode 100644
index 294255d..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/rackspace.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-Common settings for Rackspace Cloud Servers and Cloud Files
-"""
-
-__all__ = [
-    'AUTH_URL'
-]
-
-AUTH_URL = 'https://identity.api.rackspacecloud.com'

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/runabove.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/runabove.py b/apache-libcloud-1.0.0rc2/libcloud/common/runabove.py
deleted file mode 100644
index 4d45241..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/runabove.py
+++ /dev/null
@@ -1,164 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 hashlib
-import time
-
-try:
-    import simplejson as json
-except ImportError:
-    import json
-
-from libcloud.utils.py3 import httplib
-from libcloud.utils.connection import get_response_object
-from libcloud.common.types import InvalidCredsError
-from libcloud.common.base import ConnectionUserAndKey, JsonResponse
-from libcloud.httplib_ssl import LibcloudHTTPSConnection
-
-__all__ = [
-    'RunAboveResponse',
-    'RunAboveConnection'
-]
-
-API_HOST = 'api.runabove.com'
-API_ROOT = '/1.0'
-LOCATIONS = {
-    'SBG-1': {'id': 'SBG-1', 'name': 'Strasbourg 1', 'country': 'FR'},
-    'BHS-1': {'id': 'BHS-1', 'name': 'Montreal 1', 'country': 'CA'}
-}
-DEFAULT_ACCESS_RULES = [
-    {'method': 'GET', 'path': '/*'},
-    {'method': 'POST', 'path': '/*'},
-    {'method': 'PUT', 'path': '/*'},
-    {'method': 'DELETE', 'path': '/*'},
-]
-
-
-class RunAboveException(Exception):
-    pass
-
-
-class RunAboveResponse(JsonResponse):
-    def parse_error(self):
-        response = super(RunAboveResponse, self).parse_body()
-
-        if response.get('errorCode', None) == 'INVALID_SIGNATURE':
-            raise InvalidCredsError('Signature validation failed, probably '
-                                    'using invalid credentials')
-
-        return self.body
-
-
-class RunAboveConnection(ConnectionUserAndKey):
-    """
-    A connection to the RunAbove API
-
-    Wraps SSL connections to the RunAbove API, automagically injecting the
-    parameters that the API needs for each request.
-    """
-    host = API_HOST
-    request_path = API_ROOT
-    responseCls = RunAboveResponse
-    timestamp = None
-    ua = []
-    LOCATIONS = LOCATIONS
-    _timedelta = None
-
-    allow_insecure = True
-
-    def __init__(self, user_id, *args, **kwargs):
-        self.consumer_key = kwargs.pop('ex_consumer_key', None)
-        if self.consumer_key is None:
-            consumer_key_json = self.request_consumer_key(user_id)
-            msg = ("Your consumer key isn't validated, "
-                   "go to '%(validationUrl)s' for valid it. After instantiate "
-                   "your driver with \"ex_consumer_key='%(consumerKey)s'\"." %
-                   consumer_key_json)
-            raise RunAboveException(msg)
-        super(RunAboveConnection, self).__init__(user_id, *args, **kwargs)
-
-    def request_consumer_key(self, user_id):
-        action = self.request_path + '/auth/credential'
-        data = json.dumps({
-            'accessRules': DEFAULT_ACCESS_RULES,
-            'redirection': 'http://runabove.com',
-        })
-        headers = {
-            'Content-Type': 'application/json',
-            'X-Ra-Application': user_id,
-        }
-        httpcon = LibcloudHTTPSConnection(self.host)
-        httpcon.request(method='POST', url=action, body=data, headers=headers)
-        response = httpcon.getresponse()
-
-        if response.status == httplib.UNAUTHORIZED:
-            raise InvalidCredsError()
-
-        body = response.read()
-        json_response = json.loads(body)
-        httpcon.close()
-        return json_response
-
-    def get_timestamp(self):
-        if not self._timedelta:
-            url = 'https://%s/%s/auth/time' % (API_HOST, API_ROOT)
-            response = get_response_object(url=url, method='GET', headers={})
-            if not response or not response.body:
-                raise Exception('Failed to get current time from RunAbove API')
-
-            timestamp = int(response.body)
-            self._timedelta = timestamp - int(time.time())
-        return int(time.time()) + self._timedelta
-
-    def make_signature(self, method, action, data, timestamp):
-        full_url = 'https://%s%s' % (API_HOST, action)
-        sha1 = hashlib.sha1()
-        base_signature = "+".join([
-            self.key,
-            self.consumer_key,
-            method.upper(),
-            full_url,
-            data if data else '',
-            str(timestamp),
-        ])
-        sha1.update(base_signature.encode())
-        signature = '$1$' + sha1.hexdigest()
-        return signature
-
-    def add_default_params(self, params):
-        return params
-
-    def add_default_headers(self, headers):
-        headers.update({
-            'X-Ra-Application': self.user_id,
-            'X-Ra-Consumer': self.consumer_key,
-            'Content-type': 'application/json',
-        })
-        return headers
-
-    def request(self, action, params=None, data=None, headers=None,
-                method='GET', raw=False):
-        data = json.dumps(data) if data else None
-        timestamp = self.get_timestamp()
-        signature = self.make_signature(method, action, data, timestamp)
-        headers = headers or {}
-        headers.update({
-            'X-Ra-Timestamp': timestamp,
-            'X-Ra-Signature': signature
-        })
-        return super(RunAboveConnection, self)\
-            .request(action, params=params, data=data, headers=headers,
-                     method=method, raw=raw)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/softlayer.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/softlayer.py b/apache-libcloud-1.0.0rc2/libcloud/common/softlayer.py
deleted file mode 100644
index d41b431..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/softlayer.py
+++ /dev/null
@@ -1,88 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-Softlayer connection
-"""
-
-from libcloud.common.base import ConnectionUserAndKey
-from libcloud.common.xmlrpc import XMLRPCResponse, XMLRPCConnection
-from libcloud.common.types import InvalidCredsError, LibcloudError
-
-
-class SoftLayerException(LibcloudError):
-    """
-    Exception class for SoftLayer driver
-    """
-    pass
-
-
-class SoftLayerObjectDoesntExist(LibcloudError):
-    """
-    Exception class for SoftLayer driver object doesnt exist
-    """
-    pass
-
-
-class SoftLayerResponse(XMLRPCResponse):
-    defaultExceptionCls = SoftLayerException
-    exceptions = {
-        'SoftLayer_Account': InvalidCredsError,
-        'SoftLayer_Exception_ObjectNotFound': SoftLayerObjectDoesntExist
-    }
-
-
-class SoftLayerConnection(XMLRPCConnection, ConnectionUserAndKey):
-    responseCls = SoftLayerResponse
-    host = 'api.softlayer.com'
-    endpoint = '/xmlrpc/v3'
-
-    def request(self, service, method, *args, **kwargs):
-        headers = {}
-        headers.update(self._get_auth_headers())
-        headers.update(self._get_init_params(service, kwargs.get('id')))
-        headers.update(
-            self._get_object_mask(service, kwargs.get('object_mask')))
-        headers.update(
-            self._get_object_mask(service, kwargs.get('object_mask')))
-
-        args = ({'headers': headers}, ) + args
-        endpoint = '%s/%s' % (self.endpoint, service)
-        return super(SoftLayerConnection, self).request(method, *args,
-                                                        **{'endpoint':
-                                                            endpoint})
-
-    def _get_auth_headers(self):
-        return {
-            'authenticate': {
-                'username': self.user_id,
-                'apiKey': self.key
-            }
-        }
-
-    def _get_init_params(self, service, id):
-        if id is not None:
-            return {
-                '%sInitParameters' % service: {'id': id}
-            }
-        else:
-            return {}
-
-    def _get_object_mask(self, service, mask):
-        if mask is not None:
-            return {
-                '%sObjectMask' % service: {'mask': mask}
-            }
-        else:
-            return {}

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/types.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/types.py b/apache-libcloud-1.0.0rc2/libcloud/common/types.py
deleted file mode 100644
index b5ff512..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/types.py
+++ /dev/null
@@ -1,143 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from libcloud.utils.py3 import httplib
-
-__all__ = [
-    "LibcloudError",
-    "MalformedResponseError",
-    "ProviderError",
-    "InvalidCredsError",
-    "InvalidCredsException",
-    "LazyList"
-]
-
-
-class LibcloudError(Exception):
-    """The base class for other libcloud exceptions"""
-
-    def __init__(self, value, driver=None):
-        super(LibcloudError, self).__init__(value)
-        self.value = value
-        self.driver = driver
-
-    def __str__(self):
-        return self.__repr__()
-
-    def __repr__(self):
-        return ("<LibcloudError in " +
-                repr(self.driver) +
-                " " +
-                repr(self.value) + ">")
-
-
-class MalformedResponseError(LibcloudError):
-    """Exception for the cases when a provider returns a malformed
-    response, e.g. you request JSON and provider returns
-    '<h3>something</h3>' due to some error on their side."""
-
-    def __init__(self, value, body=None, driver=None):
-        self.value = value
-        self.driver = driver
-        self.body = body
-
-    def __str__(self):
-        return self.__repr__()
-
-    def __repr__(self):
-        return ("<MalformedResponseException in " +
-                repr(self.driver) +
-                " " +
-                repr(self.value) +
-                ">: " +
-                repr(self.body))
-
-
-class ProviderError(LibcloudError):
-    """
-    Exception used when provider gives back
-    error response (HTTP 4xx, 5xx) for a request.
-
-    Specific sub types can be derieved for errors like
-    HTTP 401 : InvalidCredsError
-    HTTP 404 : NodeNotFoundError, ContainerDoesNotExistError
-    """
-
-    def __init__(self, value, http_code, driver=None):
-        super(ProviderError, self).__init__(value=value, driver=driver)
-        self.http_code = http_code
-
-    def __str__(self):
-        return self.__repr__()
-
-    def __repr__(self):
-        return repr(self.value)
-
-
-class InvalidCredsError(ProviderError):
-    """Exception used when invalid credentials are used on a provider."""
-
-    def __init__(self, value='Invalid credentials with the provider',
-                 driver=None):
-        super(InvalidCredsError, self).__init__(value,
-                                                http_code=httplib.UNAUTHORIZED,
-                                                driver=driver)
-
-
-# Deprecated alias of :class:`InvalidCredsError`
-InvalidCredsException = InvalidCredsError
-
-
-class LazyList(object):
-
-    def __init__(self, get_more, value_dict=None):
-        self._data = []
-        self._last_key = None
-        self._exhausted = False
-        self._all_loaded = False
-        self._get_more = get_more
-        self._value_dict = value_dict or {}
-
-    def __iter__(self):
-        if not self._all_loaded:
-            self._load_all()
-
-        data = self._data
-        for i in data:
-            yield i
-
-    def __getitem__(self, index):
-        if index >= len(self._data) and not self._all_loaded:
-            self._load_all()
-
-        return self._data[index]
-
-    def __len__(self):
-        self._load_all()
-        return len(self._data)
-
-    def __repr__(self):
-        self._load_all()
-        repr_string = ', ' .join([repr(item) for item in self._data])
-        repr_string = '[%s]' % (repr_string)
-        return repr_string
-
-    def _load_all(self):
-        while not self._exhausted:
-            newdata, self._last_key, self._exhausted = \
-                self._get_more(last_key=self._last_key,
-                               value_dict=self._value_dict)
-            self._data.extend(newdata)
-        self._all_loaded = True

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/vultr.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/vultr.py b/apache-libcloud-1.0.0rc2/libcloud/common/vultr.py
deleted file mode 100644
index aa57105..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/vultr.py
+++ /dev/null
@@ -1,121 +0,0 @@
-from libcloud.common.base import ConnectionKey, JsonResponse
-
-
-__all__ = [
-    'API_HOST',
-    'VultrConnection',
-    'VultrException',
-    'VultrResponse',
-]
-
-# Endpoint for the Vultr API
-API_HOST = 'api.vultr.com'
-
-
-class VultrResponse(JsonResponse):
-
-    objects = None
-    error_dict = {}
-    errors = None
-    ERROR_CODE_MAP = {
-
-        400: "Invalid API location. Check the URL that you are using.",
-        403: "Invalid or missing API key. Check that your API key is present" +
-             " and matches your assigned key.",
-        405: "Invalid HTTP method. Check that the method (POST|GET) matches" +
-             " what the documentation indicates.",
-        412: "Request failed. Check the response body for a more detailed" +
-             " description.",
-        500: "Internal server error. Try again at a later time.",
-        503: "Rate limit hit. API requests are limited to an average of 1/s." +
-             " Try your request again later.",
-
-    }
-
-    def __init__(self, response, connection):
-
-        self.errors = []
-        super(VultrResponse, self).__init__(response=response,
-                                            connection=connection)
-        self.objects, self.errors = self.parse_body_and_errors()
-        if not self.success():
-            raise self._make_excp(self.errors[0])
-
-    def parse_body_and_errors(self):
-        """
-        Returns JSON data in a python list.
-        """
-        json_objects = []
-        errors = []
-
-        if self.status in self.ERROR_CODE_MAP:
-            self.error_dict['ERRORCODE'] = self.status
-            self.error_dict['ERRORMESSAGE'] = self.ERROR_CODE_MAP[self.status]
-            errors.append(self.error_dict)
-
-        js = super(VultrResponse, self).parse_body()
-        if isinstance(js, dict):
-            js = [js]
-
-        json_objects.append(js)
-
-        return (json_objects, errors)
-
-    def _make_excp(self, error):
-        """
-        Convert API error to a VultrException instance
-        """
-
-        return VultrException(error['ERRORCODE'], error['ERRORMESSAGE'])
-
-    def success(self):
-
-        return len(self.errors) == 0
-
-
-class VultrConnection(ConnectionKey):
-    """
-    A connection to the Vultr API
-    """
-    host = API_HOST
-    responseCls = VultrResponse
-
-    def add_default_params(self, params):
-        """
-        Returns default params such as api_key which is
-        needed to perform an action.Returns a dictionary.
-        Example:/v1/server/upgrade_plan?api_key=self.key
-        """
-        params['api_key'] = self.key
-
-        return params
-
-    def add_default_headers(self, headers):
-        """
-        Returns default headers such as content-type.
-        Returns a dictionary.
-        """
-        headers["Content-Type"] = "application/x-www-form-urlencoded"
-        headers["Accept"] = "text/plain"
-
-        return headers
-
-    def set_path(self):
-        self.path = '/v/'
-        return self.path
-
-
-class VultrException(Exception):
-    """
-    Error originating from the Vultr API
-    """
-    def __init__(self, code, message):
-        self.code = code
-        self.message = message
-        self.args = (code, message)
-
-    def __str__(self):
-        return "(%u) %s" % (self.code, self.message)
-
-    def __repr__(self):
-        return "VultrException code %u '%s'" % (self.code, self.message)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/worldwidedns.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/worldwidedns.py b/apache-libcloud-1.0.0rc2/libcloud/common/worldwidedns.py
deleted file mode 100644
index 1c02a12..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/worldwidedns.py
+++ /dev/null
@@ -1,195 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 re
-
-from libcloud.common.base import ConnectionUserAndKey
-from libcloud.common.base import Response
-from libcloud.common.types import ProviderError
-
-
-OK_CODES = ['200', '211', '212', '213']
-ERROR_CODES = ['401', '403', '405', '406', '407', '408', '409', '410', '411',
-               '412', '413', '414', '450', '451']
-
-
-class WorldWideDNSException(ProviderError):
-    def __init__(self, value, http_code, code, driver=None):
-        self.code = code
-        super(WorldWideDNSException, self).__init__(value, http_code, driver)
-
-
-class SuspendedAccount(WorldWideDNSException):
-    def __init__(self, http_code, driver=None):
-        value = "Login ID you supplied is SUSPENDED, you need to renew" + \
-                " your account"
-        super(SuspendedAccount, self).__init__(value, http_code, 401,
-                                               driver)
-
-
-class LoginOrPasswordNotMatch(WorldWideDNSException):
-    def __init__(self, http_code, driver=None):
-        value = "Login ID and/or Password you supplied is not on file or" + \
-                " does not match"
-        super(LoginOrPasswordNotMatch, self).__init__(value, http_code, 403,
-                                                      driver)
-
-
-class NonExistentDomain(WorldWideDNSException):
-    def __init__(self, http_code, driver=None):
-        value = "Domain name supplied is not in your account"
-        super(NonExistentDomain, self).__init__(value, http_code, 405,
-                                                driver)
-
-
-class CouldntRemoveDomain(WorldWideDNSException):
-    def __init__(self, http_code, driver=None):
-        value = "Error occured removing domain from name server, try again"
-        super(CouldntRemoveDomain, self).__init__(value, http_code, 406,
-                                                  driver)
-
-
-class LimitExceeded(WorldWideDNSException):
-    def __init__(self, http_code, driver=None):
-        value = "Your limit was exceeded, you need to upgrade your account"
-        super(LimitExceeded, self).__init__(value, http_code, 407,
-                                            driver)
-
-
-class ExistentDomain(WorldWideDNSException):
-    def __init__(self, http_code, driver=None):
-        value = "Domain already exists on our servers"
-        super(ExistentDomain, self).__init__(value, http_code, 408,
-                                             driver)
-
-
-class DomainBanned(WorldWideDNSException):
-    def __init__(self, http_code, driver=None):
-        value = "Domain is listed in DNSBL and is banned from our servers"
-        super(DomainBanned, self).__init__(value, http_code, 409,
-                                           driver)
-
-
-class InvalidDomainName(WorldWideDNSException):
-    def __init__(self, http_code, driver=None):
-        value = "Invalid domain name"
-        super(InvalidDomainName, self).__init__(value, http_code, 410,
-                                                driver)
-
-
-class ErrorOnReloadInNameServer(WorldWideDNSException):
-    def __init__(self, server, http_code, driver=None):
-        if server == 1:
-            value = "Name server #1 kicked an error on reload, contact support"
-            code = 411
-        elif server == 2:
-            value = "Name server #2 kicked an error on reload, contact support"
-            code = 412
-        elif server == 3:
-            value = "Name server #3 kicked an error on reload, contact support"
-            code = 413
-        super(ErrorOnReloadInNameServer, self).__init__(value, http_code, code,
-                                                        driver)
-
-
-class NewUserNotValid(WorldWideDNSException):
-    def __init__(self, http_code, driver=None):
-        value = "New userid is not valid"
-        super(NewUserNotValid, self).__init__(value, http_code, 414,
-                                              driver)
-
-
-class CouldntReachNameServer(WorldWideDNSException):
-    def __init__(self, http_code, driver=None):
-        value = "Couldn't reach the name server, try again later"
-        super(CouldntReachNameServer, self).__init__(value, http_code, 450,
-                                                     driver)
-
-
-class NoZoneFile(WorldWideDNSException):
-    def __init__(self, http_code, driver=None):
-        value = "No zone file in the name server queried"
-        super(NoZoneFile, self).__init__(value, http_code, 451,
-                                         driver)
-
-
-ERROR_CODE_TO_EXCEPTION_CLS = {
-    '401': SuspendedAccount,
-    '403': LoginOrPasswordNotMatch,
-    '405': NonExistentDomain,
-    '406': CouldntRemoveDomain,
-    '407': LimitExceeded,
-    '408': ExistentDomain,
-    '409': DomainBanned,
-    '410': InvalidDomainName,
-    '411': ErrorOnReloadInNameServer,
-    '412': ErrorOnReloadInNameServer,
-    '413': ErrorOnReloadInNameServer,
-    '414': NewUserNotValid,
-    '450': CouldntReachNameServer,
-    '451': NoZoneFile,
-}
-
-
-class WorldWideDNSResponse(Response):
-
-    def parse_body(self):
-        """
-        Parse response body.
-
-        :return: Parsed body.
-        :rtype: ``str``
-        """
-        if self._code_response(self.body):
-            codes = re.split('\r?\n', self.body)
-            for code in codes:
-                if code in OK_CODES:
-                    continue
-                elif code in ERROR_CODES:
-                    exception = ERROR_CODE_TO_EXCEPTION_CLS.get(code)
-                    if code in ['411', '412', '413']:
-                        server = int(code[2])
-                        raise exception(server, self.status)
-                    raise exception(self.status)
-        return self.body
-
-    def _code_response(self, body):
-        """
-        Checks if the response body contains code status.
-
-        :rtype: ``bool``
-        """
-        available_response_codes = OK_CODES + ERROR_CODES
-        codes = re.split('\r?\n', body)
-        if codes[0] in available_response_codes:
-            return True
-        return False
-
-
-class WorldWideDNSConnection(ConnectionUserAndKey):
-    host = 'www.worldwidedns.net'
-    responseCls = WorldWideDNSResponse
-
-    def add_default_params(self, params):
-        """
-        Add parameters that are necessary for every request
-
-        This method adds ``NAME`` and ``PASSWORD`` to
-        the request.
-        """
-        params["NAME"] = self.user_id
-        params["PASSWORD"] = self.key
-        if hasattr(self, 'reseller_id'):
-            params["ID"] = self.reseller_id
-        return params

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/xmlrpc.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/xmlrpc.py b/apache-libcloud-1.0.0rc2/libcloud/common/xmlrpc.py
deleted file mode 100644
index 2502ea6..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/xmlrpc.py
+++ /dev/null
@@ -1,108 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-Base classes for working with xmlrpc APIs
-"""
-
-import sys
-
-from libcloud.utils.py3 import xmlrpclib
-from libcloud.utils.py3 import httplib
-from libcloud.common.base import Response, Connection
-
-
-class ProtocolError(Exception):
-    pass
-
-
-class ErrorCodeMixin(object):
-    """
-    This is a helper for API's that have a well defined collection of error
-    codes that are easily parsed out of error messages. It acts as a factory:
-    it finds the right exception for the error code, fetches any parameters it
-    needs from the context and raises it.
-    """
-
-    exceptions = {}
-
-    def raise_exception_for_error(self, error_code, message):
-        exceptionCls = self.exceptions.get(error_code, None)
-        if exceptionCls is None:
-            return
-        context = self.connection.context
-        driver = self.connection.driver
-        params = {}
-        if hasattr(exceptionCls, 'kwargs'):
-            for key in exceptionCls.kwargs:
-                if key in context:
-                    params[key] = context[key]
-        raise exceptionCls(value=message, driver=driver, **params)
-
-
-class XMLRPCResponse(ErrorCodeMixin, Response):
-
-    defaultExceptionCls = Exception
-
-    def success(self):
-        return self.status == httplib.OK
-
-    def parse_body(self):
-        try:
-            params, methodname = xmlrpclib.loads(self.body)
-            if len(params) == 1:
-                params = params[0]
-            return params
-        except xmlrpclib.Fault:
-            e = sys.exc_info()[1]
-            self.raise_exception_for_error(e.faultCode, e.faultString)
-            error_string = '%s: %s' % (e.faultCode, e.faultString)
-            raise self.defaultExceptionCls(error_string)
-
-    def parse_error(self):
-        msg = 'Server returned an invalid xmlrpc response (%d)' % (self.status)
-        raise ProtocolError(msg)
-
-
-class XMLRPCConnection(Connection):
-    """
-    Connection class which can call XMLRPC based API's.
-
-    This class uses the xmlrpclib marshalling and demarshalling code but uses
-    the http transports provided by libcloud giving it better certificate
-    validation and debugging helpers than the core client library.
-    """
-
-    responseCls = XMLRPCResponse
-
-    def add_default_headers(self, headers):
-        headers['Content-Type'] = 'text/xml'
-        return headers
-
-    def request(self, method_name, *args, **kwargs):
-        """
-        Call a given `method_name`.
-
-        :type method_name: ``str``
-        :param method_name: A method exposed by the xmlrpc endpoint that you
-            are connecting to.
-
-        :type args: ``tuple``
-        :param args: Arguments to invoke with method with.
-        """
-        endpoint = kwargs.get('endpoint', self.endpoint)
-        data = xmlrpclib.dumps(args, methodname=method_name, allow_none=True)
-        return super(XMLRPCConnection, self).request(endpoint,
-                                                     data=data,
-                                                     method='POST')


[23/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/linode.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/linode.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/linode.py
deleted file mode 100644
index e24e367..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/linode.py
+++ /dev/null
@@ -1,683 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""libcloud driver for the Linode(R) API
-
-This driver implements all libcloud functionality for the Linode API.
-Since the API is a bit more fine-grained, create_node abstracts a significant
-amount of work (and may take a while to run).
-
-Linode home page                    http://www.linode.com/
-Linode API documentation            http://www.linode.com/api/
-Alternate bindings for reference    http://github.com/tjfontaine/linode-python
-
-Linode(R) is a registered trademark of Linode, LLC.
-
-"""
-
-import os
-
-try:
-    import simplejson as json
-except ImportError:
-    import json
-
-import itertools
-import binascii
-
-from copy import copy
-
-from libcloud.utils.py3 import PY3
-
-from libcloud.common.linode import (API_ROOT, LinodeException,
-                                    LinodeConnection, LINODE_PLAN_IDS,
-                                    LINODE_DISK_FILESYSTEMS)
-from libcloud.compute.types import Provider, NodeState
-from libcloud.compute.base import NodeDriver, NodeSize, Node, NodeLocation
-from libcloud.compute.base import NodeAuthPassword, NodeAuthSSHKey
-from libcloud.compute.base import NodeImage, StorageVolume
-
-
-class LinodeNodeDriver(NodeDriver):
-    """libcloud driver for the Linode API
-
-    Rough mapping of which is which:
-
-    - list_nodes              linode.list
-    - reboot_node             linode.reboot
-    - destroy_node            linode.delete
-    - create_node             linode.create, linode.update,
-                              linode.disk.createfromdistribution,
-                              linode.disk.create, linode.config.create,
-                              linode.ip.addprivate, linode.boot
-    - list_sizes              avail.linodeplans
-    - list_images             avail.distributions
-    - list_locations          avail.datacenters
-    - list_volumes            linode.disk.list
-    - destroy_volume          linode.disk.delete
-
-    For more information on the Linode API, be sure to read the reference:
-
-        http://www.linode.com/api/
-    """
-    type = Provider.LINODE
-    name = "Linode"
-    website = 'http://www.linode.com/'
-    connectionCls = LinodeConnection
-    _linode_plan_ids = LINODE_PLAN_IDS
-    _linode_disk_filesystems = LINODE_DISK_FILESYSTEMS
-    features = {'create_node': ['ssh_key', 'password']}
-
-    def __init__(self, key):
-        """Instantiate the driver with the given API key
-
-        :param   key: the API key to use (required)
-        :type    key: ``str``
-
-        :rtype: ``None``
-        """
-        self.datacenter = None
-        NodeDriver.__init__(self, key)
-
-    # Converts Linode's state from DB to a NodeState constant.
-    LINODE_STATES = {
-        (-2): NodeState.UNKNOWN,    # Boot Failed
-        (-1): NodeState.PENDING,    # Being Created
-        0: NodeState.PENDING,     # Brand New
-        1: NodeState.RUNNING,     # Running
-        2: NodeState.TERMINATED,  # Powered Off
-        3: NodeState.REBOOTING,   # Shutting Down
-        4: NodeState.UNKNOWN      # Reserved
-    }
-
-    def list_nodes(self):
-        """
-        List all Linodes that the API key can access
-
-        This call will return all Linodes that the API key in use has access
-         to.
-        If a node is in this list, rebooting will work; however, creation and
-        destruction are a separate grant.
-
-        :return: List of node objects that the API key can access
-        :rtype: ``list`` of :class:`Node`
-        """
-        params = {"api_action": "linode.list"}
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        return self._to_nodes(data)
-
-    def reboot_node(self, node):
-        """
-        Reboot the given Linode
-
-        Will issue a shutdown job followed by a boot job, using the last booted
-        configuration.  In most cases, this will be the only configuration.
-
-        :param      node: the Linode to reboot
-        :type       node: :class:`Node`
-
-        :rtype: ``bool``
-        """
-        params = {"api_action": "linode.reboot", "LinodeID": node.id}
-        self.connection.request(API_ROOT, params=params)
-        return True
-
-    def destroy_node(self, node):
-        """Destroy the given Linode
-
-        Will remove the Linode from the account and issue a prorated credit. A
-        grant for removing Linodes from the account is required, otherwise this
-        method will fail.
-
-        In most cases, all disk images must be removed from a Linode before the
-        Linode can be removed; however, this call explicitly skips those
-        safeguards. There is no going back from this method.
-
-        :param       node: the Linode to destroy
-        :type        node: :class:`Node`
-
-        :rtype: ``bool``
-        """
-        params = {"api_action": "linode.delete", "LinodeID": node.id,
-                  "skipChecks": True}
-        self.connection.request(API_ROOT, params=params)
-        return True
-
-    def create_node(self, **kwargs):
-        """Create a new Linode, deploy a Linux distribution, and boot
-
-        This call abstracts much of the functionality of provisioning a Linode
-        and getting it booted.  A global grant to add Linodes to the account is
-        required, as this call will result in a billing charge.
-
-        Note that there is a safety valve of 5 Linodes per hour, in order to
-        prevent a runaway script from ruining your day.
-
-        :keyword name: the name to assign the Linode (mandatory)
-        :type    name: ``str``
-
-        :keyword image: which distribution to deploy on the Linode (mandatory)
-        :type    image: :class:`NodeImage`
-
-        :keyword size: the plan size to create (mandatory)
-        :type    size: :class:`NodeSize`
-
-        :keyword auth: an SSH key or root password (mandatory)
-        :type    auth: :class:`NodeAuthSSHKey` or :class:`NodeAuthPassword`
-
-        :keyword location: which datacenter to create the Linode in
-        :type    location: :class:`NodeLocation`
-
-        :keyword ex_swap: size of the swap partition in MB (128)
-        :type    ex_swap: ``int``
-
-        :keyword ex_rsize: size of the root partition in MB (plan size - swap).
-        :type    ex_rsize: ``int``
-
-        :keyword ex_kernel: a kernel ID from avail.kernels (Latest 2.6 Stable).
-        :type    ex_kernel: ``str``
-
-        :keyword ex_payment: one of 1, 12, or 24; subscription length (1)
-        :type    ex_payment: ``int``
-
-        :keyword ex_comment: a small comment for the configuration (libcloud)
-        :type    ex_comment: ``str``
-
-        :keyword ex_private: whether or not to request a private IP (False)
-        :type    ex_private: ``bool``
-
-        :keyword lconfig: what to call the configuration (generated)
-        :type    lconfig: ``str``
-
-        :keyword lroot: what to call the root image (generated)
-        :type    lroot: ``str``
-
-        :keyword lswap: what to call the swap space (generated)
-        :type    lswap: ``str``
-
-        :return: Node representing the newly-created Linode
-        :rtype: :class:`Node`
-        """
-        name = kwargs["name"]
-        image = kwargs["image"]
-        size = kwargs["size"]
-        auth = self._get_and_check_auth(kwargs["auth"])
-
-        # Pick a location (resolves LIBCLOUD-41 in JIRA)
-        if "location" in kwargs:
-            chosen = kwargs["location"].id
-        elif self.datacenter:
-            chosen = self.datacenter
-        else:
-            raise LinodeException(0xFB, "Need to select a datacenter first")
-
-        # Step 0: Parameter validation before we purchase
-        # We're especially careful here so we don't fail after purchase, rather
-        # than getting halfway through the process and having the API fail.
-
-        # Plan ID
-        plans = self.list_sizes()
-        if size.id not in [p.id for p in plans]:
-            raise LinodeException(0xFB, "Invalid plan ID -- avail.plans")
-
-        # Payment schedule
-        payment = "1" if "ex_payment" not in kwargs else \
-            str(kwargs["ex_payment"])
-        if payment not in ["1", "12", "24"]:
-            raise LinodeException(0xFB, "Invalid subscription (1, 12, 24)")
-
-        ssh = None
-        root = None
-        # SSH key and/or root password
-        if isinstance(auth, NodeAuthSSHKey):
-            ssh = auth.pubkey
-        elif isinstance(auth, NodeAuthPassword):
-            root = auth.password
-
-        if not ssh and not root:
-            raise LinodeException(0xFB, "Need SSH key or root password")
-        if root is not None and len(root) < 6:
-            raise LinodeException(0xFB, "Root password is too short")
-
-        # Swap size
-        try:
-            swap = 128 if "ex_swap" not in kwargs else int(kwargs["ex_swap"])
-        except:
-            raise LinodeException(0xFB, "Need an integer swap size")
-
-        # Root partition size
-        imagesize = (size.disk - swap) if "ex_rsize" not in kwargs else\
-            int(kwargs["ex_rsize"])
-        if (imagesize + swap) > size.disk:
-            raise LinodeException(0xFB, "Total disk images are too big")
-
-        # Distribution ID
-        distros = self.list_images()
-        if image.id not in [d.id for d in distros]:
-            raise LinodeException(0xFB,
-                                  "Invalid distro -- avail.distributions")
-
-        # Kernel
-        if "ex_kernel" in kwargs:
-            kernel = kwargs["ex_kernel"]
-        else:
-            if image.extra['64bit']:
-                # For a list of available kernel ids, see
-                # https://www.linode.com/kernels/
-                kernel = 138
-            else:
-                kernel = 137
-        params = {"api_action": "avail.kernels"}
-        kernels = self.connection.request(API_ROOT, params=params).objects[0]
-        if kernel not in [z["KERNELID"] for z in kernels]:
-            raise LinodeException(0xFB, "Invalid kernel -- avail.kernels")
-
-        # Comments
-        comments = "Created by Apache libcloud <http://www.libcloud.org>" if\
-            "ex_comment" not in kwargs else kwargs["ex_comment"]
-
-        # Step 1: linode.create
-        params = {
-            "api_action": "linode.create",
-            "DatacenterID": chosen,
-            "PlanID": size.id,
-            "PaymentTerm": payment
-        }
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        linode = {"id": data["LinodeID"]}
-
-        # Step 1b. linode.update to rename the Linode
-        params = {
-            "api_action": "linode.update",
-            "LinodeID": linode["id"],
-            "Label": name
-        }
-        self.connection.request(API_ROOT, params=params)
-
-        # Step 1c. linode.ip.addprivate if it was requested
-        if "ex_private" in kwargs and kwargs["ex_private"]:
-            params = {
-                "api_action": "linode.ip.addprivate",
-                "LinodeID": linode["id"]
-            }
-            self.connection.request(API_ROOT, params=params)
-
-        # Step 1d. Labels
-        # use the linode id as the name can be up to 63 chars and the labels
-        # are limited to 48 chars
-        label = {
-            "lconfig": "[%s] Configuration Profile" % linode["id"],
-            "lroot": "[%s] %s Disk Image" % (linode["id"], image.name),
-            "lswap": "[%s] Swap Space" % linode["id"]
-        }
-        for what in ["lconfig", "lroot", "lswap"]:
-            if what in kwargs:
-                label[what] = kwargs[what]
-
-        # Step 2: linode.disk.createfromdistribution
-        if not root:
-            root = binascii.b2a_base64(os.urandom(8)).decode('ascii').strip()
-
-        params = {
-            "api_action": "linode.disk.createfromdistribution",
-            "LinodeID": linode["id"],
-            "DistributionID": image.id,
-            "Label": label["lroot"],
-            "Size": imagesize,
-            "rootPass": root,
-        }
-        if ssh:
-            params["rootSSHKey"] = ssh
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        linode["rootimage"] = data["DiskID"]
-
-        # Step 3: linode.disk.create for swap
-        params = {
-            "api_action": "linode.disk.create",
-            "LinodeID": linode["id"],
-            "Label": label["lswap"],
-            "Type": "swap",
-            "Size": swap
-        }
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        linode["swapimage"] = data["DiskID"]
-
-        # Step 4: linode.config.create for main profile
-        disks = "%s,%s,,,,,,," % (linode["rootimage"], linode["swapimage"])
-        params = {
-            "api_action": "linode.config.create",
-            "LinodeID": linode["id"],
-            "KernelID": kernel,
-            "Label": label["lconfig"],
-            "Comments": comments,
-            "DiskList": disks
-        }
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        linode["config"] = data["ConfigID"]
-
-        # Step 5: linode.boot
-        params = {
-            "api_action": "linode.boot",
-            "LinodeID": linode["id"],
-            "ConfigID": linode["config"]
-        }
-        self.connection.request(API_ROOT, params=params)
-
-        # Make a node out of it and hand it back
-        params = {"api_action": "linode.list", "LinodeID": linode["id"]}
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        nodes = self._to_nodes(data)
-
-        if len(nodes) == 1:
-            node = nodes[0]
-            if getattr(auth, "generated", False):
-                node.extra['password'] = auth.password
-            return node
-
-        return None
-
-    def list_sizes(self, location=None):
-        """
-        List available Linode plans
-
-        Gets the sizes that can be used for creating a Linode.  Since available
-        Linode plans vary per-location, this method can also be passed a
-        location to filter the availability.
-
-        :keyword location: the facility to retrieve plans in
-        :type    location: :class:`NodeLocation`
-
-        :rtype: ``list`` of :class:`NodeSize`
-        """
-        params = {"api_action": "avail.linodeplans"}
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        sizes = []
-        for obj in data:
-            n = NodeSize(id=obj["PLANID"], name=obj["LABEL"], ram=obj["RAM"],
-                         disk=(obj["DISK"] * 1024), bandwidth=obj["XFER"],
-                         price=obj["PRICE"], driver=self.connection.driver)
-            sizes.append(n)
-        return sizes
-
-    def list_images(self):
-        """
-        List available Linux distributions
-
-        Retrieve all Linux distributions that can be deployed to a Linode.
-
-        :rtype: ``list`` of :class:`NodeImage`
-        """
-        params = {"api_action": "avail.distributions"}
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        distros = []
-        for obj in data:
-            i = NodeImage(id=obj["DISTRIBUTIONID"],
-                          name=obj["LABEL"],
-                          driver=self.connection.driver,
-                          extra={'pvops': obj['REQUIRESPVOPSKERNEL'],
-                                 '64bit': obj['IS64BIT']})
-            distros.append(i)
-        return distros
-
-    def list_locations(self):
-        """
-        List available facilities for deployment
-
-        Retrieve all facilities that a Linode can be deployed in.
-
-        :rtype: ``list`` of :class:`NodeLocation`
-        """
-        params = {"api_action": "avail.datacenters"}
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        nl = []
-        for dc in data:
-            country = None
-            if "USA" in dc["LOCATION"]:
-                country = "US"
-            elif "UK" in dc["LOCATION"]:
-                country = "GB"
-            elif "JP" in dc["LOCATION"]:
-                country = "JP"
-            else:
-                country = "??"
-            nl.append(NodeLocation(dc["DATACENTERID"],
-                                   dc["LOCATION"],
-                                   country,
-                                   self))
-        return nl
-
-    def linode_set_datacenter(self, dc):
-        """
-        Set the default datacenter for Linode creation
-
-        Since Linodes must be created in a facility, this function sets the
-        default that :class:`create_node` will use.  If a location keyword is
-        not passed to :class:`create_node`, this method must have already been
-        used.
-
-        :keyword dc: the datacenter to create Linodes in unless specified
-        :type    dc: :class:`NodeLocation`
-
-        :rtype: ``bool``
-        """
-        did = dc.id
-        params = {"api_action": "avail.datacenters"}
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        for datacenter in data:
-            if did == dc["DATACENTERID"]:
-                self.datacenter = did
-                return
-
-        dcs = ", ".join([d["DATACENTERID"] for d in data])
-        self.datacenter = None
-        raise LinodeException(0xFD, "Invalid datacenter (use one of %s)" % dcs)
-
-    def destroy_volume(self, volume):
-        """
-        Destroys disk volume for the Linode. Linode id is to be provided as
-        extra["LinodeId"] whithin :class:`StorageVolume`. It can be retrieved
-        by :meth:`libcloud.compute.drivers.linode.LinodeNodeDriver\
-                 .ex_list_volumes`.
-
-        :param volume: Volume to be destroyed
-        :type volume: :class:`StorageVolume`
-
-        :rtype: ``bool``
-        """
-        if not isinstance(volume, StorageVolume):
-            raise LinodeException(0xFD, "Invalid volume instance")
-
-        if volume.extra["LINODEID"] is None:
-            raise LinodeException(0xFD, "Missing LinodeID")
-
-        params = {
-            "api_action": "linode.disk.delete",
-            "LinodeID": volume.extra["LINODEID"],
-            "DiskID": volume.id,
-        }
-        self.connection.request(API_ROOT, params=params)
-
-        return True
-
-    def ex_create_volume(self, size, name, node, fs_type):
-        """
-        Create disk for the Linode.
-
-        :keyword    size: Size of volume in megabytes (required)
-        :type       size: ``int``
-
-        :keyword    name: Name of the volume to be created
-        :type       name: ``str``
-
-        :keyword    node: Node to attach volume to.
-        :type       node: :class:`Node`
-
-        :keyword    fs_type: The formatted type of this disk. Valid types are:
-                             ext3, ext4, swap, raw
-        :type       fs_type: ``str``
-
-
-        :return: StorageVolume representing the newly-created volume
-        :rtype: :class:`StorageVolume`
-        """
-        # check node
-        if not isinstance(node, Node):
-            raise LinodeException(0xFD, "Invalid node instance")
-
-        # check space available
-        total_space = node.extra['TOTALHD']
-        existing_volumes = self.ex_list_volumes(node)
-        used_space = 0
-        for volume in existing_volumes:
-            used_space = used_space + volume.size
-
-        available_space = total_space - used_space
-        if available_space < size:
-            raise LinodeException(0xFD, "Volume size too big. Available space\
-                    %d" % available_space)
-
-        # check filesystem type
-        if fs_type not in self._linode_disk_filesystems:
-            raise LinodeException(0xFD, "Not valid filesystem type")
-
-        params = {
-            "api_action": "linode.disk.create",
-            "LinodeID": node.id,
-            "Label": name,
-            "Type": fs_type,
-            "Size": size
-        }
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        volume = data["DiskID"]
-        # Make a volume out of it and hand it back
-        params = {
-            "api_action": "linode.disk.list",
-            "LinodeID": node.id,
-            "DiskID": volume
-        }
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        return self._to_volumes(data)[0]
-
-    def ex_list_volumes(self, node, disk_id=None):
-        """
-        List existing disk volumes for for given Linode.
-
-        :keyword    node: Node to list disk volumes for. (required)
-        :type       node: :class:`Node`
-
-        :keyword    disk_id: Id for specific disk volume. (optional)
-        :type       disk_id: ``int``
-
-        :rtype: ``list`` of :class:`StorageVolume`
-        """
-        if not isinstance(node, Node):
-            raise LinodeException(0xFD, "Invalid node instance")
-
-        params = {
-            "api_action": "linode.disk.list",
-            "LinodeID": node.id
-        }
-        # Add param if disk_id was specified
-        if disk_id is not None:
-            params["DiskID"] = disk_id
-
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        return self._to_volumes(data)
-
-    def _to_volumes(self, objs):
-        """
-        Covert returned JSON volumes into StorageVolume instances
-
-        :keyword    objs: ``list`` of JSON dictionaries representing the
-                         StorageVolumes
-        :type       objs: ``list``
-
-        :return: ``list`` of :class:`StorageVolume`s
-        """
-        volumes = {}
-        for o in objs:
-            vid = o["DISKID"]
-            volumes[vid] = vol = StorageVolume(id=vid, name=o["LABEL"],
-                                               size=int(o["SIZE"]),
-                                               driver=self.connection.driver)
-            vol.extra = copy(o)
-        return list(volumes.values())
-
-    def _to_nodes(self, objs):
-        """Convert returned JSON Linodes into Node instances
-
-        :keyword objs: ``list`` of JSON dictionaries representing the Linodes
-        :type objs: ``list``
-        :return: ``list`` of :class:`Node`s"""
-
-        # Get the IP addresses for the Linodes
-        nodes = {}
-        batch = []
-        for o in objs:
-            lid = o["LINODEID"]
-            nodes[lid] = n = Node(id=lid, name=o["LABEL"], public_ips=[],
-                                  private_ips=[],
-                                  state=self.LINODE_STATES[o["STATUS"]],
-                                  driver=self.connection.driver)
-            n.extra = copy(o)
-            n.extra["PLANID"] = self._linode_plan_ids.get(o.get("TOTALRAM"))
-            batch.append({"api_action": "linode.ip.list", "LinodeID": lid})
-
-        # Avoid batch limitation
-        ip_answers = []
-        args = [iter(batch)] * 25
-
-        if PY3:
-            izip_longest = itertools.zip_longest
-        else:
-            izip_longest = getattr(itertools, 'izip_longest', _izip_longest)
-
-        for twenty_five in izip_longest(*args):
-            twenty_five = [q for q in twenty_five if q]
-            params = {"api_action": "batch",
-                      "api_requestArray": json.dumps(twenty_five)}
-            req = self.connection.request(API_ROOT, params=params)
-            if not req.success() or len(req.objects) == 0:
-                return None
-            ip_answers.extend(req.objects)
-
-        # Add the returned IPs to the nodes and return them
-        for ip_list in ip_answers:
-            for ip in ip_list:
-                lid = ip["LINODEID"]
-                which = nodes[lid].public_ips if ip["ISPUBLIC"] == 1 else\
-                    nodes[lid].private_ips
-                which.append(ip["IPADDRESS"])
-        return list(nodes.values())
-
-
-def _izip_longest(*args, **kwds):
-    """Taken from Python docs
-
-    http://docs.python.org/library/itertools.html#itertools.izip
-    """
-
-    fillvalue = kwds.get('fillvalue')
-
-    def sentinel(counter=([fillvalue] * (len(args) - 1)).pop):
-        yield counter()  # yields the fillvalue, or raises IndexError
-
-    fillers = itertools.repeat(fillvalue)
-    iters = [itertools.chain(it, sentinel(), fillers) for it in args]
-    try:
-        for tup in itertools.izip(*iters):
-            yield tup
-    except IndexError:
-        pass

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/medone.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/medone.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/medone.py
deleted file mode 100644
index 2273303..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/medone.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-Med-1 Driver
-"""
-
-from libcloud.compute.providers import Provider
-from libcloud.common.dimensiondata import (DimensionDataConnection,
-                                           API_ENDPOINTS)
-from libcloud.compute.drivers.dimensiondata import DimensionDataNodeDriver
-
-DEFAULT_REGION = 'med1-il'
-
-
-class MedOneNodeDriver(DimensionDataNodeDriver):
-    """
-    Med-1 node driver, based on Dimension Data driver
-    """
-
-    selected_region = None
-    connectionCls = DimensionDataConnection
-    name = 'MedOne'
-    website = 'http://www.med-1.com/'
-    type = Provider.MEDONE
-    features = {'create_node': ['password']}
-    api_version = 1.0
-
-    def __init__(self, key, secret=None, secure=True, host=None, port=None,
-                 api_version=None, region=DEFAULT_REGION, **kwargs):
-
-        if region not in API_ENDPOINTS:
-            raise ValueError('Invalid region: %s' % (region))
-
-        self.selected_region = API_ENDPOINTS[region]
-
-        super(MedOneNodeDriver, self).__init__(
-            key=key,
-            secret=secret,
-            secure=secure,
-            host=host,
-            port=port,
-            api_version=api_version,
-            region=region,
-            **kwargs)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/nephoscale.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/nephoscale.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/nephoscale.py
deleted file mode 100644
index e06b7d3..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/nephoscale.py
+++ /dev/null
@@ -1,448 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-NephoScale Cloud driver (http://www.nephoscale.com)
-API documentation: http://docs.nephoscale.com
-Created by Markos Gogoulos (https://mist.io)
-"""
-
-import base64
-import sys
-import time
-import os
-import binascii
-
-from libcloud.utils.py3 import httplib
-from libcloud.utils.py3 import b
-from libcloud.utils.py3 import urlencode
-
-from libcloud.compute.providers import Provider
-from libcloud.common.base import JsonResponse, ConnectionUserAndKey
-from libcloud.compute.types import (NodeState, InvalidCredsError,
-                                    LibcloudError)
-from libcloud.compute.base import (Node, NodeDriver, NodeImage, NodeSize,
-                                   NodeLocation)
-from libcloud.utils.networking import is_private_subnet
-
-API_HOST = 'api.nephoscale.com'
-
-NODE_STATE_MAP = {
-    'on': NodeState.RUNNING,
-    'off': NodeState.UNKNOWN,
-    'unknown': NodeState.UNKNOWN,
-}
-
-VALID_RESPONSE_CODES = [httplib.OK, httplib.ACCEPTED, httplib.CREATED,
-                        httplib.NO_CONTENT]
-
-# used in create_node and specifies how many times to get the list of nodes and
-# check if the newly created node is there. This is because when a request is
-# sent to create a node, NephoScale replies with the job id, and not the node
-# itself thus we don't have the ip addresses, that are required in deploy_node
-CONNECT_ATTEMPTS = 10
-
-
-class NodeKey(object):
-    def __init__(self, id, name, public_key=None, key_group=None,
-                 password=None):
-        self.id = id
-        self.name = name
-        self.key_group = key_group
-        self.password = password
-        self.public_key = public_key
-
-    def __repr__(self):
-        return (('<NodeKey: id=%s, name=%s>') %
-                (self.id, self.name))
-
-
-class NephoscaleResponse(JsonResponse):
-    """
-    Nephoscale API Response
-    """
-
-    def parse_error(self):
-        if self.status == httplib.UNAUTHORIZED:
-            raise InvalidCredsError('Authorization Failed')
-        if self.status == httplib.NOT_FOUND:
-            raise Exception("The resource you are looking for is not found.")
-
-        return self.body
-
-    def success(self):
-        return self.status in VALID_RESPONSE_CODES
-
-
-class NephoscaleConnection(ConnectionUserAndKey):
-    """
-    Nephoscale connection class.
-    Authenticates to the API through Basic Authentication
-    with username/password
-    """
-    host = API_HOST
-    responseCls = NephoscaleResponse
-
-    allow_insecure = False
-
-    def add_default_headers(self, headers):
-        """
-        Add parameters that are necessary for every request
-        """
-        user_b64 = base64.b64encode(b('%s:%s' % (self.user_id, self.key)))
-        headers['Authorization'] = 'Basic %s' % (user_b64.decode('utf-8'))
-        return headers
-
-
-class NephoscaleNodeDriver(NodeDriver):
-    """
-    Nephoscale node driver class.
-
-    >>> from libcloud.compute.providers import get_driver
-    >>> driver = get_driver('nephoscale')
-    >>> conn = driver('nepho_user','nepho_password')
-    >>> conn.list_nodes()
-    """
-
-    type = Provider.NEPHOSCALE
-    api_name = 'nephoscale'
-    name = 'NephoScale'
-    website = 'http://www.nephoscale.com'
-    connectionCls = NephoscaleConnection
-    features = {'create_node': ['ssh_key']}
-
-    def list_locations(self):
-        """
-        List available zones for deployment
-
-        :rtype: ``list`` of :class:`NodeLocation`
-        """
-        result = self.connection.request('/datacenter/zone/').object
-        locations = []
-        for value in result.get('data', []):
-            location = NodeLocation(id=value.get('id'),
-                                    name=value.get('name'),
-                                    country='US',
-                                    driver=self)
-            locations.append(location)
-        return locations
-
-    def list_images(self):
-        """
-        List available images for deployment
-
-        :rtype: ``list`` of :class:`NodeImage`
-        """
-        result = self.connection.request('/image/server/').object
-        images = []
-        for value in result.get('data', []):
-            extra = {'architecture': value.get('architecture'),
-                     'disks': value.get('disks'),
-                     'billable_type': value.get('billable_type'),
-                     'pcpus': value.get('pcpus'),
-                     'cores': value.get('cores'),
-                     'uri': value.get('uri'),
-                     'storage': value.get('storage'),
-                     }
-            image = NodeImage(id=value.get('id'),
-                              name=value.get('friendly_name'),
-                              driver=self,
-                              extra=extra)
-            images.append(image)
-        return images
-
-    def list_sizes(self):
-        """
-        List available sizes containing prices
-
-        :rtype: ``list`` of :class:`NodeSize`
-        """
-        result = self.connection.request('/server/type/cloud/').object
-        sizes = []
-        for value in result.get('data', []):
-            value_id = value.get('id')
-            size = NodeSize(id=value_id,
-                            name=value.get('friendly_name'),
-                            ram=value.get('ram'),
-                            disk=value.get('storage'),
-                            bandwidth=None,
-                            price=self._get_size_price(size_id=str(value_id)),
-                            driver=self)
-            sizes.append(size)
-
-        return sorted(sizes, key=lambda k: k.price)
-
-    def list_nodes(self):
-        """
-        List available nodes
-
-        :rtype: ``list`` of :class:`Node`
-        """
-        result = self.connection.request('/server/cloud/').object
-        nodes = [self._to_node(value) for value in result.get('data', [])]
-        return nodes
-
-    def rename_node(self, node, name, hostname=None):
-        """rename a cloud server, optionally specify hostname too"""
-        data = {'name': name}
-        if hostname:
-            data['hostname'] = hostname
-        params = urlencode(data)
-        result = self.connection.request('/server/cloud/%s/' % node.id,
-                                         data=params, method='PUT').object
-        return result.get('response') in VALID_RESPONSE_CODES
-
-    def reboot_node(self, node):
-        """reboot a running node"""
-        result = self.connection.request('/server/cloud/%s/initiator/restart/'
-                                         % node.id, method='POST').object
-        return result.get('response') in VALID_RESPONSE_CODES
-
-    def ex_start_node(self, node):
-        """start a stopped node"""
-        result = self.connection.request('/server/cloud/%s/initiator/start/'
-                                         % node.id, method='POST').object
-        return result.get('response') in VALID_RESPONSE_CODES
-
-    def ex_stop_node(self, node):
-        """stop a running node"""
-        result = self.connection.request('/server/cloud/%s/initiator/stop/'
-                                         % node.id, method='POST').object
-        return result.get('response') in VALID_RESPONSE_CODES
-
-    def destroy_node(self, node):
-        """destroy a node"""
-        result = self.connection.request('/server/cloud/%s/' % node.id,
-                                         method='DELETE').object
-        return result.get('response') in VALID_RESPONSE_CODES
-
-    def ex_list_keypairs(self, ssh=False, password=False, key_group=None):
-        """
-        List available console and server keys
-        There are two types of keys for NephoScale, ssh and password keys.
-        If run without arguments, lists all keys. Otherwise list only
-        ssh keys, or only password keys.
-        Password keys with key_group 4 are console keys. When a server
-        is created, it has two keys, one password or ssh key, and
-        one password console key.
-
-        :keyword ssh: if specified, show ssh keys only (optional)
-        :type    ssh: ``bool``
-
-        :keyword password: if specified, show password keys only (optional)
-        :type    password: ``bool``
-
-        :keyword key_group: if specified, show keys with this key_group only
-                            eg key_group=4 for console password keys (optional)
-        :type    key_group: ``int``
-
-        :rtype: ``list`` of :class:`NodeKey`
-        """
-        if (ssh and password):
-            raise LibcloudError('You can only supply ssh or password. To \
-get all keys call with no arguments')
-        if ssh:
-            result = self.connection.request('/key/sshrsa/').object
-        elif password:
-            result = self.connection.request('/key/password/').object
-        else:
-            result = self.connection.request('/key/').object
-        keys = [self._to_key(value) for value in result.get('data', [])]
-
-        if key_group:
-            keys = [key for key in keys if
-                    key.key_group == key_group]
-        return keys
-
-    def ex_create_keypair(self, name, public_key=None, password=None,
-                          key_group=None):
-        """Creates a key, ssh or password, for server or console
-           The group for the key (key_group) is 1 for Server and 4 for Console
-           Returns the id of the created key
-        """
-        if public_key:
-            if not key_group:
-                key_group = 1
-            data = {
-                'name': name,
-                'public_key': public_key,
-                'key_group': key_group
-
-            }
-            params = urlencode(data)
-            result = self.connection.request('/key/sshrsa/', data=params,
-                                             method='POST').object
-        else:
-            if not key_group:
-                key_group = 4
-            if not password:
-                password = self.random_password()
-                data = {
-                    'name': name,
-                    'password': password,
-                    'key_group': key_group
-                }
-            params = urlencode(data)
-            result = self.connection.request('/key/password/', data=params,
-                                             method='POST').object
-        return result.get('data', {}).get('id', '')
-
-    def ex_delete_keypair(self, key_id, ssh=False):
-        """Delete an ssh key or password given it's id
-        """
-        if ssh:
-            result = self.connection.request('/key/sshrsa/%s/' % key_id,
-                                             method='DELETE').object
-        else:
-            result = self.connection.request('/key/password/%s/' % key_id,
-                                             method='DELETE').object
-        return result.get('response') in VALID_RESPONSE_CODES
-
-    def create_node(self, name, size, image, server_key=None,
-                    console_key=None, zone=None, **kwargs):
-        """Creates the node, and sets the ssh key, console key
-        NephoScale will respond with a 200-200 response after sending a valid
-        request. If nowait=True is specified in the args, we then ask a few
-        times until the server is created and assigned a public IP address,
-        so that deploy_node can be run
-
-        >>> from libcloud.compute.providers import get_driver
-        >>> driver = get_driver('nephoscale')
-        >>> conn = driver('nepho_user','nepho_password')
-        >>> conn.list_nodes()
-        >>> name = 'staging-server'
-        >>> size = conn.list_sizes()[0]
-        <NodeSize: id=27, ...name=CS025 - 0.25GB, 10GB, ...>
-        >>> image = conn.list_images()[9]
-        <NodeImage: id=49, name=Linux Ubuntu Server 10.04 LTS 64-bit, ...>
-        >>> server_keys = conn.ex_list_keypairs(key_group=1)[0]
-        <NodeKey: id=71211, name=markos>
-        >>> server_key = conn.ex_list_keypairs(key_group=1)[0].id
-        70867
-        >>> console_keys = conn.ex_list_keypairs(key_group=4)[0]
-        <NodeKey: id=71213, name=mistio28434>
-        >>> console_key = conn.ex_list_keypairs(key_group=4)[0].id
-        70907
-        >>> node = conn.create_node(name=name, size=size, image=image, \
-                console_key=console_key, server_key=server_key)
-
-        We can also create an ssh key, plus a console key and
-        deploy node with them
-        >>> server_key = conn.ex_create_keypair(name, public_key='123')
-        71211
-        >>> console_key = conn.ex_create_keypair(name, key_group=4)
-        71213
-
-        We can increase the number of connect attempts to wait until
-        the node is created, so that deploy_node has ip address to
-        deploy the script
-        We can also specify the location
-        >>> location = conn.list_locations()[0]
-        >>> node = conn.create_node(name=name,
-        >>> ...                     size=size,
-        >>> ...                     image=image,
-        >>> ...                     console_key=console_key,
-        >>> ...                     server_key=server_key,
-        >>> ...                     connect_attempts=10,
-        >>> ...                     nowait=True,
-        >>> ...                     zone=location.id)
-        """
-        hostname = kwargs.get('hostname', name)
-        service_type = size.id
-        image = image.id
-        connect_attempts = int(kwargs.get('connect_attempts',
-                               CONNECT_ATTEMPTS))
-
-        data = {'name': name,
-                'hostname': hostname,
-                'service_type': service_type,
-                'image': image,
-                'server_key': server_key,
-                'console_key': console_key,
-                'zone': zone
-                }
-
-        params = urlencode(data)
-        try:
-            node = self.connection.request('/server/cloud/', data=params,
-                                           method='POST')
-        except Exception:
-            e = sys.exc_info()[1]
-            raise Exception("Failed to create node %s" % e)
-        node = Node(id='', name=name, state=NodeState.UNKNOWN, public_ips=[],
-                    private_ips=[], driver=self)
-
-        nowait = kwargs.get('ex_wait', False)
-        if not nowait:
-            return node
-        else:
-            # try to get the created node public ips, for use in deploy_node
-            # At this point we don't have the id of the newly created Node,
-            # so search name in nodes
-            created_node = False
-            while connect_attempts > 0:
-                nodes = self.list_nodes()
-                created_node = [c_node for c_node in nodes if
-                                c_node.name == name]
-                if created_node:
-                    return created_node[0]
-                else:
-                    time.sleep(60)
-                    connect_attempts = connect_attempts - 1
-            return node
-
-    def _to_node(self, data):
-        """Convert node in Node instances
-        """
-
-        state = NODE_STATE_MAP.get(data.get('power_status'), '4')
-        public_ips = []
-        private_ips = []
-        ip_addresses = data.get('ipaddresses', '')
-        # E.g. "ipaddresses": "198.120.14.6, 10.132.60.1"
-        if ip_addresses:
-            for ip in ip_addresses.split(','):
-                ip = ip.replace(' ', '')
-                if is_private_subnet(ip):
-                    private_ips.append(ip)
-                else:
-                    public_ips.append(ip)
-        extra = {
-            'zone_data': data.get('zone'),
-            'zone': data.get('zone', {}).get('name'),
-            'image': data.get('image', {}).get('friendly_name'),
-            'create_time': data.get('create_time'),
-            'network_ports': data.get('network_ports'),
-            'is_console_enabled': data.get('is_console_enabled'),
-            'service_type': data.get('service_type', {}).get('friendly_name'),
-            'hostname': data.get('hostname')
-        }
-
-        node = Node(id=data.get('id'), name=data.get('name'), state=state,
-                    public_ips=public_ips, private_ips=private_ips,
-                    driver=self, extra=extra)
-        return node
-
-    def _to_key(self, data):
-        return NodeKey(id=data.get('id'),
-                       name=data.get('name'),
-                       password=data.get('password'),
-                       key_group=data.get('key_group'),
-                       public_key=data.get('public_key'))
-
-    def random_password(self, size=8):
-        value = os.urandom(size)
-        password = binascii.hexlify(value).decode('ascii')
-        return password[:size]

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/ntta.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/ntta.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/ntta.py
deleted file mode 100644
index 5ef5cb9..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/ntta.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-NTT America Driver
-"""
-
-from libcloud.compute.providers import Provider
-from libcloud.common.dimensiondata import (DimensionDataConnection,
-                                           API_ENDPOINTS)
-from libcloud.compute.drivers.dimensiondata import DimensionDataNodeDriver
-
-DEFAULT_REGION = 'ntta-na'
-
-
-class NTTAmericaNodeDriver(DimensionDataNodeDriver):
-    """
-    NTT America node driver, based on Dimension Data driver
-    """
-
-    selected_region = None
-    connectionCls = DimensionDataConnection
-    name = 'NTTAmerica'
-    website = 'http://www.nttamerica.com/'
-    type = Provider.NTTA
-    features = {'create_node': ['password']}
-    api_version = 1.0
-
-    def __init__(self, key, secret=None, secure=True, host=None, port=None,
-                 api_version=None, region=DEFAULT_REGION, **kwargs):
-
-        if region not in API_ENDPOINTS:
-            raise ValueError('Invalid region: %s' % (region))
-
-        self.selected_region = API_ENDPOINTS[region]
-
-        super(NTTAmericaNodeDriver, self).__init__(
-            key=key,
-            secret=secret,
-            secure=secure,
-            host=host,
-            port=port,
-            api_version=api_version,
-            region=region,
-            **kwargs)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/onapp.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/onapp.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/onapp.py
deleted file mode 100644
index 2b0811e..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/onapp.py
+++ /dev/null
@@ -1,406 +0,0 @@
-import json
-
-from libcloud.compute.base import Node, NodeDriver
-from libcloud.common.onapp import OnAppConnection
-from libcloud.utils.networking import is_private_subnet
-from libcloud.compute.providers import Provider
-
-
-__all__ = [
-    "OnAppNodeDriver"
-]
-
-"""
-Define the extra dictionary for specific resources
-"""
-RESOURCE_EXTRA_ATTRIBUTES_MAP = {
-    "node": {
-        "add_to_marketplace": {
-            "key_name": "add_to_marketplace",
-            "transform_func": bool
-        },
-        "admin_note": {
-            "key_name": "admin_note",
-            "transform_func": str
-        },
-        "allow_resize_without_reboot": {
-            "key_name": "allow_resize_without_reboot",
-            "transform_func": bool
-        },
-        "allowed_hot_migrate": {
-            "key_name": "allowed_hot_migrate",
-            "transform_func": bool
-        },
-        "allowed_swap": {
-            "key_name": "allowed_swap",
-            "transform_func": bool
-        },
-        "booted": {
-            "key_name": "booted",
-            "transform_func": bool
-        },
-        "built": {
-            "key_name": "built",
-            "transform_func": bool
-        },
-        "cpu_priority": {
-            "key_name": "cpu_priority",
-            "transform_func": int
-        },
-        "cpu_shares": {
-            "key_name": "cpu_shares",
-            "transform_func": int
-        },
-        "cpu_sockets": {
-            "key_name": "cpu_sockets",
-            "transform_func": int
-        },
-        "cpu_threads": {
-            "key_name": "cpu_threads",
-            "transform_func": int
-        },
-        "cpu_units": {
-            "key_name": "cpu_units",
-            "transform_func": int
-        },
-        "cpus": {
-            "key_name": "cpus",
-            "transform_func": int
-        },
-        "created_at": {
-            "key_name": "created_at",
-            "transform_func": str
-        },
-        "customer_network_id": {
-            "key_name": "customer_network_id",
-            "transform_func": str
-        },
-        "deleted_at": {
-            "key_name": "deleted_at",
-            "transform_func": str
-        },
-        "edge_server_type": {
-            "key_name": "edge_server_type",
-            "transform_func": str
-        },
-        "enable_autoscale": {
-            "key_name": "enable_autoscale",
-            "transform_func": bool
-        },
-        "enable_monitis": {
-            "key_name": "enable_monitis",
-            "transform_func": bool
-        },
-        "firewall_notrack": {
-            "key_name": "firewall_notrack",
-            "transform_func": bool
-        },
-        "hostname": {
-            "key_name": "hostname",
-            "transform_func": str
-        },
-        "hypervisor_id": {
-            "key_name": "hypervisor_id",
-            "transform_func": int
-        },
-        "id": {
-            "key_name": "id",
-            "transform_func": int
-        },
-        "initial_root_password": {
-            "key_name": "initial_root_password",
-            "transform_func": str
-        },
-        "initial_root_password_encrypted": {
-            "key_name": "initial_root_password_encrypted",
-            "transform_func": bool
-        },
-        "local_remote_access_ip_address": {
-            "key_name": "local_remote_access_ip_address",
-            "transform_func": str
-        },
-        "local_remote_access_port": {
-            "key_name": "local_remote_access_port",
-            "transform_func": int
-        },
-        "locked": {
-            "key_name": "locked",
-            "transform_func": bool
-        },
-        "memory": {
-            "key_name": "memory",
-            "transform_func": int
-        },
-        "min_disk_size": {
-            "key_name": "min_disk_size",
-            "transform_func": int
-        },
-        "monthly_bandwidth_used": {
-            "key_name": "monthly_bandwidth_used",
-            "transform_func": int
-        },
-        "note": {
-            "key_name": "note",
-            "transform_func": str
-        },
-        "operating_system": {
-            "key_name": "operating_system",
-            "transform_func": str
-        },
-        "operating_system_distro": {
-            "key_name": "operating_system_distro",
-            "transform_func": str
-        },
-        "preferred_hvs": {
-            "key_name": "preferred_hvs",
-            "transform_func": list
-        },
-        "price_per_hour": {
-            "key_name": "price_per_hour",
-            "transform_func": float
-        },
-        "price_per_hour_powered_off": {
-            "key_name": "price_per_hour_powered_off",
-            "transform_func": float
-        },
-        "recovery_mode": {
-            "key_name": "recovery_mode",
-            "transform_func": bool
-        },
-        "remote_access_password": {
-            "key_name": "remote_access_password",
-            "transform_func": str
-        },
-        "service_password": {
-            "key_name": "service_password",
-            "transform_func": str
-        },
-        "state": {
-            "key_name": "state",
-            "transform_func": str
-        },
-        "storage_server_type": {
-            "key_name": "storage_server_type",
-            "transform_func": str
-        },
-        "strict_virtual_machine_id": {
-            "key_name": "strict_virtual_machine_id",
-            "transform_func": str
-        },
-        "support_incremental_backups": {
-            "key_name": "support_incremental_backups",
-            "transform_func": bool
-        },
-        "suspended": {
-            "key_name": "suspended",
-            "transform_func": bool
-        },
-        "template_id": {
-            "key_name": "template_id",
-            "transform_func": int
-        },
-        "template_label": {
-            "key_name": "template_label",
-            "transform_func": str
-        },
-        "total_disk_size": {
-            "key_name": "total_disk_size",
-            "transform_func": int
-        },
-        "updated_at": {
-            "key_name": "updated_at",
-            "transform_func": str
-        },
-        "user_id": {
-            "key_name": "user_id",
-            "transform_func": int
-        },
-        "vip": {
-            "key_name": "vip",
-            "transform_func": bool
-        },
-        "xen_id": {
-            "key_name": "xen_id",
-            "transform_func": int
-        }
-    }
-}
-
-
-class OnAppNodeDriver(NodeDriver):
-    """
-    Base OnApp node driver.
-    """
-
-    connectionCls = OnAppConnection
-    type = Provider.ONAPP
-    name = 'OnApp'
-    website = 'http://onapp.com/'
-
-    def create_node(self, name, ex_memory, ex_cpus, ex_cpu_shares,
-                    ex_hostname, ex_template_id, ex_primary_disk_size,
-                    ex_swap_disk_size, ex_required_virtual_machine_build=1,
-                    ex_required_ip_address_assignment=1, **kwargs):
-        """
-        Add a VS
-
-        :param  kwargs: All keyword arguments to create a VS
-        :type   kwargs: ``dict``
-
-        :rtype: :class:`OnAppNode`
-        """
-        server_params = dict(
-            label=name,
-            memory=ex_memory,
-            cpus=ex_cpus,
-            cpu_shares=ex_cpu_shares,
-            hostname=ex_hostname,
-            template_id=ex_template_id,
-            primary_disk_size=ex_primary_disk_size,
-            swap_disk_size=ex_swap_disk_size,
-            required_virtual_machine_build=ex_required_virtual_machine_build,
-            required_ip_address_assignment=ex_required_ip_address_assignment,
-            rate_limit=kwargs.get("rate_limit")
-        )
-
-        server_params.update(OnAppNodeDriver._create_args_to_params(**kwargs))
-        data = json.dumps({"virtual_machine": server_params})
-
-        response = self.connection.request(
-            "/virtual_machines.json",
-            data=data,
-            headers={
-                "Content-type": "application/json"},
-            method="POST")
-
-        return self._to_node(response.object["virtual_machine"])
-
-    def destroy_node(self,
-                     node,
-                     ex_convert_last_backup=0,
-                     ex_destroy_all_backups=0):
-        """
-        Delete a VS
-
-        :param node: OnApp node
-        :type  node: :class: `OnAppNode`
-
-        :param convert_last_backup: set 1 to convert the last VS's backup to
-                                    template, otherwise set 0
-        :type  convert_last_backup: ``int``
-
-        :param destroy_all_backups: set 1 to destroy all existing backups of
-                                    this VS, otherwise set 0
-        :type  destroy_all_backups: ``int``
-        """
-        server_params = {
-            "convert_last_backup": ex_convert_last_backup,
-            "destroy_all_backups": ex_destroy_all_backups
-        }
-        action = "/virtual_machines/{identifier}.json".format(
-            identifier=node.id)
-
-        self.connection.request(action, params=server_params, method="DELETE")
-        return True
-
-    def list_nodes(self):
-        """
-        List all VS
-
-        :rtype: ``list`` of :class:`OnAppNode`
-        """
-        response = self.connection.request("/virtual_machines.json")
-        nodes = []
-        for vm in response.object:
-            nodes.append(self._to_node(vm["virtual_machine"]))
-        return nodes
-
-    #
-    # Helper methods
-    #
-
-    def _to_node(self, data):
-        identifier = data["identifier"]
-        name = data["label"]
-        private_ips = []
-        public_ips = []
-        for ip in data["ip_addresses"]:
-            address = ip["ip_address"]['address']
-            if is_private_subnet(address):
-                private_ips.append(address)
-            else:
-                public_ips.append(address)
-
-        extra = OnAppNodeDriver._get_extra_dict(
-            data, RESOURCE_EXTRA_ATTRIBUTES_MAP["node"]
-        )
-        return Node(identifier,
-                    name,
-                    extra['state'],
-                    public_ips,
-                    private_ips,
-                    self,
-                    extra=extra)
-
-    @staticmethod
-    def _get_extra_dict(response, mapping):
-        """
-        Extract attributes from the element based on rules provided in the
-        mapping dictionary.
-
-        :param   response: The JSON response to parse the values from.
-        :type    response: ``dict``
-
-        :param   mapping: Dictionary with the extra layout
-        :type    mapping: ``dict``
-
-        :rtype:  ``dict``
-        """
-        extra = {}
-        for attribute, values in mapping.items():
-            transform_func = values["transform_func"]
-            value = response.get(values["key_name"])
-
-            extra[attribute] = transform_func(value) if value else None
-        return extra
-
-    @staticmethod
-    def _create_args_to_params(**kwargs):
-        """
-        Extract server params from keyword args to create a VS
-
-        :param   kwargs: keyword args
-        :return: ``dict``
-        """
-        params = [
-            "ex_cpu_sockets",
-            "ex_cpu_threads",
-            "ex_enable_autoscale",
-            "ex_data_store_group_primary_id",
-            "ex_data_store_group_swap_id",
-            "ex_hypervisor_group_id",
-            "ex_hypervisor_id",
-            "ex_initial_root_password",
-            "ex_note",
-            "ex_primary_disk_min_iops",
-            "ex_primary_network_id",
-            "ex_primary_network_group_id",
-            "ex_recipe_ids",
-            "ex_required_automatic_backup",
-            "ex_required_virtual_machine_startup",
-            "ex_required_virtual_machine_startup",
-            "ex_selected_ip_address_id",
-            "ex_swap_disk_min_iops",
-            "ex_type_of_format",
-            "ex_custom_recipe_variables",
-            "ex_licensing_key",
-            "ex_licensing_server_id",
-            "ex_licensing_type",
-        ]
-        server_params = {}
-
-        for p in params:
-            value = kwargs.get(p)
-            if value:
-                server_params[p[3:]] = value
-        return server_params


[24/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/gogrid.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/gogrid.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/gogrid.py
deleted file mode 100644
index 6c73e46..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/gogrid.py
+++ /dev/null
@@ -1,464 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-GoGrid driver
-"""
-import time
-import hashlib
-import copy
-
-from libcloud.utils.py3 import b
-
-from libcloud.common.types import InvalidCredsError, LibcloudError
-from libcloud.common.gogrid import GoGridConnection, BaseGoGridDriver
-from libcloud.compute.providers import Provider
-from libcloud.compute.types import NodeState
-from libcloud.compute.base import Node, NodeDriver
-from libcloud.compute.base import NodeSize, NodeImage, NodeLocation
-
-STATE = {
-    "Starting": NodeState.PENDING,
-    "On": NodeState.RUNNING,
-    "On/Saving": NodeState.RUNNING,
-    "Off": NodeState.PENDING,
-    "Restarting": NodeState.REBOOTING,
-    "Saving": NodeState.PENDING,
-    "Restoring": NodeState.PENDING,
-}
-
-GOGRID_INSTANCE_TYPES = {
-    '512MB': {'id': '512MB',
-              'name': '512MB',
-              'ram': 512,
-              'disk': 30,
-              'bandwidth': None},
-    '1GB': {'id': '1GB',
-            'name': '1GB',
-            'ram': 1024,
-            'disk': 60,
-            'bandwidth': None},
-    '2GB': {'id': '2GB',
-            'name': '2GB',
-            'ram': 2048,
-            'disk': 120,
-            'bandwidth': None},
-    '4GB': {'id': '4GB',
-            'name': '4GB',
-            'ram': 4096,
-            'disk': 240,
-            'bandwidth': None},
-    '8GB': {'id': '8GB',
-            'name': '8GB',
-            'ram': 8192,
-            'disk': 480,
-            'bandwidth': None},
-    '16GB': {'id': '16GB',
-             'name': '16GB',
-             'ram': 16384,
-             'disk': 960,
-             'bandwidth': None},
-    '24GB': {'id': '24GB',
-             'name': '24GB',
-             'ram': 24576,
-             'disk': 960,
-             'bandwidth': None},
-}
-
-
-class GoGridNode(Node):
-    # Generating uuid based on public ip to get around missing id on
-    # create_node in gogrid api
-    #
-    # Used public ip since it is not mutable and specified at create time,
-    # so uuid of node should not change after add is completed
-    def get_uuid(self):
-        return hashlib.sha1(
-            b("%s:%s" % (self.public_ips, self.driver.type))
-        ).hexdigest()
-
-
-class GoGridNodeDriver(BaseGoGridDriver, NodeDriver):
-    """
-    GoGrid node driver
-    """
-
-    connectionCls = GoGridConnection
-    type = Provider.GOGRID
-    api_name = 'gogrid'
-    name = 'GoGrid'
-    website = 'http://www.gogrid.com/'
-    features = {"create_node": ["generates_password"]}
-
-    _instance_types = GOGRID_INSTANCE_TYPES
-
-    def __init__(self, *args, **kwargs):
-        """
-        @inherits: :class:`NodeDriver.__init__`
-        """
-        super(GoGridNodeDriver, self).__init__(*args, **kwargs)
-
-    def _get_state(self, element):
-        try:
-            return STATE[element['state']['name']]
-        except:
-            pass
-        return NodeState.UNKNOWN
-
-    def _get_ip(self, element):
-        return element.get('ip').get('ip')
-
-    def _get_id(self, element):
-        return element.get('id')
-
-    def _to_node(self, element, password=None):
-        state = self._get_state(element)
-        ip = self._get_ip(element)
-        id = self._get_id(element)
-        n = GoGridNode(id=id,
-                       name=element['name'],
-                       state=state,
-                       public_ips=[ip],
-                       private_ips=[],
-                       extra={'ram': element.get('ram').get('name'),
-                              'description': element.get('description', '')},
-                       driver=self.connection.driver)
-        if password:
-            n.extra['password'] = password
-
-        return n
-
-    def _to_image(self, element):
-        n = NodeImage(id=element['id'],
-                      name=element['friendlyName'],
-                      driver=self.connection.driver)
-        return n
-
-    def _to_images(self, object):
-        return [self._to_image(el)
-                for el in object['list']]
-
-    def _to_location(self, element):
-        location = NodeLocation(id=element['id'],
-                                name=element['name'],
-                                country="US",
-                                driver=self.connection.driver)
-        return location
-
-    def _to_locations(self, object):
-        return [self._to_location(el)
-                for el in object['list']]
-
-    def list_images(self, location=None):
-        params = {}
-        if location is not None:
-            params["datacenter"] = location.id
-        images = self._to_images(
-            self.connection.request('/api/grid/image/list', params).object)
-        return images
-
-    def list_nodes(self):
-        """
-        @inherits: :class:`NodeDriver.list_nodes`
-        :rtype: ``list`` of :class:`GoGridNode`
-        """
-        passwords_map = {}
-
-        res = self._server_list()
-        try:
-            for password in self._password_list()['list']:
-                try:
-                    passwords_map[password['server']['id']] = \
-                        password['password']
-                except KeyError:
-                    pass
-        except InvalidCredsError:
-            # some gogrid API keys don't have permission to access the
-            # password list.
-            pass
-
-        return [self._to_node(el, passwords_map.get(el.get('id')))
-                for el in res['list']]
-
-    def reboot_node(self, node):
-        """
-        @inherits: :class:`NodeDriver.reboot_node`
-        :type node: :class:`GoGridNode`
-        """
-        id = node.id
-        power = 'restart'
-        res = self._server_power(id, power)
-        if not res.success():
-            raise Exception(res.parse_error())
-        return True
-
-    def destroy_node(self, node):
-        """
-        @inherits: :class:`NodeDriver.reboot_node`
-        :type node: :class:`GoGridNode`
-        """
-        id = node.id
-        res = self._server_delete(id)
-        if not res.success():
-            raise Exception(res.parse_error())
-        return True
-
-    def _server_list(self):
-        return self.connection.request('/api/grid/server/list').object
-
-    def _password_list(self):
-        return self.connection.request('/api/support/password/list').object
-
-    def _server_power(self, id, power):
-        # power in ['start', 'stop', 'restart']
-        params = {'id': id, 'power': power}
-        return self.connection.request("/api/grid/server/power", params,
-                                       method='POST')
-
-    def _server_delete(self, id):
-        params = {'id': id}
-        return self.connection.request("/api/grid/server/delete", params,
-                                       method='POST')
-
-    def _get_first_ip(self, location=None):
-        ips = self.ex_list_ips(public=True, assigned=False, location=location)
-        try:
-            return ips[0].ip
-        except IndexError:
-            raise LibcloudError('No public unassigned IPs left',
-                                GoGridNodeDriver)
-
-    def list_sizes(self, location=None):
-        sizes = []
-        for key, values in self._instance_types.items():
-            attributes = copy.deepcopy(values)
-            attributes.update({'price': self._get_size_price(size_id=key)})
-            sizes.append(NodeSize(driver=self.connection.driver, **attributes))
-
-        return sizes
-
-    def list_locations(self):
-        locations = self._to_locations(
-            self.connection.request('/api/common/lookup/list',
-                                    params={'lookup': 'ip.datacenter'}).object)
-        return locations
-
-    def ex_create_node_nowait(self, **kwargs):
-        """Don't block until GoGrid allocates id for a node
-        but return right away with id == None.
-
-        The existence of this method is explained by the fact
-        that GoGrid assigns id to a node only few minutes after
-        creation.
-
-
-        :keyword    name:   String with a name for this new node (required)
-        :type       name:   ``str``
-
-        :keyword    size:   The size of resources allocated to this node .
-                            (required)
-        :type       size:   :class:`NodeSize`
-
-        :keyword    image:  OS Image to boot on node. (required)
-        :type       image:  :class:`NodeImage`
-
-        :keyword    ex_description: Description of a Node
-        :type       ex_description: ``str``
-
-        :keyword    ex_ip: Public IP address to use for a Node. If not
-            specified, first available IP address will be picked
-        :type       ex_ip: ``str``
-
-        :rtype: :class:`GoGridNode`
-        """
-        name = kwargs['name']
-        image = kwargs['image']
-        size = kwargs['size']
-        try:
-            ip = kwargs['ex_ip']
-        except KeyError:
-            ip = self._get_first_ip(kwargs.get('location'))
-
-        params = {'name': name,
-                  'image': image.id,
-                  'description': kwargs.get('ex_description', ''),
-                  'server.ram': size.id,
-                  'ip': ip}
-
-        object = self.connection.request('/api/grid/server/add',
-                                         params=params, method='POST').object
-        node = self._to_node(object['list'][0])
-
-        return node
-
-    def create_node(self, **kwargs):
-        """Create a new GoGird node
-
-        @inherits: :class:`NodeDriver.create_node`
-
-        :keyword    ex_description: Description of a Node
-        :type       ex_description: ``str``
-
-        :keyword    ex_ip: Public IP address to use for a Node. If not
-                    specified, first available IP address will be picked
-        :type       ex_ip: ``str``
-
-        :rtype: :class:`GoGridNode`
-        """
-        node = self.ex_create_node_nowait(**kwargs)
-
-        timeout = 60 * 20
-        waittime = 0
-        interval = 2 * 60
-
-        while node.id is None and waittime < timeout:
-            nodes = self.list_nodes()
-
-            for i in nodes:
-                if i.public_ips[0] == node.public_ips[0] and i.id is not None:
-                    return i
-
-            waittime += interval
-            time.sleep(interval)
-
-        if id is None:
-            raise Exception(
-                "Wasn't able to wait for id allocation for the node %s"
-                % str(node))
-
-        return node
-
-    def ex_save_image(self, node, name):
-        """Create an image for node.
-
-        Please refer to GoGrid documentation to get info
-        how prepare a node for image creation:
-
-        http://wiki.gogrid.com/wiki/index.php/MyGSI
-
-        :keyword    node: node to use as a base for image
-        :type       node: :class:`GoGridNode`
-
-        :keyword    name: name for new image
-        :type       name: ``str``
-
-        :rtype: :class:`NodeImage`
-        """
-        params = {'server': node.id,
-                  'friendlyName': name}
-        object = self.connection.request('/api/grid/image/save', params=params,
-                                         method='POST').object
-
-        return self._to_images(object)[0]
-
-    def ex_edit_node(self, **kwargs):
-        """Change attributes of a node.
-
-        :keyword    node: node to be edited (required)
-        :type       node: :class:`GoGridNode`
-
-        :keyword    size: new size of a node (required)
-        :type       size: :class:`NodeSize`
-
-        :keyword    ex_description: new description of a node
-        :type       ex_description: ``str``
-
-        :rtype: :class:`Node`
-        """
-        node = kwargs['node']
-        size = kwargs['size']
-
-        params = {'id': node.id,
-                  'server.ram': size.id}
-
-        if 'ex_description' in kwargs:
-            params['description'] = kwargs['ex_description']
-
-        object = self.connection.request('/api/grid/server/edit',
-                                         params=params).object
-
-        return self._to_node(object['list'][0])
-
-    def ex_edit_image(self, **kwargs):
-        """Edit metadata of a server image.
-
-        :keyword    image: image to be edited (required)
-        :type       image: :class:`NodeImage`
-
-        :keyword    public: should be the image public (required)
-        :type       public: ``bool``
-
-        :keyword    ex_description: description of the image (optional)
-        :type       ex_description: ``str``
-
-        :keyword    name: name of the image
-        :type       name: ``str``
-
-        :rtype: :class:`NodeImage`
-        """
-
-        image = kwargs['image']
-        public = kwargs['public']
-
-        params = {'id': image.id,
-                  'isPublic': str(public).lower()}
-
-        if 'ex_description' in kwargs:
-            params['description'] = kwargs['ex_description']
-
-        if 'name' in kwargs:
-            params['friendlyName'] = kwargs['name']
-
-        object = self.connection.request('/api/grid/image/edit',
-                                         params=params).object
-
-        return self._to_image(object['list'][0])
-
-    def ex_list_ips(self, **kwargs):
-        """Return list of IP addresses assigned to
-        the account.
-
-        :keyword    public: set to True to list only
-                    public IPs or False to list only
-                    private IPs. Set to None or not specify
-                    at all not to filter by type
-        :type       public: ``bool``
-
-        :keyword    assigned: set to True to list only addresses
-                    assigned to servers, False to list unassigned
-                    addresses and set to None or don't set at all
-                    not no filter by state
-        :type       assigned: ``bool``
-
-        :keyword    location: filter IP addresses by location
-        :type       location: :class:`NodeLocation`
-
-        :rtype: ``list`` of :class:`GoGridIpAddress`
-        """
-
-        params = {}
-
-        if "public" in kwargs and kwargs["public"] is not None:
-            params["ip.type"] = {True: "Public",
-                                 False: "Private"}[kwargs["public"]]
-        if "assigned" in kwargs and kwargs["assigned"] is not None:
-            params["ip.state"] = {True: "Assigned",
-                                  False: "Unassigned"}[kwargs["assigned"]]
-        if "location" in kwargs and kwargs['location'] is not None:
-            params['datacenter'] = kwargs['location'].id
-
-        ips = self._to_ips(
-            self.connection.request('/api/grid/ip/list',
-                                    params=params).object)
-        return ips

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/gridspot.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/gridspot.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/gridspot.py
deleted file mode 100644
index 856b068..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/gridspot.py
+++ /dev/null
@@ -1,127 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from libcloud.compute.base import NodeDriver, Node
-from libcloud.compute.base import NodeState
-from libcloud.common.base import ConnectionKey, JsonResponse
-from libcloud.compute.types import Provider
-from libcloud.common.types import InvalidCredsError
-
-
-class GridspotAPIException(Exception):
-    def __str__(self):
-        return self.args[0]
-
-    def __repr__(self):
-        return "<GridspotAPIException '%s'>" % (self.args[0])
-
-
-class GridspotResponse(JsonResponse):
-    """
-    Response class for Gridspot
-    """
-    def parse_body(self):
-        body = super(GridspotResponse, self).parse_body()
-
-        if 'exception_name' in body and body['exception_name']:
-            raise GridspotAPIException(body['exception_name'])
-
-        return body
-
-    def parse_error(self):
-        # Gridspot 404s on invalid api key or instance_id
-        raise InvalidCredsError("Invalid api key/instance_id")
-
-
-class GridspotConnection(ConnectionKey):
-    """
-    Connection class to connect to Gridspot's API servers
-    """
-
-    host = 'gridspot.com'
-    responseCls = GridspotResponse
-
-    def add_default_params(self, params):
-        params['api_key'] = self.key
-        return params
-
-
-class GridspotNodeDriver(NodeDriver):
-    """
-    Gridspot (http://www.gridspot.com/) node driver.
-    """
-
-    type = Provider.GRIDSPOT
-    name = 'Gridspot'
-    website = 'http://www.gridspot.com/'
-    connectionCls = GridspotConnection
-    NODE_STATE_MAP = {
-        'Running': NodeState.RUNNING,
-        'Starting': NodeState.PENDING
-    }
-
-    def list_nodes(self):
-        data = self.connection.request(
-            '/compute_api/v1/list_instances').object
-        return [self._to_node(n) for n in data['instances']]
-
-    def destroy_node(self, node):
-        data = {'instance_id': node.id}
-        self.connection.request('/compute_api/v1/stop_instance', data).object
-        return True
-
-    def _get_node_state(self, state):
-        result = self.NODE_STATE_MAP.get(state, NodeState.UNKNOWN)
-        return result
-
-    def _add_int_param(self, params, data, field):
-        if data[field]:
-            try:
-                params[field] = int(data[field])
-            except:
-                pass
-
-    def _to_node(self, data):
-        port = None
-        ip = None
-
-        state = self._get_node_state(data['current_state'])
-
-        if data['vm_ssh_wan_ip_endpoint'] != 'null':
-            parts = data['vm_ssh_wan_ip_endpoint'].split(':')
-            ip = parts[0]
-            port = int(parts[1])
-
-        extra_params = {
-            'winning_bid_id': data['winning_bid_id'],
-            'port': port
-        }
-
-        # Spec is vague and doesn't indicate if these will always be present
-        self._add_int_param(extra_params, data, 'vm_num_logical_cores')
-        self._add_int_param(extra_params, data, 'vm_num_physical_cores')
-        self._add_int_param(extra_params, data, 'vm_ram')
-        self._add_int_param(extra_params, data, 'start_state_time')
-        self._add_int_param(extra_params, data, 'ended_state_time')
-        self._add_int_param(extra_params, data, 'running_state_time')
-
-        return Node(
-            id=data['instance_id'],
-            name=data['instance_id'],
-            state=state,
-            public_ips=[ip],
-            private_ips=[],
-            driver=self.connection.driver,
-            extra=extra_params)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/hostvirtual.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/hostvirtual.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/hostvirtual.py
deleted file mode 100644
index e56889e..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/hostvirtual.py
+++ /dev/null
@@ -1,449 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-libcloud driver for the Host Virtual Inc. (VR) API
-Home page https://www.hostvirtual.com/
-"""
-
-import time
-import re
-
-try:
-    import simplejson as json
-except ImportError:
-    import json
-
-from libcloud.common.hostvirtual import HostVirtualResponse
-from libcloud.common.hostvirtual import HostVirtualConnection
-from libcloud.common.hostvirtual import HostVirtualException
-from libcloud.compute.providers import Provider
-from libcloud.compute.types import NodeState
-from libcloud.compute.base import Node, NodeDriver
-from libcloud.compute.base import NodeImage, NodeSize, NodeLocation
-from libcloud.compute.base import NodeAuthSSHKey, NodeAuthPassword
-
-API_ROOT = ''
-
-NODE_STATE_MAP = {
-    'BUILDING': NodeState.PENDING,
-    'PENDING': NodeState.PENDING,
-    'RUNNING': NodeState.RUNNING,  # server is powered up
-    'STOPPING': NodeState.REBOOTING,
-    'REBOOTING': NodeState.REBOOTING,
-    'STARTING': NodeState.REBOOTING,
-    'TERMINATED': NodeState.TERMINATED,  # server is powered down
-    'STOPPED': NodeState.STOPPED
-}
-
-DEFAULT_NODE_LOCATION_ID = 21
-
-
-class HostVirtualComputeResponse(HostVirtualResponse):
-    pass
-
-
-class HostVirtualComputeConnection(HostVirtualConnection):
-    responseCls = HostVirtualComputeResponse
-
-
-class HostVirtualNodeDriver(NodeDriver):
-    type = Provider.HOSTVIRTUAL
-    name = 'HostVirtual'
-    website = 'http://www.hostvirtual.com'
-    connectionCls = HostVirtualComputeConnection
-    features = {'create_node': ['ssh_key', 'password']}
-
-    def __init__(self, key, secure=True, host=None, port=None):
-        self.location = None
-        super(HostVirtualNodeDriver, self).__init__(key=key, secure=secure,
-                                                    host=host, port=port)
-
-    def list_nodes(self):
-        try:
-            result = self.connection.request(
-                API_ROOT + '/cloud/servers/').object
-        except HostVirtualException:
-            return []
-        nodes = []
-        for value in result:
-            node = self._to_node(value)
-            nodes.append(node)
-        return nodes
-
-    def list_locations(self):
-        result = self.connection.request(API_ROOT + '/cloud/locations/').object
-        locations = []
-        for dc in result:
-            locations.append(NodeLocation(
-                dc["id"],
-                dc["name"],
-                dc["name"].split(',')[1].replace(" ", ""),  # country
-                self))
-        return locations
-
-    def list_sizes(self, location=None):
-        params = {}
-        if location is not None:
-            params = {'location': location.id}
-        result = self.connection.request(
-            API_ROOT + '/cloud/sizes/',
-            params=params).object
-        sizes = []
-        for size in result:
-            n = NodeSize(id=size['plan_id'],
-                         name=size['plan'],
-                         ram=size['ram'],
-                         disk=size['disk'],
-                         bandwidth=size['transfer'],
-                         price=size['price'],
-                         driver=self.connection.driver)
-            sizes.append(n)
-        return sizes
-
-    def list_images(self):
-        result = self.connection.request(API_ROOT + '/cloud/images/').object
-        images = []
-        for image in result:
-            i = NodeImage(id=image["id"],
-                          name=image["os"],
-                          driver=self.connection.driver,
-                          extra=image)
-            del i.extra['id']
-            del i.extra['os']
-            images.append(i)
-        return images
-
-    def create_node(self, name, image, size, **kwargs):
-        """
-        Creates a node
-
-        Example of node creation with ssh key deployed:
-
-        >>> from libcloud.compute.base import NodeAuthSSHKey
-        >>> key = open('/home/user/.ssh/id_rsa.pub').read()
-        >>> auth = NodeAuthSSHKey(pubkey=key)
-        >>> from libcloud.compute.providers import get_driver;
-        >>> driver = get_driver('hostvirtual')
-        >>> conn = driver('API_KEY')
-        >>> image = conn.list_images()[1]
-        >>> size = conn.list_sizes()[0]
-        >>> location = conn.list_locations()[1]
-        >>> name = 'markos-dev'
-        >>> node = conn.create_node(name, image, size, auth=auth,
-        >>>                         location=location)
-        """
-
-        dc = None
-
-        auth = self._get_and_check_auth(kwargs.get('auth'))
-
-        if not self._is_valid_fqdn(name):
-            raise HostVirtualException(
-                500, "Name should be a valid FQDN (e.g, hostname.example.com)")
-
-        # simply order a package first
-        pkg = self.ex_order_package(size)
-
-        if 'location' in kwargs:
-            dc = kwargs['location'].id
-        else:
-            dc = DEFAULT_NODE_LOCATION_ID
-
-        # create a stub node
-        stub_node = self._to_node({
-            'mbpkgid': pkg['id'],
-            'status': 'PENDING',
-            'fqdn': name,
-            'plan_id': size.id,
-            'os_id': image.id,
-            'location_id': dc
-        })
-
-        # provisioning a server using the stub node
-        self.ex_provision_node(node=stub_node, auth=auth)
-        node = self._wait_for_node(stub_node.id)
-        if getattr(auth, 'generated', False):
-            node.extra['password'] = auth.password
-
-        return node
-
-    def reboot_node(self, node):
-        params = {'force': 0, 'mbpkgid': node.id}
-        result = self.connection.request(
-            API_ROOT + '/cloud/server/reboot',
-            data=json.dumps(params),
-            method='POST').object
-
-        return bool(result)
-
-    def destroy_node(self, node):
-        params = {
-            'mbpkgid': node.id,
-            # 'reason': 'Submitted through Libcloud API'
-        }
-
-        result = self.connection.request(
-            API_ROOT + '/cloud/cancel', data=json.dumps(params),
-            method='POST').object
-
-        return bool(result)
-
-    def ex_list_packages(self):
-        """
-        List the server packages.
-
-        """
-
-        try:
-            result = self.connection.request(
-                API_ROOT + '/cloud/packages/').object
-        except HostVirtualException:
-            return []
-        pkgs = []
-        for value in result:
-            pkgs.append(value)
-        return pkgs
-
-    def ex_order_package(self, size):
-        """
-        Order a server package.
-
-        :param      size:
-        :type       node: :class:`NodeSize`
-
-        :rtype: ``str``
-        """
-
-        params = {'plan': size.name}
-        pkg = self.connection.request(API_ROOT + '/cloud/buy/',
-                                      data=json.dumps(params),
-                                      method='POST').object
-
-        return pkg
-
-    def ex_cancel_package(self, node):
-        """
-        Cancel a server package.
-
-        :param      node: Node which should be used
-        :type       node: :class:`Node`
-
-        :rtype: ``str``
-        """
-
-        params = {'mbpkgid': node.id}
-        result = self.connection.request(API_ROOT + '/cloud/cancel/',
-                                         data=json.dumps(params),
-                                         method='POST').object
-
-        return result
-
-    def ex_unlink_package(self, node):
-        """
-        Unlink a server package from location.
-
-        :param      node: Node which should be used
-        :type       node: :class:`Node`
-
-        :rtype: ``str``
-        """
-
-        params = {'mbpkgid': node.id}
-        result = self.connection.request(API_ROOT + '/cloud/unlink/',
-                                         data=json.dumps(params),
-                                         method='POST').object
-
-        return result
-
-    def ex_get_node(self, node_id):
-        """
-        Get a single node.
-
-        :param      node_id: id of the node that we need the node object for
-        :type       node_id: ``str``
-
-        :rtype: :class:`Node`
-        """
-
-        params = {'mbpkgid': node_id}
-        result = self.connection.request(
-            API_ROOT + '/cloud/server', params=params).object
-        node = self._to_node(result)
-        return node
-
-    def ex_stop_node(self, node):
-        """
-        Stop a node.
-
-        :param      node: Node which should be used
-        :type       node: :class:`Node`
-
-        :rtype: ``bool``
-        """
-        params = {'force': 0, 'mbpkgid': node.id}
-        result = self.connection.request(
-            API_ROOT + '/cloud/server/shutdown',
-            data=json.dumps(params),
-            method='POST').object
-
-        return bool(result)
-
-    def ex_start_node(self, node):
-        """
-        Start a node.
-
-        :param      node: Node which should be used
-        :type       node: :class:`Node`
-
-        :rtype: ``bool``
-        """
-        params = {'mbpkgid': node.id}
-        result = self.connection.request(
-            API_ROOT + '/cloud/server/start',
-            data=json.dumps(params),
-            method='POST').object
-
-        return bool(result)
-
-    def ex_provision_node(self, **kwargs):
-        """
-        Provision a server on a VR package and get it booted
-
-        :keyword node: node which should be used
-        :type    node: :class:`Node`
-
-        :keyword image: The distribution to deploy on your server (mandatory)
-        :type    image: :class:`NodeImage`
-
-        :keyword auth: an SSH key or root password (mandatory)
-        :type    auth: :class:`NodeAuthSSHKey` or :class:`NodeAuthPassword`
-
-        :keyword location: which datacenter to create the server in
-        :type    location: :class:`NodeLocation`
-
-        :return: Node representing the newly built server
-        :rtype: :class:`Node`
-        """
-
-        node = kwargs['node']
-
-        if 'image' in kwargs:
-            image = kwargs['image']
-        else:
-            image = node.extra['image']
-
-        params = {
-            'mbpkgid': node.id,
-            'image': image,
-            'fqdn': node.name,
-            'location': node.extra['location'],
-        }
-
-        auth = kwargs['auth']
-
-        ssh_key = None
-        password = None
-        if isinstance(auth, NodeAuthSSHKey):
-            ssh_key = auth.pubkey
-            params['ssh_key'] = ssh_key
-        elif isinstance(auth, NodeAuthPassword):
-            password = auth.password
-            params['password'] = password
-
-        if not ssh_key and not password:
-            raise HostVirtualException(
-                500, "SSH key or Root password is required")
-
-        try:
-            result = self.connection.request(API_ROOT + '/cloud/server/build',
-                                             data=json.dumps(params),
-                                             method='POST').object
-            return bool(result)
-        except HostVirtualException:
-            self.ex_cancel_package(node)
-
-    def ex_delete_node(self, node):
-        """
-        Delete a node.
-
-        :param      node: Node which should be used
-        :type       node: :class:`Node`
-
-        :rtype: ``bool``
-        """
-
-        params = {'mbpkgid': node.id}
-        result = self.connection.request(
-            API_ROOT + '/cloud/server/delete', data=json.dumps(params),
-            method='POST').object
-
-        return bool(result)
-
-    def _to_node(self, data):
-        state = NODE_STATE_MAP[data['status']]
-        public_ips = []
-        private_ips = []
-        extra = {}
-
-        if 'plan_id' in data:
-            extra['size'] = data['plan_id']
-        if 'os_id' in data:
-            extra['image'] = data['os_id']
-        if 'fqdn' in data:
-            extra['fqdn'] = data['fqdn']
-        if 'location_id' in data:
-            extra['location'] = data['location_id']
-        if 'ip' in data:
-            public_ips.append(data['ip'])
-
-        node = Node(id=data['mbpkgid'], name=data['fqdn'], state=state,
-                    public_ips=public_ips, private_ips=private_ips,
-                    driver=self.connection.driver, extra=extra)
-        return node
-
-    def _wait_for_node(self, node_id, timeout=30, interval=5.0):
-        """
-        :param node_id: ID of the node to wait for.
-        :type node_id: ``int``
-
-        :param timeout: Timeout (in seconds).
-        :type timeout: ``int``
-
-        :param interval: How long to wait (in seconds) between each attempt.
-        :type interval: ``float``
-
-        :return: Node representing the newly built server
-        :rtype: :class:`Node`
-        """
-        # poll until we get a node
-        for i in range(0, timeout, int(interval)):
-            try:
-                node = self.ex_get_node(node_id)
-                return node
-            except HostVirtualException:
-                time.sleep(interval)
-
-        raise HostVirtualException(412, 'Timeout on getting node details')
-
-    def _is_valid_fqdn(self, fqdn):
-        if len(fqdn) > 255:
-            return False
-        if fqdn[-1] == ".":
-            fqdn = fqdn[:-1]
-        valid = re.compile("(?!-)[A-Z\d-]{1,63}(?<!-)$", re.IGNORECASE)
-        if len(fqdn.split(".")) > 1:
-            return all(valid.match(x) for x in fqdn.split("."))
-        else:
-            return False

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/ikoula.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/ikoula.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/ikoula.py
deleted file mode 100644
index 554c647..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/ikoula.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from libcloud.compute.providers import Provider
-from libcloud.compute.drivers.cloudstack import CloudStackNodeDriver
-
-__all__ = [
-    'IkoulaNodeDriver'
-]
-
-
-class IkoulaNodeDriver(CloudStackNodeDriver):
-    type = Provider.IKOULA
-    name = 'Ikoula'
-    website = 'http://express.ikoula.co.uk/cloudstack'
-
-    # API endpoint info
-    host = 'cloudstack.ikoula.com'
-    path = '/client/api'

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/indosat.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/indosat.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/indosat.py
deleted file mode 100644
index 8913dfb..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/indosat.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-Indosat Driver
-"""
-
-from libcloud.compute.providers import Provider
-from libcloud.common.dimensiondata import (DimensionDataConnection,
-                                           API_ENDPOINTS)
-from libcloud.compute.drivers.dimensiondata import DimensionDataNodeDriver
-
-DEFAULT_REGION = 'indosat-id'
-
-
-class IndosatNodeDriver(DimensionDataNodeDriver):
-    """
-    Indosat node driver, based on Dimension Data driver
-    """
-
-    selected_region = None
-    connectionCls = DimensionDataConnection
-    name = 'Indosat'
-    website = 'http://www.indosat.com/'
-    type = Provider.INDOSAT
-    features = {'create_node': ['password']}
-    api_version = 1.0
-
-    def __init__(self, key, secret=None, secure=True, host=None, port=None,
-                 api_version=None, region=DEFAULT_REGION, **kwargs):
-
-        if region not in API_ENDPOINTS:
-            raise ValueError('Invalid region: %s' % (region))
-
-        self.selected_region = API_ENDPOINTS[region]
-
-        super(IndosatNodeDriver, self).__init__(
-            key=key,
-            secret=secret,
-            secure=secure,
-            host=host,
-            port=port,
-            api_version=api_version,
-            region=region,
-            **kwargs)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/internetsolutions.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/internetsolutions.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/internetsolutions.py
deleted file mode 100644
index 49415ae..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/internetsolutions.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-Internet Solutions Driver
-"""
-
-from libcloud.compute.providers import Provider
-from libcloud.common.dimensiondata import (DimensionDataConnection,
-                                           API_ENDPOINTS)
-from libcloud.compute.drivers.dimensiondata import DimensionDataNodeDriver
-
-DEFAULT_REGION = 'is-af'
-
-
-class InternetSolutionsNodeDriver(DimensionDataNodeDriver):
-    """
-    InternetSolutions node driver, based on Dimension Data driver
-    """
-
-    selected_region = None
-    connectionCls = DimensionDataConnection
-    name = 'InternetSolutions'
-    website = 'http://www.is.co.za/'
-    type = Provider.INTERNETSOLUTIONS
-    features = {'create_node': ['password']}
-    api_version = 1.0
-
-    def __init__(self, key, secret=None, secure=True, host=None, port=None,
-                 api_version=None, region=DEFAULT_REGION, **kwargs):
-
-        if region not in API_ENDPOINTS:
-            raise ValueError('Invalid region: %s' % (region))
-
-        self.selected_region = API_ENDPOINTS[region]
-
-        super(InternetSolutionsNodeDriver, self).__init__(
-            key=key,
-            secret=secret,
-            secure=secure,
-            host=host,
-            port=port,
-            api_version=api_version,
-            region=region,
-            **kwargs)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/joyent.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/joyent.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/joyent.py
deleted file mode 100644
index d1fa9c1..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/joyent.py
+++ /dev/null
@@ -1,240 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-Joyent Cloud (http://www.joyentcloud.com) driver.
-"""
-
-import base64
-
-try:
-    import simplejson as json
-except:
-    import json
-
-from libcloud.utils.py3 import httplib
-from libcloud.utils.py3 import b
-
-from libcloud.common.types import LibcloudError
-from libcloud.compute.providers import Provider
-from libcloud.common.base import JsonResponse, ConnectionUserAndKey
-from libcloud.compute.types import NodeState, InvalidCredsError
-from libcloud.compute.base import Node, NodeDriver, NodeImage, NodeSize
-from libcloud.utils.networking import is_private_subnet
-
-API_HOST_SUFFIX = '.api.joyentcloud.com'
-API_VERSION = '~6.5'
-
-
-NODE_STATE_MAP = {
-    'provisioning': NodeState.PENDING,
-    'running': NodeState.RUNNING,
-    'stopping': NodeState.TERMINATED,
-    'stopped': NodeState.TERMINATED,
-    'deleted': NodeState.TERMINATED
-}
-
-VALID_REGIONS = [
-    'us-east-1', 'us-east-2', 'us-east-3',
-    'us-west-1',
-    'us-sw-1',
-    'eu-ams-1'
-]
-DEFAULT_REGION = 'us-east-1'
-
-
-class JoyentResponse(JsonResponse):
-    """
-    Joyent response class.
-    """
-
-    valid_response_codes = [httplib.OK, httplib.ACCEPTED, httplib.CREATED,
-                            httplib.NO_CONTENT]
-
-    def parse_error(self):
-        if self.status == httplib.UNAUTHORIZED:
-            data = self.parse_body()
-            raise InvalidCredsError(data['code'] + ': ' + data['message'])
-        return self.body
-
-    def success(self):
-        return self.status in self.valid_response_codes
-
-
-class JoyentConnection(ConnectionUserAndKey):
-    """
-    Joyent connection class.
-    """
-
-    responseCls = JoyentResponse
-
-    allow_insecure = False
-
-    def add_default_headers(self, headers):
-        headers['Accept'] = 'application/json'
-        headers['Content-Type'] = 'application/json; charset=UTF-8'
-        headers['X-Api-Version'] = API_VERSION
-
-        user_b64 = base64.b64encode(b('%s:%s' % (self.user_id, self.key)))
-        headers['Authorization'] = 'Basic %s' % (user_b64.decode('utf-8'))
-        return headers
-
-
-class JoyentNodeDriver(NodeDriver):
-    """
-    Joyent node driver class.
-    """
-
-    type = Provider.JOYENT
-    name = 'Joyent'
-    website = 'http://www.joyentcloud.com'
-    connectionCls = JoyentConnection
-    features = {'create_node': ['generates_password']}
-
-    def __init__(self, key, secret=None, secure=True, host=None, port=None,
-                 region=DEFAULT_REGION, **kwargs):
-        # Location is here for backward compatibility reasons
-        if 'location' in kwargs:
-            region = kwargs['location']
-
-        if region not in VALID_REGIONS:
-            msg = 'Invalid region: "%s". Valid region: %s'
-            raise LibcloudError(msg % (region,
-                                ', '.join(VALID_REGIONS)), driver=self)
-
-        super(JoyentNodeDriver, self).__init__(key=key, secret=secret,
-                                               secure=secure, host=host,
-                                               port=port, region=region,
-                                               **kwargs)
-        self.connection.host = region + API_HOST_SUFFIX
-
-    def list_images(self):
-        result = self.connection.request('/my/datasets').object
-
-        images = []
-        for value in result:
-            extra = {'type': value['type'], 'urn': value['urn'],
-                     'os': value['os'], 'default': value['default']}
-            image = NodeImage(id=value['id'], name=value['name'],
-                              driver=self.connection.driver, extra=extra)
-            images.append(image)
-
-        return images
-
-    def list_sizes(self):
-        result = self.connection.request('/my/packages').object
-
-        sizes = []
-        for value in result:
-            size = NodeSize(id=value['name'], name=value['name'],
-                            ram=value['memory'], disk=value['disk'],
-                            bandwidth=None, price=0.0,
-                            driver=self.connection.driver)
-            sizes.append(size)
-
-        return sizes
-
-    def list_nodes(self):
-        result = self.connection.request('/my/machines').object
-
-        nodes = []
-        for value in result:
-            node = self._to_node(value)
-            nodes.append(node)
-
-        return nodes
-
-    def reboot_node(self, node):
-        data = json.dumps({'action': 'reboot'})
-        result = self.connection.request('/my/machines/%s' % (node.id),
-                                         data=data, method='POST')
-        return result.status == httplib.ACCEPTED
-
-    def destroy_node(self, node):
-        result = self.connection.request('/my/machines/%s' % (node.id),
-                                         method='DELETE')
-        return result.status == httplib.NO_CONTENT
-
-    def create_node(self, **kwargs):
-        name = kwargs['name']
-        size = kwargs['size']
-        image = kwargs['image']
-
-        data = json.dumps({'name': name, 'package': size.id,
-                           'dataset': image.id})
-        result = self.connection.request('/my/machines', data=data,
-                                         method='POST')
-        return self._to_node(result.object)
-
-    def ex_stop_node(self, node):
-        """
-        Stop node
-
-        :param  node: The node to be stopped
-        :type   node: :class:`Node`
-
-        :rtype: ``bool``
-        """
-        data = json.dumps({'action': 'stop'})
-        result = self.connection.request('/my/machines/%s' % (node.id),
-                                         data=data, method='POST')
-        return result.status == httplib.ACCEPTED
-
-    def ex_start_node(self, node):
-        """
-        Start node
-
-        :param  node: The node to be stopped
-        :type   node: :class:`Node`
-
-        :rtype: ``bool``
-        """
-        data = json.dumps({'action': 'start'})
-        result = self.connection.request('/my/machines/%s' % (node.id),
-                                         data=data, method='POST')
-        return result.status == httplib.ACCEPTED
-
-    def ex_get_node(self, node_id):
-        """
-        Return a Node object based on a node ID.
-
-        :param  node_id: ID of the node
-        :type   node_id: ``str``
-
-        :return:  A Node object for the node
-        :rtype:   :class:`Node`
-        """
-        result = self.connection.request('/my/machines/%s' % (node_id))
-        return self._to_node(result.object)
-
-    def _to_node(self, data):
-        state = NODE_STATE_MAP[data['state']]
-        public_ips = []
-        private_ips = []
-        extra = {}
-
-        for ip in data['ips']:
-            if is_private_subnet(ip):
-                private_ips.append(ip)
-            else:
-                public_ips.append(ip)
-
-        if 'credentials' in data['metadata']:
-            extra['password'] = data['metadata']['credentials']['root']
-
-        node = Node(id=data['id'], name=data['name'], state=state,
-                    public_ips=public_ips, private_ips=private_ips,
-                    driver=self.connection.driver, extra=extra)
-        return node

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/kili.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/kili.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/kili.py
deleted file mode 100644
index 11c1c7b..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/kili.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-HP Public cloud driver which is essentially just a small wrapper around
-OpenStack driver.
-"""
-
-from libcloud.compute.types import Provider, LibcloudError
-from libcloud.compute.drivers.openstack import OpenStack_1_1_Connection
-from libcloud.compute.drivers.openstack import OpenStack_1_1_NodeDriver
-
-__all__ = [
-    'KiliCloudNodeDriver'
-]
-
-ENDPOINT_ARGS = {
-    'service_type': 'compute',
-    'name': 'nova',
-    'region': 'RegionOne'
-}
-
-AUTH_URL = 'https://api.kili.io/keystone/v2.0/tokens'
-
-
-class KiliCloudConnection(OpenStack_1_1_Connection):
-    _auth_version = '2.0_password'
-
-    def __init__(self, *args, **kwargs):
-        self.region = kwargs.pop('region', None)
-        self.get_endpoint_args = kwargs.pop('get_endpoint_args', None)
-        super(KiliCloudConnection, self).__init__(*args, **kwargs)
-
-    def get_endpoint(self):
-        if not self.get_endpoint_args:
-            raise LibcloudError(
-                'KiliCloudConnection must have get_endpoint_args set')
-
-        if '2.0_password' in self._auth_version:
-            ep = self.service_catalog.get_endpoint(**self.get_endpoint_args)
-        else:
-            raise LibcloudError(
-                'Auth version "%s" not supported' % (self._auth_version))
-
-        public_url = ep.url
-
-        if not public_url:
-            raise LibcloudError('Could not find specified endpoint')
-
-        return public_url
-
-
-class KiliCloudNodeDriver(OpenStack_1_1_NodeDriver):
-    name = 'Kili Public Cloud'
-    website = 'http://kili.io/'
-    connectionCls = KiliCloudConnection
-    type = Provider.HPCLOUD
-
-    def __init__(self, key, secret, tenant_name, secure=True,
-                 host=None, port=None, **kwargs):
-        """
-        Note: tenant_name argument is required for Kili cloud.
-        """
-        self.tenant_name = tenant_name
-        super(KiliCloudNodeDriver, self).__init__(key=key, secret=secret,
-                                                  secure=secure, host=host,
-                                                  port=port,
-                                                  **kwargs)
-
-    def _ex_connection_class_kwargs(self):
-        kwargs = self.openstack_connection_kwargs()
-        kwargs['get_endpoint_args'] = ENDPOINT_ARGS
-        kwargs['ex_force_auth_url'] = AUTH_URL
-        kwargs['ex_tenant_name'] = self.tenant_name
-
-        return kwargs

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/ktucloud.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/ktucloud.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/ktucloud.py
deleted file mode 100644
index 1bc8544..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/ktucloud.py
+++ /dev/null
@@ -1,103 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from libcloud.compute.providers import Provider
-from libcloud.compute.base import Node, NodeImage, NodeSize
-from libcloud.compute.drivers.cloudstack import CloudStackNodeDriver
-
-
-class KTUCloudNodeDriver(CloudStackNodeDriver):
-    "Driver for KTUCloud Compute platform."
-
-    EMPTY_DISKOFFERINGID = '0'
-    type = Provider.KTUCLOUD
-    name = 'KTUCloud'
-    website = 'https://ucloudbiz.olleh.com/'
-
-    def list_images(self, location=None):
-        args = {
-            'templatefilter': 'executable'
-        }
-        if location is not None:
-            args['zoneid'] = location.id
-
-        imgs = self._sync_request(command='listAvailableProductTypes',
-                                  method='GET')
-        images = []
-
-        for img in imgs['producttypes']:
-            images.append(
-                NodeImage(
-                    img['serviceofferingid'],
-                    img['serviceofferingdesc'],
-                    self,
-                    {'hypervisor': '',
-                     'format': '',
-                     'os': img['templatedesc'],
-                     'templateid': img['templateid'],
-                     'zoneid': img['zoneid']}
-                )
-            )
-
-        return images
-
-    def list_sizes(self, location=None):
-        szs = self._sync_request('listAvailableProductTypes')
-        sizes = []
-        for sz in szs['producttypes']:
-            diskofferingid = sz.get('diskofferingid',
-                                    self.EMPTY_DISKOFFERINGID)
-            sizes.append(NodeSize(
-                diskofferingid,
-                sz['diskofferingdesc'],
-                0, 0, 0, 0, self)
-            )
-        return sizes
-
-    def create_node(self, name, size, image, location=None, **kwargs):
-        params = {'displayname': name,
-                  'serviceofferingid': image.id,
-                  'templateid': str(image.extra['templateid']),
-                  'zoneid': str(image.extra['zoneid'])}
-
-        usageplantype = kwargs.pop('usageplantype', None)
-        if usageplantype is None:
-            params['usageplantype'] = 'hourly'
-        else:
-            params['usageplantype'] = usageplantype
-
-        if size.id != self.EMPTY_DISKOFFERINGID:
-            params['diskofferingid'] = size.id
-
-        result = self._async_request(
-            command='deployVirtualMachine',
-            params=params,
-            method='GET')
-
-        node = result['virtualmachine']
-
-        return Node(
-            id=node['id'],
-            name=node['displayname'],
-            state=self.NODE_STATE_MAP[node['state']],
-            public_ips=[],
-            private_ips=[],
-            driver=self,
-            extra={
-                'zoneid': image.extra['zoneid'],
-                'ip_addresses': [],
-                'forwarding_rules': [],
-            }
-        )

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/libvirt_driver.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/libvirt_driver.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/libvirt_driver.py
deleted file mode 100644
index 3618ac4..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/libvirt_driver.py
+++ /dev/null
@@ -1,335 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-from __future__ import with_statement
-
-import re
-import os
-import time
-import platform
-import subprocess
-import mimetypes
-
-from os.path import join as pjoin
-from collections import defaultdict
-
-try:
-    from lxml import etree as ET
-except ImportError:
-    from xml.etree import ElementTree as ET
-
-from libcloud.compute.base import NodeDriver, Node
-from libcloud.compute.base import NodeState
-from libcloud.compute.types import Provider
-from libcloud.utils.networking import is_public_subnet
-
-try:
-    import libvirt
-    have_libvirt = True
-except ImportError:
-    have_libvirt = False
-
-
-class LibvirtNodeDriver(NodeDriver):
-    """
-    Libvirt (http://libvirt.org/) node driver.
-
-    To enable debug mode, set LIBVIR_DEBUG environment variable.
-    """
-
-    type = Provider.LIBVIRT
-    name = 'Libvirt'
-    website = 'http://libvirt.org/'
-
-    NODE_STATE_MAP = {
-        0: NodeState.TERMINATED,  # no state
-        1: NodeState.RUNNING,  # domain is running
-        2: NodeState.PENDING,  # domain is blocked on resource
-        3: NodeState.TERMINATED,  # domain is paused by user
-        4: NodeState.TERMINATED,  # domain is being shut down
-        5: NodeState.TERMINATED,  # domain is shut off
-        6: NodeState.UNKNOWN,  # domain is crashed
-        7: NodeState.UNKNOWN,  # domain is suspended by guest power management
-    }
-
-    def __init__(self, uri):
-        """
-        :param  uri: Hypervisor URI (e.g. vbox:///session, qemu:///system,
-                     etc.).
-        :type   uri: ``str``
-        """
-        if not have_libvirt:
-            raise RuntimeError('Libvirt driver requires \'libvirt\' Python ' +
-                               'package')
-
-        self._uri = uri
-        self.connection = libvirt.open(uri)
-
-    def list_nodes(self):
-        domains = self.connection.listAllDomains()
-        nodes = self._to_nodes(domains=domains)
-        return nodes
-
-    def reboot_node(self, node):
-        domain = self._get_domain_for_node(node=node)
-        return domain.reboot(flags=0) == 0
-
-    def destroy_node(self, node):
-        domain = self._get_domain_for_node(node=node)
-        return domain.destroy() == 0
-
-    def ex_start_node(self, node):
-        """
-        Start a stopped node.
-
-        :param  node: Node which should be used
-        :type   node: :class:`Node`
-
-        :rtype: ``bool``
-        """
-        domain = self._get_domain_for_node(node=node)
-        return domain.create() == 0
-
-    def ex_shutdown_node(self, node):
-        """
-        Shutdown a running node.
-
-        Note: Usually this will result in sending an ACPI event to the node.
-
-        :param  node: Node which should be used
-        :type   node: :class:`Node`
-
-        :rtype: ``bool``
-        """
-        domain = self._get_domain_for_node(node=node)
-        return domain.shutdown() == 0
-
-    def ex_suspend_node(self, node):
-        """
-        Suspend a running node.
-
-        :param  node: Node which should be used
-        :type   node: :class:`Node`
-
-        :rtype: ``bool``
-        """
-        domain = self._get_domain_for_node(node=node)
-        return domain.suspend() == 0
-
-    def ex_resume_node(self, node):
-        """
-        Resume a suspended node.
-
-        :param  node: Node which should be used
-        :type   node: :class:`Node`
-
-        :rtype: ``bool``
-        """
-        domain = self._get_domain_for_node(node=node)
-        return domain.resume() == 0
-
-    def ex_take_node_screenshot(self, node, directory, screen=0):
-        """
-        Take a screenshot of a monitoring of a running instance.
-
-        :param node: Node to take the screenshot of.
-        :type node: :class:`libcloud.compute.base.Node`
-
-        :param directory: Path where the screenshot will be saved.
-        :type directory: ``str``
-
-        :param screen: ID of the monitor to take the screenshot of.
-        :type screen: ``int``
-
-        :return: Full path where the screenshot has been saved.
-        :rtype: ``str``
-        """
-        if not os.path.exists(directory) or not os.path.isdir(directory):
-            raise ValueError('Invalid value for directory argument')
-
-        domain = self._get_domain_for_node(node=node)
-        stream = self.connection.newStream()
-        mime_type = domain.screenshot(stream=stream, screen=0)
-        extensions = mimetypes.guess_all_extensions(type=mime_type)
-
-        if extensions:
-            extension = extensions[0]
-        else:
-            extension = '.png'
-
-        name = 'screenshot-%s%s' % (int(time.time()), extension)
-        file_path = pjoin(directory, name)
-
-        with open(file_path, 'wb') as fp:
-            def write(stream, buf, opaque):
-                fp.write(buf)
-
-            stream.recvAll(write, None)
-
-        try:
-            stream.finish()
-        except Exception:
-            # Finish is not supported by all backends
-            pass
-
-        return file_path
-
-    def ex_get_hypervisor_hostname(self):
-        """
-        Return a system hostname on which the hypervisor is running.
-        """
-        hostname = self.connection.getHostname()
-        return hostname
-
-    def ex_get_hypervisor_sysinfo(self):
-        """
-        Retrieve hypervisor system information.
-
-        :rtype: ``dict``
-        """
-        xml = self.connection.getSysinfo()
-        etree = ET.XML(xml)
-
-        attributes = ['bios', 'system', 'processor', 'memory_device']
-
-        sysinfo = {}
-        for attribute in attributes:
-            element = etree.find(attribute)
-            entries = self._get_entries(element=element)
-            sysinfo[attribute] = entries
-
-        return sysinfo
-
-    def _to_nodes(self, domains):
-        nodes = [self._to_node(domain=domain) for domain in domains]
-        return nodes
-
-    def _to_node(self, domain):
-        state, max_mem, memory, vcpu_count, used_cpu_time = domain.info()
-        state = self.NODE_STATE_MAP.get(state, NodeState.UNKNOWN)
-
-        public_ips, private_ips = [], []
-
-        ip_addresses = self._get_ip_addresses_for_domain(domain)
-
-        for ip_address in ip_addresses:
-            if is_public_subnet(ip_address):
-                public_ips.append(ip_address)
-            else:
-                private_ips.append(ip_address)
-
-        extra = {'uuid': domain.UUIDString(), 'os_type': domain.OSType(),
-                 'types': self.connection.getType(),
-                 'used_memory': memory / 1024, 'vcpu_count': vcpu_count,
-                 'used_cpu_time': used_cpu_time}
-
-        node = Node(id=domain.ID(), name=domain.name(), state=state,
-                    public_ips=public_ips, private_ips=private_ips,
-                    driver=self, extra=extra)
-        node._uuid = domain.UUIDString()  # we want to use a custom UUID
-        return node
-
-    def _get_ip_addresses_for_domain(self, domain):
-        """
-        Retrieve IP addresses for the provided domain.
-
-        Note: This functionality is currently only supported on Linux and
-        only works if this code is run on the same machine as the VMs run
-        on.
-
-        :return: IP addresses for the provided domain.
-        :rtype: ``list``
-        """
-        result = []
-
-        if platform.system() != 'Linux':
-            # Only Linux is supported atm
-            return result
-
-        mac_addresses = self._get_mac_addresses_for_domain(domain=domain)
-
-        cmd = ['arp', '-an']
-        child = subprocess.Popen(cmd, stdout=subprocess.PIPE,
-                                 stderr=subprocess.PIPE)
-        stdout, _ = child.communicate()
-        arp_table = self._parse_arp_table(arp_output=stdout)
-
-        for mac_address in mac_addresses:
-            if mac_address in arp_table:
-                ip_addresses = arp_table[mac_address]
-                result.extend(ip_addresses)
-
-        return result
-
-    def _get_mac_addresses_for_domain(self, domain):
-        """
-        Parses network interface MAC addresses from the provided domain.
-        """
-        xml = domain.XMLDesc()
-        etree = ET.XML(xml)
-        elems = etree.findall("devices/interface[@type='network']/mac")
-
-        result = []
-        for elem in elems:
-            mac_address = elem.get('address')
-            result.append(mac_address)
-
-        return result
-
-    def _get_domain_for_node(self, node):
-        """
-        Return libvirt domain object for the provided node.
-        """
-        domain = self.connection.lookupByUUIDString(node.uuid)
-        return domain
-
-    def _get_entries(self, element):
-        """
-        Parse entries dictionary.
-
-        :rtype: ``dict``
-        """
-        elements = element.findall('entry')
-
-        result = {}
-        for element in elements:
-            name = element.get('name')
-            value = element.text
-            result[name] = value
-
-        return result
-
-    def _parse_arp_table(self, arp_output):
-        """
-        Parse arp command output and return a dictionary which maps mac address
-        to an IP address.
-
-        :return: Dictionary which maps mac address to IP address.
-        :rtype: ``dict``
-        """
-        lines = arp_output.split('\n')
-
-        arp_table = defaultdict(list)
-        for line in lines:
-            match = re.match('.*?\((.*?)\) at (.*?)\s+', line)
-
-            if not match:
-                continue
-
-            groups = match.groups()
-            ip_address = groups[0]
-            mac_address = groups[1]
-            arp_table[mac_address].append(ip_address)
-
-        return arp_table


[10/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/httplib_ssl.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/httplib_ssl.py b/apache-libcloud-1.0.0rc2/libcloud/httplib_ssl.py
deleted file mode 100644
index b3e3101..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/httplib_ssl.py
+++ /dev/null
@@ -1,344 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-Subclass for httplib.HTTPSConnection with optional certificate name
-verification, depending on libcloud.security settings.
-"""
-import os
-import sys
-import socket
-import ssl
-import base64
-import warnings
-
-import libcloud.security
-from libcloud.utils.py3 import b
-from libcloud.utils.py3 import httplib
-from libcloud.utils.py3 import urlparse
-from libcloud.utils.py3 import urlunquote
-from libcloud.utils.py3 import match_hostname
-from libcloud.utils.py3 import CertificateError
-
-
-__all__ = [
-    'LibcloudBaseConnection',
-    'LibcloudHTTPConnection',
-    'LibcloudHTTPSConnection'
-]
-
-HTTP_PROXY_ENV_VARIABLE_NAME = 'http_proxy'
-
-# Error message which is thrown when establishing SSL / TLS connection fails
-UNSUPPORTED_TLS_VERSION_ERROR_MSG = """
-Failed to establish SSL / TLS connection (%s). It is possible that the server \
-doesn't support requested SSL / TLS version (%s).
-For information on how to work around this issue, please see \
-https://libcloud.readthedocs.org/en/latest/other/\
-ssl-certificate-validation.html#changing-used-ssl-tls-version
-""".strip()
-
-# Maps ssl.PROTOCOL_* constant to the actual SSL / TLS version name
-SSL_CONSTANT_TO_TLS_VERSION_MAP = {
-    0: 'SSL v2',
-    2: 'SSLv3, TLS v1.0, TLS v1.1, TLS v1.2',
-    3: 'TLS v1.0',
-    4: 'TLS v1.1',
-    5: 'TLS v1.2'
-}
-
-
-class LibcloudBaseConnection(object):
-    """
-    Base connection class to inherit from.
-
-    Note: This class should not be instantiated directly.
-    """
-
-    proxy_scheme = None
-    proxy_host = None
-    proxy_port = None
-
-    proxy_username = None
-    proxy_password = None
-
-    http_proxy_used = False
-
-    def set_http_proxy(self, proxy_url):
-        """
-        Set a HTTP proxy which will be used with this connection.
-
-        :param proxy_url: Proxy URL (e.g. http://<hostname>:<port> without
-                          authentication and
-                          http://<username>:<password>@<hostname>:<port> for
-                          basic auth authentication information.
-        :type proxy_url: ``str``
-        """
-        result = self._parse_proxy_url(proxy_url=proxy_url)
-        scheme = result[0]
-        host = result[1]
-        port = result[2]
-        username = result[3]
-        password = result[4]
-
-        self.proxy_scheme = scheme
-        self.proxy_host = host
-        self.proxy_port = port
-        self.proxy_username = username
-        self.proxy_password = password
-        self.http_proxy_used = True
-
-        self._setup_http_proxy()
-
-    def _parse_proxy_url(self, proxy_url):
-        """
-        Parse and validate a proxy URL.
-
-        :param proxy_url: Proxy URL (e.g. http://hostname:3128)
-        :type proxy_url: ``str``
-
-        :rtype: ``tuple`` (``scheme``, ``hostname``, ``port``)
-        """
-        parsed = urlparse.urlparse(proxy_url)
-
-        if parsed.scheme != 'http':
-            raise ValueError('Only http proxies are supported')
-
-        if not parsed.hostname or not parsed.port:
-            raise ValueError('proxy_url must be in the following format: '
-                             'http://<proxy host>:<proxy port>')
-
-        proxy_scheme = parsed.scheme
-        proxy_host, proxy_port = parsed.hostname, parsed.port
-
-        netloc = parsed.netloc
-
-        if '@' in netloc:
-            username_password = netloc.split('@', 1)[0]
-            split = username_password.split(':', 1)
-
-            if len(split) < 2:
-                raise ValueError('URL is in an invalid format')
-
-            proxy_username, proxy_password = split[0], split[1]
-        else:
-            proxy_username = None
-            proxy_password = None
-
-        return (proxy_scheme, proxy_host, proxy_port, proxy_username,
-                proxy_password)
-
-    def _setup_http_proxy(self):
-        """
-        Set up HTTP proxy.
-
-        :param proxy_url: Proxy URL (e.g. http://<host>:3128)
-        :type proxy_url: ``str``
-        """
-        headers = {}
-
-        if self.proxy_username and self.proxy_password:
-            # Include authentication header
-            user_pass = '%s:%s' % (self.proxy_username, self.proxy_password)
-            encoded = base64.encodestring(b(urlunquote(user_pass))).strip()
-            auth_header = 'Basic %s' % (encoded.decode('utf-8'))
-            headers['Proxy-Authorization'] = auth_header
-
-        if hasattr(self, 'set_tunnel'):
-            # Python 2.7 and higher
-            # pylint: disable=no-member
-            self.set_tunnel(host=self.host, port=self.port, headers=headers)
-        elif hasattr(self, '_set_tunnel'):
-            # Python 2.6
-            # pylint: disable=no-member
-            self._set_tunnel(host=self.host, port=self.port, headers=headers)
-        else:
-            raise ValueError('Unsupported Python version')
-
-        self._set_hostport(host=self.proxy_host, port=self.proxy_port)
-
-    def _activate_http_proxy(self, sock):
-        self.sock = sock
-        self._tunnel()  # pylint: disable=no-member
-
-    def _set_hostport(self, host, port):
-        """
-        Backported from Python stdlib so Proxy support also works with
-        Python 3.4.
-        """
-        if port is None:
-            i = host.rfind(':')
-            j = host.rfind(']')         # ipv6 addresses have [...]
-            if i > j:
-                try:
-                    port = int(host[i + 1:])
-                except ValueError:
-                    msg = "nonnumeric port: '%s'" % (host[i + 1:])
-                    raise httplib.InvalidURL(msg)
-                host = host[:i]
-            else:
-                port = self.default_port  # pylint: disable=no-member
-            if host and host[0] == '[' and host[-1] == ']':
-                host = host[1:-1]
-        self.host = host
-        self.port = port
-
-
-class LibcloudHTTPConnection(httplib.HTTPConnection, LibcloudBaseConnection):
-    def __init__(self, *args, **kwargs):
-        # Support for HTTP proxy
-        proxy_url_env = os.environ.get(HTTP_PROXY_ENV_VARIABLE_NAME, None)
-        proxy_url = kwargs.pop('proxy_url', proxy_url_env)
-
-        super(LibcloudHTTPConnection, self).__init__(*args, **kwargs)
-
-        if proxy_url:
-            self.set_http_proxy(proxy_url=proxy_url)
-
-
-class LibcloudHTTPSConnection(httplib.HTTPSConnection, LibcloudBaseConnection):
-    """
-    LibcloudHTTPSConnection
-
-    Subclass of HTTPSConnection which verifies certificate names
-    if and only if CA certificates are available.
-    """
-    verify = True         # verify by default
-    ca_cert = None        # no default CA Certificate
-
-    def __init__(self, *args, **kwargs):
-        """
-        Constructor
-        """
-        self._setup_verify()
-        # Support for HTTP proxy
-        proxy_url_env = os.environ.get(HTTP_PROXY_ENV_VARIABLE_NAME, None)
-        proxy_url = kwargs.pop('proxy_url', proxy_url_env)
-
-        super(LibcloudHTTPSConnection, self).__init__(*args, **kwargs)
-
-        if proxy_url:
-            self.set_http_proxy(proxy_url=proxy_url)
-
-    def _setup_verify(self):
-        """
-        Setup Verify SSL or not
-
-        Reads security module's VERIFY_SSL_CERT and toggles whether
-        the class overrides the connect() class method or runs the
-        inherited httplib.HTTPSConnection connect()
-        """
-        self.verify = libcloud.security.VERIFY_SSL_CERT
-
-        if self.verify:
-            self._setup_ca_cert()
-        else:
-            warnings.warn(libcloud.security.VERIFY_SSL_DISABLED_MSG)
-
-    def _setup_ca_cert(self):
-        """
-        Setup CA Certs
-
-        Search in CA_CERTS_PATH for valid candidates and
-        return first match.  Otherwise, complain about certs
-        not being available.
-        """
-        if not self.verify:
-            return
-
-        ca_certs_available = [cert
-                              for cert in libcloud.security.CA_CERTS_PATH
-                              if os.path.exists(cert) and os.path.isfile(cert)]
-        if ca_certs_available:
-            # use first available certificate
-            self.ca_cert = ca_certs_available[0]
-        else:
-            raise RuntimeError(
-                libcloud.security.CA_CERTS_UNAVAILABLE_ERROR_MSG)
-
-    def connect(self):
-        """
-        Connect
-
-        Checks if verification is toggled; if not, just call
-        httplib.HTTPSConnection's connect
-        """
-        if not self.verify:
-            return httplib.HTTPSConnection.connect(self)
-
-        # otherwise, create a connection and verify the hostname
-        # use socket.create_connection (in 2.6+) if possible
-        if getattr(socket, 'create_connection', None):
-            sock = socket.create_connection((self.host, self.port),
-                                            self.timeout)
-        else:
-            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-            sock.connect((self.host, self.port))
-
-        # Activate the HTTP proxy
-        if self.http_proxy_used:
-            self._activate_http_proxy(sock=sock)
-
-        ssl_version = libcloud.security.SSL_VERSION
-
-        try:
-            self.sock = ssl.wrap_socket(
-                sock,
-                self.key_file,
-                self.cert_file,
-                cert_reqs=ssl.CERT_REQUIRED,
-                ca_certs=self.ca_cert,
-                ssl_version=ssl_version)
-        except socket.error:
-            exc = sys.exc_info()[1]
-            # Re-throw an exception with a more friendly error message
-            exc = get_socket_error_exception(ssl_version=ssl_version, exc=exc)
-            raise exc
-
-        cert = self.sock.getpeercert()
-        try:
-            match_hostname(cert, self.host)
-        except CertificateError:
-            e = sys.exc_info()[1]
-            raise ssl.SSLError('Failed to verify hostname: %s' % (str(e)))
-
-
-def get_socket_error_exception(ssl_version, exc):
-    """
-    Function which intercepts socket.error exceptions and re-throws an
-    exception with a more user-friendly message in case server doesn't support
-    requested SSL version.
-    """
-    exc_msg = str(exc)
-
-    # Re-throw an exception with a more friendly error message
-    if 'connection reset by peer' in exc_msg.lower():
-        ssl_version_name = SSL_CONSTANT_TO_TLS_VERSION_MAP[ssl_version]
-        msg = (UNSUPPORTED_TLS_VERSION_ERROR_MSG %
-               (exc_msg, ssl_version_name))
-
-        # Note: In some cases arguments are (errno, message) and in
-        # other it's just (message,)
-        exc_args = getattr(exc, 'args', [])
-
-        if len(exc_args) == 2:
-            new_exc_args = [exc.args[0], msg]
-        else:
-            new_exc_args = [msg]
-
-        new_exc = socket.error(*new_exc_args)
-        new_exc.original_exc = exc
-        return new_exc
-    else:
-        return exc

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/__init__.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/__init__.py b/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/__init__.py
deleted file mode 100644
index 7089177..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/__init__.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-Module for working with Load Balancers
-"""
-
-__all__ = [
-    'base',
-    'providers',
-    'types',
-    'drivers'
-]

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/base.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/base.py b/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/base.py
deleted file mode 100644
index 171b6bf..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/base.py
+++ /dev/null
@@ -1,349 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from libcloud.common.base import ConnectionKey, BaseDriver
-from libcloud.common.types import LibcloudError
-
-__all__ = [
-    'Member',
-    'LoadBalancer',
-    'Algorithm',
-    'Driver',
-    'DEFAULT_ALGORITHM'
-]
-
-
-class Member(object):
-    """
-    Represents a load balancer member.
-    """
-
-    def __init__(self, id, ip, port, balancer=None, extra=None):
-        """
-        :param id: Member ID.
-        :type id: ``str``
-
-        :param ip: IP address of this member.
-        :param ip: ``str``
-
-        :param port: Port of this member
-        :param port: ``str``
-
-        :param balancer: Balancer this member is attached to. (optional)
-        :param balancer: :class:`.LoadBalancer`
-
-        :param extra: Provider specific attributes.
-        :type extra: ``dict``
-        """
-        self.id = str(id) if id else None
-        self.ip = ip
-        self.port = port
-        self.balancer = balancer
-        self.extra = extra or {}
-
-    def __repr__(self):
-        return ('<Member: id=%s, address=%s:%s>' % (self.id,
-                                                    self.ip, self.port))
-
-
-class LoadBalancer(object):
-    """
-    Provide a common interface for handling Load Balancers.
-    """
-
-    def __init__(self, id, name, state, ip, port, driver, extra=None):
-        """
-        :param id: Load balancer ID.
-        :type id: ``str``
-
-        :param name: Load balancer name.
-        :type name: ``str``
-
-        :param state: State this loadbalancer is in.
-        :type state: :class:`libcloud.loadbalancer.types.State`
-
-        :param ip: IP address of this loadbalancer.
-        :type ip: ``str``
-
-        :param port: Port of this loadbalancer.
-        :type port: ``int``
-
-        :param driver: Driver this loadbalancer belongs to.
-        :type driver: :class:`.Driver`
-
-        :param extra: Provider specific attributes. (optional)
-        :type extra: ``dict``
-        """
-        self.id = str(id) if id else None
-        self.name = name
-        self.state = state
-        self.ip = ip
-        self.port = port
-        self.driver = driver
-        self.extra = extra or {}
-
-    def attach_compute_node(self, node):
-        return self.driver.balancer_attach_compute_node(balancer=self,
-                                                        node=node)
-
-    def attach_member(self, member):
-        return self.driver.balancer_attach_member(balancer=self,
-                                                  member=member)
-
-    def detach_member(self, member):
-        return self.driver.balancer_detach_member(balancer=self,
-                                                  member=member)
-
-    def list_members(self):
-        return self.driver.balancer_list_members(balancer=self)
-
-    def destroy(self):
-        return self.driver.destroy_balancer(balancer=self)
-
-    def __repr__(self):
-        return ('<LoadBalancer: id=%s, name=%s, state=%s, ip=%s, '
-                'port=%s>' % (self.id, self.name, self.state, self.ip,
-                              self.port))
-
-
-class Algorithm(object):
-    """
-    Represents a load balancing algorithm.
-    """
-
-    RANDOM = 0
-    ROUND_ROBIN = 1
-    LEAST_CONNECTIONS = 2
-    WEIGHTED_ROUND_ROBIN = 3
-    WEIGHTED_LEAST_CONNECTIONS = 4
-    SHORTEST_RESPONSE = 5
-    PERSISTENT_IP = 6
-
-DEFAULT_ALGORITHM = Algorithm.ROUND_ROBIN
-
-
-class Driver(BaseDriver):
-    """
-    A base Driver class to derive from
-
-    This class is always subclassed by a specific driver.
-    """
-
-    name = None
-    website = None
-
-    connectionCls = ConnectionKey
-    _ALGORITHM_TO_VALUE_MAP = {}
-    _VALUE_TO_ALGORITHM_MAP = {}
-
-    def __init__(self, key, secret=None, secure=True, host=None,
-                 port=None, **kwargs):
-        super(Driver, self).__init__(key=key, secret=secret, secure=secure,
-                                     host=host, port=port, **kwargs)
-
-    def list_protocols(self):
-        """
-        Return a list of supported protocols.
-
-        :rtype: ``list`` of ``str``
-        """
-        raise NotImplementedError(
-            'list_protocols not implemented for this driver')
-
-    def list_balancers(self):
-        """
-        List all loadbalancers
-
-        :rtype: ``list`` of :class:`LoadBalancer`
-        """
-        raise NotImplementedError(
-            'list_balancers not implemented for this driver')
-
-    def create_balancer(self, name, port, protocol, algorithm, members):
-        """
-        Create a new load balancer instance
-
-        :param name: Name of the new load balancer (required)
-        :type  name: ``str``
-
-        :param port: Port the load balancer should listen on, defaults to 80
-        :type  port: ``str``
-
-        :param protocol: Loadbalancer protocol, defaults to http.
-        :type  protocol: ``str``
-
-        :param members: list of Members to attach to balancer
-        :type  members: ``list`` of :class:`Member`
-
-        :param algorithm: Load balancing algorithm, defaults to ROUND_ROBIN.
-        :type algorithm: :class:`.Algorithm`
-
-        :rtype: :class:`LoadBalancer`
-        """
-        raise NotImplementedError(
-            'create_balancer not implemented for this driver')
-
-    def destroy_balancer(self, balancer):
-        """
-        Destroy a load balancer
-
-        :param balancer: LoadBalancer which should be used
-        :type  balancer: :class:`LoadBalancer`
-
-        :return: ``True`` if the destroy was successful, otherwise ``False``.
-        :rtype: ``bool``
-        """
-
-        raise NotImplementedError(
-            'destroy_balancer not implemented for this driver')
-
-    def get_balancer(self, balancer_id):
-        """
-        Return a :class:`LoadBalancer` object.
-
-        :param balancer_id: id of a load balancer you want to fetch
-        :type  balancer_id: ``str``
-
-        :rtype: :class:`LoadBalancer`
-        """
-
-        raise NotImplementedError(
-            'get_balancer not implemented for this driver')
-
-    def update_balancer(self, balancer, **kwargs):
-        """
-        Sets the name, algorithm, protocol, or port on a load balancer.
-
-        :param   balancer: LoadBalancer which should be used
-        :type    balancer: :class:`LoadBalancer`
-
-        :param name: New load balancer name
-        :type    name: ``str``
-
-        :param algorithm: New load balancer algorithm
-        :type    algorithm: :class:`.Algorithm`
-
-        :param protocol: New load balancer protocol
-        :type    protocol: ``str``
-
-        :param port: New load balancer port
-        :type    port: ``int``
-
-        :rtype: :class:`LoadBalancer`
-        """
-        raise NotImplementedError(
-            'update_balancer not implemented for this driver')
-
-    def balancer_attach_compute_node(self, balancer, node):
-        """
-        Attach a compute node as a member to the load balancer.
-
-        :param balancer: LoadBalancer which should be used
-        :type  balancer: :class:`LoadBalancer`
-
-        :param node: Node to join to the balancer
-        :type  node: :class:`Node`
-
-        :return: Member after joining the balancer.
-        :rtype: :class:`Member`
-        """
-
-        member = Member(id=None, ip=node.public_ips[0], port=balancer.port)
-        return self.balancer_attach_member(balancer, member)
-
-    def balancer_attach_member(self, balancer, member):
-        """
-        Attach a member to balancer
-
-        :param balancer: LoadBalancer which should be used
-        :type  balancer: :class:`LoadBalancer`
-
-        :param member: Member to join to the balancer
-        :type member: :class:`Member`
-
-        :return: Member after joining the balancer.
-        :rtype: :class:`Member`
-        """
-
-        raise NotImplementedError(
-            'balancer_attach_member not implemented for this driver')
-
-    def balancer_detach_member(self, balancer, member):
-        """
-        Detach member from balancer
-
-        :param balancer: LoadBalancer which should be used
-        :type  balancer: :class:`LoadBalancer`
-
-        :param member: Member which should be used
-        :type member: :class:`Member`
-
-        :return: ``True`` if member detach was successful, otherwise ``False``.
-        :rtype: ``bool``
-        """
-
-        raise NotImplementedError(
-            'balancer_detach_member not implemented for this driver')
-
-    def balancer_list_members(self, balancer):
-        """
-        Return list of members attached to balancer
-
-        :param balancer: LoadBalancer which should be used
-        :type  balancer: :class:`LoadBalancer`
-
-        :rtype: ``list`` of :class:`Member`
-        """
-
-        raise NotImplementedError(
-            'balancer_list_members not implemented for this driver')
-
-    def list_supported_algorithms(self):
-        """
-        Return algorithms supported by this driver.
-
-        :rtype: ``list`` of ``str``
-        """
-        return list(self._ALGORITHM_TO_VALUE_MAP.keys())
-
-    def _value_to_algorithm(self, value):
-        """
-        Return :class:`.Algorithm` based on the value.
-
-        :param value: Algorithm name (e.g. http, tcp, ...).
-        :type  value: ``str``
-
-        :rtype: :class:`.Algorithm`
-        """
-        try:
-            return self._VALUE_TO_ALGORITHM_MAP[value]
-        except KeyError:
-            raise LibcloudError(value='Invalid value: %s' % (value),
-                                driver=self)
-
-    def _algorithm_to_value(self, algorithm):
-        """
-        Return string value for the provided algorithm.
-
-        :param value: Algorithm enum.
-        :type  value: :class:`Algorithm`
-
-        :rtype: ``str``
-        """
-        try:
-            return self._ALGORITHM_TO_VALUE_MAP[algorithm]
-        except KeyError:
-            raise LibcloudError(value='Invalid algorithm: %s' % (algorithm),
-                                driver=self)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/__init__.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/__init__.py b/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/__init__.py
deleted file mode 100644
index f4fdb86..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/__init__.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-__all__ = [
-    'rackspace',
-    'gogrid'
-]

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/brightbox.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/brightbox.py b/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/brightbox.py
deleted file mode 100644
index 9788a1e..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/brightbox.py
+++ /dev/null
@@ -1,138 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-
-from libcloud.utils.py3 import httplib
-from libcloud.common.brightbox import BrightboxConnection
-from libcloud.loadbalancer.base import Driver, Algorithm, Member
-from libcloud.loadbalancer.base import LoadBalancer
-from libcloud.loadbalancer.types import State
-from libcloud.utils.misc import reverse_dict
-
-API_VERSION = '1.0'
-
-
-class BrightboxLBDriver(Driver):
-    connectionCls = BrightboxConnection
-
-    name = 'Brightbox'
-    website = 'http://www.brightbox.co.uk/'
-
-    LB_STATE_MAP = {
-        'creating': State.PENDING,
-        'active': State.RUNNING,
-        'deleting': State.UNKNOWN,
-        'deleted': State.UNKNOWN,
-        'failing': State.UNKNOWN,
-        'failed': State.UNKNOWN,
-    }
-
-    _VALUE_TO_ALGORITHM_MAP = {
-        'round-robin': Algorithm.ROUND_ROBIN,
-        'least-connections': Algorithm.LEAST_CONNECTIONS
-    }
-
-    _ALGORITHM_TO_VALUE_MAP = reverse_dict(_VALUE_TO_ALGORITHM_MAP)
-
-    def list_protocols(self):
-        return ['tcp', 'http']
-
-    def list_balancers(self):
-        data = self.connection.request('/%s/load_balancers' % API_VERSION) \
-                   .object
-
-        return list(map(self._to_balancer, data))
-
-    def create_balancer(self, name, port, protocol, algorithm, members):
-        response = self._post(
-            '/%s/load_balancers' % API_VERSION,
-            {'name': name,
-             'nodes': list(map(self._member_to_node, members)),
-             'policy': self._algorithm_to_value(algorithm),
-             'listeners': [{'in': port, 'out': port, 'protocol': protocol}],
-             'healthcheck': {'type': protocol, 'port': port}}
-        )
-
-        return self._to_balancer(response.object)
-
-    def destroy_balancer(self, balancer):
-        response = self.connection.request('/%s/load_balancers/%s' %
-                                           (API_VERSION, balancer.id),
-                                           method='DELETE')
-
-        return response.status == httplib.ACCEPTED
-
-    def get_balancer(self, balancer_id):
-        data = self.connection.request(
-            '/%s/load_balancers/%s' % (API_VERSION, balancer_id)).object
-        return self._to_balancer(data)
-
-    def balancer_attach_compute_node(self, balancer, node):
-        return self.balancer_attach_member(balancer, node)
-
-    def balancer_attach_member(self, balancer, member):
-        path = '/%s/load_balancers/%s/add_nodes' % (API_VERSION, balancer.id)
-
-        self._post(path, {'nodes': [self._member_to_node(member)]})
-
-        return member
-
-    def balancer_detach_member(self, balancer, member):
-        path = '/%s/load_balancers/%s/remove_nodes' % (API_VERSION,
-                                                       balancer.id)
-
-        response = self._post(path, {'nodes': [self._member_to_node(member)]})
-
-        return response.status == httplib.ACCEPTED
-
-    def balancer_list_members(self, balancer):
-        path = '/%s/load_balancers/%s' % (API_VERSION, balancer.id)
-
-        data = self.connection.request(path).object
-
-        def func(data):
-            return self._node_to_member(data, balancer)
-
-        return list(map(func, data['nodes']))
-
-    def _post(self, path, data={}):
-        headers = {'Content-Type': 'application/json'}
-
-        return self.connection.request(path, data=data, headers=headers,
-                                       method='POST')
-
-    def _to_balancer(self, data):
-        return LoadBalancer(
-            id=data['id'],
-            name=data['name'],
-            state=self.LB_STATE_MAP.get(data['status'], State.UNKNOWN),
-            ip=self._public_ip(data),
-            port=data['listeners'][0]['in'],
-            driver=self.connection.driver
-        )
-
-    def _member_to_node(self, member):
-        return {'node': member.id}
-
-    def _node_to_member(self, data, balancer):
-        return Member(id=data['id'], ip=None, port=None, balancer=balancer)
-
-    def _public_ip(self, data):
-        if len(data['cloud_ips']) > 0:
-            ip = data['cloud_ips'][0]['public_ip']
-        else:
-            ip = None
-
-        return ip

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/cloudstack.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/cloudstack.py b/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/cloudstack.py
deleted file mode 100644
index a8d5485..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/cloudstack.py
+++ /dev/null
@@ -1,209 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from libcloud.common.cloudstack import CloudStackDriverMixIn
-from libcloud.loadbalancer.base import LoadBalancer, Member, Driver, Algorithm
-from libcloud.loadbalancer.base import DEFAULT_ALGORITHM
-from libcloud.loadbalancer.types import Provider
-from libcloud.loadbalancer.types import State
-from libcloud.utils.misc import reverse_dict
-
-
-class CloudStackLBDriver(CloudStackDriverMixIn, Driver):
-    """Driver for CloudStack load balancers."""
-
-    api_name = 'cloudstack_lb'
-    name = 'CloudStack'
-    website = 'http://cloudstack.org/'
-    type = Provider.CLOUDSTACK
-
-    _VALUE_TO_ALGORITHM_MAP = {
-        'roundrobin': Algorithm.ROUND_ROBIN,
-        'leastconn': Algorithm.LEAST_CONNECTIONS
-    }
-    _ALGORITHM_TO_VALUE_MAP = reverse_dict(_VALUE_TO_ALGORITHM_MAP)
-
-    LB_STATE_MAP = {
-        'Active': State.RUNNING,
-    }
-
-    def __init__(self, key, secret=None, secure=True, host=None,
-                 path=None, port=None, *args, **kwargs):
-        """
-        @inherits: :class:`Driver.__init__`
-        """
-        host = host if host else self.host
-        path = path if path else self.path
-
-        if path is not None:
-            self.path = path
-
-        if host is not None:
-            self.host = host
-
-        if (self.type == Provider.CLOUDSTACK) and (not host or not path):
-            raise Exception('When instantiating CloudStack driver directly ' +
-                            'you also need to provide host and path argument')
-
-        super(CloudStackLBDriver, self).__init__(key=key, secret=secret,
-                                                 secure=secure,
-                                                 host=host, port=port)
-
-    def list_protocols(self):
-        """
-        We don't actually have any protocol awareness beyond TCP.
-
-        :rtype: ``list`` of ``str``
-        """
-        return ['tcp']
-
-    def list_balancers(self):
-        balancers = self._sync_request(command='listLoadBalancerRules',
-                                       method='GET')
-        balancers = balancers.get('loadbalancerrule', [])
-        return [self._to_balancer(balancer) for balancer in balancers]
-
-    def get_balancer(self, balancer_id):
-        balancer = self._sync_request(command='listLoadBalancerRules',
-                                      params={'id': balancer_id},
-                                      method='GET')
-        balancer = balancer.get('loadbalancerrule', [])
-        if not balancer:
-            raise Exception("no such load balancer: " + str(balancer_id))
-        return self._to_balancer(balancer[0])
-
-    def create_balancer(self, name, members, protocol='http', port=80,
-                        algorithm=DEFAULT_ALGORITHM, location=None,
-                        private_port=None, network_id=None, vpc_id=None):
-        """
-        @inherits: :class:`Driver.create_balancer`
-
-        :param location: Location
-        :type  location: :class:`NodeLocation`
-
-        :param private_port: Private port
-        :type  private_port: ``int``
-
-        :param network_id: The guest network this rule will be created for.
-        :type  network_id: ``str``
-        """
-
-        args = {}
-        ip_args = {}
-
-        if location is None:
-            locations = self._sync_request(command='listZones', method='GET')
-            location = locations['zone'][0]['id']
-        else:
-            location = location.id
-        if private_port is None:
-            private_port = port
-
-        if network_id is not None:
-            args['networkid'] = network_id
-            ip_args['networkid'] = network_id
-
-        if vpc_id is not None:
-            ip_args['vpcid'] = vpc_id
-
-        ip_args.update({'zoneid': location,
-                        'networkid': network_id,
-                        'vpc_id': vpc_id})
-
-        result = self._async_request(command='associateIpAddress',
-                                     params=ip_args,
-                                     method='GET')
-        public_ip = result['ipaddress']
-
-        args.update({'algorithm': self._ALGORITHM_TO_VALUE_MAP[algorithm],
-                     'name': name,
-                     'privateport': private_port,
-                     'publicport': port,
-                     'publicipid': public_ip['id']})
-
-        result = self._sync_request(
-            command='createLoadBalancerRule',
-            params=args,
-            method='GET')
-
-        listbalancers = self._sync_request(
-            command='listLoadBalancerRules',
-            params=args,
-            method='GET')
-
-        listbalancers = [rule for rule in listbalancers['loadbalancerrule'] if
-                         rule['id'] == result['id']]
-        if len(listbalancers) != 1:
-            return None
-
-        balancer = self._to_balancer(listbalancers[0])
-
-        for member in members:
-            balancer.attach_member(member)
-
-        return balancer
-
-    def destroy_balancer(self, balancer):
-        self._async_request(command='deleteLoadBalancerRule',
-                            params={'id': balancer.id},
-
-                            method='GET')
-        self._async_request(command='disassociateIpAddress',
-                            params={'id': balancer.ex_public_ip_id},
-                            method='GET')
-
-    def balancer_attach_member(self, balancer, member):
-        member.port = balancer.ex_private_port
-        self._async_request(command='assignToLoadBalancerRule',
-                            params={'id': balancer.id,
-                                    'virtualmachineids': member.id},
-                            method='GET')
-        return True
-
-    def balancer_detach_member(self, balancer, member):
-        self._async_request(command='removeFromLoadBalancerRule',
-                            params={'id': balancer.id,
-                                    'virtualmachineids': member.id},
-                            method='GET')
-        return True
-
-    def balancer_list_members(self, balancer):
-        members = self._sync_request(command='listLoadBalancerRuleInstances',
-                                     params={'id': balancer.id},
-                                     method='GET')
-        members = members['loadbalancerruleinstance']
-        return [self._to_member(m, balancer.ex_private_port, balancer)
-                for m in members]
-
-    def _to_balancer(self, obj):
-        balancer = LoadBalancer(
-            id=obj['id'],
-            name=obj['name'],
-            state=self.LB_STATE_MAP.get(obj['state'], State.UNKNOWN),
-            ip=obj['publicip'],
-            port=obj['publicport'],
-            driver=self.connection.driver
-        )
-        balancer.ex_private_port = obj['privateport']
-        balancer.ex_public_ip_id = obj['publicipid']
-        return balancer
-
-    def _to_member(self, obj, port, balancer):
-        return Member(
-            id=obj['id'],
-            ip=obj['nic'][0]['ipaddress'],
-            port=port,
-            balancer=balancer
-        )

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/dimensiondata.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/dimensiondata.py b/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/dimensiondata.py
deleted file mode 100644
index 9fd0143..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/dimensiondata.py
+++ /dev/null
@@ -1,1126 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance withv
-# 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.
-
-try:
-    from lxml import etree as ET
-except ImportError:
-    from xml.etree import ElementTree as ET
-
-from libcloud.common.dimensiondata import DimensionDataConnection
-from libcloud.common.dimensiondata import DimensionDataPool
-from libcloud.common.dimensiondata import DimensionDataPoolMember
-from libcloud.common.dimensiondata import DimensionDataVirtualListener
-from libcloud.common.dimensiondata import DimensionDataVIPNode
-from libcloud.common.dimensiondata import DimensionDataDefaultHealthMonitor
-from libcloud.common.dimensiondata import DimensionDataPersistenceProfile
-from libcloud.common.dimensiondata import \
-    DimensionDataVirtualListenerCompatibility
-from libcloud.common.dimensiondata import DimensionDataDefaultiRule
-from libcloud.common.dimensiondata import API_ENDPOINTS
-from libcloud.common.dimensiondata import DEFAULT_REGION
-from libcloud.common.dimensiondata import TYPES_URN
-from libcloud.utils.misc import reverse_dict
-from libcloud.utils.xml import fixxpath, findtext, findall
-from libcloud.loadbalancer.types import State
-from libcloud.loadbalancer.base import Algorithm, Driver, LoadBalancer
-from libcloud.loadbalancer.base import Member
-from libcloud.loadbalancer.types import Provider
-
-
-class DimensionDataLBDriver(Driver):
-    """
-    DimensionData node driver.
-    """
-
-    selected_region = None
-    connectionCls = DimensionDataConnection
-    name = 'Dimension Data Load Balancer'
-    website = 'https://cloud.dimensiondata.com/'
-    type = Provider.DIMENSIONDATA
-    api_version = 1.0
-
-    network_domain_id = None
-
-    _VALUE_TO_ALGORITHM_MAP = {
-        'ROUND_ROBIN': Algorithm.ROUND_ROBIN,
-        'LEAST_CONNECTIONS': Algorithm.LEAST_CONNECTIONS,
-        'SHORTEST_RESPONSE': Algorithm.SHORTEST_RESPONSE,
-        'PERSISTENT_IP': Algorithm.PERSISTENT_IP
-    }
-    _ALGORITHM_TO_VALUE_MAP = reverse_dict(_VALUE_TO_ALGORITHM_MAP)
-
-    _VALUE_TO_STATE_MAP = {
-        'NORMAL': State.RUNNING,
-        'PENDING_ADD': State.PENDING,
-        'PENDING_CHANGE': State.PENDING,
-        'PENDING_DELETE': State.PENDING,
-        'FAILED_ADD': State.ERROR,
-        'FAILED_CHANGE': State.ERROR,
-        'FAILED_DELETE': State.ERROR,
-        'REQUIRES_SUPPORT': State.ERROR
-    }
-
-    def __init__(self, key, secret=None, secure=True, host=None, port=None,
-                 api_version=None, region=DEFAULT_REGION, **kwargs):
-
-        if region not in API_ENDPOINTS:
-            raise ValueError('Invalid region: %s' % (region))
-
-        self.selected_region = API_ENDPOINTS[region]
-
-        super(DimensionDataLBDriver, self).__init__(key=key, secret=secret,
-                                                    secure=secure, host=host,
-                                                    port=port,
-                                                    api_version=api_version,
-                                                    region=region,
-                                                    **kwargs)
-
-    def _ex_connection_class_kwargs(self):
-        """
-            Add the region to the kwargs before the connection is instantiated
-        """
-
-        kwargs = super(DimensionDataLBDriver,
-                       self)._ex_connection_class_kwargs()
-        kwargs['region'] = self.selected_region
-        return kwargs
-
-    def create_balancer(self, name, port, protocol, algorithm, members):
-        """
-        Create a new load balancer instance
-
-        :param name: Name of the new load balancer (required)
-        :type  name: ``str``
-
-        :param port: Port the load balancer should listen on,
-                    defaults to 80 (required)
-        :type  port: ``str``
-
-        :param protocol: Loadbalancer protocol, defaults to http.
-        :type  protocol: ``str``
-
-        :param members: list of Members to attach to balancer (optional)
-        :type  members: ``list`` of :class:`Member`
-
-        :param algorithm: Load balancing algorithm, defaults to ROUND_ROBIN.
-        :type algorithm: :class:`.Algorithm`
-
-        :rtype: :class:`LoadBalancer`
-        """
-        network_domain_id = self.network_domain_id
-        if port is None:
-            port = 80
-        if protocol is None:
-            protocol = 'http'
-        if algorithm is None:
-            algorithm = Algorithm.ROUND_ROBIN
-
-        # Create a pool first
-        pool = self.ex_create_pool(
-            network_domain_id=network_domain_id,
-            name=name,
-            ex_description=None,
-            balancer_method=self._ALGORITHM_TO_VALUE_MAP[algorithm])
-
-        # Attach the members to the pool as nodes
-        if members is not None:
-            for member in members:
-                node = self.ex_create_node(
-                    network_domain_id=network_domain_id,
-                    name=member.ip,
-                    ip=member.ip,
-                    ex_description=None)
-                self.ex_create_pool_member(
-                    pool=pool,
-                    node=node,
-                    port=port)
-
-        # Create the virtual listener (balancer)
-        listener = self.ex_create_virtual_listener(
-            network_domain_id=network_domain_id,
-            name=name,
-            ex_description=name,
-            port=port,
-            pool=pool)
-
-        return LoadBalancer(
-            id=listener.id,
-            name=listener.name,
-            state=State.RUNNING,
-            ip=listener.ip,
-            port=port,
-            driver=self,
-            extra={'pool_id': pool.id,
-                   'network_domain_id': network_domain_id}
-        )
-
-    def list_balancers(self):
-        """
-        List all loadbalancers inside a geography.
-
-        In Dimension Data terminology these are known as virtual listeners
-
-        :rtype: ``list`` of :class:`LoadBalancer`
-        """
-
-        return self._to_balancers(
-            self.connection
-            .request_with_orgId_api_2('networkDomainVip/virtualListener')
-            .object)
-
-    def get_balancer(self, balancer_id):
-        """
-        Return a :class:`LoadBalancer` object.
-
-        :param balancer_id: id of a load balancer you want to fetch
-        :type  balancer_id: ``str``
-
-        :rtype: :class:`LoadBalancer`
-        """
-
-        bal = self.connection \
-            .request_with_orgId_api_2('networkDomainVip/virtualListener/%s'
-                                      % balancer_id).object
-        return self._to_balancer(bal)
-
-    def list_protocols(self):
-        """
-        Return a list of supported protocols.
-
-        Since all protocols are support by Dimension Data, this is a list
-        of common protocols.
-
-        :rtype: ``list`` of ``str``
-        """
-        return ['http', 'https', 'tcp', 'udp']
-
-    def balancer_list_members(self, balancer):
-        """
-        Return list of members attached to balancer.
-
-        In Dimension Data terminology these are the members of the pools
-        within a virtual listener.
-
-        :param balancer: LoadBalancer which should be used
-        :type  balancer: :class:`LoadBalancer`
-
-        :rtype: ``list`` of :class:`Member`
-        """
-        pool_members = self.ex_get_pool_members(balancer.extra['pool_id'])
-        members = []
-        for pool_member in pool_members:
-            members.append(Member(
-                id=pool_member.id,
-                ip=pool_member.ip,
-                port=pool_member.port,
-                balancer=balancer,
-                extra=None
-            ))
-        return members
-
-    def balancer_attach_member(self, balancer, member):
-        """
-        Attach a member to balancer
-
-        :param balancer: LoadBalancer which should be used
-        :type  balancer: :class:`LoadBalancer`
-
-        :param member: Member to join to the balancer
-        :type member: :class:`Member`
-
-        :return: Member after joining the balancer.
-        :rtype: :class:`Member`
-        """
-        node = self.ex_create_node(
-            network_domain_id=balancer.extra['network_domain_id'],
-            name='Member.' + member.ip,
-            ip=member.ip,
-            ex_description=''
-        )
-        if node is False:
-            return False
-        pool = self.ex_get_pool(balancer.extra['pool_id'])
-        pool_member = self.ex_create_pool_member(
-            pool=pool,
-            node=node,
-            port=member.port)
-        member.id = pool_member.id
-        return member
-
-    def balancer_detach_member(self, balancer, member):
-        """
-        Detach member from balancer
-
-        :param balancer: LoadBalancer which should be used
-        :type  balancer: :class:`LoadBalancer`
-
-        :param member: Member which should be used
-        :type member: :class:`Member`
-
-        :return: ``True`` if member detach was successful, otherwise ``False``.
-        :rtype: ``bool``
-        """
-        create_pool_m = ET.Element('removePoolMember', {'xmlns': TYPES_URN,
-                                                        'id': member.id})
-
-        result = self.connection.request_with_orgId_api_2(
-            'networkDomainVip/removePoolMember',
-            method='POST',
-            data=ET.tostring(create_pool_m)).object
-        response_code = findtext(result, 'responseCode', TYPES_URN)
-        return response_code in ['IN_PROGRESS', 'OK']
-
-    def destroy_balancer(self, balancer):
-        """
-        Destroy a load balancer (virtual listener)
-
-        :param balancer: LoadBalancer which should be used
-        :type  balancer: :class:`LoadBalancer`
-
-        :return: ``True`` if the destroy was successful, otherwise ``False``.
-        :rtype: ``bool``
-        """
-        delete_listener = ET.Element('deleteVirtualListener',
-                                     {'xmlns': TYPES_URN,
-                                      'id': balancer.id})
-
-        result = self.connection.request_with_orgId_api_2(
-            'networkDomainVip/deleteVirtualListener',
-            method='POST',
-            data=ET.tostring(delete_listener)).object
-        response_code = findtext(result, 'responseCode', TYPES_URN)
-        return response_code in ['IN_PROGRESS', 'OK']
-
-    def ex_set_current_network_domain(self, network_domain_id):
-        """
-        Set the network domain (part of the network) of the driver
-
-        :param network_domain_id: ID of the pool (required)
-        :type  network_domain_id: ``str``
-        """
-        self.network_domain_id = network_domain_id
-
-    def ex_get_current_network_domain(self):
-        """
-        Get the current network domain ID of the driver.
-
-        :return: ID of the network domain
-        :rtype: ``str``
-        """
-        return self.network_domain_id
-
-    def ex_create_pool_member(self, pool, node, port=None):
-        """
-        Create a new member in an existing pool from an existing node
-
-        :param pool: Instance of ``DimensionDataPool`` (required)
-        :type  pool: ``DimensionDataPool``
-
-        :param node: Instance of ``DimensionDataVIPNode`` (required)
-        :type  node: ``DimensionDataVIPNode``
-
-        :param port: Port the the service will listen on
-        :type  port: ``str``
-
-        :return: The node member, instance of ``DimensionDataPoolMember``
-        :rtype: ``DimensionDataPoolMember``
-        """
-        create_pool_m = ET.Element('addPoolMember', {'xmlns': TYPES_URN})
-        ET.SubElement(create_pool_m, "poolId").text = pool.id
-        ET.SubElement(create_pool_m, "nodeId").text = node.id
-        if port is not None:
-            ET.SubElement(create_pool_m, "port").text = str(port)
-        ET.SubElement(create_pool_m, "status").text = 'ENABLED'
-
-        response = self.connection.request_with_orgId_api_2(
-            'networkDomainVip/addPoolMember',
-            method='POST',
-            data=ET.tostring(create_pool_m)).object
-
-        member_id = None
-        node_name = None
-        for info in findall(response, 'info', TYPES_URN):
-            if info.get('name') == 'poolMemberId':
-                member_id = info.get('value')
-            if info.get('name') == 'nodeName':
-                node_name = info.get('value')
-
-        return DimensionDataPoolMember(
-            id=member_id,
-            name=node_name,
-            status=State.RUNNING,
-            ip=node.ip,
-            port=port,
-            node_id=node.id
-        )
-
-    def ex_create_node(self,
-                       network_domain_id,
-                       name,
-                       ip,
-                       ex_description,
-                       connection_limit=25000,
-                       connection_rate_limit=2000):
-        """
-        Create a new node
-
-        :param network_domain_id: Network Domain ID (required)
-        :type  name: ``str``
-
-        :param name: name of the node (required)
-        :type  name: ``str``
-
-        :param ip: IPv4 address of the node (required)
-        :type  ip: ``str``
-
-        :param ex_description: Description of the node (required)
-        :type  ex_description: ``str``
-
-        :param connection_limit: Maximum number
-                of concurrent connections per sec
-        :type  connection_limit: ``int``
-
-        :param connection_rate_limit: Maximum number of concurrent sessions
-        :type  connection_rate_limit: ``int``
-
-        :return: Instance of ``DimensionDataVIPNode``
-        :rtype: ``DimensionDataVIPNode``
-        """
-        create_node_elm = ET.Element('createNode', {'xmlns': TYPES_URN})
-        ET.SubElement(create_node_elm, "networkDomainId") \
-            .text = network_domain_id
-        ET.SubElement(create_node_elm, "name").text = name
-        ET.SubElement(create_node_elm, "description").text \
-            = str(ex_description)
-        ET.SubElement(create_node_elm, "ipv4Address").text = ip
-        ET.SubElement(create_node_elm, "status").text = 'ENABLED'
-        ET.SubElement(create_node_elm, "connectionLimit") \
-            .text = str(connection_limit)
-        ET.SubElement(create_node_elm, "connectionRateLimit") \
-            .text = str(connection_rate_limit)
-
-        response = self.connection.request_with_orgId_api_2(
-            action='networkDomainVip/createNode',
-            method='POST',
-            data=ET.tostring(create_node_elm)).object
-
-        node_id = None
-        node_name = None
-        for info in findall(response, 'info', TYPES_URN):
-            if info.get('name') == 'nodeId':
-                node_id = info.get('value')
-            if info.get('name') == 'name':
-                node_name = info.get('value')
-        return DimensionDataVIPNode(
-            id=node_id,
-            name=node_name,
-            status=State.RUNNING,
-            ip=ip
-        )
-
-    def ex_update_node(self, node):
-        """
-        Update the properties of a node
-
-        :param pool: The instance of ``DimensionDataNode`` to update
-        :type  pool: ``DimensionDataNode``
-
-        :return: The instance of ``DimensionDataNode``
-        :rtype: ``DimensionDataNode``
-        """
-        create_node_elm = ET.Element('editNode', {'xmlns': TYPES_URN})
-        ET.SubElement(create_node_elm, "connectionLimit") \
-            .text = str(node.connection_limit)
-        ET.SubElement(create_node_elm, "connectionRateLimit") \
-            .text = str(node.connection_rate_limit)
-
-        self.connection.request_with_orgId_api_2(
-            action='networkDomainVip/createNode',
-            method='POST',
-            data=ET.tostring(create_node_elm)).object
-        return node
-
-    def ex_set_node_state(self, node, enabled):
-        """
-        Change the state of a node (enable/disable)
-
-        :param pool: The instance of ``DimensionDataNode`` to update
-        :type  pool: ``DimensionDataNode``
-
-        :param enabled: The target state of the node
-        :type  enabled: ``bool``
-
-        :return: The instance of ``DimensionDataNode``
-        :rtype: ``DimensionDataNode``
-        """
-        create_node_elm = ET.Element('editNode', {'xmlns': TYPES_URN})
-        ET.SubElement(create_node_elm, "status") \
-            .text = "ENABLED" if enabled is True else "DISABLED"
-
-        self.connection.request_with_orgId_api_2(
-            action='networkDomainVip/editNode',
-            method='POST',
-            data=ET.tostring(create_node_elm)).object
-        return node
-
-    def ex_create_pool(self,
-                       network_domain_id,
-                       name,
-                       balancer_method,
-                       ex_description,
-                       health_monitors=None,
-                       service_down_action='NONE',
-                       slow_ramp_time=30):
-        """
-        Create a new pool
-
-        :param network_domain_id: Network Domain ID (required)
-        :type  name: ``str``
-
-        :param name: name of the node (required)
-        :type  name: ``str``
-
-        :param balancer_method: The load balancer algorithm (required)
-        :type  balancer_method: ``str``
-
-        :param ex_description: Description of the node (required)
-        :type  ex_description: ``str``
-
-        :param health_monitors: A list of health monitors to use for the pool.
-        :type  health_monitors: ``list`` of
-            :class:`DimensionDataDefaultHealthMonitor`
-
-        :param service_down_action: What to do when node
-                                    is unavailable NONE, DROP or RESELECT
-        :type  service_down_action: ``str``
-
-        :param slow_ramp_time: Number of seconds to stagger ramp up of nodes
-        :type  slow_ramp_time: ``int``
-
-        :return: Instance of ``DimensionDataPool``
-        :rtype: ``DimensionDataPool``
-        """
-        # Names cannot contain spaces.
-        name.replace(' ', '_')
-        create_node_elm = ET.Element('createPool', {'xmlns': TYPES_URN})
-        ET.SubElement(create_node_elm, "networkDomainId") \
-            .text = network_domain_id
-        ET.SubElement(create_node_elm, "name").text = name
-        ET.SubElement(create_node_elm, "description").text \
-            = str(ex_description)
-        ET.SubElement(create_node_elm, "loadBalanceMethod") \
-            .text = str(balancer_method)
-
-        if health_monitors is not None:
-            for monitor in health_monitors:
-                ET.SubElement(create_node_elm, "healthMonitorId") \
-                    .text = str(monitor.id)
-
-        ET.SubElement(create_node_elm, "serviceDownAction") \
-            .text = service_down_action
-        ET.SubElement(create_node_elm, "slowRampTime").text \
-            = str(slow_ramp_time)
-
-        response = self.connection.request_with_orgId_api_2(
-            action='networkDomainVip/createPool',
-            method='POST',
-            data=ET.tostring(create_node_elm)).object
-
-        pool_id = None
-        for info in findall(response, 'info', TYPES_URN):
-            if info.get('name') == 'poolId':
-                pool_id = info.get('value')
-
-        return DimensionDataPool(
-            id=pool_id,
-            name=name,
-            description=ex_description,
-            status=State.RUNNING,
-            load_balance_method=str(balancer_method),
-            health_monitor_id=None,
-            service_down_action=service_down_action,
-            slow_ramp_time=str(slow_ramp_time)
-        )
-
-    def ex_create_virtual_listener(self,
-                                   network_domain_id,
-                                   name,
-                                   ex_description,
-                                   port,
-                                   pool,
-                                   listener_ip_address=None,
-                                   persistence_profile=None,
-                                   fallback_persistence_profile=None,
-                                   irule=None,
-                                   protocol='TCP',
-                                   connection_limit=25000,
-                                   connection_rate_limit=2000,
-                                   source_port_preservation='PRESERVE'):
-        """
-        Create a new virtual listener (load balancer)
-
-        :param network_domain_id: Network Domain ID (required)
-        :type  name: ``str``
-
-        :param name: name of the listener (required)
-        :type  name: ``str``
-
-        :param ex_description: Description of the node (required)
-        :type  ex_description: ``str``
-
-        :param port: Description of the node (required)
-        :type  port: ``str``
-
-        :param pool: The pool to use for the listener
-        :type  pool: :class:`DimensionDataPool`
-
-        :param listener_ip_address: The IPv4 Address of the virtual listener
-        :type  listener_ip_address: ``str``
-
-        :param persistence_profile: Persistence profile
-        :type  persistence_profile: :class:`DimensionDataPersistenceProfile`
-
-        :param fallback_persistence_profile: Fallback persistence profile
-        :type  fallback_persistence_profile:
-            :class:`DimensionDataPersistenceProfile`
-
-        :param irule: The iRule to apply
-        :type  irule: :class:`DimensionDataDefaultiRule`
-
-        :param protocol: For STANDARD type, ANY, TCP or UDP
-                         for PERFORMANCE_LAYER_4 choice of ANY, TCP, UDP, HTTP
-        :type  protcol: ``str``
-
-        :param connection_limit: Maximum number
-                                of concurrent connections per sec
-        :type  connection_limit: ``int``
-
-        :param connection_rate_limit: Maximum number of concurrent sessions
-        :type  connection_rate_limit: ``int``
-
-        :param source_port_preservation: Choice of PRESERVE,
-                                        PRESERVE_STRICT or CHANGE
-        :type  source_port_preservation: ``str``
-
-        :return: Instance of the listener
-        :rtype: ``DimensionDataVirtualListener``
-        """
-        if port is 80 or 443:
-            listener_type = 'PERFORMANCE_LAYER_4'
-            protocol = 'HTTP'
-        else:
-            listener_type = 'STANDARD'
-
-        create_node_elm = ET.Element('createVirtualListener',
-                                     {'xmlns': TYPES_URN})
-        ET.SubElement(create_node_elm, "networkDomainId") \
-            .text = network_domain_id
-        ET.SubElement(create_node_elm, "name").text = name
-        ET.SubElement(create_node_elm, "description").text = \
-            str(ex_description)
-        ET.SubElement(create_node_elm, "type").text = listener_type
-        ET.SubElement(create_node_elm, "protocol") \
-            .text = protocol
-        if listener_ip_address is not None:
-            ET.SubElement(create_node_elm, "listenerIpAddress").text = \
-                str(listener_ip_address)
-        ET.SubElement(create_node_elm, "port").text = str(port)
-        ET.SubElement(create_node_elm, "enabled").text = 'true'
-        ET.SubElement(create_node_elm, "connectionLimit") \
-            .text = str(connection_limit)
-        ET.SubElement(create_node_elm, "connectionRateLimit") \
-            .text = str(connection_rate_limit)
-        ET.SubElement(create_node_elm, "sourcePortPreservation") \
-            .text = source_port_preservation
-        ET.SubElement(create_node_elm, "poolId") \
-            .text = pool.id
-        if persistence_profile is not None:
-            ET.SubElement(create_node_elm, "persistenceProfileId") \
-                .text = persistence_profile.id
-        if fallback_persistence_profile is not None:
-            ET.SubElement(create_node_elm, "fallbackPersistenceProfileId") \
-                .text = fallback_persistence_profile.id
-        if irule is not None:
-            ET.SubElement(create_node_elm, "iruleId") \
-                .text = irule.id
-
-        response = self.connection.request_with_orgId_api_2(
-            action='networkDomainVip/createVirtualListener',
-            method='POST',
-            data=ET.tostring(create_node_elm)).object
-
-        virtual_listener_id = None
-        virtual_listener_ip = None
-        for info in findall(response, 'info', TYPES_URN):
-            if info.get('name') == 'virtualListenerId':
-                virtual_listener_id = info.get('value')
-            if info.get('name') == 'listenerIpAddress':
-                virtual_listener_ip = info.get('value')
-
-        return DimensionDataVirtualListener(
-            id=virtual_listener_id,
-            name=name,
-            ip=virtual_listener_ip,
-            status=State.RUNNING
-        )
-
-    def ex_get_pools(self):
-        """
-        Get all of the pools inside the current geography
-
-        :return: Returns a ``list`` of type ``DimensionDataPool``
-        :rtype: ``list`` of ``DimensionDataPool``
-        """
-        pools = self.connection \
-            .request_with_orgId_api_2('networkDomainVip/pool').object
-        return self._to_pools(pools)
-
-    def ex_get_pool(self, pool_id):
-        """
-        Get a specific pool inside the current geography
-
-        :param pool_id: The identifier of the pool
-        :type  pool_id: ``str``
-
-        :return: Returns an instance of ``DimensionDataPool``
-        :rtype: ``DimensionDataPool``
-        """
-        pool = self.connection \
-            .request_with_orgId_api_2('networkDomainVip/pool/%s'
-                                      % pool_id).object
-        return self._to_pool(pool)
-
-    def ex_update_pool(self, pool):
-        """
-        Update the properties of an existing pool
-        only method, serviceDownAction and slowRampTime are updated
-
-        :param pool: The instance of ``DimensionDataPool`` to update
-        :type  pool: ``DimensionDataPool``
-
-        :return: ``True`` for success, ``False`` for failure
-        :rtype: ``bool``
-        """
-        create_node_elm = ET.Element('editPool', {'xmlns': TYPES_URN})
-
-        ET.SubElement(create_node_elm, "loadBalanceMethod") \
-            .text = str(pool.load_balance_method)
-        ET.SubElement(create_node_elm, "serviceDownAction") \
-            .text = pool.service_down_action
-        ET.SubElement(create_node_elm, "slowRampTime").text \
-            = str(pool.slow_ramp_time)
-
-        response = self.connection.request_with_orgId_api_2(
-            action='networkDomainVip/editPool',
-            method='POST',
-            data=ET.tostring(create_node_elm)).object
-        response_code = findtext(response, 'responseCode', TYPES_URN)
-        return response_code in ['IN_PROGRESS', 'OK']
-
-    def ex_destroy_pool(self, pool):
-        """
-        Destroy an existing pool
-
-        :param pool: The instance of ``DimensionDataPool`` to destroy
-        :type  pool: ``DimensionDataPool``
-
-        :return: ``True`` for success, ``False`` for failure
-        :rtype: ``bool``
-        """
-        destroy_request = ET.Element('deletePool',
-                                     {'xmlns': TYPES_URN,
-                                      'id': pool.id})
-
-        result = self.connection.request_with_orgId_api_2(
-            action='networkDomainVip/deletePool',
-            method='POST',
-            data=ET.tostring(destroy_request)).object
-        response_code = findtext(result, 'responseCode', TYPES_URN)
-        return response_code in ['IN_PROGRESS', 'OK']
-
-    def ex_get_pool_members(self, pool_id):
-        """
-        Get the members of a pool
-
-        :param pool: The instance of a pool
-        :type  pool: ``DimensionDataPool``
-
-        :return: Returns an ``list`` of ``DimensionDataPoolMember``
-        :rtype: ``list`` of ``DimensionDataPoolMember``
-        """
-        members = self.connection \
-            .request_with_orgId_api_2('networkDomainVip/poolMember?poolId=%s'
-                                      % pool_id).object
-        return self._to_members(members)
-
-    def ex_get_pool_member(self, pool_member_id):
-        """
-        Get a specific member of a pool
-
-        :param pool: The id of a pool member
-        :type  pool: ``str``
-
-        :return: Returns an instance of ``DimensionDataPoolMember``
-        :rtype: ``DimensionDataPoolMember``
-        """
-        member = self.connection \
-            .request_with_orgId_api_2('networkDomainVip/poolMember/%s'
-                                      % pool_member_id).object
-        return self._to_member(member)
-
-    def ex_set_pool_member_state(self, member, enabled=True):
-        request = ET.Element('editPoolMember',
-                             {'xmlns': TYPES_URN,
-                              'id': member.id})
-        state = "ENABLED" if enabled is True else "DISABLED"
-        ET.SubElement(request, 'status').text = state
-
-        result = self.connection.request_with_orgId_api_2(
-            action='networkDomainVip/editPoolMember',
-            method='POST',
-            data=ET.tostring(request)).object
-
-        response_code = findtext(result, 'responseCode', TYPES_URN)
-        return response_code in ['IN_PROGRESS', 'OK']
-
-    def ex_destroy_pool_member(self, member, destroy_node=False):
-        """
-        Destroy a specific member of a pool
-
-        :param pool: The instance of a pool member
-        :type  pool: ``DimensionDataPoolMember``
-
-        :param destroy_node: Also destroy the associated node
-        :type  destroy_node: ``bool``
-
-        :return: ``True`` for success, ``False`` for failure
-        :rtype: ``bool``
-        """
-        # remove the pool member
-        destroy_request = ET.Element('removePoolMember',
-                                     {'xmlns': TYPES_URN,
-                                      'id': member.id})
-
-        result = self.connection.request_with_orgId_api_2(
-            action='networkDomainVip/removePoolMember',
-            method='POST',
-            data=ET.tostring(destroy_request)).object
-
-        if member.node_id is not None and destroy_node is True:
-            return self.ex_destroy_node(member.node_id)
-        else:
-            response_code = findtext(result, 'responseCode', TYPES_URN)
-            return response_code in ['IN_PROGRESS', 'OK']
-
-    def ex_get_nodes(self):
-        """
-        Get the nodes within this geography
-
-        :return: Returns an ``list`` of ``DimensionDataVIPNode``
-        :rtype: ``list`` of ``DimensionDataVIPNode``
-        """
-        nodes = self.connection \
-            .request_with_orgId_api_2('networkDomainVip/node').object
-        return self._to_nodes(nodes)
-
-    def ex_get_node(self, node_id):
-        """
-        Get the node specified by node_id
-
-        :return: Returns an instance of ``DimensionDataVIPNode``
-        :rtype: Instance of ``DimensionDataVIPNode``
-        """
-        nodes = self.connection \
-            .request_with_orgId_api_2('networkDomainVip/node/%s'
-                                      % node_id).object
-        return self._to_node(nodes)
-
-    def ex_destroy_node(self, node_id):
-        """
-        Destroy a specific node
-
-        :param node_id: The ID of of a ``DimensionDataVIPNode``
-        :type  node_id: ``str``
-
-        :return: ``True`` for success, ``False`` for failure
-        :rtype: ``bool``
-        """
-        # Destroy the node
-        destroy_request = ET.Element('deleteNode',
-                                     {'xmlns': TYPES_URN,
-                                      'id': node_id})
-
-        result = self.connection.request_with_orgId_api_2(
-            action='networkDomainVip/deleteNode',
-            method='POST',
-            data=ET.tostring(destroy_request)).object
-        response_code = findtext(result, 'responseCode', TYPES_URN)
-        return response_code in ['IN_PROGRESS', 'OK']
-
-    def ex_wait_for_state(self, state, func, poll_interval=2,
-                          timeout=60, *args, **kwargs):
-        """
-        Wait for the function which returns a instance
-        with field status to match
-
-        Keep polling func until one of the desired states is matched
-
-        :param state: Either the desired state (`str`) or a `list` of states
-        :type  state: ``str`` or ``list``
-
-        :param  func: The function to call, e.g. ex_get_vlan
-        :type   func: ``function``
-
-        :param  poll_interval: The number of seconds to wait between checks
-        :type   poll_interval: `int`
-
-        :param  timeout: The total number of seconds to wait to reach a state
-        :type   timeout: `int`
-
-        :param  args: The arguments for func
-        :type   args: Positional arguments
-
-        :param  kwargs: The arguments for func
-        :type   kwargs: Keyword arguments
-        """
-        return self.connection.wait_for_state(state, func, poll_interval,
-                                              timeout, *args, **kwargs)
-
-    def ex_get_default_health_monitors(self, network_domain_id):
-        """
-        Get the default health monitors available for a network domain
-
-        :param network_domain_id: The ID of of a ``DimensionDataNetworkDomain``
-        :type  network_domain_id: ``str``
-
-        :rtype: `list` of :class:`DimensionDataDefaultHealthMonitor`
-        """
-        result = self.connection.request_with_orgId_api_2(
-            action='networkDomainVip/defaultHealthMonitor',
-            params={'networkDomainId': network_domain_id},
-            method='GET').object
-        return self._to_health_monitors(result)
-
-    def ex_get_default_persistence_profiles(self, network_domain_id):
-        """
-        Get the default persistence profiles available for a network domain
-
-        :param network_domain_id: The ID of of a ``DimensionDataNetworkDomain``
-        :type  network_domain_id: ``str``
-
-        :rtype: `list` of :class:`DimensionDataPersistenceProfile`
-        """
-        result = self.connection.request_with_orgId_api_2(
-            action='networkDomainVip/defaultPersistenceProfile',
-            params={'networkDomainId': network_domain_id},
-            method='GET').object
-        return self._to_persistence_profiles(result)
-
-    def ex_get_default_irules(self, network_domain_id):
-        """
-        Get the default iRules available for a network domain
-
-        :param network_domain_id: The ID of of a ``DimensionDataNetworkDomain``
-        :type  network_domain_id: ``str``
-
-        :rtype: `list` of :class:`DimensionDataDefaultiRule`
-        """
-        result = self.connection.request_with_orgId_api_2(
-            action='networkDomainVip/defaultIrule',
-            params={'networkDomainId': network_domain_id},
-            method='GET').object
-        return self._to_irules(result)
-
-    def _to_irules(self, object):
-        irules = []
-        matches = object.findall(
-            fixxpath('defaultIrule', TYPES_URN))
-        for element in matches:
-            irules.append(self._to_irule(element))
-        return irules
-
-    def _to_irule(self, element):
-        compatible = []
-        matches = element.findall(
-            fixxpath('virtualListenerCompatibility', TYPES_URN))
-        for match_element in matches:
-            compatible.append(
-                DimensionDataVirtualListenerCompatibility(
-                    type=match_element.get('type'),
-                    protocol=match_element.get('protocol', None)))
-        irule_element = element.find(fixxpath('irule', TYPES_URN))
-        return DimensionDataDefaultiRule(
-            id=irule_element.get('id'),
-            name=irule_element.get('name'),
-            compatible_listeners=compatible
-        )
-
-    def _to_persistence_profiles(self, object):
-        profiles = []
-        matches = object.findall(
-            fixxpath('defaultPersistenceProfile', TYPES_URN))
-        for element in matches:
-            profiles.append(self._to_persistence_profile(element))
-        return profiles
-
-    def _to_persistence_profile(self, element):
-        compatible = []
-        matches = element.findall(
-            fixxpath('virtualListenerCompatibility', TYPES_URN))
-        for match_element in matches:
-            compatible.append(
-                DimensionDataVirtualListenerCompatibility(
-                    type=match_element.get('type'),
-                    protocol=match_element.get('protocol', None)))
-
-        return DimensionDataPersistenceProfile(
-            id=element.get('id'),
-            fallback_compatible=bool(
-                element.get('fallbackCompatible') == "true"),
-            name=findtext(element, 'name', TYPES_URN),
-            compatible_listeners=compatible
-        )
-
-    def _to_health_monitors(self, object):
-        monitors = []
-        matches = object.findall(fixxpath('defaultHealthMonitor', TYPES_URN))
-        for element in matches:
-            monitors.append(self._to_health_monitor(element))
-        return monitors
-
-    def _to_health_monitor(self, element):
-        return DimensionDataDefaultHealthMonitor(
-            id=element.get('id'),
-            name=findtext(element, 'name', TYPES_URN),
-            node_compatible=bool(
-                findtext(element, 'nodeCompatible', TYPES_URN) == "true"),
-            pool_compatible=bool(
-                findtext(element, 'poolCompatible', TYPES_URN) == "true"),
-        )
-
-    def _to_nodes(self, object):
-        nodes = []
-        for element in object.findall(fixxpath("node", TYPES_URN)):
-            nodes.append(self._to_node(element))
-
-        return nodes
-
-    def _to_node(self, element):
-        ipaddress = findtext(element, 'ipv4Address', TYPES_URN)
-        if ipaddress is None:
-            ipaddress = findtext(element, 'ipv6Address', TYPES_URN)
-
-        name = findtext(element, 'name', TYPES_URN)
-
-        node = DimensionDataVIPNode(
-            id=element.get('id'),
-            name=name,
-            status=self._VALUE_TO_STATE_MAP.get(
-                findtext(element, 'state', TYPES_URN),
-                State.UNKNOWN),
-            connection_rate_limit=findtext(element,
-                                           'connectionRateLimit', TYPES_URN),
-            connection_limit=findtext(element, 'connectionLimit', TYPES_URN),
-            ip=ipaddress)
-
-        return node
-
-    def _to_balancers(self, object):
-        loadbalancers = []
-        for element in object.findall(fixxpath("virtualListener", TYPES_URN)):
-            loadbalancers.append(self._to_balancer(element))
-
-        return loadbalancers
-
-    def _to_balancer(self, element):
-        ipaddress = findtext(element, 'listenerIpAddress', TYPES_URN)
-        name = findtext(element, 'name', TYPES_URN)
-        port = findtext(element, 'port', TYPES_URN)
-        extra = {}
-
-        pool_element = element.find(fixxpath(
-            'pool',
-            TYPES_URN))
-        if pool_element is None:
-            extra['pool_id'] = None
-
-        else:
-            extra['pool_id'] = pool_element.get('id')
-
-        extra['network_domain_id'] = findtext(element, 'networkDomainId',
-                                              TYPES_URN)
-
-        balancer = LoadBalancer(
-            id=element.get('id'),
-            name=name,
-            state=self._VALUE_TO_STATE_MAP.get(
-                findtext(element, 'state', TYPES_URN),
-                State.UNKNOWN),
-            ip=ipaddress,
-            port=port,
-            driver=self.connection.driver,
-            extra=extra
-        )
-
-        return balancer
-
-    def _to_members(self, object):
-        members = []
-        for element in object.findall(fixxpath("poolMember", TYPES_URN)):
-            members.append(self._to_member(element))
-
-        return members
-
-    def _to_member(self, element):
-        port = findtext(element, 'port', TYPES_URN)
-        if port is not None:
-            port = int(port)
-        pool_member = DimensionDataPoolMember(
-            id=element.get('id'),
-            name=element.find(fixxpath(
-                'node',
-                TYPES_URN)).get('name'),
-            status=findtext(element, 'state', TYPES_URN),
-            node_id=element.find(fixxpath(
-                'node',
-                TYPES_URN)).get('id'),
-            ip=element.find(fixxpath(
-                'node',
-                TYPES_URN)).get('ipAddress'),
-            port=port
-        )
-        return pool_member
-
-    def _to_pools(self, object):
-        pools = []
-        for element in object.findall(fixxpath("pool", TYPES_URN)):
-            pools.append(self._to_pool(element))
-
-        return pools
-
-    def _to_pool(self, element):
-        pool = DimensionDataPool(
-            id=element.get('id'),
-            name=findtext(element, 'name', TYPES_URN),
-            status=findtext(element, 'state', TYPES_URN),
-            description=findtext(element, 'description', TYPES_URN),
-            load_balance_method=findtext(element, 'loadBalanceMethod',
-                                         TYPES_URN),
-            health_monitor_id=findtext(element, 'healthMonitorId', TYPES_URN),
-            service_down_action=findtext(element, 'serviceDownAction',
-                                         TYPES_URN),
-            slow_ramp_time=findtext(element, 'slowRampTime', TYPES_URN),
-        )
-        return pool


[52/56] [abbrv] libcloud git commit: add unit test

Posted by an...@apache.org.
add unit test


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/f646f1c7
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/f646f1c7
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/f646f1c7

Branch: refs/heads/trunk
Commit: f646f1c78188a92b0fbdad67a1bd51224460c7fb
Parents: eafeccc
Author: hequn <he...@hihuron.com>
Authored: Mon Nov 14 09:53:01 2016 +0800
Committer: Anthony Shaw <an...@apache.org>
Committed: Tue Nov 15 10:20:52 2016 +1100

----------------------------------------------------------------------
 libcloud/test/compute/test_ecs.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/f646f1c7/libcloud/test/compute/test_ecs.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_ecs.py b/libcloud/test/compute/test_ecs.py
index 5c4b099..d1bbae9 100644
--- a/libcloud/test/compute/test_ecs.py
+++ b/libcloud/test/compute/test_ecs.py
@@ -579,7 +579,7 @@ class ECSMockHttp(MockHttpTestCase):
                   'InternetMaxBandwidthIn': '200',
                   'HostName': 'hostname',
                   'Password': 'password',
-                  'IoOptimized': 'true',
+                  'IoOptimized': 'optimized',
                   'SystemDisk.Category': 'cloud',
                   'SystemDisk.DiskName': 'root',
                   'SystemDisk.Description': 'sys',


[18/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/vcloud.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/vcloud.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/vcloud.py
deleted file mode 100644
index 9789eaf..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/vcloud.py
+++ /dev/null
@@ -1,2226 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-VMware vCloud driver.
-"""
-import copy
-import sys
-import re
-import base64
-import os
-from libcloud.utils.py3 import httplib
-from libcloud.utils.py3 import urlencode
-from libcloud.utils.py3 import urlparse
-from libcloud.utils.py3 import b
-from libcloud.utils.py3 import next
-
-urlparse = urlparse.urlparse
-
-import time
-
-try:
-    from lxml import etree as ET
-except ImportError:
-    from xml.etree import ElementTree as ET
-
-from xml.parsers.expat import ExpatError
-
-from libcloud.common.base import XmlResponse, ConnectionUserAndKey
-from libcloud.common.types import InvalidCredsError, LibcloudError
-from libcloud.compute.providers import Provider
-from libcloud.compute.types import NodeState
-from libcloud.compute.base import Node, NodeDriver, NodeLocation
-from libcloud.compute.base import NodeSize, NodeImage
-
-"""
-From vcloud api "The VirtualQuantity element defines the number of MB
-of memory. This should be either 512 or a multiple of 1024 (1 GB)."
-"""
-VIRTUAL_MEMORY_VALS = [512] + [1024 * i for i in range(1, 9)]
-
-# Default timeout (in seconds) for long running tasks
-DEFAULT_TASK_COMPLETION_TIMEOUT = 600
-
-DEFAULT_API_VERSION = '0.8'
-
-"""
-Valid vCloud API v1.5 input values.
-"""
-VIRTUAL_CPU_VALS_1_5 = [i for i in range(1, 9)]
-FENCE_MODE_VALS_1_5 = ['bridged', 'isolated', 'natRouted']
-IP_MODE_VALS_1_5 = ['POOL', 'DHCP', 'MANUAL', 'NONE']
-
-
-def fixxpath(root, xpath):
-    """ElementTree wants namespaces in its xpaths, so here we add them."""
-    namespace, root_tag = root.tag[1:].split("}", 1)
-    fixed_xpath = "/".join(["{%s}%s" % (namespace, e)
-                            for e in xpath.split("/")])
-    return fixed_xpath
-
-
-def get_url_path(url):
-    return urlparse(url.strip()).path
-
-
-class Vdc(object):
-    """
-    Virtual datacenter (vDC) representation
-    """
-    def __init__(self, id, name, driver, allocation_model=None, cpu=None,
-                 memory=None, storage=None):
-        self.id = id
-        self.name = name
-        self.driver = driver
-        self.allocation_model = allocation_model
-        self.cpu = cpu
-        self.memory = memory
-        self.storage = storage
-
-    def __repr__(self):
-        return ('<Vdc: id=%s, name=%s, driver=%s  ...>'
-                % (self.id, self.name, self.driver.name))
-
-
-class Capacity(object):
-    """
-    Represents CPU, Memory or Storage capacity of vDC.
-    """
-    def __init__(self, limit, used, units):
-        self.limit = limit
-        self.used = used
-        self.units = units
-
-    def __repr__(self):
-        return ('<Capacity: limit=%s, used=%s, units=%s>'
-                % (self.limit, self.used, self.units))
-
-
-class ControlAccess(object):
-    """
-    Represents control access settings of a node
-    """
-    class AccessLevel(object):
-        READ_ONLY = 'ReadOnly'
-        CHANGE = 'Change'
-        FULL_CONTROL = 'FullControl'
-
-    def __init__(self, node, everyone_access_level, subjects=None):
-        self.node = node
-        self.everyone_access_level = everyone_access_level
-        if not subjects:
-            subjects = []
-        self.subjects = subjects
-
-    def __repr__(self):
-        return ('<ControlAccess: node=%s, everyone_access_level=%s, '
-                'subjects=%s>'
-                % (self.node, self.everyone_access_level, self.subjects))
-
-
-class Subject(object):
-    """
-    User or group subject
-    """
-    def __init__(self, type, name, access_level, id=None):
-        self.type = type
-        self.name = name
-        self.access_level = access_level
-        self.id = id
-
-    def __repr__(self):
-        return ('<Subject: type=%s, name=%s, access_level=%s>'
-                % (self.type, self.name, self.access_level))
-
-
-class InstantiateVAppXML(object):
-
-    def __init__(self, name, template, net_href, cpus, memory,
-                 password=None, row=None, group=None):
-        self.name = name
-        self.template = template
-        self.net_href = net_href
-        self.cpus = cpus
-        self.memory = memory
-        self.password = password
-        self.row = row
-        self.group = group
-
-        self._build_xmltree()
-
-    def tostring(self):
-        return ET.tostring(self.root)
-
-    def _build_xmltree(self):
-        self.root = self._make_instantiation_root()
-
-        self._add_vapp_template(self.root)
-        instantiation_params = ET.SubElement(self.root,
-                                             "InstantiationParams")
-
-        # product and virtual hardware
-        self._make_product_section(instantiation_params)
-        self._make_virtual_hardware(instantiation_params)
-
-        network_config_section = ET.SubElement(instantiation_params,
-                                               "NetworkConfigSection")
-
-        network_config = ET.SubElement(network_config_section,
-                                       "NetworkConfig")
-        self._add_network_association(network_config)
-
-    def _make_instantiation_root(self):
-        return ET.Element(
-            "InstantiateVAppTemplateParams",
-            {'name': self.name,
-             'xml:lang': 'en',
-             'xmlns': "http://www.vmware.com/vcloud/v0.8",
-             'xmlns:xsi': "http://www.w3.org/2001/XMLSchema-instance"}
-        )
-
-    def _add_vapp_template(self, parent):
-        return ET.SubElement(
-            parent,
-            "VAppTemplate",
-            {'href': self.template}
-        )
-
-    def _make_product_section(self, parent):
-        prod_section = ET.SubElement(
-            parent,
-            "ProductSection",
-            {'xmlns:q1': "http://www.vmware.com/vcloud/v0.8",
-             'xmlns:ovf': "http://schemas.dmtf.org/ovf/envelope/1"}
-        )
-
-        if self.password:
-            self._add_property(prod_section, 'password', self.password)
-
-        if self.row:
-            self._add_property(prod_section, 'row', self.row)
-
-        if self.group:
-            self._add_property(prod_section, 'group', self.group)
-
-        return prod_section
-
-    def _add_property(self, parent, ovfkey, ovfvalue):
-        return ET.SubElement(
-            parent,
-            "Property",
-            {'xmlns': 'http://schemas.dmtf.org/ovf/envelope/1',
-             'ovf:key': ovfkey,
-             'ovf:value': ovfvalue}
-        )
-
-    def _make_virtual_hardware(self, parent):
-        vh = ET.SubElement(
-            parent,
-            "VirtualHardwareSection",
-            {'xmlns:q1': "http://www.vmware.com/vcloud/v0.8"}
-        )
-
-        self._add_cpu(vh)
-        self._add_memory(vh)
-
-        return vh
-
-    def _add_cpu(self, parent):
-        cpu_item = ET.SubElement(
-            parent,
-            "Item",
-            {'xmlns': "http://schemas.dmtf.org/ovf/envelope/1"}
-        )
-        self._add_instance_id(cpu_item, '1')
-        self._add_resource_type(cpu_item, '3')
-        self._add_virtual_quantity(cpu_item, self.cpus)
-
-        return cpu_item
-
-    def _add_memory(self, parent):
-        mem_item = ET.SubElement(
-            parent,
-            'Item',
-            {'xmlns': "http://schemas.dmtf.org/ovf/envelope/1"}
-        )
-        self._add_instance_id(mem_item, '2')
-        self._add_resource_type(mem_item, '4')
-        self._add_virtual_quantity(mem_item, self.memory)
-
-        return mem_item
-
-    def _add_instance_id(self, parent, id):
-        elm = ET.SubElement(
-            parent,
-            'InstanceID',
-            {'xmlns': 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/'
-                      'CIM_ResourceAllocationSettingData'}
-        )
-        elm.text = id
-        return elm
-
-    def _add_resource_type(self, parent, type):
-        elm = ET.SubElement(
-            parent,
-            'ResourceType',
-            {'xmlns': 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/'
-                      'CIM_ResourceAllocationSettingData'}
-        )
-        elm.text = type
-        return elm
-
-    def _add_virtual_quantity(self, parent, amount):
-        elm = ET.SubElement(
-            parent,
-            'VirtualQuantity',
-            {'xmlns': 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/'
-                      'CIM_ResourceAllocationSettingData'}
-        )
-        elm.text = amount
-        return elm
-
-    def _add_network_association(self, parent):
-        return ET.SubElement(
-            parent,
-            'NetworkAssociation',
-            {'href': self.net_href}
-        )
-
-
-class VCloudResponse(XmlResponse):
-
-    def success(self):
-        return self.status in (httplib.OK, httplib.CREATED,
-                               httplib.NO_CONTENT, httplib.ACCEPTED)
-
-
-class VCloudConnection(ConnectionUserAndKey):
-
-    """
-    Connection class for the vCloud driver
-    """
-
-    responseCls = VCloudResponse
-    token = None
-    host = None
-
-    def request(self, *args, **kwargs):
-        self._get_auth_token()
-        return super(VCloudConnection, self).request(*args, **kwargs)
-
-    def check_org(self):
-        # the only way to get our org is by logging in.
-        self._get_auth_token()
-
-    def _get_auth_headers(self):
-        """Some providers need different headers than others"""
-        return {
-            'Authorization': "Basic %s" % base64.b64encode(
-                b('%s:%s' % (self.user_id, self.key))).decode('utf-8'),
-            'Content-Length': '0',
-            'Accept': 'application/*+xml'
-        }
-
-    def _get_auth_token(self):
-        if not self.token:
-            self.connection.request(method='POST', url='/api/v0.8/login',
-                                    headers=self._get_auth_headers())
-
-            resp = self.connection.getresponse()
-            headers = dict(resp.getheaders())
-            body = ET.XML(resp.read())
-
-            try:
-                self.token = headers['set-cookie']
-            except KeyError:
-                raise InvalidCredsError()
-
-            self.driver.org = get_url_path(
-                body.find(fixxpath(body, 'Org')).get('href')
-            )
-
-    def add_default_headers(self, headers):
-        headers['Cookie'] = self.token
-        headers['Accept'] = 'application/*+xml'
-        return headers
-
-
-class VCloudNodeDriver(NodeDriver):
-
-    """
-    vCloud node driver
-    """
-
-    type = Provider.VCLOUD
-    name = 'vCloud'
-    website = 'http://www.vmware.com/products/vcloud/'
-    connectionCls = VCloudConnection
-    org = None
-    _vdcs = None
-
-    NODE_STATE_MAP = {'0': NodeState.PENDING,
-                      '1': NodeState.PENDING,
-                      '2': NodeState.PENDING,
-                      '3': NodeState.PENDING,
-                      '4': NodeState.RUNNING}
-
-    features = {'create_node': ['password']}
-
-    def __new__(cls, key, secret=None, secure=True, host=None, port=None,
-                api_version=DEFAULT_API_VERSION, **kwargs):
-        if cls is VCloudNodeDriver:
-            if api_version == '0.8':
-                cls = VCloudNodeDriver
-            elif api_version == '1.5':
-                cls = VCloud_1_5_NodeDriver
-            elif api_version == '5.1':
-                cls = VCloud_5_1_NodeDriver
-            elif api_version == '5.5':
-                cls = VCloud_5_5_NodeDriver
-            else:
-                raise NotImplementedError(
-                    "No VCloudNodeDriver found for API version %s" %
-                    (api_version))
-        return super(VCloudNodeDriver, cls).__new__(cls)
-
-    @property
-    def vdcs(self):
-        """
-        vCloud virtual data centers (vDCs).
-
-        :return: list of vDC objects
-        :rtype: ``list`` of :class:`Vdc`
-        """
-        if not self._vdcs:
-            self.connection.check_org()  # make sure the org is set.
-            res = self.connection.request(self.org)
-            self._vdcs = [
-                self._to_vdc(
-                    self.connection.request(get_url_path(i.get('href'))).object
-                )
-                for i in res.object.findall(fixxpath(res.object, "Link"))
-                if i.get('type') == 'application/vnd.vmware.vcloud.vdc+xml'
-            ]
-        return self._vdcs
-
-    def _to_vdc(self, vdc_elm):
-        return Vdc(vdc_elm.get('href'), vdc_elm.get('name'), self)
-
-    def _get_vdc(self, vdc_name):
-        vdc = None
-        if not vdc_name:
-            # Return the first organisation VDC found
-            vdc = self.vdcs[0]
-        else:
-            for v in self.vdcs:
-                if v.name == vdc_name:
-                    vdc = v
-            if vdc is None:
-                raise ValueError('%s virtual data centre could not be found',
-                                 vdc_name)
-        return vdc
-
-    @property
-    def networks(self):
-        networks = []
-        for vdc in self.vdcs:
-            res = self.connection.request(get_url_path(vdc.id)).object
-            networks.extend(
-                [network
-                 for network in res.findall(
-                     fixxpath(res, 'AvailableNetworks/Network')
-
-                 )]
-            )
-
-        return networks
-
-    def _to_image(self, image):
-        image = NodeImage(id=image.get('href'),
-                          name=image.get('name'),
-                          driver=self.connection.driver)
-        return image
-
-    def _to_node(self, elm):
-        state = self.NODE_STATE_MAP[elm.get('status')]
-        name = elm.get('name')
-        public_ips = []
-        private_ips = []
-
-        # Following code to find private IPs works for Terremark
-        connections = elm.findall('%s/%s' % (
-            '{http://schemas.dmtf.org/ovf/envelope/1}NetworkConnectionSection',
-            fixxpath(elm, 'NetworkConnection'))
-        )
-        if not connections:
-            connections = elm.findall(
-                fixxpath(
-                    elm,
-                    'Children/Vm/NetworkConnectionSection/NetworkConnection'))
-
-        for connection in connections:
-            ips = [ip.text
-                   for ip
-                   in connection.findall(fixxpath(elm, "IpAddress"))]
-            if connection.get('Network') == 'Internal':
-                private_ips.extend(ips)
-            else:
-                public_ips.extend(ips)
-
-        node = Node(id=elm.get('href'),
-                    name=name,
-                    state=state,
-                    public_ips=public_ips,
-                    private_ips=private_ips,
-                    driver=self.connection.driver)
-
-        return node
-
-    def _get_catalog_hrefs(self):
-        res = self.connection.request(self.org)
-        catalogs = [
-            i.get('href')
-            for i in res.object.findall(fixxpath(res.object, "Link"))
-            if i.get('type') == 'application/vnd.vmware.vcloud.catalog+xml'
-        ]
-
-        return catalogs
-
-    def _wait_for_task_completion(self, task_href,
-                                  timeout=DEFAULT_TASK_COMPLETION_TIMEOUT):
-        start_time = time.time()
-        res = self.connection.request(get_url_path(task_href))
-        status = res.object.get('status')
-        while status != 'success':
-            if status == 'error':
-                # Get error reason from the response body
-                error_elem = res.object.find(fixxpath(res.object, 'Error'))
-                error_msg = "Unknown error"
-                if error_elem is not None:
-                    error_msg = error_elem.get('message')
-                raise Exception("Error status returned by task %s.: %s"
-                                % (task_href, error_msg))
-            if status == 'canceled':
-                raise Exception("Canceled status returned by task %s."
-                                % task_href)
-            if (time.time() - start_time >= timeout):
-                raise Exception("Timeout (%s sec) while waiting for task %s."
-                                % (timeout, task_href))
-            time.sleep(5)
-            res = self.connection.request(get_url_path(task_href))
-            status = res.object.get('status')
-
-    def destroy_node(self, node):
-        node_path = get_url_path(node.id)
-        # blindly poweroff node, it will throw an exception if already off
-        try:
-            res = self.connection.request('%s/power/action/poweroff'
-                                          % node_path,
-                                          method='POST')
-            self._wait_for_task_completion(res.object.get('href'))
-        except Exception:
-            pass
-
-        try:
-            res = self.connection.request('%s/action/undeploy' % node_path,
-                                          method='POST')
-            self._wait_for_task_completion(res.object.get('href'))
-        except ExpatError:
-            # The undeploy response is malformed XML atm.
-            # We can remove this whent he providers fix the problem.
-            pass
-        except Exception:
-            # Some vendors don't implement undeploy at all yet,
-            # so catch this and move on.
-            pass
-
-        res = self.connection.request(node_path, method='DELETE')
-        return res.status == httplib.ACCEPTED
-
-    def reboot_node(self, node):
-        res = self.connection.request('%s/power/action/reset'
-                                      % get_url_path(node.id),
-                                      method='POST')
-        return res.status in [httplib.ACCEPTED, httplib.NO_CONTENT]
-
-    def list_nodes(self):
-        return self.ex_list_nodes()
-
-    def ex_list_nodes(self, vdcs=None):
-        """
-        List all nodes across all vDCs. Using 'vdcs' you can specify which vDCs
-        should be queried.
-
-        :param vdcs: None, vDC or a list of vDCs to query. If None all vDCs
-                     will be queried.
-        :type vdcs: :class:`Vdc`
-
-        :rtype: ``list`` of :class:`Node`
-        """
-        if not vdcs:
-            vdcs = self.vdcs
-        if not isinstance(vdcs, (list, tuple)):
-            vdcs = [vdcs]
-        nodes = []
-        for vdc in vdcs:
-            res = self.connection.request(get_url_path(vdc.id))
-            elms = res.object.findall(fixxpath(
-                res.object, "ResourceEntities/ResourceEntity")
-            )
-            vapps = [
-                (i.get('name'), i.get('href'))
-                for i in elms if
-                i.get('type') == 'application/vnd.vmware.vcloud.vApp+xml' and
-                i.get('name')
-            ]
-
-            for vapp_name, vapp_href in vapps:
-                try:
-                    res = self.connection.request(
-                        get_url_path(vapp_href),
-                        headers={'Content-Type':
-                                 'application/vnd.vmware.vcloud.vApp+xml'}
-                    )
-                    nodes.append(self._to_node(res.object))
-                except Exception:
-                    # The vApp was probably removed since the previous vDC
-                    # query, ignore
-                    e = sys.exc_info()[1]
-                    if not (e.args[0].tag.endswith('Error') and
-                            e.args[0].get('minorErrorCode') ==
-                            'ACCESS_TO_RESOURCE_IS_FORBIDDEN'):
-                        raise
-
-        return nodes
-
-    def _to_size(self, ram):
-        ns = NodeSize(
-            id=None,
-            name="%s Ram" % ram,
-            ram=ram,
-            disk=None,
-            bandwidth=None,
-            price=None,
-            driver=self.connection.driver
-        )
-        return ns
-
-    def list_sizes(self, location=None):
-        sizes = [self._to_size(i) for i in VIRTUAL_MEMORY_VALS]
-        return sizes
-
-    def _get_catalogitems_hrefs(self, catalog):
-        """Given a catalog href returns contained catalog item hrefs"""
-        res = self.connection.request(
-            get_url_path(catalog),
-            headers={
-                'Content-Type': 'application/vnd.vmware.vcloud.catalog+xml'
-            }
-        ).object
-
-        cat_items = res.findall(fixxpath(res, "CatalogItems/CatalogItem"))
-        cat_item_hrefs = [i.get('href')
-                          for i in cat_items
-                          if i.get('type') ==
-                          'application/vnd.vmware.vcloud.catalogItem+xml']
-
-        return cat_item_hrefs
-
-    def _get_catalogitem(self, catalog_item):
-        """Given a catalog item href returns elementree"""
-        res = self.connection.request(
-            get_url_path(catalog_item),
-            headers={
-                'Content-Type': 'application/vnd.vmware.vcloud.catalogItem+xml'
-            }
-        ).object
-
-        return res
-
-    def list_images(self, location=None):
-        images = []
-        for vdc in self.vdcs:
-            res = self.connection.request(get_url_path(vdc.id)).object
-            res_ents = res.findall(fixxpath(
-                res, "ResourceEntities/ResourceEntity")
-            )
-            images += [
-                self._to_image(i)
-                for i in res_ents
-                if i.get('type') ==
-                'application/vnd.vmware.vcloud.vAppTemplate+xml'
-            ]
-
-        for catalog in self._get_catalog_hrefs():
-            for cat_item in self._get_catalogitems_hrefs(catalog):
-                res = self._get_catalogitem(cat_item)
-                res_ents = res.findall(fixxpath(res, 'Entity'))
-                images += [
-                    self._to_image(i)
-                    for i in res_ents
-                    if i.get('type') ==
-                    'application/vnd.vmware.vcloud.vAppTemplate+xml'
-                ]
-
-        def idfun(image):
-            return image.id
-
-        return self._uniquer(images, idfun)
-
-    def _uniquer(self, seq, idfun=None):
-        if idfun is None:
-            def idfun(x):
-                return x
-        seen = {}
-        result = []
-        for item in seq:
-            marker = idfun(item)
-            if marker in seen:
-                continue
-            seen[marker] = 1
-            result.append(item)
-        return result
-
-    def create_node(self, **kwargs):
-        """
-        Creates and returns node.
-
-        :keyword    ex_network: link to a "Network" e.g.,
-                    ``https://services.vcloudexpress...``
-        :type       ex_network: ``str``
-
-        :keyword    ex_vdc: Name of organisation's virtual data
-                            center where vApp VMs will be deployed.
-        :type       ex_vdc: ``str``
-
-        :keyword    ex_cpus: number of virtual cpus (limit depends on provider)
-        :type       ex_cpus: ``int``
-
-        :type       ex_row: ``str``
-
-        :type       ex_group: ``str``
-        """
-        name = kwargs['name']
-        image = kwargs['image']
-        size = kwargs['size']
-
-        # Some providers don't require a network link
-        try:
-            network = kwargs.get('ex_network', self.networks[0].get('href'))
-        except IndexError:
-            network = ''
-
-        password = None
-        auth = self._get_and_check_auth(kwargs.get('auth'))
-        password = auth.password
-
-        instantiate_xml = InstantiateVAppXML(
-            name=name,
-            template=image.id,
-            net_href=network,
-            cpus=str(kwargs.get('ex_cpus', 1)),
-            memory=str(size.ram),
-            password=password,
-            row=kwargs.get('ex_row', None),
-            group=kwargs.get('ex_group', None)
-        )
-
-        vdc = self._get_vdc(kwargs.get('ex_vdc', None))
-
-        # Instantiate VM and get identifier.
-        content_type = \
-            'application/vnd.vmware.vcloud.instantiateVAppTemplateParams+xml'
-        res = self.connection.request(
-            '%s/action/instantiateVAppTemplate' % get_url_path(vdc.id),
-            data=instantiate_xml.tostring(),
-            method='POST',
-            headers={'Content-Type': content_type}
-        )
-        vapp_path = get_url_path(res.object.get('href'))
-
-        # Deploy the VM from the identifier.
-        res = self.connection.request('%s/action/deploy' % vapp_path,
-                                      method='POST')
-
-        self._wait_for_task_completion(res.object.get('href'))
-
-        # Power on the VM.
-        res = self.connection.request('%s/power/action/powerOn' % vapp_path,
-                                      method='POST')
-
-        res = self.connection.request(vapp_path)
-        node = self._to_node(res.object)
-
-        if getattr(auth, "generated", False):
-            node.extra['password'] = auth.password
-
-        return node
-
-
-class HostingComConnection(VCloudConnection):
-
-    """
-    vCloud connection subclass for Hosting.com
-    """
-
-    host = "vcloud.safesecureweb.com"
-
-    def _get_auth_headers(self):
-        """hosting.com doesn't follow the standard vCloud authentication API"""
-        return {
-            'Authentication': base64.b64encode(b('%s:%s' % (self.user_id,
-                                                            self.key))),
-            'Content-Length': '0'
-        }
-
-
-class HostingComDriver(VCloudNodeDriver):
-
-    """
-    vCloud node driver for Hosting.com
-    """
-    connectionCls = HostingComConnection
-
-
-class TerremarkConnection(VCloudConnection):
-
-    """
-    vCloud connection subclass for Terremark
-    """
-
-    host = "services.vcloudexpress.terremark.com"
-
-
-class TerremarkDriver(VCloudNodeDriver):
-
-    """
-    vCloud node driver for Terremark
-    """
-
-    connectionCls = TerremarkConnection
-
-    def list_locations(self):
-        return [NodeLocation(0, "Terremark Texas", 'US', self)]
-
-
-class VCloud_1_5_Connection(VCloudConnection):
-
-    def _get_auth_headers(self):
-        """Compatibility for using v1.5 API under vCloud Director 5.1"""
-        return {
-            'Authorization': "Basic %s" % base64.b64encode(
-                b('%s:%s' % (self.user_id, self.key))).decode('utf-8'),
-            'Content-Length': '0',
-            'Accept': 'application/*+xml;version=1.5'
-        }
-
-    def _get_auth_token(self):
-        if not self.token:
-            # Log In
-            self.connection.request(method='POST', url='/api/sessions',
-                                    headers=self._get_auth_headers())
-
-            resp = self.connection.getresponse()
-            headers = dict(resp.getheaders())
-
-            # Set authorization token
-            try:
-                self.token = headers['x-vcloud-authorization']
-            except KeyError:
-                raise InvalidCredsError()
-
-            # Get the URL of the Organization
-            body = ET.XML(resp.read())
-            self.org_name = body.get('org')
-            org_list_url = get_url_path(
-                next((link for link in body.findall(fixxpath(body, 'Link'))
-                     if link.get('type') ==
-                     'application/vnd.vmware.vcloud.orgList+xml')).get('href')
-            )
-
-            if self.proxy_url is not None:
-                self.connection.set_http_proxy(self.proxy_url)
-            self.connection.request(method='GET', url=org_list_url,
-                                    headers=self.add_default_headers({}))
-            body = ET.XML(self.connection.getresponse().read())
-            self.driver.org = get_url_path(
-                next((org for org in body.findall(fixxpath(body, 'Org'))
-                     if org.get('name') == self.org_name)).get('href')
-            )
-
-    def add_default_headers(self, headers):
-        headers['Accept'] = 'application/*+xml;version=1.5'
-        headers['x-vcloud-authorization'] = self.token
-        return headers
-
-
-class VCloud_5_5_Connection(VCloud_1_5_Connection):
-    def add_default_headers(self, headers):
-        headers['Accept'] = 'application/*+xml;version=5.5'
-        headers['x-vcloud-authorization'] = self.token
-        return headers
-
-
-class Instantiate_1_5_VAppXML(object):
-
-    def __init__(self, name, template, network, vm_network=None,
-                 vm_fence=None):
-        self.name = name
-        self.template = template
-        self.network = network
-        self.vm_network = vm_network
-        self.vm_fence = vm_fence
-        self._build_xmltree()
-
-    def tostring(self):
-        return ET.tostring(self.root)
-
-    def _build_xmltree(self):
-        self.root = self._make_instantiation_root()
-
-        if self.network is not None:
-            instantionation_params = ET.SubElement(self.root,
-                                                   'InstantiationParams')
-            network_config_section = ET.SubElement(instantionation_params,
-                                                   'NetworkConfigSection')
-            ET.SubElement(
-                network_config_section,
-                'Info',
-                {'xmlns': 'http://schemas.dmtf.org/ovf/envelope/1'}
-            )
-            network_config = ET.SubElement(network_config_section,
-                                           'NetworkConfig')
-            self._add_network_association(network_config)
-
-        self._add_vapp_template(self.root)
-
-    def _make_instantiation_root(self):
-        return ET.Element(
-            'InstantiateVAppTemplateParams',
-            {'name': self.name,
-             'deploy': 'false',
-             'powerOn': 'false',
-             'xml:lang': 'en',
-             'xmlns': 'http://www.vmware.com/vcloud/v1.5',
-             'xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance'}
-        )
-
-    def _add_vapp_template(self, parent):
-        return ET.SubElement(
-            parent,
-            'Source',
-            {'href': self.template}
-        )
-
-    def _add_network_association(self, parent):
-        if self.vm_network is None:
-            # Don't set a custom vApp VM network name
-            parent.set('networkName', self.network.get('name'))
-        else:
-            # Set a custom vApp VM network name
-            parent.set('networkName', self.vm_network)
-        configuration = ET.SubElement(parent, 'Configuration')
-        ET.SubElement(configuration, 'ParentNetwork',
-                      {'href': self.network.get('href')})
-
-        if self.vm_fence is None:
-            fencemode = self.network.find(fixxpath(self.network,
-                                          'Configuration/FenceMode')).text
-        else:
-            fencemode = self.vm_fence
-        ET.SubElement(configuration, 'FenceMode').text = fencemode
-
-
-class VCloud_1_5_NodeDriver(VCloudNodeDriver):
-    connectionCls = VCloud_1_5_Connection
-
-    # Based on
-    # http://pubs.vmware.com/vcloud-api-1-5/api_prog/
-    # GUID-843BE3AD-5EF6-4442-B864-BCAE44A51867.html
-    NODE_STATE_MAP = {'-1': NodeState.UNKNOWN,
-                      '0': NodeState.PENDING,
-                      '1': NodeState.PENDING,
-                      '2': NodeState.PENDING,
-                      '3': NodeState.PENDING,
-                      '4': NodeState.RUNNING,
-                      '5': NodeState.RUNNING,
-                      '6': NodeState.UNKNOWN,
-                      '7': NodeState.UNKNOWN,
-                      '8': NodeState.STOPPED,
-                      '9': NodeState.UNKNOWN,
-                      '10': NodeState.UNKNOWN}
-
-    def list_locations(self):
-        return [NodeLocation(id=self.connection.host,
-                name=self.connection.host, country="N/A", driver=self)]
-
-    def ex_find_node(self, node_name, vdcs=None):
-        """
-        Searches for node across specified vDCs. This is more effective than
-        querying all nodes to get a single instance.
-
-        :param node_name: The name of the node to search for
-        :type node_name: ``str``
-
-        :param vdcs: None, vDC or a list of vDCs to search in. If None all vDCs
-                     will be searched.
-        :type vdcs: :class:`Vdc`
-
-        :return: node instance or None if not found
-        :rtype: :class:`Node` or ``None``
-        """
-        if not vdcs:
-            vdcs = self.vdcs
-        if not getattr(vdcs, '__iter__', False):
-            vdcs = [vdcs]
-        for vdc in vdcs:
-            res = self.connection.request(get_url_path(vdc.id))
-            xpath = fixxpath(res.object, "ResourceEntities/ResourceEntity")
-            entity_elems = res.object.findall(xpath)
-            for entity_elem in entity_elems:
-                if entity_elem.get('type') == \
-                        'application/vnd.vmware.vcloud.vApp+xml' and \
-                        entity_elem.get('name') == node_name:
-                    path = get_url_path(entity_elem.get('href'))
-                    headers = {'Content-Type':
-                               'application/vnd.vmware.vcloud.vApp+xml'}
-                    res = self.connection.request(path,
-                                                  headers=headers)
-                    return self._to_node(res.object)
-        return None
-
-    def destroy_node(self, node):
-        try:
-            self.ex_undeploy_node(node)
-        except Exception:
-            # Some vendors don't implement undeploy at all yet,
-            # so catch this and move on.
-            pass
-
-        res = self.connection.request(get_url_path(node.id), method='DELETE')
-        return res.status == httplib.ACCEPTED
-
-    def reboot_node(self, node):
-        res = self.connection.request('%s/power/action/reset'
-                                      % get_url_path(node.id),
-                                      method='POST')
-        if res.status in [httplib.ACCEPTED, httplib.NO_CONTENT]:
-            self._wait_for_task_completion(res.object.get('href'))
-            return True
-        else:
-            return False
-
-    def ex_deploy_node(self, node):
-        """
-        Deploys existing node. Equal to vApp "start" operation.
-
-        :param  node: The node to be deployed
-        :type   node: :class:`Node`
-
-        :rtype: :class:`Node`
-        """
-        data = {'powerOn': 'true',
-                'xmlns': 'http://www.vmware.com/vcloud/v1.5'}
-        deploy_xml = ET.Element('DeployVAppParams', data)
-        path = get_url_path(node.id)
-        headers = {
-            'Content-Type':
-            'application/vnd.vmware.vcloud.deployVAppParams+xml'
-        }
-        res = self.connection.request('%s/action/deploy' % path,
-                                      data=ET.tostring(deploy_xml),
-                                      method='POST',
-                                      headers=headers)
-        self._wait_for_task_completion(res.object.get('href'))
-        res = self.connection.request(get_url_path(node.id))
-        return self._to_node(res.object)
-
-    def ex_undeploy_node(self, node):
-        """
-        Undeploys existing node. Equal to vApp "stop" operation.
-
-        :param  node: The node to be deployed
-        :type   node: :class:`Node`
-
-        :rtype: :class:`Node`
-        """
-        data = {'xmlns': 'http://www.vmware.com/vcloud/v1.5'}
-        undeploy_xml = ET.Element('UndeployVAppParams', data)
-        undeploy_power_action_xml = ET.SubElement(undeploy_xml,
-                                                  'UndeployPowerAction')
-        undeploy_power_action_xml.text = 'shutdown'
-
-        headers = {
-            'Content-Type':
-            'application/vnd.vmware.vcloud.undeployVAppParams+xml'
-        }
-
-        try:
-            res = self.connection.request(
-                '%s/action/undeploy' % get_url_path(node.id),
-                data=ET.tostring(undeploy_xml),
-                method='POST',
-                headers=headers)
-
-            self._wait_for_task_completion(res.object.get('href'))
-        except Exception:
-            undeploy_power_action_xml.text = 'powerOff'
-            res = self.connection.request(
-                '%s/action/undeploy' % get_url_path(node.id),
-                data=ET.tostring(undeploy_xml),
-                method='POST',
-                headers=headers)
-            self._wait_for_task_completion(res.object.get('href'))
-
-        res = self.connection.request(get_url_path(node.id))
-        return self._to_node(res.object)
-
-    def ex_power_off_node(self, node):
-        """
-        Powers on all VMs under specified node. VMs need to be This operation
-        is allowed only when the vApp/VM is powered on.
-
-        :param  node: The node to be powered off
-        :type   node: :class:`Node`
-
-        :rtype: :class:`Node`
-        """
-        return self._perform_power_operation(node, 'powerOff')
-
-    def ex_power_on_node(self, node):
-        """
-        Powers on all VMs under specified node. This operation is allowed
-        only when the vApp/VM is powered off or suspended.
-
-        :param  node: The node to be powered on
-        :type   node: :class:`Node`
-
-        :rtype: :class:`Node`
-        """
-        return self._perform_power_operation(node, 'powerOn')
-
-    def ex_shutdown_node(self, node):
-        """
-        Shutdowns all VMs under specified node. This operation is allowed only
-        when the vApp/VM is powered on.
-
-        :param  node: The node to be shut down
-        :type   node: :class:`Node`
-
-        :rtype: :class:`Node`
-        """
-        return self._perform_power_operation(node, 'shutdown')
-
-    def ex_suspend_node(self, node):
-        """
-        Suspends all VMs under specified node. This operation is allowed only
-        when the vApp/VM is powered on.
-
-        :param  node: The node to be suspended
-        :type   node: :class:`Node`
-
-        :rtype: :class:`Node`
-        """
-        return self._perform_power_operation(node, 'suspend')
-
-    def _perform_power_operation(self, node, operation):
-        res = self.connection.request(
-            '%s/power/action/%s' % (get_url_path(node.id), operation),
-            method='POST')
-        self._wait_for_task_completion(res.object.get('href'))
-        res = self.connection.request(get_url_path(node.id))
-        return self._to_node(res.object)
-
-    def ex_get_control_access(self, node):
-        """
-        Returns the control access settings for specified node.
-
-        :param  node: node to get the control access for
-        :type   node: :class:`Node`
-
-        :rtype: :class:`ControlAccess`
-        """
-        res = self.connection.request(
-            '%s/controlAccess' % get_url_path(node.id))
-        everyone_access_level = None
-        is_shared_elem = res.object.find(
-            fixxpath(res.object, "IsSharedToEveryone"))
-        if is_shared_elem is not None and is_shared_elem.text == 'true':
-            everyone_access_level = res.object.find(
-                fixxpath(res.object, "EveryoneAccessLevel")).text
-
-        # Parse all subjects
-        subjects = []
-        xpath = fixxpath(res.object, "AccessSettings/AccessSetting")
-        for elem in res.object.findall(xpath):
-            access_level = elem.find(fixxpath(res.object, "AccessLevel")).text
-            subject_elem = elem.find(fixxpath(res.object, "Subject"))
-            if subject_elem.get('type') == \
-               'application/vnd.vmware.admin.group+xml':
-                subj_type = 'group'
-            else:
-                subj_type = 'user'
-
-            path = get_url_path(subject_elem.get('href'))
-            res = self.connection.request(path)
-            name = res.object.get('name')
-            subject = Subject(type=subj_type,
-                              name=name,
-                              access_level=access_level,
-                              id=subject_elem.get('href'))
-            subjects.append(subject)
-
-        return ControlAccess(node, everyone_access_level, subjects)
-
-    def ex_set_control_access(self, node, control_access):
-        """
-        Sets control access for the specified node.
-
-        :param  node: node
-        :type   node: :class:`Node`
-
-        :param  control_access: control access settings
-        :type   control_access: :class:`ControlAccess`
-
-        :rtype: ``None``
-        """
-        xml = ET.Element('ControlAccessParams',
-                         {'xmlns': 'http://www.vmware.com/vcloud/v1.5'})
-        shared_to_everyone = ET.SubElement(xml, 'IsSharedToEveryone')
-        if control_access.everyone_access_level:
-            shared_to_everyone.text = 'true'
-            everyone_access_level = ET.SubElement(xml, 'EveryoneAccessLevel')
-            everyone_access_level.text = control_access.everyone_access_level
-        else:
-            shared_to_everyone.text = 'false'
-
-        # Set subjects
-        if control_access.subjects:
-            access_settings_elem = ET.SubElement(xml, 'AccessSettings')
-        for subject in control_access.subjects:
-            setting = ET.SubElement(access_settings_elem, 'AccessSetting')
-            if subject.id:
-                href = subject.id
-            else:
-                res = self.ex_query(type=subject.type, filter='name==' +
-                                    subject.name)
-                if not res:
-                    raise LibcloudError('Specified subject "%s %s" not found '
-                                        % (subject.type, subject.name))
-                href = res[0]['href']
-            ET.SubElement(setting, 'Subject', {'href': href})
-            ET.SubElement(setting, 'AccessLevel').text = subject.access_level
-
-        headers = {
-            'Content-Type': 'application/vnd.vmware.vcloud.controlAccess+xml'
-        }
-        self.connection.request(
-            '%s/action/controlAccess' % get_url_path(node.id),
-            data=ET.tostring(xml),
-            headers=headers,
-            method='POST')
-
-    def ex_get_metadata(self, node):
-        """
-        :param  node: node
-        :type   node: :class:`Node`
-
-        :return: dictionary mapping metadata keys to metadata values
-        :rtype: dictionary mapping ``str`` to ``str``
-        """
-        res = self.connection.request('%s/metadata' % (get_url_path(node.id)))
-        xpath = fixxpath(res.object, 'MetadataEntry')
-        metadata_entries = res.object.findall(xpath)
-        res_dict = {}
-
-        for entry in metadata_entries:
-            key = entry.findtext(fixxpath(res.object, 'Key'))
-            value = entry.findtext(fixxpath(res.object, 'Value'))
-            res_dict[key] = value
-
-        return res_dict
-
-    def ex_set_metadata_entry(self, node, key, value):
-        """
-        :param  node: node
-        :type   node: :class:`Node`
-
-        :param key: metadata key to be set
-        :type key: ``str``
-
-        :param value: metadata value to be set
-        :type value: ``str``
-
-        :rtype: ``None``
-        """
-        metadata_elem = ET.Element(
-            'Metadata',
-            {'xmlns': "http://www.vmware.com/vcloud/v1.5",
-             'xmlns:xsi': "http://www.w3.org/2001/XMLSchema-instance"}
-        )
-        entry = ET.SubElement(metadata_elem, 'MetadataEntry')
-        key_elem = ET.SubElement(entry, 'Key')
-        key_elem.text = key
-        value_elem = ET.SubElement(entry, 'Value')
-        value_elem.text = value
-
-        # send it back to the server
-        res = self.connection.request(
-            '%s/metadata' % get_url_path(node.id),
-            data=ET.tostring(metadata_elem),
-            headers={
-                'Content-Type': 'application/vnd.vmware.vcloud.metadata+xml'
-            },
-            method='POST')
-        self._wait_for_task_completion(res.object.get('href'))
-
-    def ex_query(self, type, filter=None, page=1, page_size=100, sort_asc=None,
-                 sort_desc=None):
-        """
-        Queries vCloud for specified type. See
-        http://www.vmware.com/pdf/vcd_15_api_guide.pdf for details. Each
-        element of the returned list is a dictionary with all attributes from
-        the record.
-
-        :param type: type to query (r.g. user, group, vApp etc.)
-        :type  type: ``str``
-
-        :param filter: filter expression (see documentation for syntax)
-        :type  filter: ``str``
-
-        :param page: page number
-        :type  page: ``int``
-
-        :param page_size: page size
-        :type  page_size: ``int``
-
-        :param sort_asc: sort in ascending order by specified field
-        :type  sort_asc: ``str``
-
-        :param sort_desc: sort in descending order by specified field
-        :type  sort_desc: ``str``
-
-        :rtype: ``list`` of dict
-        """
-        # This is a workaround for filter parameter encoding
-        # the urllib encodes (name==Developers%20Only) into
-        # %28name%3D%3DDevelopers%20Only%29) which is not accepted by vCloud
-        params = {
-            'type': type,
-            'pageSize': page_size,
-            'page': page,
-        }
-        if sort_asc:
-            params['sortAsc'] = sort_asc
-        if sort_desc:
-            params['sortDesc'] = sort_desc
-
-        url = '/api/query?' + urlencode(params)
-        if filter:
-            if not filter.startswith('('):
-                filter = '(' + filter + ')'
-            url += '&filter=' + filter.replace(' ', '+')
-
-        results = []
-        res = self.connection.request(url)
-        for elem in res.object:
-            if not elem.tag.endswith('Link'):
-                result = elem.attrib
-                result['type'] = elem.tag.split('}')[1]
-                results.append(result)
-        return results
-
-    def create_node(self, **kwargs):
-        """
-        Creates and returns node. If the source image is:
-          - vApp template - a new vApp is instantiated from template
-          - existing vApp - a new vApp is cloned from the source vApp. Can
-                            not clone more vApps is parallel otherwise
-                            resource busy error is raised.
-
-
-        @inherits: :class:`NodeDriver.create_node`
-
-        :keyword    image:  OS Image to boot on node. (required). Can be a
-                            NodeImage or existing Node that will be cloned.
-        :type       image:  :class:`NodeImage` or :class:`Node`
-
-        :keyword    ex_network: Organisation's network name for attaching vApp
-                                VMs to.
-        :type       ex_network: ``str``
-
-        :keyword    ex_vdc: Name of organisation's virtual data center where
-                            vApp VMs will be deployed.
-        :type       ex_vdc: ``str``
-
-        :keyword    ex_vm_names: list of names to be used as a VM and computer
-                                 name. The name must be max. 15 characters
-                                 long and follow the host name requirements.
-        :type       ex_vm_names: ``list`` of ``str``
-
-        :keyword    ex_vm_cpu: number of virtual CPUs/cores to allocate for
-                               each vApp VM.
-        :type       ex_vm_cpu: ``int``
-
-        :keyword    ex_vm_memory: amount of memory in MB to allocate for each
-                                  vApp VM.
-        :type       ex_vm_memory: ``int``
-
-        :keyword    ex_vm_script: full path to file containing guest
-                                  customisation script for each vApp VM.
-                                  Useful for creating users & pushing out
-                                  public SSH keys etc.
-        :type       ex_vm_script: ``str``
-
-        :keyword    ex_vm_network: Override default vApp VM network name.
-                                   Useful for when you've imported an OVF
-                                   originating from outside of the vCloud.
-        :type       ex_vm_network: ``str``
-
-        :keyword    ex_vm_fence: Fence mode for connecting the vApp VM network
-                                 (ex_vm_network) to the parent
-                                 organisation network (ex_network).
-        :type       ex_vm_fence: ``str``
-
-        :keyword    ex_vm_ipmode: IP address allocation mode for all vApp VM
-                                  network connections.
-        :type       ex_vm_ipmode: ``str``
-
-        :keyword    ex_deploy: set to False if the node shouldn't be deployed
-                               (started) after creation
-        :type       ex_deploy: ``bool``
-
-        :keyword    ex_clone_timeout: timeout in seconds for clone/instantiate
-                                      VM operation.
-                                      Cloning might be a time consuming
-                                      operation especially when linked clones
-                                      are disabled or VMs are created on
-                                      different datastores.
-                                      Overrides the default task completion
-                                      value.
-        :type       ex_clone_timeout: ``int``
-        """
-        name = kwargs['name']
-        image = kwargs['image']
-        ex_vm_names = kwargs.get('ex_vm_names')
-        ex_vm_cpu = kwargs.get('ex_vm_cpu')
-        ex_vm_memory = kwargs.get('ex_vm_memory')
-        ex_vm_script = kwargs.get('ex_vm_script')
-        ex_vm_fence = kwargs.get('ex_vm_fence', None)
-        ex_network = kwargs.get('ex_network', None)
-        ex_vm_network = kwargs.get('ex_vm_network', None)
-        ex_vm_ipmode = kwargs.get('ex_vm_ipmode', None)
-        ex_deploy = kwargs.get('ex_deploy', True)
-        ex_vdc = kwargs.get('ex_vdc', None)
-        ex_clone_timeout = kwargs.get('ex_clone_timeout',
-                                      DEFAULT_TASK_COMPLETION_TIMEOUT)
-
-        self._validate_vm_names(ex_vm_names)
-        self._validate_vm_cpu(ex_vm_cpu)
-        self._validate_vm_memory(ex_vm_memory)
-        self._validate_vm_fence(ex_vm_fence)
-        self._validate_vm_ipmode(ex_vm_ipmode)
-        ex_vm_script = self._validate_vm_script(ex_vm_script)
-
-        # Some providers don't require a network link
-        if ex_network:
-            network_href = self._get_network_href(ex_network)
-            network_elem = self.connection.request(
-                get_url_path(network_href)).object
-        else:
-            network_elem = None
-
-        vdc = self._get_vdc(ex_vdc)
-
-        if self._is_node(image):
-            vapp_name, vapp_href = self._clone_node(name,
-                                                    image,
-                                                    vdc,
-                                                    ex_clone_timeout)
-        else:
-            vapp_name, vapp_href = self._instantiate_node(name, image,
-                                                          network_elem,
-                                                          vdc, ex_vm_network,
-                                                          ex_vm_fence,
-                                                          ex_clone_timeout)
-
-        self._change_vm_names(vapp_href, ex_vm_names)
-        self._change_vm_cpu(vapp_href, ex_vm_cpu)
-        self._change_vm_memory(vapp_href, ex_vm_memory)
-        self._change_vm_script(vapp_href, ex_vm_script)
-        self._change_vm_ipmode(vapp_href, ex_vm_ipmode)
-
-        # Power on the VM.
-        if ex_deploy:
-            # Retry 3 times: when instantiating large number of VMs at the same
-            # time some may fail on resource allocation
-            retry = 3
-            while True:
-                try:
-                    res = self.connection.request(
-                        '%s/power/action/powerOn' % get_url_path(vapp_href),
-                        method='POST')
-                    self._wait_for_task_completion(res.object.get('href'))
-                    break
-                except Exception:
-                    if retry <= 0:
-                        raise
-                    retry -= 1
-                    time.sleep(10)
-
-        res = self.connection.request(get_url_path(vapp_href))
-        node = self._to_node(res.object)
-        return node
-
-    def _instantiate_node(self, name, image, network_elem, vdc, vm_network,
-                          vm_fence, instantiate_timeout):
-        instantiate_xml = Instantiate_1_5_VAppXML(
-            name=name,
-            template=image.id,
-            network=network_elem,
-            vm_network=vm_network,
-            vm_fence=vm_fence
-        )
-
-        # Instantiate VM and get identifier.
-        headers = {
-            'Content-Type':
-            'application/vnd.vmware.vcloud.instantiateVAppTemplateParams+xml'
-        }
-        res = self.connection.request(
-            '%s/action/instantiateVAppTemplate' % get_url_path(vdc.id),
-            data=instantiate_xml.tostring(),
-            method='POST',
-            headers=headers
-        )
-        vapp_name = res.object.get('name')
-        vapp_href = res.object.get('href')
-
-        task_href = res.object.find(fixxpath(res.object, "Tasks/Task")).get(
-            'href')
-        self._wait_for_task_completion(task_href, instantiate_timeout)
-        return vapp_name, vapp_href
-
-    def _clone_node(self, name, sourceNode, vdc, clone_timeout):
-        clone_xml = ET.Element(
-            "CloneVAppParams",
-            {'name': name, 'deploy': 'false', 'powerOn': 'false',
-             'xmlns': "http://www.vmware.com/vcloud/v1.5",
-             'xmlns:xsi': "http://www.w3.org/2001/XMLSchema-instance"}
-        )
-        ET.SubElement(clone_xml,
-                      'Description').text = 'Clone of ' + sourceNode.name
-        ET.SubElement(clone_xml, 'Source', {'href': sourceNode.id})
-
-        headers = {
-            'Content-Type': 'application/vnd.vmware.vcloud.cloneVAppParams+xml'
-        }
-        res = self.connection.request(
-            '%s/action/cloneVApp' % get_url_path(vdc.id),
-            data=ET.tostring(clone_xml),
-            method='POST',
-            headers=headers
-        )
-        vapp_name = res.object.get('name')
-        vapp_href = res.object.get('href')
-
-        task_href = res.object.find(
-            fixxpath(res.object, "Tasks/Task")).get('href')
-        self._wait_for_task_completion(task_href, clone_timeout)
-
-        res = self.connection.request(get_url_path(vapp_href))
-
-        vms = res.object.findall(fixxpath(res.object, "Children/Vm"))
-
-        # Fix the networking for VMs
-        for i, vm in enumerate(vms):
-            # Remove network
-            network_xml = ET.Element("NetworkConnectionSection", {
-                'ovf:required': 'false',
-                'xmlns': "http://www.vmware.com/vcloud/v1.5",
-                'xmlns:ovf': 'http://schemas.dmtf.org/ovf/envelope/1'})
-            ET.SubElement(network_xml, "ovf:Info").text = \
-                'Specifies the available VM network connections'
-
-            headers = {
-                'Content-Type':
-                'application/vnd.vmware.vcloud.networkConnectionSection+xml'
-            }
-            res = self.connection.request(
-                '%s/networkConnectionSection' % get_url_path(vm.get('href')),
-                data=ET.tostring(network_xml),
-                method='PUT',
-                headers=headers
-            )
-            self._wait_for_task_completion(res.object.get('href'))
-
-            # Re-add network
-            network_xml = vm.find(fixxpath(vm, 'NetworkConnectionSection'))
-            network_conn_xml = network_xml.find(
-                fixxpath(network_xml, 'NetworkConnection'))
-            network_conn_xml.set('needsCustomization', 'true')
-            network_conn_xml.remove(
-                network_conn_xml.find(fixxpath(network_xml, 'IpAddress')))
-            network_conn_xml.remove(
-                network_conn_xml.find(fixxpath(network_xml, 'MACAddress')))
-
-            headers = {
-                'Content-Type':
-                'application/vnd.vmware.vcloud.networkConnectionSection+xml'
-            }
-            res = self.connection.request(
-                '%s/networkConnectionSection' % get_url_path(vm.get('href')),
-                data=ET.tostring(network_xml),
-                method='PUT',
-                headers=headers
-            )
-            self._wait_for_task_completion(res.object.get('href'))
-
-        return vapp_name, vapp_href
-
-    def ex_set_vm_cpu(self, vapp_or_vm_id, vm_cpu):
-        """
-        Sets the number of virtual CPUs for the specified VM or VMs under
-        the vApp. If the vapp_or_vm_id param represents a link to an vApp
-        all VMs that are attached to this vApp will be modified.
-
-        Please ensure that hot-adding a virtual CPU is enabled for the
-        powered on virtual machines. Otherwise use this method on undeployed
-        vApp.
-
-        :keyword    vapp_or_vm_id: vApp or VM ID that will be modified. If
-                                   a vApp ID is used here all attached VMs
-                                   will be modified
-        :type       vapp_or_vm_id: ``str``
-
-        :keyword    vm_cpu: number of virtual CPUs/cores to allocate for
-                            specified VMs
-        :type       vm_cpu: ``int``
-
-        :rtype: ``None``
-        """
-        self._validate_vm_cpu(vm_cpu)
-        self._change_vm_cpu(vapp_or_vm_id, vm_cpu)
-
-    def ex_set_vm_memory(self, vapp_or_vm_id, vm_memory):
-        """
-        Sets the virtual memory in MB to allocate for the specified VM or
-        VMs under the vApp. If the vapp_or_vm_id param represents a link
-        to an vApp all VMs that are attached to this vApp will be modified.
-
-        Please ensure that hot-change of virtual memory is enabled for the
-        powered on virtual machines. Otherwise use this method on undeployed
-        vApp.
-
-        :keyword    vapp_or_vm_id: vApp or VM ID that will be modified. If
-                                   a vApp ID is used here all attached VMs
-                                   will be modified
-        :type       vapp_or_vm_id: ``str``
-
-        :keyword    vm_memory: virtual memory in MB to allocate for the
-                               specified VM or VMs
-        :type       vm_memory: ``int``
-
-        :rtype: ``None``
-        """
-        self._validate_vm_memory(vm_memory)
-        self._change_vm_memory(vapp_or_vm_id, vm_memory)
-
-    def ex_add_vm_disk(self, vapp_or_vm_id, vm_disk_size):
-        """
-        Adds a virtual disk to the specified VM or VMs under the vApp. If the
-        vapp_or_vm_id param represents a link to an vApp all VMs that are
-        attached to this vApp will be modified.
-
-        :keyword    vapp_or_vm_id: vApp or VM ID that will be modified. If a
-                                   vApp ID is used here all attached VMs
-                                   will be modified
-        :type       vapp_or_vm_id: ``str``
-
-        :keyword    vm_disk_size: the disk capacity in GB that will be added
-                                  to the specified VM or VMs
-        :type       vm_disk_size: ``int``
-
-        :rtype: ``None``
-        """
-        self._validate_vm_disk_size(vm_disk_size)
-        self._add_vm_disk(vapp_or_vm_id, vm_disk_size)
-
-    @staticmethod
-    def _validate_vm_names(names):
-        if names is None:
-            return
-        hname_re = re.compile(
-            '^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9]*)[\-])*([A-Za-z]|[A-Za-z][A-Za-z0-9]*[A-Za-z0-9])$')  # NOQA
-        for name in names:
-            if len(name) > 15:
-                raise ValueError(
-                    'The VM name "' + name + '" is too long for the computer '
-                    'name (max 15 chars allowed).')
-            if not hname_re.match(name):
-                raise ValueError('The VM name "' + name + '" can not be '
-                                 'used. "' + name + '" is not a valid '
-                                 'computer name for the VM.')
-
-    @staticmethod
-    def _validate_vm_memory(vm_memory):
-        if vm_memory is None:
-            return
-        elif vm_memory not in VIRTUAL_MEMORY_VALS:
-            raise ValueError(
-                '%s is not a valid vApp VM memory value' % vm_memory)
-
-    @staticmethod
-    def _validate_vm_cpu(vm_cpu):
-        if vm_cpu is None:
-            return
-        elif vm_cpu not in VIRTUAL_CPU_VALS_1_5:
-            raise ValueError('%s is not a valid vApp VM CPU value' % vm_cpu)
-
-    @staticmethod
-    def _validate_vm_disk_size(vm_disk):
-        if vm_disk is None:
-            return
-        elif int(vm_disk) < 0:
-            raise ValueError('%s is not a valid vApp VM disk space value',
-                             vm_disk)
-
-    @staticmethod
-    def _validate_vm_script(vm_script):
-        if vm_script is None:
-            return
-        # Try to locate the script file
-        if not os.path.isabs(vm_script):
-            vm_script = os.path.expanduser(vm_script)
-            vm_script = os.path.abspath(vm_script)
-        if not os.path.isfile(vm_script):
-            raise LibcloudError(
-                "%s the VM script file does not exist" % vm_script)
-        try:
-            open(vm_script).read()
-        except:
-            raise
-        return vm_script
-
-    @staticmethod
-    def _validate_vm_fence(vm_fence):
-        if vm_fence is None:
-            return
-        elif vm_fence not in FENCE_MODE_VALS_1_5:
-            raise ValueError('%s is not a valid fencing mode value' % vm_fence)
-
-    @staticmethod
-    def _validate_vm_ipmode(vm_ipmode):
-        if vm_ipmode is None:
-            return
-        elif vm_ipmode == 'MANUAL':
-            raise NotImplementedError(
-                'MANUAL IP mode: The interface for supplying '
-                'IPAddress does not exist yet')
-        elif vm_ipmode not in IP_MODE_VALS_1_5:
-            raise ValueError(
-                '%s is not a valid IP address allocation mode value'
-                % vm_ipmode)
-
-    def _change_vm_names(self, vapp_or_vm_id, vm_names):
-        if vm_names is None:
-            return
-
-        vms = self._get_vm_elements(vapp_or_vm_id)
-        for i, vm in enumerate(vms):
-            if len(vm_names) <= i:
-                return
-
-            # Get GuestCustomizationSection
-            res = self.connection.request(
-                '%s/guestCustomizationSection' % get_url_path(vm.get('href')))
-
-            # Update GuestCustomizationSection
-            res.object.find(
-                fixxpath(res.object, 'ComputerName')).text = vm_names[i]
-            # Remove AdminPassword from customization section
-            admin_pass = res.object.find(fixxpath(res.object, 'AdminPassword'))
-            if admin_pass is not None:
-                res.object.remove(admin_pass)
-
-            headers = {
-                'Content-Type':
-                'application/vnd.vmware.vcloud.guestCustomizationSection+xml'
-            }
-            res = self.connection.request(
-                '%s/guestCustomizationSection' % get_url_path(vm.get('href')),
-                data=ET.tostring(res.object),
-                method='PUT',
-                headers=headers
-            )
-            self._wait_for_task_completion(res.object.get('href'))
-
-            # Update Vm name
-            req_xml = ET.Element("Vm", {
-                'name': vm_names[i],
-                'xmlns': "http://www.vmware.com/vcloud/v1.5"})
-            res = self.connection.request(
-                get_url_path(vm.get('href')),
-                data=ET.tostring(req_xml),
-                method='PUT',
-                headers={
-                    'Content-Type': 'application/vnd.vmware.vcloud.vm+xml'}
-            )
-            self._wait_for_task_completion(res.object.get('href'))
-
-    def _change_vm_cpu(self, vapp_or_vm_id, vm_cpu):
-        if vm_cpu is None:
-            return
-
-        vms = self._get_vm_elements(vapp_or_vm_id)
-        for vm in vms:
-            # Get virtualHardwareSection/cpu section
-            res = self.connection.request(
-                '%s/virtualHardwareSection/cpu' % get_url_path(vm.get('href')))
-
-            # Update VirtualQuantity field
-            xpath = ('{http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/'
-                     'CIM_ResourceAllocationSettingData}VirtualQuantity')
-            res.object.find(xpath).text = str(vm_cpu)
-
-            headers = {
-                'Content-Type': 'application/vnd.vmware.vcloud.rasdItem+xml'
-            }
-            res = self.connection.request(
-                '%s/virtualHardwareSection/cpu' % get_url_path(vm.get('href')),
-                data=ET.tostring(res.object),
-                method='PUT',
-                headers=headers
-            )
-            self._wait_for_task_completion(res.object.get('href'))
-
-    def _change_vm_memory(self, vapp_or_vm_id, vm_memory):
-        if vm_memory is None:
-            return
-
-        vms = self._get_vm_elements(vapp_or_vm_id)
-        for vm in vms:
-            # Get virtualHardwareSection/memory section
-            res = self.connection.request(
-                '%s/virtualHardwareSection/memory' %
-                get_url_path(vm.get('href')))
-
-            # Update VirtualQuantity field
-            xpath = ('{http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/'
-                     'CIM_ResourceAllocationSettingData}VirtualQuantity')
-            res.object.find(xpath).text = str(vm_memory)
-
-            headers = {
-                'Content-Type': 'application/vnd.vmware.vcloud.rasdItem+xml'
-            }
-            res = self.connection.request(
-                '%s/virtualHardwareSection/memory' % get_url_path(
-                    vm.get('href')),
-                data=ET.tostring(res.object),
-                method='PUT',
-                headers=headers
-            )
-            self._wait_for_task_completion(res.object.get('href'))
-
-    def _add_vm_disk(self, vapp_or_vm_id, vm_disk):
-        if vm_disk is None:
-            return
-
-        rasd_ns = ('{http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/'
-                   'CIM_ResourceAllocationSettingData}')
-
-        vms = self._get_vm_elements(vapp_or_vm_id)
-        for vm in vms:
-            # Get virtualHardwareSection/disks section
-            res = self.connection.request(
-                '%s/virtualHardwareSection/disks' %
-                get_url_path(vm.get('href')))
-
-            existing_ids = []
-            new_disk = None
-            for item in res.object.findall(fixxpath(res.object, 'Item')):
-                # Clean Items from unnecessary stuff
-                for elem in item:
-                    if elem.tag == '%sInstanceID' % rasd_ns:
-                        existing_ids.append(int(elem.text))
-                    if elem.tag in ['%sAddressOnParent' % rasd_ns,
-                                    '%sParent' % rasd_ns]:
-                        item.remove(elem)
-                if item.find('%sHostResource' % rasd_ns) is not None:
-                    new_disk = item
-
-            new_disk = copy.deepcopy(new_disk)
-            disk_id = max(existing_ids) + 1
-            new_disk.find('%sInstanceID' % rasd_ns).text = str(disk_id)
-            new_disk.find('%sElementName' %
-                          rasd_ns).text = 'Hard Disk ' + str(disk_id)
-            new_disk.find('%sHostResource' % rasd_ns).set(
-                fixxpath(new_disk, 'capacity'), str(int(vm_disk) * 1024))
-            res.object.append(new_disk)
-
-            headers = {
-                'Content-Type':
-                'application/vnd.vmware.vcloud.rasditemslist+xml'
-            }
-            res = self.connection.request(
-                '%s/virtualHardwareSection/disks' % get_url_path(
-                    vm.get('href')),
-                data=ET.tostring(res.object),
-                method='PUT',
-                headers=headers
-            )
-            self._wait_for_task_completion(res.object.get('href'))
-
-    def _change_vm_script(self, vapp_or_vm_id, vm_script):
-        if vm_script is None:
-            return
-
-        vms = self._get_vm_elements(vapp_or_vm_id)
-        try:
-            script = open(vm_script).read()
-        except:
-            return
-
-        # ElementTree escapes script characters automatically. Escape
-        # requirements:
-        # http://www.vmware.com/support/vcd/doc/rest-api-doc-1.5-html/types/
-        # GuestCustomizationSectionType.html
-        for vm in vms:
-            # Get GuestCustomizationSection
-            res = self.connection.request(
-                '%s/guestCustomizationSection' % get_url_path(vm.get('href')))
-
-            # Attempt to update any existing CustomizationScript element
-            try:
-                res.object.find(
-                    fixxpath(res.object, 'CustomizationScript')).text = script
-            except:
-                # CustomizationScript section does not exist, insert it just
-                # before ComputerName
-                for i, e in enumerate(res.object):
-                    if e.tag == \
-                            '{http://www.vmware.com/vcloud/v1.5}ComputerName':
-                        break
-                e = ET.Element(
-                    '{http://www.vmware.com/vcloud/v1.5}CustomizationScript')
-                e.text = script
-                res.object.insert(i, e)
-
-            # Remove AdminPassword from customization section due to an API
-            # quirk
-            admin_pass = res.object.find(fixxpath(res.object, 'AdminPassword'))
-            if admin_pass is not None:
-                res.object.remove(admin_pass)
-
-            # Update VM's GuestCustomizationSection
-            headers = {
-                'Content-Type':
-                'application/vnd.vmware.vcloud.guestCustomizationSection+xml'
-            }
-            res = self.connection.request(
-                '%s/guestCustomizationSection' % get_url_path(vm.get('href')),
-                data=ET.tostring(res.object),
-                method='PUT',
-                headers=headers
-            )
-            self._wait_for_task_completion(res.object.get('href'))
-
-    def _change_vm_ipmode(self, vapp_or_vm_id, vm_ipmode):
-        if vm_ipmode is None:
-            return
-
-        vms = self._get_vm_elements(vapp_or_vm_id)
-
-        for vm in vms:
-            res = self.connection.request(
-                '%s/networkConnectionSection' % get_url_path(vm.get('href')))
-            net_conns = res.object.findall(
-                fixxpath(res.object, 'NetworkConnection'))
-            for c in net_conns:
-                c.find(fixxpath(c, 'IpAddressAllocationMode')).text = vm_ipmode
-
-            headers = {
-                'Content-Type':
-                'application/vnd.vmware.vcloud.networkConnectionSection+xml'
-            }
-
-            res = self.connection.request(
-                '%s/networkConnectionSection' % get_url_path(vm.get('href')),
-                data=ET.tostring(res.object),
-                method='PUT',
-                headers=headers
-            )
-            self._wait_for_task_completion(res.object.get('href'))
-
-    def _get_network_href(self, network_name):
-        network_href = None
-
-        # Find the organisation's network href
-        res = self.connection.request(self.org)
-        links = res.object.findall(fixxpath(res.object, 'Link'))
-        for l in links:
-            if l.attrib['type'] == \
-                    'application/vnd.vmware.vcloud.orgNetwork+xml' \
-                    and l.attrib['name'] == network_name:
-                network_href = l.attrib['href']
-
-        if network_href is None:
-            raise ValueError(
-                '%s is not a valid organisation network name' % network_name)
-        else:
-            return network_href
-
-    def _get_vm_elements(self, vapp_or_vm_id):
-        res = self.connection.request(get_url_path(vapp_or_vm_id))
-        if res.object.tag.endswith('VApp'):
-            vms = res.object.findall(fixxpath(res.object, 'Children/Vm'))
-        elif res.object.tag.endswith('Vm'):
-            vms = [res.object]
-        else:
-            raise ValueError(
-                'Specified ID value is not a valid VApp or Vm identifier.')
-        return vms
-
-    def _is_node(self, node_or_image):
-        return isinstance(node_or_image, Node)
-
-    def _to_node(self, node_elm):
-        # Parse snapshots and VMs as extra
-        if node_elm.find(fixxpath(node_elm, "SnapshotSection")) is None:
-            snapshots = None
-        else:
-            snapshots = []
-            for snapshot_elem in node_elm.findall(
-                    fixxpath(node_elm, 'SnapshotSection/Snapshot')):
-                snapshots.append({
-                    "created": snapshot_elem.get("created"),
-                    "poweredOn": snapshot_elem.get("poweredOn"),
-                    "size": snapshot_elem.get("size"),
-                })
-
-        vms = []
-        for vm_elem in node_elm.findall(fixxpath(node_elm, 'Children/Vm')):
-            public_ips = []
-            private_ips = []
-
-            xpath = fixxpath(vm_elem,
-                             'NetworkConnectionSection/NetworkConnection')
-            for connection in vm_elem.findall(xpath):
-                ip = connection.find(fixxpath(connection, "IpAddress"))
-                if ip is not None:
-                    private_ips.append(ip.text)
-                external_ip = connection.find(
-                    fixxpath(connection, "ExternalIpAddress"))
-                if external_ip is not None:
-                    public_ips.append(external_ip.text)
-                elif ip is not None:
-                    public_ips.append(ip.text)
-
-            xpath = ('{http://schemas.dmtf.org/ovf/envelope/1}'
-                     'OperatingSystemSection')
-            os_type_elem = vm_elem.find(xpath)
-            if os_type_elem is not None:
-                os_type = os_type_elem.get(
-                    '{http://www.vmware.com/schema/ovf}osType')
-            else:
-                os_type = None
-            vm = {
-                'id': vm_elem.get('href'),
-                'name': vm_elem.get('name'),
-                'state': self.NODE_STATE_MAP[vm_elem.get('status')],
-                'public_ips': public_ips,
-                'private_ips': private_ips,
-                'os_type': os_type
-            }
-            vms.append(vm)
-
-        # Take the node IP addresses from all VMs
-        public_ips = []
-        private_ips = []
-        for vm in vms:
-            public_ips.extend(vm['public_ips'])
-            private_ips.extend(vm['private_ips'])
-
-        # Find vDC
-        vdc_id = next(link.get('href') for link
-                      in node_elm.findall(fixxpath(node_elm, 'Link'))
-                      if link.get('type') ==
-                      'application/vnd.vmware.vcloud.vdc+xml')
-        vdc = next(vdc for vdc in self.vdcs if vdc.id == vdc_id)
-
-        extra = {'vdc': vdc.name, 'vms': vms}
-        if snapshots is not None:
-            extra['snapshots'] = snapshots
-
-        node = Node(id=node_elm.get('href'),
-                    name=node_elm.get('name'),
-                    state=self.NODE_STATE_MAP[node_elm.get('status')],
-                    public_ips=public_ips,
-                    private_ips=private_ips,
-                    driver=self.connection.driver,
-                    extra=extra)
-        return node
-
-    def _to_vdc(self, vdc_elm):
-
-        def get_capacity_values(capacity_elm):
-            if capacity_elm is None:
-                return None
-            limit = int(capacity_elm.findtext(fixxpath(capacity_elm, 'Limit')))
-            used = int(capacity_elm.findtext(fixxpath(capacity_elm, 'Used')))
-            units = capacity_elm.findtext(fixxpath(capacity_elm, 'Units'))
-            return Capacity(limit, used, units)
-
-        cpu = get_capacity_values(
-            vdc_elm.find(fixxpath(vdc_elm, 'ComputeCapacity/Cpu')))
-        memory = get_capacity_values(
-            vdc_elm.find(fixxpath(vdc_elm, 'ComputeCapacity/Memory')))
-        storage = get_capacity_values(
-            vdc_elm.find(fixxpath(vdc_elm, 'StorageCapacity')))
-
-        return Vdc(id=vdc_elm.get('href'),
-                   name=vdc_elm.get('name'),
-                   driver=self,
-                   allocation_model=vdc_elm.findtext(
-                       fixxpath(vdc_elm, 'AllocationModel')),
-                   cpu=cpu,
-                   memory=memory,
-                   storage=storage)
-
-
-class VCloud_5_1_NodeDriver(VCloud_1_5_NodeDriver):
-
-    @staticmethod
-    def _validate_vm_memory(vm_memory):
-        if vm_memory is None:
-            return None
-        elif (vm_memory % 4) != 0:
-            # The vcd 5.1 virtual machine memory size must be a multiple of 4
-            # MB
-            raise ValueError(
-                '%s is not a valid vApp VM memory value' % (vm_memory))
-
-
-class VCloud_5_5_NodeDriver(VCloud_5_1_NodeDriver):
-    '''Use 5.5 Connection class to explicitly set 5.5 for the version in
-    Accept headers
-    '''
-    connectionCls = VCloud_5_5_Connection
-
-    def ex_create_snapshot(self, node):
-        """
-        Creates new snapshot of a virtual machine or of all
-        the virtual machines in a vApp. Prior to creation of the new
-        snapshots, any existing user created snapshots associated
-        with the virtual machines are removed.
-
-        :param  node: node
-        :type   node: :class:`Node`
-
-        :rtype: :class:`Node`
-        """
-        snapshot_xml = ET.Element(
-            "CreateSnapshotParams",
-            {'memory': 'true',
-             'name': 'name',
-             'quiesce': 'true',
-             'xmlns': "http://www.vmware.com/vcloud/v1.5",
-             'xmlns:xsi': "http://www.w3.org/2001/XMLSchema-instance"}
-        )
-        ET.SubElement(snapshot_xml, 'Description').text = 'Description'
-        content_type = 'application/vnd.vmware.vcloud.createSnapshotParams+xml'
-        headers = {
-            'Content-Type': content_type
-        }
-        return self._perform_snapshot_operation(node,
-                                                "createSnapshot",
-                                                snapshot_xml,
-                                                headers)
-
-    def ex_remove_snapshots(self, node):
-        """
-        Removes all user created snapshots for a vApp or virtual machine.
-
-        :param  node: node
-        :type   node: :class:`Node`
-
-        :rtype: :class:`Node`
-        """
-        return self._perform_snapshot_operation(node,
-                                                "removeAllSnapshots",
-                                                None,
-                                                None)
-
-    def ex_revert_to_snapshot(self, node):
-        """
-        Reverts a vApp or virtual machine to the current snapshot, if any.
-
-        :param  node: node
-        :type   node: :class:`Node`
-
-        :rtype: :class:`Node`
-        """
-        return self._perform_snapshot_operation(node,
-                                                "revertToCurrentSnapshot",
-                                                None,
-                                                None)
-
-    def _perform_snapshot_operation(self, node, operation, xml_data, headers):
-        res = self.connection.request(
-            '%s/action/%s' % (get_url_path(node.id), operation),
-            data=ET.tostring(xml_data) if xml_data else None,
-            method='POST',
-            headers=headers)
-        self._wait_for_task_completion(res.object.get('href'))
-        res = self.connection.request(get_url_path(node.id))
-        return self._to_node(res.object)
-
-    def ex_acquire_mks_ticket(self, vapp_or_vm_id, vm_num=0):
-        """
-        Retrieve a mks ticket that you can use to gain access to the console
-        of a running VM. If successful, returns a dict with the following
-        keys:
-
-          - host: host (or proxy) through which the console connection
-                is made
-          - vmx: a reference to the VMX file of the VM for which this
-               ticket was issued
-          - ticket: screen ticket to use to authenticate the client
-          - port: host port to be used for console access
-
-        :param  vapp_or_vm_id: vApp or VM ID you want to connect to.
-        :type   vapp_or_vm_id: ``str``
-
-        :param  vm_num: If a vApp ID is provided, vm_num is position in the
-                vApp VM list of the VM you want to get a screen ticket.
-                Default is 0.
-        :type   vm_num: ``int``
-
-        :rtype: ``dict``
-        """
-        vm = self._get_vm_elements(vapp_or_vm_id)[vm_num]
-        try:
-            res = self.connection.request('%s/screen/action/acquireMksTicket' %
-                                          (get_url_path(vm.get('href'))),
-                                          method='POST')
-            output = {
-                "host": res.object.find(fixxpath(res.object, 'Host')).text,
-                "vmx": res.object.find(fixxpath(res.object, 'Vmx')).text,
-                "ticket": res.object.find(fixxpath(res.object, 'Ticket')).text,
-                "port": res.object.find(fixxpath(res.object, 'Port')).text,
-            }
-            return output
-        except:
-            return None


[41/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/aws.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/aws.py b/apache-libcloud-1.0.0rc2/libcloud/common/aws.py
deleted file mode 100644
index 74922a6..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/aws.py
+++ /dev/null
@@ -1,426 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 base64
-from datetime import datetime
-import hashlib
-import hmac
-import time
-from hashlib import sha256
-
-try:
-    import simplejson as json
-except ImportError:
-    import json
-
-try:
-    from lxml import etree as ET
-except ImportError:
-    from xml.etree import ElementTree as ET
-
-from libcloud.common.base import ConnectionUserAndKey, XmlResponse, BaseDriver
-from libcloud.common.base import JsonResponse
-from libcloud.common.types import InvalidCredsError, MalformedResponseError
-from libcloud.utils.py3 import b, httplib, urlquote
-from libcloud.utils.xml import findtext, findall
-
-__all__ = [
-    'AWSBaseResponse',
-    'AWSGenericResponse',
-
-    'AWSTokenConnection',
-    'SignedAWSConnection',
-
-    'AWSRequestSignerAlgorithmV2',
-    'AWSRequestSignerAlgorithmV4',
-
-    'AWSDriver'
-]
-
-DEFAULT_SIGNATURE_VERSION = '2'
-UNSIGNED_PAYLOAD = 'UNSIGNED-PAYLOAD'
-
-
-class AWSBaseResponse(XmlResponse):
-    namespace = None
-
-    def _parse_error_details(self, element):
-        """
-        Parse code and message from the provided error element.
-
-        :return: ``tuple`` with two elements: (code, message)
-        :rtype: ``tuple``
-        """
-        code = findtext(element=element, xpath='Code',
-                        namespace=self.namespace)
-        message = findtext(element=element, xpath='Message',
-                           namespace=self.namespace)
-
-        return code, message
-
-
-class AWSGenericResponse(AWSBaseResponse):
-    # There are multiple error messages in AWS, but they all have an Error node
-    # with Code and Message child nodes. Xpath to select them
-    # None if the root node *is* the Error node
-    xpath = None
-
-    # This dict maps <Error><Code>CodeName</Code></Error> to a specific
-    # exception class that is raised immediately.
-    # If a custom exception class is not defined, errors are accumulated and
-    # returned from the parse_error method.
-    expections = {}
-
-    def success(self):
-        return self.status in [httplib.OK, httplib.CREATED, httplib.ACCEPTED]
-
-    def parse_error(self):
-        context = self.connection.context
-        status = int(self.status)
-
-        # FIXME: Probably ditch this as the forbidden message will have
-        # corresponding XML.
-        if status == httplib.FORBIDDEN:
-            if not self.body:
-                raise InvalidCredsError(str(self.status) + ': ' + self.error)
-            else:
-                raise InvalidCredsError(self.body)
-
-        try:
-            body = ET.XML(self.body)
-        except Exception:
-            raise MalformedResponseError('Failed to parse XML',
-                                         body=self.body,
-                                         driver=self.connection.driver)
-
-        if self.xpath:
-            errs = findall(element=body, xpath=self.xpath,
-                           namespace=self.namespace)
-        else:
-            errs = [body]
-
-        msgs = []
-        for err in errs:
-            code, message = self._parse_error_details(element=err)
-            exceptionCls = self.exceptions.get(code, None)
-
-            if exceptionCls is None:
-                msgs.append('%s: %s' % (code, message))
-                continue
-
-            # Custom exception class is defined, immediately throw an exception
-            params = {}
-            if hasattr(exceptionCls, 'kwargs'):
-                for key in exceptionCls.kwargs:
-                    if key in context:
-                        params[key] = context[key]
-
-            raise exceptionCls(value=message, driver=self.connection.driver,
-                               **params)
-
-        return "\n".join(msgs)
-
-
-class AWSTokenConnection(ConnectionUserAndKey):
-    def __init__(self, user_id, key, secure=True,
-                 host=None, port=None, url=None, timeout=None, proxy_url=None,
-                 token=None, retry_delay=None, backoff=None):
-        self.token = token
-        super(AWSTokenConnection, self).__init__(user_id, key, secure=secure,
-                                                 host=host, port=port, url=url,
-                                                 timeout=timeout,
-                                                 retry_delay=retry_delay,
-                                                 backoff=backoff,
-                                                 proxy_url=proxy_url)
-
-    def add_default_params(self, params):
-        # Even though we are adding it to the headers, we need it here too
-        # so that the token is added to the signature.
-        if self.token:
-            params['x-amz-security-token'] = self.token
-        return super(AWSTokenConnection, self).add_default_params(params)
-
-    def add_default_headers(self, headers):
-        if self.token:
-            headers['x-amz-security-token'] = self.token
-        return super(AWSTokenConnection, self).add_default_headers(headers)
-
-
-class AWSRequestSigner(object):
-    """
-    Class which handles signing the outgoing AWS requests.
-    """
-
-    def __init__(self, access_key, access_secret, version, connection):
-        """
-        :param access_key: Access key.
-        :type access_key: ``str``
-
-        :param access_secret: Access secret.
-        :type access_secret: ``str``
-
-        :param version: API version.
-        :type version: ``str``
-
-        :param connection: Connection instance.
-        :type connection: :class:`Connection`
-        """
-        self.access_key = access_key
-        self.access_secret = access_secret
-        self.version = version
-        # TODO: Remove cycling dependency between connection and signer
-        self.connection = connection
-
-    def get_request_params(self, params, method='GET', path='/'):
-        return params
-
-    def get_request_headers(self, params, headers, method='GET', path='/',
-                            data=None):
-        return params, headers
-
-
-class AWSRequestSignerAlgorithmV2(AWSRequestSigner):
-    def get_request_params(self, params, method='GET', path='/'):
-        params['SignatureVersion'] = '2'
-        params['SignatureMethod'] = 'HmacSHA256'
-        params['AWSAccessKeyId'] = self.access_key
-        params['Version'] = self.version
-        params['Timestamp'] = time.strftime('%Y-%m-%dT%H:%M:%SZ',
-                                            time.gmtime())
-        params['Signature'] = self._get_aws_auth_param(
-            params=params,
-            secret_key=self.access_secret,
-            path=path)
-        return params
-
-    def _get_aws_auth_param(self, params, secret_key, path='/'):
-        """
-        Creates the signature required for AWS, per
-        http://bit.ly/aR7GaQ [docs.amazonwebservices.com]:
-
-        StringToSign = HTTPVerb + "\n" +
-                       ValueOfHostHeaderInLowercase + "\n" +
-                       HTTPRequestURI + "\n" +
-                       CanonicalizedQueryString <from the preceding step>
-        """
-        connection = self.connection
-
-        keys = list(params.keys())
-        keys.sort()
-        pairs = []
-        for key in keys:
-            value = str(params[key])
-            pairs.append(urlquote(key, safe='') + '=' +
-                         urlquote(value, safe='-_~'))
-
-        qs = '&'.join(pairs)
-
-        hostname = connection.host
-        if (connection.secure and connection.port != 443) or \
-           (not connection.secure and connection.port != 80):
-            hostname += ':' + str(connection.port)
-
-        string_to_sign = '\n'.join(('GET', hostname, path, qs))
-
-        b64_hmac = base64.b64encode(
-            hmac.new(b(secret_key), b(string_to_sign),
-                     digestmod=sha256).digest()
-        )
-
-        return b64_hmac.decode('utf-8')
-
-
-class AWSRequestSignerAlgorithmV4(AWSRequestSigner):
-    def get_request_params(self, params, method='GET', path='/'):
-        if method == 'GET':
-            params['Version'] = self.version
-        return params
-
-    def get_request_headers(self, params, headers, method='GET', path='/',
-                            data=None):
-        now = datetime.utcnow()
-        headers['X-AMZ-Date'] = now.strftime('%Y%m%dT%H%M%SZ')
-        headers['X-AMZ-Content-SHA256'] = self._get_payload_hash(method, data)
-        headers['Authorization'] = \
-            self._get_authorization_v4_header(params=params, headers=headers,
-                                              dt=now, method=method, path=path,
-                                              data=data)
-
-        return params, headers
-
-    def _get_authorization_v4_header(self, params, headers, dt, method='GET',
-                                     path='/', data=None):
-        credentials_scope = self._get_credential_scope(dt=dt)
-        signed_headers = self._get_signed_headers(headers=headers)
-        signature = self._get_signature(params=params, headers=headers,
-                                        dt=dt, method=method, path=path,
-                                        data=data)
-
-        return 'AWS4-HMAC-SHA256 Credential=%(u)s/%(c)s, ' \
-               'SignedHeaders=%(sh)s, Signature=%(s)s' % {
-                   'u': self.access_key,
-                   'c': credentials_scope,
-                   'sh': signed_headers,
-                   's': signature
-               }
-
-    def _get_signature(self, params, headers, dt, method, path, data):
-        key = self._get_key_to_sign_with(dt)
-        string_to_sign = self._get_string_to_sign(params=params,
-                                                  headers=headers, dt=dt,
-                                                  method=method, path=path,
-                                                  data=data)
-        return _sign(key=key, msg=string_to_sign, hex=True)
-
-    def _get_key_to_sign_with(self, dt):
-        return _sign(
-            _sign(
-                _sign(
-                    _sign(('AWS4' + self.access_secret),
-                          dt.strftime('%Y%m%d')),
-                    self.connection.driver.region_name),
-                self.connection.service_name),
-            'aws4_request')
-
-    def _get_string_to_sign(self, params, headers, dt, method, path, data):
-        canonical_request = self._get_canonical_request(params=params,
-                                                        headers=headers,
-                                                        method=method,
-                                                        path=path,
-                                                        data=data)
-
-        return '\n'.join(['AWS4-HMAC-SHA256',
-                          dt.strftime('%Y%m%dT%H%M%SZ'),
-                          self._get_credential_scope(dt),
-                          _hash(canonical_request)])
-
-    def _get_credential_scope(self, dt):
-        return '/'.join([dt.strftime('%Y%m%d'),
-                         self.connection.driver.region_name,
-                         self.connection.service_name,
-                         'aws4_request'])
-
-    def _get_signed_headers(self, headers):
-        return ';'.join([k.lower() for k in sorted(headers.keys())])
-
-    def _get_canonical_headers(self, headers):
-        return '\n'.join([':'.join([k.lower(), str(v).strip()])
-                          for k, v in sorted(headers.items())]) + '\n'
-
-    def _get_payload_hash(self, method, data=None):
-        if method in ('POST', 'PUT'):
-            if data:
-                return _hash(data)
-            else:
-                # When upload file, we can't know payload here even if given
-                return UNSIGNED_PAYLOAD
-        else:
-            return _hash('')
-
-    def _get_request_params(self, params):
-        # For self.method == GET
-        return '&'.join(["%s=%s" %
-                         (urlquote(k, safe=''), urlquote(str(v), safe='~'))
-                         for k, v in sorted(params.items())])
-
-    def _get_canonical_request(self, params, headers, method, path, data):
-        return '\n'.join([
-            method,
-            path,
-            self._get_request_params(params),
-            self._get_canonical_headers(headers),
-            self._get_signed_headers(headers),
-            self._get_payload_hash(method, data)
-        ])
-
-
-class SignedAWSConnection(AWSTokenConnection):
-    def __init__(self, user_id, key, secure=True, host=None, port=None,
-                 url=None, timeout=None, proxy_url=None, token=None,
-                 retry_delay=None, backoff=None,
-                 signature_version=DEFAULT_SIGNATURE_VERSION):
-        super(SignedAWSConnection, self).__init__(user_id=user_id, key=key,
-                                                  secure=secure, host=host,
-                                                  port=port, url=url,
-                                                  timeout=timeout, token=token,
-                                                  retry_delay=retry_delay,
-                                                  backoff=backoff,
-                                                  proxy_url=proxy_url)
-        self.signature_version = str(signature_version)
-
-        if self.signature_version == '2':
-            signer_cls = AWSRequestSignerAlgorithmV2
-        elif self.signature_version == '4':
-            signer_cls = AWSRequestSignerAlgorithmV4
-        else:
-            raise ValueError('Unsupported signature_version: %s' %
-                             (signature_version))
-
-        self.signer = signer_cls(access_key=self.user_id,
-                                 access_secret=self.key,
-                                 version=self.version,
-                                 connection=self)
-
-    def add_default_params(self, params):
-        params = self.signer.get_request_params(params=params,
-                                                method=self.method,
-                                                path=self.action)
-        return params
-
-    def pre_connect_hook(self, params, headers):
-        params, headers = self.signer.get_request_headers(params=params,
-                                                          headers=headers,
-                                                          method=self.method,
-                                                          path=self.action,
-                                                          data=self.data)
-        return params, headers
-
-
-class AWSJsonResponse(JsonResponse):
-    """
-    Amazon ECS response class.
-    ECS API uses JSON unlike the s3, elb drivers
-    """
-    def parse_error(self):
-        response = json.loads(self.body)
-        code = response['__type']
-        message = response.get('Message', response['message'])
-        return ('%s: %s' % (code, message))
-
-
-def _sign(key, msg, hex=False):
-    if hex:
-        return hmac.new(b(key), b(msg), hashlib.sha256).hexdigest()
-    else:
-        return hmac.new(b(key), b(msg), hashlib.sha256).digest()
-
-
-def _hash(msg):
-    return hashlib.sha256(b(msg)).hexdigest()
-
-
-class AWSDriver(BaseDriver):
-    def __init__(self, key, secret=None, secure=True, host=None, port=None,
-                 api_version=None, region=None, token=None, **kwargs):
-        self.token = token
-        super(AWSDriver, self).__init__(key, secret=secret, secure=secure,
-                                        host=host, port=port,
-                                        api_version=api_version, region=region,
-                                        token=token, **kwargs)
-
-    def _ex_connection_class_kwargs(self):
-        kwargs = super(AWSDriver, self)._ex_connection_class_kwargs()
-        kwargs['token'] = self.token
-        return kwargs

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/azure.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/azure.py b/apache-libcloud-1.0.0rc2/libcloud/common/azure.py
deleted file mode 100644
index bd3c504..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/azure.py
+++ /dev/null
@@ -1,294 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 copy
-import os
-import time
-import base64
-import hmac
-
-from hashlib import sha256
-from libcloud.utils.py3 import httplib
-from libcloud.utils.py3 import b
-from libcloud.utils.xml import fixxpath
-
-try:
-    from lxml import etree as ET
-except ImportError:
-    from xml.etree import ElementTree as ET
-
-from libcloud.common.types import InvalidCredsError
-from libcloud.common.types import LibcloudError, MalformedResponseError
-from libcloud.common.base import ConnectionUserAndKey, RawResponse
-from libcloud.common.base import CertificateConnection
-from libcloud.common.base import XmlResponse
-
-# Azure API version
-API_VERSION = '2012-02-12'
-
-# The time format for headers in Azure requests
-AZURE_TIME_FORMAT = '%a, %d %b %Y %H:%M:%S GMT'
-
-
-class AzureRedirectException(Exception):
-
-    def __init__(self, response):
-        self.location = response.headers['location']
-
-
-class AzureResponse(XmlResponse):
-
-    valid_response_codes = [
-        httplib.NOT_FOUND,
-        httplib.CONFLICT,
-        httplib.BAD_REQUEST,
-        httplib.TEMPORARY_REDIRECT
-        # added TEMPORARY_REDIRECT as this can sometimes be
-        # sent by azure instead of a success or fail response
-    ]
-
-    def success(self):
-        i = int(self.status)
-        return 200 <= i <= 299 or i in self.valid_response_codes
-
-    def parse_error(self, msg=None):
-        error_msg = 'Unknown error'
-
-        try:
-            # Azure does give some meaningful errors, but is inconsistent
-            # Some APIs respond with an XML error. Others just dump HTML
-            body = self.parse_body()
-
-            if type(body) == ET.Element:
-                code = body.findtext(fixxpath(xpath='Code'))
-                message = body.findtext(fixxpath(xpath='Message'))
-                message = message.split('\n')[0]
-                error_msg = '%s: %s' % (code, message)
-
-        except MalformedResponseError:
-            pass
-
-        if msg:
-            error_msg = '%s - %s' % (msg, error_msg)
-
-        if self.status in [httplib.UNAUTHORIZED, httplib.FORBIDDEN]:
-            raise InvalidCredsError(error_msg)
-
-        raise LibcloudError(
-            '%s Status code: %d.' % (error_msg, self.status),
-            driver=self
-        )
-
-    def parse_body(self):
-        is_redirect = int(self.status) == httplib.TEMPORARY_REDIRECT
-
-        if is_redirect and self.connection.driver.follow_redirects:
-            raise AzureRedirectException(self)
-        else:
-            return super(AzureResponse, self).parse_body()
-
-
-class AzureRawResponse(RawResponse):
-    pass
-
-
-class AzureConnection(ConnectionUserAndKey):
-    """
-    Represents a single connection to Azure
-    """
-
-    responseCls = AzureResponse
-    rawResponseCls = AzureRawResponse
-
-    def add_default_params(self, params):
-        return params
-
-    def pre_connect_hook(self, params, headers):
-        headers = copy.deepcopy(headers)
-
-        # We have to add a date header in GMT
-        headers['x-ms-date'] = time.strftime(AZURE_TIME_FORMAT, time.gmtime())
-        headers['x-ms-version'] = API_VERSION
-
-        # Add the authorization header
-        headers['Authorization'] = self._get_azure_auth_signature(
-            method=self.method,
-            headers=headers,
-            params=params,
-            account=self.user_id,
-            secret_key=self.key,
-            path=self.action
-        )
-
-        # Azure cribs about this in 'raw' connections
-        headers.pop('Host', None)
-
-        return params, headers
-
-    def _get_azure_auth_signature(self,
-                                  method,
-                                  headers,
-                                  params,
-                                  account,
-                                  secret_key,
-                                  path='/'):
-        """
-        Signature = Base64( HMAC-SHA1( YourSecretAccessKeyID,
-                            UTF-8-Encoding-Of( StringToSign ) ) ) );
-
-        StringToSign = HTTP-VERB + "\n" +
-            Content-Encoding + "\n" +
-            Content-Language + "\n" +
-            Content-Length + "\n" +
-            Content-MD5 + "\n" +
-            Content-Type + "\n" +
-            Date + "\n" +
-            If-Modified-Since + "\n" +
-            If-Match + "\n" +
-            If-None-Match + "\n" +
-            If-Unmodified-Since + "\n" +
-            Range + "\n" +
-            CanonicalizedHeaders +
-            CanonicalizedResource;
-        """
-        special_header_values = []
-        xms_header_values = []
-        param_list = []
-        special_header_keys = [
-            'content-encoding',
-            'content-language',
-            'content-length',
-            'content-md5',
-            'content-type',
-            'date',
-            'if-modified-since',
-            'if-match',
-            'if-none-match',
-            'if-unmodified-since',
-            'range'
-        ]
-
-        # Split the x-ms headers and normal headers and make everything
-        # lower case
-        headers_copy = {}
-        for header, value in headers.items():
-            header = header.lower()
-            value = str(value).strip()
-            if header.startswith('x-ms-'):
-                xms_header_values.append((header, value))
-            else:
-                headers_copy[header] = value
-
-        # Get the values for the headers in the specific order
-        for header in special_header_keys:
-            header = header.lower()  # Just for safety
-            if header in headers_copy:
-                special_header_values.append(headers_copy[header])
-            else:
-                special_header_values.append('')
-
-        # Prepare the first section of the string to be signed
-        values_to_sign = [method] + special_header_values
-        # string_to_sign = '\n'.join([method] + special_header_values)
-
-        # The x-ms-* headers have to be in lower case and sorted
-        xms_header_values.sort()
-
-        for header, value in xms_header_values:
-            values_to_sign.append('%s:%s' % (header, value))
-
-        # Add the canonicalized path
-        values_to_sign.append('/%s%s' % (account, path))
-
-        # URL query parameters (sorted and lower case)
-        for key, value in params.items():
-            param_list.append((key.lower(), str(value).strip()))
-
-        param_list.sort()
-
-        for key, value in param_list:
-            values_to_sign.append('%s:%s' % (key, value))
-
-        string_to_sign = b('\n'.join(values_to_sign))
-        secret_key = b(secret_key)
-        b64_hmac = base64.b64encode(
-            hmac.new(secret_key, string_to_sign, digestmod=sha256).digest()
-        )
-
-        return 'SharedKey %s:%s' % (self.user_id, b64_hmac.decode('utf-8'))
-
-
-class AzureBaseDriver(object):
-    name = "Microsoft Azure Service Management API"
-
-
-class AzureServiceManagementConnection(CertificateConnection):
-    # This needs the following approach -
-    # 1. Make request using LibcloudHTTPSConnection which is a overloaded
-    # class which takes in a client certificate
-    # 2. Depending on the type of operation use a PollingConnection
-    # when the response id is returned
-    # 3. The Response can be used in an AzureServiceManagementResponse
-
-    """
-    Authentication class for "Service Account" authentication.
-    """
-
-    driver = AzureBaseDriver
-    responseCls = AzureResponse
-    rawResponseCls = AzureRawResponse
-    name = 'Azure Service Management API Connection'
-    host = 'management.core.windows.net'
-    keyfile = ""
-
-    def __init__(self, subscription_id, key_file, *args, **kwargs):
-        """
-        Check to see if PyCrypto is available, and convert key file path into a
-        key string if the key is in a file.
-
-        :param  subscription_id: Azure subscription ID.
-        :type   subscription_id: ``str``
-
-        :param  key_file: The PEM file used to authenticate with the service.
-        :type   key_file: ``str``
-        """
-
-        super(AzureServiceManagementConnection, self).__init__(
-            key_file,
-            *args,
-            **kwargs
-        )
-
-        self.subscription_id = subscription_id
-
-        keypath = os.path.expanduser(key_file)
-        self.keyfile = keypath
-        is_file_path = os.path.exists(keypath) and os.path.isfile(keypath)
-        if not is_file_path:
-            raise InvalidCredsError(
-                'You need an certificate PEM file to authenticate with '
-                'Microsoft Azure. This can be found in the portal.'
-            )
-        self.key_file = key_file
-
-    def add_default_headers(self, headers):
-        """
-        @inherits: :class:`Connection.add_default_headers`
-        TODO: move to constant..
-        """
-        headers['x-ms-version'] = "2014-05-01"
-        headers['x-ms-date'] = time.strftime(AZURE_TIME_FORMAT, time.gmtime())
-        #  headers['host'] = self.host
-        return headers

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/azure_arm.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/azure_arm.py b/apache-libcloud-1.0.0rc2/libcloud/common/azure_arm.py
deleted file mode 100644
index 2611921..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/azure_arm.py
+++ /dev/null
@@ -1,124 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-try:
-    import simplejson as json
-except ImportError:
-    import json
-
-import time
-
-from libcloud.common.base import (ConnectionUserAndKey,
-                                  JsonResponse,
-                                  RawResponse)
-from libcloud.httplib_ssl import LibcloudHTTPSConnection
-from libcloud.utils.py3 import basestring, urlencode
-
-
-class AzureBaseDriver(object):
-    name = "Microsoft Azure Resource Management API"
-
-
-class AzureJsonResponse(JsonResponse):
-    def parse_error(self):
-        b = self.parse_body()
-
-        if isinstance(b, basestring):
-            return b
-        elif isinstance(b, dict) and "error" in b:
-            return "[%s] %s" % (b["error"].get("code"),
-                                b["error"].get("message"))
-        else:
-            return str(b)
-
-
-class AzureAuthJsonResponse(JsonResponse):
-    def parse_error(self):
-        b = self.parse_body()
-
-        if isinstance(b, basestring):
-            return b
-        elif isinstance(b, dict) and "error_description" in b:
-            return b["error_description"]
-        else:
-            return str(b)
-
-
-class AzureResourceManagementConnection(ConnectionUserAndKey):
-    """
-    Represents a single connection to Azure
-    """
-
-    conn_classes = (None, LibcloudHTTPSConnection)
-    driver = AzureBaseDriver
-    name = 'Azure AD Auth'
-    responseCls = AzureJsonResponse
-    rawResponseCls = RawResponse
-    host = 'management.azure.com'
-    login_host = 'login.windows.net'
-    login_resource = 'https://management.core.windows.net/'
-
-    def __init__(self, key, secret, secure=True, tenant_id=None,
-                 subscription_id=None, **kwargs):
-        super(AzureResourceManagementConnection, self) \
-            .__init__(key, secret, **kwargs)
-        self.tenant_id = tenant_id
-        self.subscription_id = subscription_id
-
-    def add_default_headers(self, headers):
-        headers['Content-Type'] = "application/json"
-        headers['Authorization'] = "Bearer %s" % self.access_token
-        return headers
-
-    def encode_data(self, data):
-        """Encode data to JSON"""
-        return json.dumps(data)
-
-    def get_token_from_credentials(self):
-        """
-        Log in and get bearer token used to authorize API requests.
-        """
-
-        conn = self.conn_classes[1](self.login_host, 443)
-        conn.connect()
-        params = urlencode({
-            "grant_type": "client_credentials",
-            "client_id": self.user_id,
-            "client_secret": self.key,
-            "resource": self.login_resource
-        })
-        headers = {"Content-type": "application/x-www-form-urlencoded"}
-        conn.request("POST", "/%s/oauth2/token" % self.tenant_id,
-                     params, headers)
-        js = AzureAuthJsonResponse(conn.getresponse(), conn)
-        self.access_token = js.object["access_token"]
-        self.expires_on = js.object["expires_on"]
-
-    def connect(self, **kwargs):
-        self.get_token_from_credentials()
-        return super(AzureResourceManagementConnection, self).connect(**kwargs)
-
-    def request(self, action, params=None, data=None, headers=None,
-                method='GET', raw=False):
-
-        # Log in again if the token has expired or is going to expire soon
-        # (next 5 minutes).
-        if (time.time() + 300) >= self.expires_on:
-            self.get_token_from_credentials(self)
-
-        return super(AzureResourceManagementConnection, self) \
-            .request(action, params=params,
-                     data=data, headers=headers,
-                     method=method, raw=raw)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/base.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/base.py b/apache-libcloud-1.0.0rc2/libcloud/common/base.py
deleted file mode 100644
index 0cdb257..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/base.py
+++ /dev/null
@@ -1,1179 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 os
-import sys
-import ssl
-import socket
-import copy
-import binascii
-import time
-
-import xml.dom.minidom
-
-try:
-    from lxml import etree as ET
-except ImportError:
-    from xml.etree import ElementTree as ET
-
-from pipes import quote as pquote
-
-try:
-    import simplejson as json
-except:
-    import json
-
-import libcloud
-
-from libcloud.utils.py3 import PY3, PY25
-from libcloud.utils.py3 import httplib
-from libcloud.utils.py3 import urlparse
-from libcloud.utils.py3 import urlencode
-from libcloud.utils.py3 import StringIO
-from libcloud.utils.py3 import u
-from libcloud.utils.py3 import b
-
-from libcloud.utils.misc import lowercase_keys, retry
-from libcloud.utils.compression import decompress_data
-
-from libcloud.common.exceptions import exception_from_message
-from libcloud.common.types import LibcloudError, MalformedResponseError
-from libcloud.httplib_ssl import LibcloudHTTPConnection
-from libcloud.httplib_ssl import LibcloudHTTPSConnection
-
-__all__ = [
-    'RETRY_FAILED_HTTP_REQUESTS',
-
-    'BaseDriver',
-
-    'Connection',
-    'PollingConnection',
-    'ConnectionKey',
-    'ConnectionUserAndKey',
-    'CertificateConnection',
-    'LoggingHTTPConnection',
-    'LoggingHTTPSConnection',
-
-    'Response',
-    'HTTPResponse',
-    'JsonResponse',
-    'XmlResponse',
-    'RawResponse'
-]
-
-# Module level variable indicates if the failed HTTP requests should be retried
-RETRY_FAILED_HTTP_REQUESTS = False
-
-
-class LazyObject(object):
-    """An object that doesn't get initialized until accessed."""
-
-    @classmethod
-    def _proxy(cls, *lazy_init_args, **lazy_init_kwargs):
-        class Proxy(cls, object):
-            _lazy_obj = None
-
-            def __init__(self):
-                # Must override the lazy_cls __init__
-                pass
-
-            def __getattribute__(self, attr):
-                lazy_obj = object.__getattribute__(self, '_get_lazy_obj')()
-                return getattr(lazy_obj, attr)
-
-            def __setattr__(self, attr, value):
-                lazy_obj = object.__getattribute__(self, '_get_lazy_obj')()
-                setattr(lazy_obj, attr, value)
-
-            def _get_lazy_obj(self):
-                lazy_obj = object.__getattribute__(self, '_lazy_obj')
-                if lazy_obj is None:
-                    lazy_obj = cls(*lazy_init_args, **lazy_init_kwargs)
-                    object.__setattr__(self, '_lazy_obj', lazy_obj)
-                return lazy_obj
-
-        return Proxy()
-
-    @classmethod
-    def lazy(cls, *lazy_init_args, **lazy_init_kwargs):
-        """Create a lazily instantiated instance of the subclass, cls."""
-        return cls._proxy(*lazy_init_args, **lazy_init_kwargs)
-
-
-class HTTPResponse(httplib.HTTPResponse):
-    # On python 2.6 some calls can hang because HEAD isn't quite properly
-    # supported.
-    # In particular this happens on S3 when calls are made to get_object to
-    # objects that don't exist.
-    # This applies the behaviour from 2.7, fixing the hangs.
-    def read(self, amt=None):
-        if self.fp is None:
-            return ''
-
-        if self._method == 'HEAD':
-            self.close()
-            return ''
-
-        return httplib.HTTPResponse.read(self, amt)
-
-
-class Response(object):
-    """
-    A base Response class to derive from.
-    """
-
-    status = httplib.OK  # Response status code
-    headers = {}  # Response headers
-    body = None  # Raw response body
-    object = None  # Parsed response body
-
-    error = None  # Reason returned by the server.
-    connection = None  # Parent connection class
-    parse_zero_length_body = False
-
-    def __init__(self, response, connection):
-        """
-        :param response: HTTP response object. (optional)
-        :type response: :class:`httplib.HTTPResponse`
-
-        :param connection: Parent connection object.
-        :type connection: :class:`.Connection`
-        """
-        self.connection = connection
-
-        # http.client In Python 3 doesn't automatically lowercase the header
-        # names
-        self.headers = lowercase_keys(dict(response.getheaders()))
-        self.error = response.reason
-        self.status = response.status
-
-        # This attribute is set when using LoggingConnection.
-        original_data = getattr(response, '_original_data', None)
-
-        if original_data:
-            # LoggingConnection already decompresses data so it can log it
-            # which means we don't need to decompress it here.
-            self.body = response._original_data
-        else:
-            self.body = self._decompress_response(body=response.read(),
-                                                  headers=self.headers)
-
-        if PY3:
-            self.body = b(self.body).decode('utf-8')
-
-        if not self.success():
-            raise exception_from_message(code=self.status,
-                                         message=self.parse_error(),
-                                         headers=self.headers)
-
-        self.object = self.parse_body()
-
-    def parse_body(self):
-        """
-        Parse response body.
-
-        Override in a provider's subclass.
-
-        :return: Parsed body.
-        :rtype: ``str``
-        """
-        return self.body
-
-    def parse_error(self):
-        """
-        Parse the error messages.
-
-        Override in a provider's subclass.
-
-        :return: Parsed error.
-        :rtype: ``str``
-        """
-        return self.body
-
-    def success(self):
-        """
-        Determine if our request was successful.
-
-        The meaning of this can be arbitrary; did we receive OK status? Did
-        the node get created? Were we authenticated?
-
-        :rtype: ``bool``
-        :return: ``True`` or ``False``
-        """
-        return self.status in [httplib.OK, httplib.CREATED]
-
-    def _decompress_response(self, body, headers):
-        """
-        Decompress a response body if it is using deflate or gzip encoding.
-
-        :param body: Response body.
-        :type body: ``str``
-
-        :param headers: Response headers.
-        :type headers: ``dict``
-
-        :return: Decompressed response
-        :rtype: ``str``
-        """
-        encoding = headers.get('content-encoding', None)
-
-        if encoding in ['zlib', 'deflate']:
-            body = decompress_data('zlib', body)
-        elif encoding in ['gzip', 'x-gzip']:
-            body = decompress_data('gzip', body)
-        else:
-            body = body.strip()
-
-        return body
-
-
-class JsonResponse(Response):
-    """
-    A Base JSON Response class to derive from.
-    """
-
-    def parse_body(self):
-        if len(self.body) == 0 and not self.parse_zero_length_body:
-            return self.body
-
-        try:
-            body = json.loads(self.body)
-        except:
-            raise MalformedResponseError(
-                'Failed to parse JSON',
-                body=self.body,
-                driver=self.connection.driver)
-        return body
-
-    parse_error = parse_body
-
-
-class XmlResponse(Response):
-    """
-    A Base XML Response class to derive from.
-    """
-
-    def parse_body(self):
-        if len(self.body) == 0 and not self.parse_zero_length_body:
-            return self.body
-
-        try:
-            body = ET.XML(self.body)
-        except:
-            raise MalformedResponseError('Failed to parse XML',
-                                         body=self.body,
-                                         driver=self.connection.driver)
-        return body
-
-    parse_error = parse_body
-
-
-class RawResponse(Response):
-
-    def __init__(self, connection):
-        """
-        :param connection: Parent connection object.
-        :type connection: :class:`.Connection`
-        """
-        self._status = None
-        self._response = None
-        self._headers = {}
-        self._error = None
-        self._reason = None
-        self.connection = connection
-
-    @property
-    def response(self):
-        if not self._response:
-            response = self.connection.connection.getresponse()
-            self._response, self.body = response, response
-            if not self.success():
-                self.parse_error()
-        return self._response
-
-    @property
-    def status(self):
-        if not self._status:
-            self._status = self.response.status
-        return self._status
-
-    @property
-    def headers(self):
-        if not self._headers:
-            self._headers = lowercase_keys(dict(self.response.getheaders()))
-        return self._headers
-
-    @property
-    def reason(self):
-        if not self._reason:
-            self._reason = self.response.reason
-        return self._reason
-
-
-# TODO: Move this to a better location/package
-class LoggingConnection():
-    """
-    Debug class to log all HTTP(s) requests as they could be made
-    with the curl command.
-
-    :cvar log: file-like object that logs entries are written to.
-    """
-
-    log = None
-    http_proxy_used = False
-
-    def _log_response(self, r):
-        rv = "# -------- begin %d:%d response ----------\n" % (id(self), id(r))
-        ht = ""
-        v = r.version
-        if r.version == 10:
-            v = "HTTP/1.0"
-        if r.version == 11:
-            v = "HTTP/1.1"
-        ht += "%s %s %s\r\n" % (v, r.status, r.reason)
-        body = r.read()
-        for h in r.getheaders():
-            ht += "%s: %s\r\n" % (h[0].title(), h[1])
-        ht += "\r\n"
-
-        # this is evil. laugh with me. ha arharhrhahahaha
-        class fakesock(object):
-            def __init__(self, s):
-                self.s = s
-
-            def makefile(self, *args, **kwargs):
-                if PY3:
-                    from io import BytesIO
-                    cls = BytesIO
-                else:
-                    cls = StringIO
-
-                return cls(b(self.s))
-        rr = r
-        headers = lowercase_keys(dict(r.getheaders()))
-
-        encoding = headers.get('content-encoding', None)
-        content_type = headers.get('content-type', None)
-
-        if encoding in ['zlib', 'deflate']:
-            body = decompress_data('zlib', body)
-        elif encoding in ['gzip', 'x-gzip']:
-            body = decompress_data('gzip', body)
-
-        pretty_print = os.environ.get('LIBCLOUD_DEBUG_PRETTY_PRINT_RESPONSE',
-                                      False)
-
-        if r.chunked:
-            ht += "%x\r\n" % (len(body))
-            ht += body.decode('utf-8')
-            ht += "\r\n0\r\n"
-        else:
-            if pretty_print and content_type == 'application/json':
-                try:
-                    body = json.loads(body.decode('utf-8'))
-                    body = json.dumps(body, sort_keys=True, indent=4)
-                except:
-                    # Invalid JSON or server is lying about content-type
-                    pass
-            elif pretty_print and content_type == 'text/xml':
-                try:
-                    elem = xml.dom.minidom.parseString(body.decode('utf-8'))
-                    body = elem.toprettyxml()
-                except Exception:
-                    # Invalid XML
-                    pass
-
-            ht += u(body)
-
-        if sys.version_info >= (2, 6) and sys.version_info < (2, 7):
-            cls = HTTPResponse
-        else:
-            cls = httplib.HTTPResponse
-
-        rr = cls(sock=fakesock(ht), method=r._method,
-                 debuglevel=r.debuglevel)
-        rr.begin()
-        rv += ht
-        rv += ("\n# -------- end %d:%d response ----------\n"
-               % (id(self), id(r)))
-
-        rr._original_data = body
-        return (rr, rv)
-
-    def _log_curl(self, method, url, body, headers):
-        cmd = ["curl"]
-
-        if self.http_proxy_used:
-            if self.proxy_username and self.proxy_password:
-                proxy_url = 'http://%s:%s@%s:%s' % (self.proxy_username,
-                                                    self.proxy_password,
-                                                    self.proxy_host,
-                                                    self.proxy_port)
-            else:
-                proxy_url = 'http://%s:%s' % (self.proxy_host,
-                                              self.proxy_port)
-            proxy_url = pquote(proxy_url)
-            cmd.extend(['--proxy', proxy_url])
-
-        cmd.extend(['-i'])
-
-        if method.lower() == 'head':
-            # HEAD method need special handling
-            cmd.extend(["--head"])
-        else:
-            cmd.extend(["-X", pquote(method)])
-
-        for h in headers:
-            cmd.extend(["-H", pquote("%s: %s" % (h, headers[h]))])
-
-        cert_file = getattr(self, 'cert_file', None)
-
-        if cert_file:
-            cmd.extend(["--cert", pquote(cert_file)])
-
-        # TODO: in python 2.6, body can be a file-like object.
-        if body is not None and len(body) > 0:
-            cmd.extend(["--data-binary", pquote(body)])
-
-        cmd.extend(["--compress"])
-        cmd.extend([pquote("%s://%s:%d%s" % (self.protocol, self.host,
-                                             self.port, url))])
-        return " ".join(cmd)
-
-
-class LoggingHTTPSConnection(LoggingConnection, LibcloudHTTPSConnection):
-    """
-    Utility Class for logging HTTPS connections
-    """
-
-    protocol = 'https'
-
-    def getresponse(self):
-        r = LibcloudHTTPSConnection.getresponse(self)
-        if self.log is not None:
-            r, rv = self._log_response(r)
-            self.log.write(rv + "\n")
-            self.log.flush()
-        return r
-
-    def request(self, method, url, body=None, headers=None):
-        headers.update({'X-LC-Request-ID': str(id(self))})
-        if self.log is not None:
-            pre = "# -------- begin %d request ----------\n" % id(self)
-            self.log.write(pre +
-                           self._log_curl(method, url, body, headers) + "\n")
-            self.log.flush()
-        return LibcloudHTTPSConnection.request(self, method, url, body,
-                                               headers)
-
-
-class LoggingHTTPConnection(LoggingConnection, LibcloudHTTPConnection):
-    """
-    Utility Class for logging HTTP connections
-    """
-
-    protocol = 'http'
-
-    def getresponse(self):
-        r = LibcloudHTTPConnection.getresponse(self)
-        if self.log is not None:
-            r, rv = self._log_response(r)
-            self.log.write(rv + "\n")
-            self.log.flush()
-        return r
-
-    def request(self, method, url, body=None, headers=None):
-        headers.update({'X-LC-Request-ID': str(id(self))})
-        if self.log is not None:
-            pre = '# -------- begin %d request ----------\n' % id(self)
-            self.log.write(pre +
-                           self._log_curl(method, url, body, headers) + "\n")
-            self.log.flush()
-        return LibcloudHTTPConnection.request(self, method, url,
-                                              body, headers)
-
-
-class Connection(object):
-    """
-    A Base Connection class to derive from.
-    """
-    # conn_classes = (LoggingHTTPSConnection)
-    conn_classes = (LibcloudHTTPConnection, LibcloudHTTPSConnection)
-
-    responseCls = Response
-    rawResponseCls = RawResponse
-    connection = None
-    host = '127.0.0.1'
-    port = 443
-    timeout = None
-    secure = 1
-    driver = None
-    action = None
-    cache_busting = False
-    backoff = None
-    retry_delay = None
-
-    allow_insecure = True
-
-    def __init__(self, secure=True, host=None, port=None, url=None,
-                 timeout=None, proxy_url=None, retry_delay=None, backoff=None):
-        self.secure = secure and 1 or 0
-        self.ua = []
-        self.context = {}
-
-        if not self.allow_insecure and not secure:
-            # TODO: We should eventually switch to whitelist instead of
-            # blacklist approach
-            raise ValueError('Non https connections are not allowed (use '
-                             'secure=True)')
-
-        self.request_path = ''
-
-        if host:
-            self.host = host
-
-        if port is not None:
-            self.port = port
-        else:
-            if self.secure == 1:
-                self.port = 443
-            else:
-                self.port = 80
-
-        if url:
-            (self.host, self.port, self.secure,
-             self.request_path) = self._tuple_from_url(url)
-
-        self.timeout = timeout or self.timeout
-        self.retry_delay = retry_delay
-        self.backoff = backoff
-        self.proxy_url = proxy_url
-
-    def set_http_proxy(self, proxy_url):
-        """
-        Set a HTTP proxy which will be used with this connection.
-
-        :param proxy_url: Proxy URL (e.g. http://<hostname>:<port> without
-                          authentication and
-                          http://<username>:<password>@<hostname>:<port> for
-                          basic auth authentication information.
-        :type proxy_url: ``str``
-        """
-        self.proxy_url = proxy_url
-
-    def set_context(self, context):
-        if not isinstance(context, dict):
-            raise TypeError('context needs to be a dictionary')
-
-        self.context = context
-
-    def reset_context(self):
-        self.context = {}
-
-    def _tuple_from_url(self, url):
-        secure = 1
-        port = None
-        (scheme, netloc, request_path, param,
-         query, fragment) = urlparse.urlparse(url)
-
-        if scheme not in ['http', 'https']:
-            raise LibcloudError('Invalid scheme: %s in url %s' % (scheme, url))
-
-        if scheme == "http":
-            secure = 0
-
-        if ":" in netloc:
-            netloc, port = netloc.rsplit(":")
-            port = int(port)
-
-        if not port:
-            if scheme == "http":
-                port = 80
-            else:
-                port = 443
-
-        host = netloc
-        port = int(port)
-
-        return (host, port, secure, request_path)
-
-    def connect(self, host=None, port=None, base_url=None, **kwargs):
-        """
-        Establish a connection with the API server.
-
-        :type host: ``str``
-        :param host: Optional host to override our default
-
-        :type port: ``int``
-        :param port: Optional port to override our default
-
-        :returns: A connection
-        """
-        # prefer the attribute base_url if its set or sent
-        connection = None
-        secure = self.secure
-
-        if getattr(self, 'base_url', None) and base_url is None:
-            (host, port,
-             secure, request_path) = self._tuple_from_url(self.base_url)
-        elif base_url is not None:
-            (host, port,
-             secure, request_path) = self._tuple_from_url(base_url)
-        else:
-            host = host or self.host
-            port = port or self.port
-
-        # Make sure port is an int
-        port = int(port)
-
-        if not hasattr(kwargs, 'host'):
-            kwargs.update({'host': host})
-
-        if not hasattr(kwargs, 'port'):
-            kwargs.update({'port': port})
-
-        if not hasattr(kwargs, 'key_file') and hasattr(self, 'key_file'):
-            kwargs.update({'key_file': self.key_file})
-
-        if not hasattr(kwargs, 'cert_file') and hasattr(self, 'cert_file'):
-            kwargs.update({'cert_file': self.cert_file})
-
-        #  kwargs = {'host': host, 'port': int(port)}
-
-        # Timeout is only supported in Python 2.6 and later
-        # http://docs.python.org/library/httplib.html#httplib.HTTPConnection
-        if self.timeout and not PY25:
-            kwargs.update({'timeout': self.timeout})
-
-        if self.proxy_url:
-            kwargs.update({'proxy_url': self.proxy_url})
-
-        connection = self.conn_classes[secure](**kwargs)
-        # You can uncoment this line, if you setup a reverse proxy server
-        # which proxies to your endpoint, and lets you easily capture
-        # connections in cleartext when you setup the proxy to do SSL
-        # for you
-        # connection = self.conn_classes[False]("127.0.0.1", 8080)
-
-        self.connection = connection
-
-    def _user_agent(self):
-        user_agent_suffix = ' '.join(['(%s)' % x for x in self.ua])
-
-        if self.driver:
-            user_agent = 'libcloud/%s (%s) %s' % (
-                libcloud.__version__,
-                self.driver.name, user_agent_suffix)
-        else:
-            user_agent = 'libcloud/%s %s' % (
-                libcloud.__version__, user_agent_suffix)
-
-        return user_agent
-
-    def user_agent_append(self, token):
-        """
-        Append a token to a user agent string.
-
-        Users of the library should call this to uniquely identify their
-        requests to a provider.
-
-        :type token: ``str``
-        :param token: Token to add to the user agent.
-        """
-        self.ua.append(token)
-
-    def request(self, action, params=None, data=None, headers=None,
-                method='GET', raw=False):
-        """
-        Request a given `action`.
-
-        Basically a wrapper around the connection
-        object's `request` that does some helpful pre-processing.
-
-        :type action: ``str``
-        :param action: A path. This can include arguments. If included,
-            any extra parameters are appended to the existing ones.
-
-        :type params: ``dict``
-        :param params: Optional mapping of additional parameters to send. If
-            None, leave as an empty ``dict``.
-
-        :type data: ``unicode``
-        :param data: A body of data to send with the request.
-
-        :type headers: ``dict``
-        :param headers: Extra headers to add to the request
-            None, leave as an empty ``dict``.
-
-        :type method: ``str``
-        :param method: An HTTP method such as "GET" or "POST".
-
-        :type raw: ``bool``
-        :param raw: True to perform a "raw" request aka only send the headers
-                     and use the rawResponseCls class. This is used with
-                     storage API when uploading a file.
-
-        :return: An :class:`Response` instance.
-        :rtype: :class:`Response` instance
-
-        """
-        if params is None:
-            params = {}
-        else:
-            params = copy.copy(params)
-
-        if headers is None:
-            headers = {}
-        else:
-            headers = copy.copy(headers)
-
-        retry_enabled = os.environ.get('LIBCLOUD_RETRY_FAILED_HTTP_REQUESTS',
-                                       False) or RETRY_FAILED_HTTP_REQUESTS
-
-        action = self.morph_action_hook(action)
-        self.action = action
-        self.method = method
-        self.data = data
-
-        # Extend default parameters
-        params = self.add_default_params(params)
-
-        # Add cache busting parameters (if enabled)
-        if self.cache_busting and method == 'GET':
-            params = self._add_cache_busting_to_params(params=params)
-
-        # Extend default headers
-        headers = self.add_default_headers(headers)
-
-        # We always send a user-agent header
-        headers.update({'User-Agent': self._user_agent()})
-
-        # Indicate that we support gzip and deflate compression
-        headers.update({'Accept-Encoding': 'gzip,deflate'})
-
-        port = int(self.port)
-
-        if port not in (80, 443):
-            headers.update({'Host': "%s:%d" % (self.host, port)})
-        else:
-            headers.update({'Host': self.host})
-
-        if data:
-            data = self.encode_data(data)
-            headers['Content-Length'] = str(len(data))
-        elif method.upper() in ['POST', 'PUT'] and not raw:
-            # Only send Content-Length 0 with POST and PUT request.
-            #
-            # Note: Content-Length is not added when using "raw" mode means
-            # means that headers are upfront and the body is sent at some point
-            # later on. With raw mode user can specify Content-Length with
-            # "data" not being set.
-            headers['Content-Length'] = '0'
-
-        params, headers = self.pre_connect_hook(params, headers)
-
-        if params:
-            if '?' in action:
-                url = '&'.join((action, urlencode(params, doseq=True)))
-            else:
-                url = '?'.join((action, urlencode(params, doseq=True)))
-        else:
-            url = action
-
-        # Removed terrible hack...this a less-bad hack that doesn't execute a
-        # request twice, but it's still a hack.
-        self.connect()
-        try:
-            # @TODO: Should we just pass File object as body to request method
-            # instead of dealing with splitting and sending the file ourselves?
-            if raw:
-                self.connection.putrequest(method, url,
-                                           skip_host=1,
-                                           skip_accept_encoding=1)
-
-                for key, value in list(headers.items()):
-                    self.connection.putheader(key, str(value))
-
-                self.connection.endheaders()
-            else:
-                if retry_enabled:
-                    retry_request = retry(timeout=self.timeout,
-                                          retry_delay=self.retry_delay,
-                                          backoff=self.backoff)
-                    retry_request(self.connection.request)(method=method,
-                                                           url=url,
-                                                           body=data,
-                                                           headers=headers)
-                else:
-                    self.connection.request(method=method, url=url, body=data,
-                                            headers=headers)
-        except socket.gaierror:
-            e = sys.exc_info()[1]
-            message = str(e)
-            errno = getattr(e, 'errno', None)
-
-            if errno == -5:
-                # Throw a more-friendly exception on "no address associated
-                # with hostname" error. This error could simpli indicate that
-                # "host" Connection class attribute is set to an incorrect
-                # value
-                class_name = self.__class__.__name__
-                msg = ('%s. Perhaps "host" Connection class attribute '
-                       '(%s.connection) is set to an invalid, non-hostname '
-                       'value (%s)?' %
-                       (message, class_name, self.host))
-                raise socket.gaierror(msg)
-            self.reset_context()
-            raise e
-        except ssl.SSLError:
-            e = sys.exc_info()[1]
-            self.reset_context()
-            raise ssl.SSLError(str(e))
-
-        if raw:
-            responseCls = self.rawResponseCls
-            kwargs = {'connection': self}
-        else:
-            responseCls = self.responseCls
-            kwargs = {'connection': self,
-                      'response': self.connection.getresponse()}
-
-        try:
-            response = responseCls(**kwargs)
-        finally:
-            # Always reset the context after the request has completed
-            self.reset_context()
-
-        return response
-
-    def morph_action_hook(self, action):
-        return self.request_path + action
-
-    def add_default_params(self, params):
-        """
-        Adds default parameters (such as API key, version, etc.)
-        to the passed `params`
-
-        Should return a dictionary.
-        """
-        return params
-
-    def add_default_headers(self, headers):
-        """
-        Adds default headers (such as Authorization, X-Foo-Bar)
-        to the passed `headers`
-
-        Should return a dictionary.
-        """
-        return headers
-
-    def pre_connect_hook(self, params, headers):
-        """
-        A hook which is called before connecting to the remote server.
-        This hook can perform a final manipulation on the params, headers and
-        url parameters.
-
-        :type params: ``dict``
-        :param params: Request parameters.
-
-        :type headers: ``dict``
-        :param headers: Request headers.
-        """
-        return params, headers
-
-    def encode_data(self, data):
-        """
-        Encode body data.
-
-        Override in a provider's subclass.
-        """
-        return data
-
-    def _add_cache_busting_to_params(self, params):
-        """
-        Add cache busting parameter to the query parameters of a GET request.
-
-        Parameters are only added if "cache_busting" class attribute is set to
-        True.
-
-        Note: This should only be used with *naughty* providers which use
-        excessive caching of responses.
-        """
-        cache_busting_value = binascii.hexlify(os.urandom(8)).decode('ascii')
-
-        if isinstance(params, dict):
-            params['cache-busting'] = cache_busting_value
-        else:
-            params.append(('cache-busting', cache_busting_value))
-
-        return params
-
-
-class PollingConnection(Connection):
-    """
-    Connection class which can also work with the async APIs.
-
-    After initial requests, this class periodically polls for jobs status and
-    waits until the job has finished.
-    If job doesn't finish in timeout seconds, an Exception thrown.
-    """
-    poll_interval = 0.5
-    timeout = 200
-    request_method = 'request'
-
-    def async_request(self, action, params=None, data=None, headers=None,
-                      method='GET', context=None):
-        """
-        Perform an 'async' request to the specified path. Keep in mind that
-        this function is *blocking* and 'async' in this case means that the
-        hit URL only returns a job ID which is the periodically polled until
-        the job has completed.
-
-        This function works like this:
-
-        - Perform a request to the specified path. Response should contain a
-          'job_id'.
-
-        - Returned 'job_id' is then used to construct a URL which is used for
-          retrieving job status. Constructed URL is then periodically polled
-          until the response indicates that the job has completed or the
-          timeout of 'self.timeout' seconds has been reached.
-
-        :type action: ``str``
-        :param action: A path
-
-        :type params: ``dict``
-        :param params: Optional mapping of additional parameters to send. If
-            None, leave as an empty ``dict``.
-
-        :type data: ``unicode``
-        :param data: A body of data to send with the request.
-
-        :type headers: ``dict``
-        :param headers: Extra headers to add to the request
-            None, leave as an empty ``dict``.
-
-        :type method: ``str``
-        :param method: An HTTP method such as "GET" or "POST".
-
-        :type context: ``dict``
-        :param context: Context dictionary which is passed to the functions
-                        which construct initial and poll URL.
-
-        :return: An :class:`Response` instance.
-        :rtype: :class:`Response` instance
-        """
-
-        request = getattr(self, self.request_method)
-        kwargs = self.get_request_kwargs(action=action, params=params,
-                                         data=data, headers=headers,
-                                         method=method,
-                                         context=context)
-        response = request(**kwargs)
-        kwargs = self.get_poll_request_kwargs(response=response,
-                                              context=context,
-                                              request_kwargs=kwargs)
-
-        end = time.time() + self.timeout
-        completed = False
-        while time.time() < end and not completed:
-            response = request(**kwargs)
-            completed = self.has_completed(response=response)
-            if not completed:
-                time.sleep(self.poll_interval)
-
-        if not completed:
-            raise LibcloudError('Job did not complete in %s seconds' %
-                                (self.timeout))
-
-        return response
-
-    def get_request_kwargs(self, action, params=None, data=None, headers=None,
-                           method='GET', context=None):
-        """
-        Arguments which are passed to the initial request() call inside
-        async_request.
-        """
-        kwargs = {'action': action, 'params': params, 'data': data,
-                  'headers': headers, 'method': method}
-        return kwargs
-
-    def get_poll_request_kwargs(self, response, context, request_kwargs):
-        """
-        Return keyword arguments which are passed to the request() method when
-        polling for the job status.
-
-        :param response: Response object returned by poll request.
-        :type response: :class:`HTTPResponse`
-
-        :param request_kwargs: Kwargs previously used to initiate the
-                                  poll request.
-        :type response: ``dict``
-
-        :return ``dict`` Keyword arguments
-        """
-        raise NotImplementedError('get_poll_request_kwargs not implemented')
-
-    def has_completed(self, response):
-        """
-        Return job completion status.
-
-        :param response: Response object returned by poll request.
-        :type response: :class:`HTTPResponse`
-
-        :return ``bool`` True if the job has completed, False otherwise.
-        """
-        raise NotImplementedError('has_completed not implemented')
-
-
-class ConnectionKey(Connection):
-    """
-    Base connection class which accepts a single ``key`` argument.
-    """
-    def __init__(self, key, secure=True, host=None, port=None, url=None,
-                 timeout=None, proxy_url=None, backoff=None, retry_delay=None):
-        """
-        Initialize `user_id` and `key`; set `secure` to an ``int`` based on
-        passed value.
-        """
-        super(ConnectionKey, self).__init__(secure=secure, host=host,
-                                            port=port, url=url,
-                                            timeout=timeout,
-                                            proxy_url=proxy_url,
-                                            backoff=backoff,
-                                            retry_delay=retry_delay)
-        self.key = key
-
-
-class CertificateConnection(Connection):
-    """
-    Base connection class which accepts a single ``cert_file`` argument.
-    """
-    def __init__(self, cert_file, secure=True, host=None, port=None, url=None,
-                 proxy_url=None, timeout=None, backoff=None, retry_delay=None):
-        """
-        Initialize `cert_file`; set `secure` to an ``int`` based on
-        passed value.
-        """
-        super(CertificateConnection, self).__init__(secure=secure, host=host,
-                                                    port=port, url=url,
-                                                    timeout=timeout,
-                                                    backoff=backoff,
-                                                    retry_delay=retry_delay,
-                                                    proxy_url=proxy_url)
-
-        self.cert_file = cert_file
-
-
-class ConnectionUserAndKey(ConnectionKey):
-    """
-    Base connection class which accepts a ``user_id`` and ``key`` argument.
-    """
-
-    user_id = None
-
-    def __init__(self, user_id, key, secure=True, host=None, port=None,
-                 url=None, timeout=None, proxy_url=None,
-                 backoff=None, retry_delay=None):
-        super(ConnectionUserAndKey, self).__init__(key, secure=secure,
-                                                   host=host, port=port,
-                                                   url=url, timeout=timeout,
-                                                   backoff=backoff,
-                                                   retry_delay=retry_delay,
-                                                   proxy_url=proxy_url)
-        self.user_id = user_id
-
-
-class BaseDriver(object):
-    """
-    Base driver class from which other classes can inherit from.
-    """
-
-    connectionCls = ConnectionKey
-
-    def __init__(self, key, secret=None, secure=True, host=None, port=None,
-                 api_version=None, region=None, **kwargs):
-        """
-        :param    key:    API key or username to be used (required)
-        :type     key:    ``str``
-
-        :param    secret: Secret password to be used (required)
-        :type     secret: ``str``
-
-        :param    secure: Whether to use HTTPS or HTTP. Note: Some providers
-                            only support HTTPS, and it is on by default.
-        :type     secure: ``bool``
-
-        :param    host: Override hostname used for connections.
-        :type     host: ``str``
-
-        :param    port: Override port used for connections.
-        :type     port: ``int``
-
-        :param    api_version: Optional API version. Only used by drivers
-                                 which support multiple API versions.
-        :type     api_version: ``str``
-
-        :param region: Optional driver region. Only used by drivers which
-                       support multiple regions.
-        :type region: ``str``
-
-        :rtype: ``None``
-        """
-
-        self.key = key
-        self.secret = secret
-        self.secure = secure
-        args = [self.key]
-
-        if self.secret is not None:
-            args.append(self.secret)
-
-        args.append(secure)
-
-        if host is not None:
-            args.append(host)
-
-        if port is not None:
-            args.append(port)
-
-        self.api_version = api_version
-        self.region = region
-
-        conn_kwargs = self._ex_connection_class_kwargs()
-        conn_kwargs.update({'timeout': kwargs.pop('timeout', None),
-                            'retry_delay': kwargs.pop('retry_delay', None),
-                            'backoff': kwargs.pop('backoff', None),
-                            'proxy_url': kwargs.pop('proxy_url', None)})
-        self.connection = self.connectionCls(*args, **conn_kwargs)
-
-        self.connection.driver = self
-        self.connection.connect()
-
-    @classmethod
-    def list_regions(cls):
-        """
-        Method which returns a list of the available / supported regions.
-
-        :rtype: ``list`` of ``str``
-        """
-        return []
-
-    def _ex_connection_class_kwargs(self):
-        """
-        Return extra connection keyword arguments which are passed to the
-        Connection class constructor.
-        """
-        return {}

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/brightbox.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/brightbox.py b/apache-libcloud-1.0.0rc2/libcloud/common/brightbox.py
deleted file mode 100644
index 1943dda..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/brightbox.py
+++ /dev/null
@@ -1,101 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 base64
-
-from libcloud.common.base import ConnectionUserAndKey, JsonResponse
-from libcloud.compute.types import InvalidCredsError
-
-from libcloud.utils.py3 import b
-from libcloud.utils.py3 import httplib
-
-try:
-    import simplejson as json
-except ImportError:
-    import json
-
-
-class BrightboxResponse(JsonResponse):
-    def success(self):
-        return self.status >= httplib.OK and self.status < httplib.BAD_REQUEST
-
-    def parse_body(self):
-        if self.headers['content-type'].split(';')[0] == 'application/json':
-            return super(BrightboxResponse, self).parse_body()
-        else:
-            return self.body
-
-    def parse_error(self):
-        response = super(BrightboxResponse, self).parse_body()
-
-        if 'error' in response:
-            if response['error'] in ['invalid_client', 'unauthorized_client']:
-                raise InvalidCredsError(response['error'])
-
-            return response['error']
-        elif 'error_name' in response:
-            return '%s: %s' % (response['error_name'], response['errors'][0])
-
-        return self.body
-
-
-class BrightboxConnection(ConnectionUserAndKey):
-    """
-    Connection class for the Brightbox driver
-    """
-
-    host = 'api.gb1.brightbox.com'
-    responseCls = BrightboxResponse
-
-    def _fetch_oauth_token(self):
-        body = json.dumps({'client_id': self.user_id, 'grant_type': 'none'})
-
-        authorization = 'Basic ' + str(base64.encodestring(b('%s:%s' %
-                                       (self.user_id, self.key)))).rstrip()
-
-        self.connect()
-
-        headers = {
-            'Host': self.host,
-            'User-Agent': self._user_agent(),
-            'Authorization': authorization,
-            'Content-Type': 'application/json',
-            'Content-Length': str(len(body))
-        }
-
-        response = self.connection.request(method='POST', url='/token',
-                                           body=body, headers=headers)
-
-        response = self.connection.getresponse()
-
-        if response.status == httplib.OK:
-            return json.loads(response.read())['access_token']
-        else:
-            responseCls = BrightboxResponse(response=response, connection=self)
-            message = responseCls.parse_error()
-            raise InvalidCredsError(message)
-
-    def add_default_headers(self, headers):
-        try:
-            headers['Authorization'] = 'OAuth ' + self.token
-        except AttributeError:
-            self.token = self._fetch_oauth_token()
-
-            headers['Authorization'] = 'OAuth ' + self.token
-
-        return headers
-
-    def encode_data(self, data):
-        return json.dumps(data)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/buddyns.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/buddyns.py b/apache-libcloud-1.0.0rc2/libcloud/common/buddyns.py
deleted file mode 100644
index ae312ae..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/buddyns.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from libcloud.common.base import ConnectionKey, JsonResponse
-
-
-__all__ = [
-    'API_HOST',
-    'BuddyNSException',
-    'BuddyNSResponse',
-    'BuddyNSConnection'
-]
-
-# Endpoint for buddyns api
-API_HOST = 'www.buddyns.com'
-
-
-class BuddyNSResponse(JsonResponse):
-    errors = []
-    objects = []
-
-    def __init__(self, response, connection):
-        super(BuddyNSResponse, self).__init__(response=response,
-                                              connection=connection)
-        self.errors, self.objects = self.parse_body_and_errors()
-        if not self.success():
-            raise BuddyNSException(code=self.status,
-                                   message=self.errors.pop()['detail'])
-
-    def parse_body_and_errors(self):
-        js = super(BuddyNSResponse, self).parse_body()
-        if 'detail' in js:
-            self.errors.append(js)
-        else:
-            self.objects.append(js)
-
-        return self.errors, self.objects
-
-    def success(self):
-        return len(self.errors) == 0
-
-
-class BuddyNSConnection(ConnectionKey):
-    host = API_HOST
-    responseCls = BuddyNSResponse
-
-    def add_default_headers(self, headers):
-        headers['content-type'] = 'application/json'
-        headers['Authorization'] = 'Token' + ' ' + self.key
-
-        return headers
-
-
-class BuddyNSException(Exception):
-
-    def __init__(self, code, message):
-        self.code = code
-        self.message = message
-        self.args = (code, message)
-
-    def __str__(self):
-        return "%s %s" % (self.code, self.message)
-
-    def __repr__(self):
-        return "BuddyNSException %s %s" % (self.code, self.message)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/cloudsigma.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/cloudsigma.py b/apache-libcloud-1.0.0rc2/libcloud/common/cloudsigma.py
deleted file mode 100644
index cb5c263..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/cloudsigma.py
+++ /dev/null
@@ -1,165 +0,0 @@
-# -*- coding: utf-8 -*-
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-__all__ = [
-    'API_ENDPOINTS_1_0',
-    'API_ENDPOINTS_2_0',
-    'API_VERSIONS',
-    'INSTANCE_TYPES'
-]
-
-# API end-points
-API_ENDPOINTS_1_0 = {
-    'zrh': {
-        'name': 'Zurich',
-        'country': 'Switzerland',
-        'host': 'api.zrh.cloudsigma.com'
-    },
-    'lvs': {
-        'name': 'Las Vegas',
-        'country': 'United States',
-        'host': 'api.lvs.cloudsigma.com'
-    }
-}
-
-API_ENDPOINTS_2_0 = {
-    'zrh': {
-        'name': 'Zurich',
-        'country': 'Switzerland',
-        'host': 'zrh.cloudsigma.com'
-    },
-    'sjc': {
-        'name': 'San Jose, CA',
-        'country': 'United States',
-        'host': 'sjc.cloudsigma.com'
-    },
-    'mia': {
-        'name': 'Miami, FL',
-        'country': 'United States',
-        'host': 'mia.cloudsigma.com'
-    },
-    'wdc': {
-        'name': 'Washington, DC',
-        'country': 'United States',
-        'host': 'wdc.cloudsigma.com'
-    },
-    'hnl': {
-        'name': 'Honolulu, HI',
-        'country': 'United States',
-        'host': 'hnl.cloudsigma.com'
-    },
-    'per': {
-        'name': 'Perth, Australia',
-        'country': 'Australia',
-        'host': 'per.cloudsigma.com'
-    },
-    'mnl': {
-        'name': 'Manila, Philippines',
-        'country': 'Philippines',
-        'host': 'mnl.cloudsigma.com'
-    }
-}
-
-DEFAULT_REGION = 'zrh'
-
-# Supported API versions.
-API_VERSIONS = [
-    '1.0'  # old and deprecated
-    '2.0'
-]
-
-DEFAULT_API_VERSION = '2.0'
-
-# CloudSigma doesn't specify special instance types.
-# Basically for CPU any value between 0.5 GHz and 20.0 GHz should work,
-# 500 MB to 32000 MB for ram
-# and 1 GB to 1024 GB for hard drive size.
-# Plans in this file are based on examples listed on http://www.cloudsigma
-# .com/en/pricing/price-schedules
-INSTANCE_TYPES = [
-    {
-        'id': 'micro-regular',
-        'name': 'Micro/Regular instance',
-        'cpu': 1100,
-        'memory': 640,
-        'disk': 10 + 3,
-        'bandwidth': None,
-    },
-    {
-        'id': 'micro-high-cpu',
-        'name': 'Micro/High CPU instance',
-        'cpu': 2200,
-        'memory': 640,
-        'disk': 80,
-        'bandwidth': None,
-    },
-    {
-        'id': 'standard-small',
-        'name': 'Standard/Small instance',
-        'cpu': 1100,
-        'memory': 1741,
-        'disk': 50,
-        'bandwidth': None,
-    },
-    {
-        'id': 'standard-large',
-        'name': 'Standard/Large instance',
-        'cpu': 4400,
-        'memory': 7680,
-        'disk': 250,
-        'bandwidth': None,
-    },
-    {
-        'id': 'standard-extra-large',
-        'name': 'Standard/Extra Large instance',
-        'cpu': 8800,
-        'memory': 15360,
-        'disk': 500,
-        'bandwidth': None,
-    },
-    {
-        'id': 'high-memory-extra-large',
-        'name': 'High Memory/Extra Large instance',
-        'cpu': 7150,
-        'memory': 17510,
-        'disk': 250,
-        'bandwidth': None,
-    },
-    {
-        'id': 'high-memory-double-extra-large',
-        'name': 'High Memory/Double Extra Large instance',
-        'cpu': 14300,
-        'memory': 32768,
-        'disk': 500,
-        'bandwidth': None,
-    },
-    {
-        'id': 'high-cpu-medium',
-        'name': 'High CPU/Medium instance',
-        'cpu': 5500,
-        'memory': 1741,
-        'disk': 150,
-        'bandwidth': None,
-    },
-    {
-        'id': 'high-cpu-extra-large',
-        'name': 'High CPU/Extra Large instance',
-        'cpu': 20000,
-        'memory': 7168,
-        'disk': 500,
-        'bandwidth': None,
-    }
-]


[12/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/nsone.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/nsone.py b/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/nsone.py
deleted file mode 100644
index 06297e6..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/nsone.py
+++ /dev/null
@@ -1,344 +0,0 @@
-import sys
-try:
-    import simplejson as json
-except ImportError:
-    import json
-
-from libcloud.dns.types import Provider, ZoneDoesNotExistError, \
-    ZoneAlreadyExistsError, RecordDoesNotExistError, RecordAlreadyExistsError
-from libcloud.utils.py3 import httplib
-from libcloud.dns.base import DNSDriver, Zone, Record, RecordType
-from libcloud.common.nsone import NsOneConnection, NsOneResponse, \
-    NsOneException
-
-__all__ = [
-    'NsOneDNSDriver'
-]
-
-
-class NsOneDNSResponse(NsOneResponse):
-    pass
-
-
-class NsOneDNSConnection(NsOneConnection):
-    responseCls = NsOneDNSResponse
-
-
-class NsOneDNSDriver(DNSDriver):
-    name = 'NS1 DNS'
-    website = 'https://ns1.com'
-    type = Provider.NSONE
-    connectionCls = NsOneDNSConnection
-
-    RECORD_TYPE_MAP = {
-        RecordType.A: 'A',
-        RecordType.AAAA: 'AAAA',
-        RecordType.CNAME: 'CNAME',
-        RecordType.MX: 'MX',
-        RecordType.NS: 'NS',
-        RecordType.PTR: 'PTR',
-        RecordType.SOA: 'SOA',
-        RecordType.SRV: 'SRV',
-        RecordType.TXT: 'TXT'
-    }
-
-    def list_zones(self):
-        action = '/v1/zones'
-        response = self.connection.request(action=action, method='GET')
-        zones = self._to_zones(items=response.parse_body())
-
-        return zones
-
-    def get_zone(self, zone_id):
-        """
-        :param zone_id: Zone domain name (e.g. example.com)
-        :return: :class:`Zone`
-        """
-        action = '/v1/zones/%s' % zone_id
-        try:
-            response = self.connection.request(action=action, method='GET')
-        except NsOneException:
-            e = sys.exc_info()[1]
-            if e.message == 'zone not found':
-                raise ZoneDoesNotExistError(value=e.message, driver=self,
-                                            zone_id=zone_id)
-            else:
-                raise e
-        zone = self._to_zone(response.objects[0])
-
-        return zone
-
-    def create_zone(self, domain, type='master', ttl=None, extra=None):
-        """
-        :param domain: Zone domain name (e.g. example.com)
-        :type domain: ``str``
-
-        :param type: Zone type (This is not really used. See API docs for extra
-          parameters)
-        :type type: ``str``
-
-        :param ttl: TTL for new records (This is used through the extra param)
-        :type ttl: ``int``
-
-        :param extra: Extra attributes that are specific to the driver
-        such as ttl.
-        :type extra: ``dict``
-
-        :rtype: :class:`Zone`
-        """
-        action = '/v1/zones/%s' % domain
-        raw_data = {'zone': domain}
-        if extra is not None:
-            raw_data.update(extra)
-        post_data = json.dumps(raw_data)
-        try:
-            response = self.connection.request(action=action, method='PUT',
-                                               data=post_data)
-        except NsOneException:
-            e = sys.exc_info()[1]
-            if e.message == 'zone already exists':
-                raise ZoneAlreadyExistsError(value=e.message, driver=self,
-                                             zone_id=domain)
-            else:
-                raise e
-
-        zone = self._to_zone(response.objects[0])
-
-        return zone
-
-    def delete_zone(self, zone):
-        """
-        :param zone: Zone to be deleted.
-        :type zone: :class:`Zone`
-
-        :return: Boolean
-        """
-        action = '/v1/zones/%s' % zone.domain
-        """zones_list = self.list_zones()
-        if not self.ex_zone_exists(zone_id=zone.id, zones_list=zones_list):
-            raise ZoneDoesNotExistError(value='', driver=self, zone_id=zone.id)
-        """
-        try:
-            response = self.connection.request(action=action, method='DELETE')
-        except NsOneException:
-            e = sys.exc_info()[1]
-            if e.message == 'zone not found':
-                raise ZoneDoesNotExistError(value=e.message, driver=self,
-                                            zone_id=zone.id)
-            else:
-                raise e
-
-        return response.status == httplib.OK
-
-    def list_records(self, zone):
-        """
-        :param zone: Zone to list records for.
-        :type zone: :class:`Zone`
-
-        :return: ``list`` of :class:`Record`
-        """
-        action = '/v1/zones/%s' % zone.domain
-        try:
-            response = self.connection.request(action=action, method='GET')
-        except NsOneException:
-            e = sys.exc_info()[1]
-            if e.message == 'zone not found':
-                raise ZoneDoesNotExistError(value=e.message, driver=self,
-                                            zone_id=zone.id)
-            else:
-                raise e
-        records = self._to_records(items=response.parse_body()['records'],
-                                   zone=zone)
-
-        return records
-
-    def get_record(self, zone_id, record_id):
-        """
-        :param zone_id: The id of the zone where to search for
-        the record (e.g. example.com)
-        :type zone_id: ``str``
-        :param record_id: The type of record to search for
-        (e.g. A, AAA, MX etc)
-
-        :return: :class:`Record`
-        """
-        action = '/v1/zones/%s/%s/%s' % (zone_id, zone_id, record_id)
-        try:
-            response = self.connection.request(action=action, method='GET')
-        except NsOneException:
-            e = sys.exc_info()[1]
-            if e.message == 'record not found':
-                raise RecordDoesNotExistError(value=e.message, driver=self,
-                                              record_id=record_id)
-            else:
-                raise e
-        zone = self.get_zone(zone_id=zone_id)
-        record = self._to_record(item=response.parse_body(), zone=zone)
-
-        return record
-
-    def delete_record(self, record):
-        """
-        :param record: Record to delete.
-        :type record: :class:`Record`
-
-        :return: Boolean
-        """
-        action = '/v1/zones/%s/%s/%s' % (record.zone.domain, record.name,
-                                         record.type)
-        try:
-            response = self.connection.request(action=action, method='DELETE')
-        except NsOneException:
-            e = sys.exc_info()[1]
-            if e.message == 'record not found':
-                raise RecordDoesNotExistError(value=e.message, driver=self,
-                                              record_id=record.id)
-            else:
-                raise e
-
-        return response.status == httplib.OK
-
-    def create_record(self, name, zone, type, data, extra=None):
-        """
-        :param name: Name of the record to create (e.g. foo).
-        :type name: ``str``
-        :param zone: Zone where the record should be created.
-        :type zone: :class:`Zone`
-        :param type: Type of record (e.g. A, MX etc)
-        :type type: ``str``
-        :param data: Data of the record (e.g. 127.0.0.1 for the A record)
-        :type data: ``str``
-        :param extra: Extra data needed to create different types of records
-        :type extra: ``dict``
-        :return: :class:`Record`
-        """
-        action = '/v1/zones/%s/%s/%s' % (zone.domain, '%s.%s' %
-                                         (name, zone.domain), type)
-        raw_data = {
-            "answers": [
-                {
-                    "answer": [
-                        data
-                    ], }
-            ],
-            "type": type,
-            "domain": '%s.%s' % (name, zone.domain),
-            "zone": zone.domain
-        }
-        if extra is not None and extra.get('answers'):
-            raw_data['answers'] = extra.get('answers')
-        post_data = json.dumps(raw_data)
-        try:
-            response = self.connection.request(action=action, method='PUT',
-                                               data=post_data)
-        except NsOneException:
-            e = sys.exc_info()[1]
-            if e.message == 'record already exists':
-                raise RecordAlreadyExistsError(value=e.message, driver=self,
-                                               record_id='')
-            else:
-                raise e
-        record = self._to_record(item=response.parse_body(), zone=zone)
-
-        return record
-
-    def update_record(self, record, name, type, data, extra=None):
-        """
-        :param record: Record to update
-        :type record: :class:`Record`
-        :param name: Name of the record to update (e.g. foo).
-        :type name: ``str``
-        :param type: Type of record (e.g. A, MX etc)
-        :type type: ``str``
-        :param data: Data of the record (e.g. 127.0.0.1 for the A record)
-        :type data: ``str``
-        :param extra: Extra data needed to create different types of records
-        :type extra: ``dict``
-        :return: :class:`Record`
-        """
-        zone = record.zone
-        action = '/v1/zones/%s/%s/%s' % (zone.domain, '%s.%s' %
-                                         (name, zone.domain), type)
-        raw_data = {
-            "answers": [
-                {
-                    "answer": [
-                        data
-                    ], }
-            ]
-        }
-        if extra is not None and extra.get('answers'):
-            raw_data['answers'] = extra.get('answers')
-        post_data = json.dumps(raw_data)
-        try:
-            response = self.connection.request(action=action, data=post_data,
-                                               method='POST')
-        except NsOneException:
-            e = sys.exc_info()[1]
-            if e.message == 'record does not exist':
-                raise RecordDoesNotExistError(value=e.message, driver=self,
-                                              id=record.id)
-            else:
-                raise e
-        record = self._to_record(item=response.parse_body(), zone=zone)
-
-        return record
-
-    def ex_zone_exists(self, zone_id, zones_list):
-        """
-        Function to check if a `Zone` object exists.
-        :param zone_id: ID of the `Zone` object.
-        :type zone_id: ``str``
-
-        :param zones_list: A list containing `Zone` objects.
-        :type zones_list: ``list``.
-
-        :rtype: Returns `True` or `False`.
-        """
-        zone_ids = []
-        for zone in zones_list:
-            zone_ids.append(zone.id)
-
-        return zone_id in zone_ids
-
-    def _to_zone(self, item):
-        common_attr = ['zone', 'id', 'type']
-        extra = {}
-        for key in item.keys():
-            if key not in common_attr:
-                extra[key] = item.get(key)
-
-        zone = Zone(domain=item['zone'], id=item['id'], type=item.get('type'),
-                    extra=extra, ttl=extra.get('ttl'), driver=self)
-
-        return zone
-
-    def _to_zones(self, items):
-        zones = []
-        for item in items:
-            zones.append(self._to_zone(item))
-
-        return zones
-
-    def _to_record(self, item, zone):
-        common_attr = ['id', 'short_answers', 'answers', 'domain', 'type']
-        extra = {}
-        for key in item.keys():
-            if key not in common_attr:
-                extra[key] = item.get(key)
-        if item.get('answers') is not None:
-            data = item.get('answers')[0]['answer']
-        else:
-            data = item.get('short_answers')
-        record = Record(id=item['id'], name=item['domain'], type=item['type'],
-                        data=data, zone=zone, driver=self,
-                        extra=extra)
-
-        return record
-
-    def _to_records(self, items, zone):
-        records = []
-        for item in items:
-            records.append(self._to_record(item, zone))
-
-        return records

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/pointdns.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/pointdns.py b/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/pointdns.py
deleted file mode 100644
index 1523bb9..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/pointdns.py
+++ /dev/null
@@ -1,791 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-Point DNS Driver
-"""
-
-__all__ = [
-    'PointDNSException',
-    'Redirect',
-    'MailRedirect',
-    'PointDNSDriver'
-]
-
-import sys
-
-try:
-    import simplejson as json
-except ImportError:
-    import json
-
-from libcloud.utils.py3 import httplib
-from libcloud.common.types import ProviderError
-from libcloud.common.types import MalformedResponseError
-from libcloud.common.pointdns import PointDNSConnection
-from libcloud.common.exceptions import BaseHTTPError
-from libcloud.dns.types import Provider, RecordType
-from libcloud.dns.types import ZoneDoesNotExistError
-from libcloud.dns.types import RecordDoesNotExistError
-from libcloud.dns.base import DNSDriver, Zone, Record
-
-
-class PointDNSException(ProviderError):
-
-    def __init__(self, value, http_code, driver=None):
-        super(PointDNSException, self).__init__(value=value,
-                                                http_code=http_code,
-                                                driver=driver)
-        self.args = (http_code, value)
-
-
-class Redirect(object):
-    """
-    Point DNS redirect.
-    """
-
-    def __init__(self, id, name, data, type, driver, zone, iframe=None,
-                 query=False):
-        """
-        :param id: Redirect id.
-        :type id: ``str``
-
-        :param name: The FQDN for the record.
-        :type name: ``str``
-
-        :param data: The data field. (redirect_to)
-        :type data: ``str``
-
-        :param type: The type of redirects 301, 302 or 0 for iframes.
-        :type type: ``str``
-
-        :param driver: DNSDriver instance.
-        :type driver: :class:`DNSDriver`
-
-        :param zone: Zone where redirect belongs.
-        :type  zone: :class:`Zone`
-
-        :param iframe: Title of iframe (optional).
-        :type iframe: ``str``
-
-        :param query: boolean Information about including query string when
-                      redirecting. (optional).
-        :type query: ``bool``
-        """
-        self.id = str(id) if id else None
-        self.name = name
-        self.data = data
-        self.type = str(type) if type else None
-        self.driver = driver
-        self.zone = zone
-        self.iframe = iframe
-        self.query = query
-
-    def update(self, data, name=None, type=None, iframe=None, query=None):
-        return self.driver.ex_update_redirect(redirect=self, name=name,
-                                              data=data, type=type,
-                                              iframe=iframe, query=query)
-
-    def delete(self):
-        return self.driver.ex_delete_redirect(redirect=self)
-
-    def __repr__(self):
-        return ('<PointDNSRedirect: name=%s, data=%s, type=%s ...>' %
-                (self.name, self.data, self.type))
-
-
-class MailRedirect(object):
-    """
-    Point DNS mail redirect.
-    """
-
-    def __init__(self, id, source, destination, zone, driver):
-        """
-        :param id: MailRedirect id.
-        :type id: ``str``
-
-        :param source: The source address of mail redirect.
-        :type source: ``str``
-
-        :param destination: The destination address of mail redirect.
-        :type destination: ``str``
-
-        :param zone: Zone where mail redirect belongs.
-        :type  zone: :class:`Zone`
-
-        :param driver: DNSDriver instance.
-        :type driver: :class:`DNSDriver`
-        """
-        self.id = str(id) if id else None
-        self.source = source
-        self.destination = destination
-        self.zone = zone
-        self.driver = driver
-
-    def update(self, destination, source=None):
-        return self.driver.ex_update_mail_redirect(mail_r=self,
-                                                   destination=destination,
-                                                   source=None)
-
-    def delete(self):
-        return self.driver.ex_delete_mail_redirect(mail_r=self)
-
-    def __repr__(self):
-        return ('<PointDNSMailRedirect: source=%s, destination=%s,zone=%s ...>'
-                % (self.source, self.destination, self.zone.id))
-
-
-class PointDNSDriver(DNSDriver):
-    type = Provider.POINTDNS
-    name = 'Point DNS'
-    website = 'https://pointhq.com/'
-    connectionCls = PointDNSConnection
-
-    RECORD_TYPE_MAP = {
-        RecordType.A: 'A',
-        RecordType.AAAA: 'AAAA',
-        RecordType.ALIAS: 'ALIAS',
-        RecordType.CNAME: 'CNAME',
-        RecordType.MX: 'MX',
-        RecordType.NS: 'NS',
-        RecordType.PTR: 'PTR',
-        RecordType.SRV: 'SRV',
-        RecordType.SSHFP: 'SSHFP',
-        RecordType.TXT: 'TXT'
-    }
-
-    def list_zones(self):
-        """
-        Return a list of zones.
-
-        :return: ``list`` of :class:`Zone`
-        """
-        response = self.connection.request('/zones')
-        zones = self._to_zones(response.object)
-        return zones
-
-    def list_records(self, zone):
-        """
-        Return a list of records for the provided zone.
-
-        :param zone: Zone to list records for.
-        :type zone: :class:`Zone`
-
-        :return: ``list`` of :class:`Record`
-        """
-        response = self.connection.request('/zones/%s/records' % zone.id)
-        records = self._to_records(response.object, zone)
-        return records
-
-    def get_zone(self, zone_id):
-        """
-        Return a Zone instance.
-
-        :param zone_id: ID of the required zone
-        :type  zone_id: ``str``
-
-        :rtype: :class:`Zone`
-        """
-        try:
-            response = self.connection.request('/zones/%s' % zone_id)
-        except MalformedResponseError:
-            e = sys.exc_info()[1]
-            if e.body == 'Not found':
-                raise ZoneDoesNotExistError(driver=self,
-                                            value="The zone doesn't exists",
-                                            zone_id=zone_id)
-            raise e
-
-        zone = self._to_zone(response.object)
-        return zone
-
-    def get_record(self, zone_id, record_id):
-        """
-        Return a Record instance.
-
-        :param zone_id: ID of the required zone
-        :type  zone_id: ``str``
-
-        :param record_id: ID of the required record
-        :type  record_id: ``str``
-
-        :rtype: :class:`Record`
-        """
-        try:
-            response = self.connection.request('/zones/%s/records/%s' %
-                                               (zone_id, record_id))
-        except MalformedResponseError:
-            e = sys.exc_info()[1]
-            if e.body == 'Not found':
-                raise RecordDoesNotExistError(value="Record doesn't exists",
-                                              driver=self,
-                                              record_id=record_id)
-            raise e
-
-        record = self._to_record(response.object, zone_id=zone_id)
-        return record
-
-    def create_zone(self, domain, type='master', ttl=None, extra=None):
-        """
-        Create a new zone.
-
-        :param domain: Zone domain name (e.g. example.com)
-        :type domain: ``str``
-
-        :param type: Zone type (All zones are master by design).
-        :type  type: ``str``
-
-        :param ttl: TTL for new records. (optional)
-        :type  ttl: ``int``
-
-        :param extra: Extra attributes (driver specific). (optional)
-        :type extra: ``dict``
-
-        :rtype: :class:`Zone`
-        """
-        r_json = {'name': domain}
-        if ttl is not None:
-            r_json['ttl'] = ttl
-        if extra is not None:
-            r_json.update(extra)
-        r_data = json.dumps({'zone': r_json})
-        try:
-            response = self.connection.request('/zones', method='POST',
-                                               data=r_data)
-        except BaseHTTPError:
-            e = sys.exc_info()[1]
-            raise PointDNSException(value=e.message, http_code=e.code,
-                                    driver=self)
-        zone = self._to_zone(response.object)
-        return zone
-
-    def create_record(self, name, zone, type, data, extra=None):
-        """
-        Create a new record.
-
-        :param name: Record name without the domain name (e.g. www).
-                     Note: If you want to create a record for a base domain
-                     name, you should specify empty string ('') for this
-                     argument.
-        :type  name: ``str``
-
-        :param zone: Zone where the requested record is created.
-        :type  zone: :class:`Zone`
-
-        :param type: DNS record type (A, AAAA, ...).
-        :type  type: :class:`RecordType`
-
-        :param data: Data for the record (depends on the record type).
-        :type  data: ``str``
-
-        :param extra: Extra attributes (driver specific). (optional)
-        :type extra: ``dict``
-
-        :rtype: :class:`Record`
-        """
-        r_json = {'name': name, 'data': data, 'record_type': type}
-        if extra is not None:
-            r_json.update(extra)
-        r_data = json.dumps({'zone_record': r_json})
-        try:
-            response = self.connection.request('/zones/%s/records' % zone.id,
-                                               method='POST', data=r_data)
-        except BaseHTTPError:
-            e = sys.exc_info()[1]
-            raise PointDNSException(value=e.message, http_code=e.code,
-                                    driver=self)
-        record = self._to_record(response.object, zone=zone)
-        return record
-
-    def update_zone(self, zone, domain, type='master', ttl=None, extra=None):
-        """
-        Update en existing zone.
-
-        :param zone: Zone to update.
-        :type  zone: :class:`Zone`
-
-        :param domain: Zone domain name (e.g. example.com)
-        :type  domain: ``str``
-
-        :param type: Zone type (All zones are master by design).
-        :type  type: ``str``
-
-        :param ttl: TTL for new records. (optional)
-        :type  ttl: ``int``
-
-        :param extra: Extra attributes (group, user-id). (optional)
-        :type  extra: ``dict``
-
-        :rtype: :class:`Zone`
-        """
-        r_json = {'name': domain}
-        if extra is not None:
-            r_json.update(extra)
-        r_data = json.dumps({'zone': r_json})
-        try:
-            response = self.connection.request('/zones/%s' % zone.id,
-                                               method='PUT', data=r_data)
-        except (BaseHTTPError, MalformedResponseError):
-            e = sys.exc_info()[1]
-            if isinstance(e, MalformedResponseError) and e.body == 'Not found':
-                raise ZoneDoesNotExistError(value="Zone doesn't exists",
-                                            driver=self,
-                                            zone_id=zone.id)
-            raise PointDNSException(value=e.message, http_code=e.code,
-                                    driver=self)
-        zone = self._to_zone(response.object)
-        return zone
-
-    def update_record(self, record, name, type, data, extra=None):
-        """
-        Update an existing record.
-
-        :param record: Record to update.
-        :type  record: :class:`Record`
-
-        :param name: Record name without the domain name (e.g. www).
-                     Note: If you want to create a record for a base domain
-                     name, you should specify empty string ('') for this
-                     argument.
-        :type  name: ``str``
-
-        :param type: DNS record type (A, AAAA, ...).
-        :type  type: :class:`RecordType`
-
-        :param data: Data for the record (depends on the record type).
-        :type  data: ``str``
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type  extra: ``dict``
-
-        :rtype: :class:`Record`
-        """
-        zone = record.zone
-        r_json = {'name': name, 'data': data, 'record_type': type}
-        if extra is not None:
-            r_json.update(extra)
-        r_data = json.dumps({'zone_record': r_json})
-        try:
-            response = self.connection.request('/zones/%s/records/%s' %
-                                               (zone.id, record.id),
-                                               method='PUT', data=r_data)
-        except (BaseHTTPError, MalformedResponseError):
-            e = sys.exc_info()[1]
-            if isinstance(e, MalformedResponseError) and e.body == 'Not found':
-                raise RecordDoesNotExistError(value="Record doesn't exists",
-                                              driver=self,
-                                              record_id=record.id)
-            raise PointDNSException(value=e.message, http_code=e.code,
-                                    driver=self)
-        record = self._to_record(response.object, zone=zone)
-        return record
-
-    def delete_zone(self, zone):
-        """
-        Delete a zone.
-
-        Note: This will delete all the records belonging to this zone.
-
-        :param zone: Zone to delete.
-        :type  zone: :class:`Zone`
-
-        :rtype: ``bool``
-        """
-        try:
-            self.connection.request('/zones/%s' % zone.id, method='DELETE')
-        except MalformedResponseError:
-            e = sys.exc_info()[1]
-            if e.body == 'Not found':
-                raise ZoneDoesNotExistError(driver=self,
-                                            value="The zone doesn't exists",
-                                            zone_id=zone.id)
-            raise e
-        return True
-
-    def delete_record(self, record):
-        """
-        Delete a record.
-
-        :param record: Record to delete.
-        :type  record: :class:`Record`
-
-        :rtype: ``bool``
-        """
-        zone_id = record.zone.id
-        record_id = record.id
-        try:
-            self.connection.request('/zones/%s/records/%s' % (zone_id,
-                                                              record_id),
-                                    method='DELETE')
-        except MalformedResponseError:
-            e = sys.exc_info()[1]
-            if e.body == 'Not found':
-                raise RecordDoesNotExistError(value="Record doesn't exists",
-                                              driver=self,
-                                              record_id=record_id)
-            raise e
-        return True
-
-    def ex_list_redirects(self, zone):
-        """
-        :param zone: Zone to list redirects for.
-        :type zone: :class:`Zone`
-
-        :rtype: ``list`` of :class:`Record`
-        """
-        response = self.connection.request('/zones/%s/redirects' % zone.id)
-        redirects = self._to_redirects(response.object, zone)
-        return redirects
-
-    def ex_list_mail_redirects(self, zone):
-        """
-        :param zone: Zone to list redirects for.
-        :type zone: :class:`Zone`
-
-        :rtype: ``list`` of :class:`MailRedirect`
-        """
-        response = self.connection.request('/zones/%s/mail_redirects' %
-                                           zone.id)
-        mail_redirects = self._to_mail_redirects(response.object, zone)
-        return mail_redirects
-
-    def ex_create_redirect(self, redirect_to, name, type, zone, iframe=None,
-                           query=None):
-        """
-        :param redirect_to: The data field. (redirect_to)
-        :type redirect_to: ``str``
-
-        :param name: The FQDN for the record.
-        :type name: ``str``
-
-        :param type: The type of redirects 301, 302 or 0 for iframes.
-        :type type: ``str``
-
-        :param zone: Zone to list redirects for.
-        :type zone: :class:`Zone`
-
-        :param iframe: Title of iframe (optional).
-        :type iframe: ``str``
-
-        :param query: boolean Information about including query string when
-                      redirecting. (optional).
-        :type query: ``bool``
-
-        :rtype: :class:`Record`
-        """
-        r_json = {'name': name, 'redirect_to': redirect_to}
-        if type is not None:
-            r_json['redirect_type'] = type
-        if iframe is not None:
-            r_json['iframe_title'] = iframe
-        if query is not None:
-            r_json['redirect_query_string'] = query
-        r_data = json.dumps({'zone_redirect': r_json})
-        try:
-            response = self.connection.request('/zones/%s/redirects' % zone.id,
-                                               method='POST', data=r_data)
-        except (BaseHTTPError, MalformedResponseError):
-            e = sys.exc_info()[1]
-            raise PointDNSException(value=e.message, http_code=e.code,
-                                    driver=self)
-        redirect = self._to_redirect(response.object, zone=zone)
-        return redirect
-
-    def ex_create_mail_redirect(self, destination, source, zone):
-        """
-        :param destination: The destination address of mail redirect.
-        :type destination: ``str``
-
-        :param source: The source address of mail redirect.
-        :type source: ``str``
-
-        :param zone: Zone to list redirects for.
-        :type zone: :class:`Zone`
-
-        :rtype: ``list`` of :class:`MailRedirect`
-        """
-        r_json = {'destination_address': destination, 'source_address': source}
-        r_data = json.dumps({'zone_mail_redirect': r_json})
-        try:
-            response = self.connection.request('/zones/%s/mail_redirects' %
-                                               zone.id, method='POST',
-                                               data=r_data)
-        except (BaseHTTPError, MalformedResponseError):
-            e = sys.exc_info()[1]
-            raise PointDNSException(value=e.message, http_code=e.code,
-                                    driver=self)
-        mail_redirect = self._to_mail_redirect(response.object, zone=zone)
-        return mail_redirect
-
-    def ex_get_redirect(self, zone_id, redirect_id):
-        """
-        :param zone: Zone to list redirects for.
-        :type zone: :class:`Zone`
-
-        :param redirect_id: Redirect id.
-        :type redirect_id: ``str``
-
-        :rtype: ``list`` of :class:`Redirect`
-        """
-        try:
-            response = self.connection.request('/zones/%s/redirects/%s' %
-                                               (zone_id, redirect_id))
-        except (BaseHTTPError, MalformedResponseError):
-            e = sys.exc_info()[1]
-            if isinstance(e, MalformedResponseError) and e.body == 'Not found':
-                raise PointDNSException(value='Couldn\'t found redirect',
-                                        http_code=httplib.NOT_FOUND,
-                                        driver=self)
-            raise PointDNSException(value=e.message, http_code=e.code,
-                                    driver=self)
-        redirect = self._to_redirect(response.object, zone_id=zone_id)
-        return redirect
-
-    def ex_get_mail_redirects(self, zone_id, mail_r_id):
-        """
-        :param zone: Zone to list redirects for.
-        :type zone: :class:`Zone`
-
-        :param mail_r_id: Mail redirect id.
-        :type mail_r_id: ``str``
-
-        :rtype: ``list`` of :class:`MailRedirect`
-        """
-        try:
-            response = self.connection.request('/zones/%s/mail_redirects/%s' %
-                                               (zone_id, mail_r_id))
-        except (BaseHTTPError, MalformedResponseError):
-            e = sys.exc_info()[1]
-            if isinstance(e, MalformedResponseError) and e.body == 'Not found':
-                raise PointDNSException(value='Couldn\'t found mail redirect',
-                                        http_code=httplib.NOT_FOUND,
-                                        driver=self)
-            raise PointDNSException(value=e.message, http_code=e.code,
-                                    driver=self)
-        mail_redirect = self._to_mail_redirect(response.object,
-                                               zone_id=zone_id)
-        return mail_redirect
-
-    def ex_update_redirect(self, redirect, redirect_to=None, name=None,
-                           type=None, iframe=None, query=None):
-        """
-        :param redirect: Record to update
-        :type id: :class:`Redirect`
-
-        :param redirect_to: The data field. (optional).
-        :type redirect_to: ``str``
-
-        :param name: The FQDN for the record.
-        :type name: ``str``
-
-        :param type: The type of redirects 301, 302 or 0 for iframes.
-                     (optional).
-        :type type: ``str``
-
-        :param iframe: Title of iframe (optional).
-        :type iframe: ``str``
-
-        :param query: boolean Information about including query string when
-                      redirecting. (optional).
-        :type query: ``bool``
-
-        :rtype: ``list`` of :class:`Redirect`
-        """
-        zone_id = redirect.zone.id
-        r_json = {}
-        if redirect_to is not None:
-            r_json['redirect_to'] = redirect_to
-        if name is not None:
-            r_json['name'] = name
-        if type is not None:
-            r_json['record_type'] = type
-        if iframe is not None:
-            r_json['iframe_title'] = iframe
-        if query is not None:
-            r_json['redirect_query_string'] = query
-        r_data = json.dumps({'zone_redirect': r_json})
-        try:
-            response = self.connection.request('/zones/%s/redirects/%s' %
-                                               (zone_id, redirect.id),
-                                               method='PUT', data=r_data)
-        except (BaseHTTPError, MalformedResponseError):
-            e = sys.exc_info()[1]
-            if isinstance(e, MalformedResponseError) and e.body == 'Not found':
-                raise PointDNSException(value='Couldn\'t found redirect',
-                                        http_code=httplib.NOT_FOUND,
-                                        driver=self)
-            raise PointDNSException(value=e.message, http_code=e.code,
-                                    driver=self)
-        redirect = self._to_redirect(response.object, zone=redirect.zone)
-        return redirect
-
-    def ex_update_mail_redirect(self, mail_r, destination, source=None):
-        """
-        :param mail_r: Mail redirect to update
-        :type mail_r: :class:`MailRedirect`
-
-        :param destination: The destination address of mail redirect.
-        :type destination: ``str``
-
-        :param source: The source address of mail redirect. (optional)
-        :type source: ``str``
-
-        :rtype: ``list`` of :class:`MailRedirect`
-        """
-        zone_id = mail_r.zone.id
-        r_json = {'destination_address': destination}
-        if source is not None:
-            r_json['source_address'] = source
-        r_data = json.dumps({'zone_redirect': r_json})
-        try:
-            response = self.connection.request('/zones/%s/mail_redirects/%s' %
-                                               (zone_id, mail_r.id),
-                                               method='PUT', data=r_data)
-        except (BaseHTTPError, MalformedResponseError):
-            e = sys.exc_info()[1]
-            if isinstance(e, MalformedResponseError) and e.body == 'Not found':
-                raise PointDNSException(value='Couldn\'t found mail redirect',
-                                        http_code=httplib.NOT_FOUND,
-                                        driver=self)
-            raise PointDNSException(value=e.message, http_code=e.code,
-                                    driver=self)
-        mail_redirect = self._to_mail_redirect(response.object,
-                                               zone=mail_r.zone)
-        return mail_redirect
-
-    def ex_delete_redirect(self, redirect):
-        """
-        :param mail_r: Redirect to delete
-        :type mail_r: :class:`Redirect`
-
-        :rtype: ``bool``
-        """
-        zone_id = redirect.zone.id
-        redirect_id = redirect.id
-        try:
-            self.connection.request('/zones/%s/redirects/%s' % (zone_id,
-                                    redirect_id), method='DELETE')
-        except (BaseHTTPError, MalformedResponseError):
-            e = sys.exc_info()[1]
-            if isinstance(e, MalformedResponseError) and e.body == 'Not found':
-                raise PointDNSException(value='Couldn\'t found redirect',
-                                        http_code=httplib.NOT_FOUND,
-                                        driver=self)
-            raise PointDNSException(value=e.message, http_code=e.code,
-                                    driver=self)
-        return True
-
-    def ex_delete_mail_redirect(self, mail_r):
-        """
-        :param mail_r: Mail redirect to update
-        :type mail_r: :class:`MailRedirect`
-
-        :rtype: ``bool``
-        """
-        zone_id = mail_r.zone.id
-        mail_r_id = mail_r.id
-        try:
-            self.connection.request('/zones/%s/mail_redirects/%s' % (zone_id,
-                                    mail_r_id), method='DELETE')
-        except (BaseHTTPError, MalformedResponseError):
-            e = sys.exc_info()[1]
-            if isinstance(e, MalformedResponseError) and e.body == 'Not found':
-                raise PointDNSException(value='Couldn\'t found mail redirect',
-                                        http_code=httplib.NOT_FOUND,
-                                        driver=self)
-            raise PointDNSException(value=e.message, http_code=e.code,
-                                    driver=self)
-        return True
-
-    def _to_zones(self, data):
-        zones = []
-        for zone in data:
-            _zone = self._to_zone(zone)
-            zones.append(_zone)
-
-        return zones
-
-    def _to_zone(self, data):
-        zone = data.get('zone')
-        id = zone.get('id')
-        name = zone.get('name')
-        ttl = zone.get('ttl')
-        extra = {'group': zone.get('group'),
-                 'user-id': zone.get('user-id')}
-
-        # All zones are a primary ones by design, so they
-        # assume that are the master source of info about the
-        # zone, which is the case when domain DNS records
-        # points to PointDNS nameservers.
-        type = 'master'
-
-        return Zone(id=id, domain=name, type=type, ttl=ttl, driver=self,
-                    extra=extra)
-
-    def _to_records(self, data, zone):
-        records = []
-        for item in data:
-            record = self._to_record(item, zone=zone)
-            records.append(record)
-        return records
-
-    def _to_record(self, data, zone_id=None, zone=None):
-        if not zone:  # We need zone_id or zone
-            zone = self.get_zone(zone_id)
-        record = data.get('zone_record')
-        id = record.get('id')
-        name = record.get('name')
-        type = record.get('record_type')
-        data = record.get('data')
-        extra = {'ttl': record.get('ttl'),
-                 'zone_id': record.get('zone_id'),
-                 'aux': record.get('aux')}
-        return Record(id=id, name=name, type=type, data=data, zone=zone,
-                      driver=self, ttl=record.get('ttl', None), extra=extra)
-
-    def _to_redirects(self, data, zone):
-        redirects = []
-        for item in data:
-            redirect = self._to_redirect(item, zone=zone)
-            redirects.append(redirect)
-        return redirects
-
-    def _to_redirect(self, data, zone_id=None, zone=None):
-        if not zone:  # We need zone_id or zone
-            zone = self.get_zone(zone_id)
-        record = data.get('zone_redirect')
-        id = record.get('id')
-        name = record.get('name')
-        redirect_to = record.get('redirect_to')
-        type = record.get('redirect_type')
-        iframe = record.get('iframe_title')
-        query = record.get('redirect_query_string')
-        return Redirect(id, name, redirect_to, type, self, zone,
-                        iframe=iframe, query=query)
-
-    def _to_mail_redirects(self, data, zone):
-        mail_redirects = []
-        for item in data:
-            mail_redirect = self._to_mail_redirect(item, zone=zone)
-            mail_redirects.append(mail_redirect)
-        return mail_redirects
-
-    def _to_mail_redirect(self, data, zone_id=None, zone=None):
-        if not zone:  # We need zone_id or zone
-            zone = self.get_zone(zone_id)
-        record = data.get('zone_mail_redirect')
-        id = record.get('id')
-        destination = record.get('destination_address')
-        source = record.get('source_address')
-        return MailRedirect(id, source, destination, zone, self)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/rackspace.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/rackspace.py b/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/rackspace.py
deleted file mode 100644
index 6d231e0..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/rackspace.py
+++ /dev/null
@@ -1,662 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 copy
-
-from libcloud.utils.py3 import httplib
-from libcloud.common.openstack import OpenStackDriverMixin
-from libcloud.common.base import PollingConnection
-from libcloud.common.exceptions import BaseHTTPError
-from libcloud.common.types import LibcloudError
-from libcloud.utils.misc import merge_valid_keys, get_new_obj
-from libcloud.common.rackspace import AUTH_URL
-from libcloud.compute.drivers.openstack import OpenStack_1_1_Connection
-from libcloud.compute.drivers.openstack import OpenStack_1_1_Response
-
-from libcloud.dns.types import Provider, RecordType
-from libcloud.dns.types import ZoneDoesNotExistError, RecordDoesNotExistError
-from libcloud.dns.base import DNSDriver, Zone, Record
-
-__all__ = [
-    'RackspaceDNSResponse',
-    'RackspaceDNSConnection'
-]
-
-VALID_ZONE_EXTRA_PARAMS = ['email', 'comment', 'ns1']
-VALID_RECORD_EXTRA_PARAMS = ['ttl', 'comment', 'priority', 'created',
-                             'updated']
-
-
-class RackspaceDNSResponse(OpenStack_1_1_Response):
-    """
-    Rackspace DNS Response class.
-    """
-
-    def parse_error(self):
-        status = int(self.status)
-        context = self.connection.context
-        body = self.parse_body()
-
-        if status == httplib.NOT_FOUND:
-            if context['resource'] == 'zone':
-                raise ZoneDoesNotExistError(value='', driver=self,
-                                            zone_id=context['id'])
-            elif context['resource'] == 'record':
-                raise RecordDoesNotExistError(value='', driver=self,
-                                              record_id=context['id'])
-        if body:
-            if 'code' and 'message' in body:
-                err = '%s - %s (%s)' % (body['code'], body['message'],
-                                        body['details'])
-                return err
-            elif 'validationErrors' in body:
-                errors = [m for m in body['validationErrors']['messages']]
-                err = 'Validation errors: %s' % ', '.join(errors)
-                return err
-
-        raise LibcloudError('Unexpected status code: %s' % (status))
-
-
-class RackspaceDNSConnection(OpenStack_1_1_Connection, PollingConnection):
-    """
-    Rackspace DNS Connection class.
-    """
-
-    responseCls = RackspaceDNSResponse
-    XML_NAMESPACE = None
-    poll_interval = 2.5
-    timeout = 30
-
-    auth_url = AUTH_URL
-    _auth_version = '2.0'
-
-    def __init__(self, *args, **kwargs):
-            self.region = kwargs.pop('region', None)
-            super(RackspaceDNSConnection, self).__init__(*args, **kwargs)
-
-    def get_poll_request_kwargs(self, response, context, request_kwargs):
-        job_id = response.object['jobId']
-        kwargs = {'action': '/status/%s' % (job_id),
-                  'params': {'showDetails': True}}
-        return kwargs
-
-    def has_completed(self, response):
-        status = response.object['status']
-        if status == 'ERROR':
-            data = response.object['error']
-
-            if 'code' and 'message' in data:
-                message = '%s - %s (%s)' % (data['code'], data['message'],
-                                            data['details'])
-            else:
-                message = data['message']
-
-            raise LibcloudError(message,
-                                driver=self.driver)
-
-        return status == 'COMPLETED'
-
-    def get_endpoint(self):
-        if '2.0' in self._auth_version:
-            ep = self.service_catalog.get_endpoint(name='cloudDNS',
-                                                   service_type='rax:dns',
-                                                   region=None)
-        else:
-            raise LibcloudError("Auth version %s not supported" %
-                                (self._auth_version))
-
-        public_url = ep.url
-
-        # This is a nasty hack, but because of how global auth and old accounts
-        # work, there is no way around it.
-        if self.region == 'us':
-            # Old UK account, which only has us endpoint in the catalog
-            public_url = public_url.replace('https://lon.dns.api',
-                                            'https://dns.api')
-        if self.region == 'uk':
-            # Old US account, which only has uk endpoint in the catalog
-            public_url = public_url.replace('https://dns.api',
-                                            'https://lon.dns.api')
-
-        return public_url
-
-
-class RackspacePTRRecord(object):
-    def __init__(self, id, ip, domain, driver, extra=None):
-        self.id = str(id) if id else None
-        self.ip = ip
-        self.type = RecordType.PTR
-        self.domain = domain
-        self.driver = driver
-        self.extra = extra or {}
-
-    def update(self, domain, extra=None):
-        return self.driver.ex_update_ptr_record(record=self, domain=domain,
-                                                extra=extra)
-
-    def delete(self):
-        return self.driver.ex_delete_ptr_record(record=self)
-
-    def __repr__(self):
-        return ('<%s: ip=%s, domain=%s, provider=%s ...>' %
-                (self.__class__.__name__, self.ip,
-                 self.domain, self.driver.name))
-
-
-class RackspaceDNSDriver(DNSDriver, OpenStackDriverMixin):
-    name = 'Rackspace DNS'
-    website = 'http://www.rackspace.com/'
-    type = Provider.RACKSPACE
-    connectionCls = RackspaceDNSConnection
-
-    def __init__(self, key, secret=None, secure=True, host=None, port=None,
-                 region='us', **kwargs):
-        valid_regions = self.list_regions()
-        if region not in valid_regions:
-            raise ValueError('Invalid region: %s' % (region))
-
-        OpenStackDriverMixin.__init__(self, **kwargs)
-        super(RackspaceDNSDriver, self).__init__(key=key, secret=secret,
-                                                 host=host, port=port,
-                                                 region=region)
-
-    RECORD_TYPE_MAP = {
-        RecordType.A: 'A',
-        RecordType.AAAA: 'AAAA',
-        RecordType.CNAME: 'CNAME',
-        RecordType.MX: 'MX',
-        RecordType.NS: 'NS',
-        RecordType.PTR: 'PTR',
-        RecordType.SRV: 'SRV',
-        RecordType.TXT: 'TXT',
-    }
-
-    @classmethod
-    def list_regions(cls):
-        return ['us', 'uk']
-
-    def iterate_zones(self):
-        offset = 0
-        limit = 100
-        while True:
-            params = {
-                'limit': limit,
-                'offset': offset,
-            }
-            response = self.connection.request(
-                action='/domains', params=params).object
-            zones_list = response['domains']
-            for item in zones_list:
-                yield self._to_zone(item)
-
-            if _rackspace_result_has_more(response, len(zones_list), limit):
-                offset += limit
-            else:
-                break
-
-    def iterate_records(self, zone):
-        self.connection.set_context({'resource': 'zone', 'id': zone.id})
-        offset = 0
-        limit = 100
-        while True:
-            params = {
-                'showRecord': True,
-                'limit': limit,
-                'offset': offset,
-            }
-            response = self.connection.request(
-                action='/domains/%s' % (zone.id), params=params).object
-            records_list = response['recordsList']
-            records = records_list['records']
-            for item in records:
-                record = self._to_record(data=item, zone=zone)
-                yield record
-
-            if _rackspace_result_has_more(records_list, len(records), limit):
-                offset += limit
-            else:
-                break
-
-    def get_zone(self, zone_id):
-        self.connection.set_context({'resource': 'zone', 'id': zone_id})
-        response = self.connection.request(action='/domains/%s' % (zone_id))
-        zone = self._to_zone(data=response.object)
-        return zone
-
-    def get_record(self, zone_id, record_id):
-        zone = self.get_zone(zone_id=zone_id)
-        self.connection.set_context({'resource': 'record', 'id': record_id})
-        response = self.connection.request(action='/domains/%s/records/%s' %
-                                           (zone_id, record_id)).object
-        record = self._to_record(data=response, zone=zone)
-        return record
-
-    def create_zone(self, domain, type='master', ttl=None, extra=None):
-        extra = extra if extra else {}
-
-        # Email address is required
-        if 'email' not in extra:
-            raise ValueError('"email" key must be present in extra dictionary')
-
-        payload = {'name': domain, 'emailAddress': extra['email'],
-                   'recordsList': {'records': []}}
-
-        if ttl:
-            payload['ttl'] = ttl
-
-        if 'comment' in extra:
-            payload['comment'] = extra['comment']
-
-        data = {'domains': [payload]}
-        response = self.connection.async_request(action='/domains',
-                                                 method='POST', data=data)
-        zone = self._to_zone(data=response.object['response']['domains'][0])
-        return zone
-
-    def update_zone(self, zone, domain=None, type=None, ttl=None, extra=None):
-        # Only ttl, comment and email address can be changed
-        extra = extra if extra else {}
-
-        if domain:
-            raise LibcloudError('Domain cannot be changed', driver=self)
-
-        data = {}
-
-        if ttl:
-            data['ttl'] = int(ttl)
-
-        if 'email' in extra:
-            data['emailAddress'] = extra['email']
-
-        if 'comment' in extra:
-            data['comment'] = extra['comment']
-
-        type = type if type else zone.type
-        ttl = ttl if ttl else zone.ttl
-
-        self.connection.set_context({'resource': 'zone', 'id': zone.id})
-        self.connection.async_request(action='/domains/%s' % (zone.id),
-                                      method='PUT', data=data)
-        merged = merge_valid_keys(params=copy.deepcopy(zone.extra),
-                                  valid_keys=VALID_ZONE_EXTRA_PARAMS,
-                                  extra=extra)
-        updated_zone = get_new_obj(obj=zone, klass=Zone,
-                                   attributes={'type': type,
-                                               'ttl': ttl,
-                                               'extra': merged})
-        return updated_zone
-
-    def create_record(self, name, zone, type, data, extra=None):
-        # Name must be a FQDN - e.g. if domain is "foo.com" then a record
-        # name is "bar.foo.com"
-        extra = extra if extra else {}
-
-        name = self._to_full_record_name(domain=zone.domain, name=name)
-        data = {'name': name, 'type': self.RECORD_TYPE_MAP[type],
-                'data': data}
-
-        if 'ttl' in extra:
-            data['ttl'] = int(extra['ttl'])
-
-        if 'priority' in extra:
-            data['priority'] = int(extra['priority'])
-
-        payload = {'records': [data]}
-        self.connection.set_context({'resource': 'zone', 'id': zone.id})
-        response = self.connection.async_request(action='/domains/%s/records'
-                                                 % (zone.id), data=payload,
-                                                 method='POST').object
-        record = self._to_record(data=response['response']['records'][0],
-                                 zone=zone)
-        return record
-
-    def update_record(self, record, name=None, type=None, data=None,
-                      extra=None):
-        # Only data, ttl, and comment attributes can be modified, but name
-        # attribute must always be present.
-        extra = extra if extra else {}
-
-        name = self._to_full_record_name(domain=record.zone.domain,
-                                         name=record.name)
-        payload = {'name': name}
-
-        if data:
-            payload['data'] = data
-
-        if 'ttl' in extra:
-            payload['ttl'] = extra['ttl']
-
-        if 'comment' in extra:
-            payload['comment'] = extra['comment']
-
-        type = type if type is not None else record.type
-        data = data if data else record.data
-
-        self.connection.set_context({'resource': 'record', 'id': record.id})
-        self.connection.async_request(action='/domains/%s/records/%s' %
-                                      (record.zone.id, record.id),
-                                      method='PUT', data=payload)
-
-        merged = merge_valid_keys(params=copy.deepcopy(record.extra),
-                                  valid_keys=VALID_RECORD_EXTRA_PARAMS,
-                                  extra=extra)
-        updated_record = get_new_obj(obj=record, klass=Record,
-                                     attributes={'type': type,
-                                                 'data': data,
-                                                 'driver': self,
-                                                 'extra': merged})
-        return updated_record
-
-    def delete_zone(self, zone):
-        self.connection.set_context({'resource': 'zone', 'id': zone.id})
-        self.connection.async_request(action='/domains/%s' % (zone.id),
-                                      method='DELETE')
-        return True
-
-    def delete_record(self, record):
-        self.connection.set_context({'resource': 'record', 'id': record.id})
-        self.connection.async_request(action='/domains/%s/records/%s' %
-                                      (record.zone.id, record.id),
-                                      method='DELETE')
-        return True
-
-    def ex_iterate_ptr_records(self, device):
-        """
-        Return a generator to iterate over existing PTR Records.
-
-        The ``device`` should be an instance of one of these:
-            :class:`libcloud.compute.base.Node`
-            :class:`libcloud.loadbalancer.base.LoadBalancer`
-
-        And it needs to have the following ``extra`` fields set:
-            service_name - the service catalog name for the device
-            uri - the URI pointing to the GET endpoint for the device
-
-        Those are automatically set for you if you got the device from
-        the Rackspace driver for that service.
-
-        For example:
-            server = rs_compute.ex_get_node_details(id)
-            ptr_iter = rs_dns.ex_list_ptr_records(server)
-
-            loadbalancer = rs_lbs.get_balancer(id)
-            ptr_iter = rs_dns.ex_list_ptr_records(loadbalancer)
-
-        Note: the Rackspace DNS API docs indicate that the device 'href' is
-        optional, but testing does not bear this out. It throws a
-        400 Bad Request error if you do not pass in the 'href' from
-        the server or loadbalancer.  So ``device`` is required.
-
-        :param device: the device that owns the IP
-        :rtype: ``generator`` of :class:`RackspacePTRRecord`
-        """
-        _check_ptr_extra_fields(device)
-        params = {'href': device.extra['uri']}
-
-        service_name = device.extra['service_name']
-
-        # without a valid context, the 404 on empty list will blow up
-        # in the error-handling code
-        self.connection.set_context({'resource': 'ptr_records'})
-        try:
-            response = self.connection.request(
-                action='/rdns/%s' % (service_name), params=params).object
-            records = response['records']
-            link = dict(rel=service_name, **params)
-            for item in records:
-                record = self._to_ptr_record(data=item, link=link)
-                yield record
-        except BaseHTTPError as exc:
-            # 404 just means empty list
-            if exc.code == 404:
-                return
-            raise
-
-    def ex_get_ptr_record(self, service_name, record_id):
-        """
-        Get a specific PTR record by id.
-
-        :param service_name: the service catalog name of the linked device(s)
-                             i.e. cloudLoadBalancers or cloudServersOpenStack
-        :param record_id: the id (i.e. PTR-12345) of the PTR record
-        :rtype: instance of :class:`RackspacePTRRecord`
-        """
-        self.connection.set_context({'resource': 'record', 'id': record_id})
-        response = self.connection.request(
-            action='/rdns/%s/%s' % (service_name, record_id)).object
-        item = next(iter(response['recordsList']['records']))
-        return self._to_ptr_record(data=item, link=response['link'])
-
-    def ex_create_ptr_record(self, device, ip, domain, extra=None):
-        """
-        Create a PTR record for a specific IP on a specific device.
-
-        The ``device`` should be an instance of one of these:
-            :class:`libcloud.compute.base.Node`
-            :class:`libcloud.loadbalancer.base.LoadBalancer`
-
-        And it needs to have the following ``extra`` fields set:
-            service_name - the service catalog name for the device
-            uri - the URI pointing to the GET endpoint for the device
-
-        Those are automatically set for you if you got the device from
-        the Rackspace driver for that service.
-
-        For example:
-            server = rs_compute.ex_get_node_details(id)
-            rs_dns.create_ptr_record(server, ip, domain)
-
-            loadbalancer = rs_lbs.get_balancer(id)
-            rs_dns.create_ptr_record(loadbalancer, ip, domain)
-
-        :param device: the device that owns the IP
-        :param ip: the IP for which you want to set reverse DNS
-        :param domain: the fqdn you want that IP to represent
-        :param extra: a ``dict`` with optional extra values:
-            ttl - the time-to-live of the PTR record
-        :rtype: instance of :class:`RackspacePTRRecord`
-        """
-        _check_ptr_extra_fields(device)
-
-        if extra is None:
-            extra = {}
-
-        # the RDNS API reverse the name and data fields for PTRs
-        # the record name *should* be the ip and the data the fqdn
-        data = {
-            "name": domain,
-            "type": RecordType.PTR,
-            "data": ip
-        }
-
-        if 'ttl' in extra:
-            data['ttl'] = extra['ttl']
-
-        payload = {
-            "recordsList": {
-                "records": [data]
-            },
-            "link": {
-                "content": "",
-                "href": device.extra['uri'],
-                "rel": device.extra['service_name'],
-            }
-        }
-        response = self.connection.async_request(
-            action='/rdns', method='POST', data=payload).object
-        item = next(iter(response['response']['records']))
-        return self._to_ptr_record(data=item, link=payload['link'])
-
-    def ex_update_ptr_record(self, record, domain=None, extra=None):
-        """
-        Update a PTR record for a specific IP on a specific device.
-
-        If you need to change the domain or ttl, use this API to
-        update the record by deleting the old one and creating a new one.
-
-        :param record: the original :class:`RackspacePTRRecord`
-        :param domain: the fqdn you want that IP to represent
-        :param extra: a ``dict`` with optional extra values:
-            ttl - the time-to-live of the PTR record
-        :rtype: instance of :class:`RackspacePTRRecord`
-        """
-        if domain is not None and domain == record.domain:
-            domain = None
-
-        if extra is not None:
-            extra = dict(extra)
-            for key in extra:
-                if key in record.extra and record.extra[key] == extra[key]:
-                    del extra[key]
-
-        if domain is None and not extra:
-            # nothing to do, it already matches
-            return record
-
-        _check_ptr_extra_fields(record)
-        ip = record.ip
-
-        self.ex_delete_ptr_record(record)
-        # records have the same metadata in 'extra' as the original device
-        # so you can pass the original record object in instead
-        return self.ex_create_ptr_record(record, ip, domain, extra=extra)
-
-    def ex_delete_ptr_record(self, record):
-        """
-        Delete an existing PTR Record
-
-        :param record: the original :class:`RackspacePTRRecord`
-        :rtype: ``bool``
-        """
-        _check_ptr_extra_fields(record)
-        self.connection.set_context({'resource': 'record', 'id': record.id})
-        self.connection.async_request(
-            action='/rdns/%s' % (record.extra['service_name']),
-            method='DELETE',
-            params={'href': record.extra['uri'], 'ip': record.ip},
-        )
-        return True
-
-    def _to_zone(self, data):
-        id = data['id']
-        domain = data['name']
-        type = 'master'
-        ttl = data.get('ttl', 0)
-        extra = {}
-
-        if 'emailAddress' in data:
-            extra['email'] = data['emailAddress']
-
-        if 'comment' in data:
-            extra['comment'] = data['comment']
-
-        zone = Zone(id=str(id), domain=domain, type=type, ttl=int(ttl),
-                    driver=self, extra=extra)
-        return zone
-
-    def _to_record(self, data, zone):
-        id = data['id']
-        fqdn = data['name']
-        name = self._to_partial_record_name(domain=zone.domain, name=fqdn)
-        type = self._string_to_record_type(data['type'])
-        record_data = data['data']
-        extra = {'fqdn': fqdn}
-
-        for key in VALID_RECORD_EXTRA_PARAMS:
-            if key in data:
-                extra[key] = data[key]
-
-        record = Record(id=str(id), name=name, type=type, data=record_data,
-                        zone=zone, driver=self, ttl=extra.get('ttl', None),
-                        extra=extra)
-        return record
-
-    def _to_ptr_record(self, data, link):
-        id = data['id']
-        ip = data['data']
-        domain = data['name']
-        extra = {'uri': link['href'], 'service_name': link['rel']}
-
-        for key in VALID_RECORD_EXTRA_PARAMS:
-            if key in data:
-                extra[key] = data[key]
-
-        record = RackspacePTRRecord(id=str(id), ip=ip, domain=domain,
-                                    driver=self, extra=extra)
-        return record
-
-    def _to_full_record_name(self, domain, name):
-        """
-        Build a FQDN from a domain and record name.
-
-        :param domain: Domain name.
-        :type domain: ``str``
-
-        :param name: Record name.
-        :type name: ``str``
-        """
-        if name:
-            name = '%s.%s' % (name, domain)
-        else:
-            name = domain
-
-        return name
-
-    def _to_partial_record_name(self, domain, name):
-        """
-        Remove domain portion from the record name.
-
-        :param domain: Domain name.
-        :type domain: ``str``
-
-        :param name: Full record name (fqdn).
-        :type name: ``str``
-        """
-        if name == domain:
-            # Map "root" record names to None to be consistent with other
-            # drivers
-            return None
-
-        # Strip domain portion
-        name = name.replace('.%s' % (domain), '')
-        return name
-
-    def _ex_connection_class_kwargs(self):
-        kwargs = self.openstack_connection_kwargs()
-        kwargs['region'] = self.region
-        return kwargs
-
-
-def _rackspace_result_has_more(response, result_length, limit):
-    # If rackspace returns less than the limit, then we've reached the end of
-    # the result set.
-    if result_length < limit:
-        return False
-
-    # Paginated results return links to the previous and next sets of data, but
-    # 'next' only exists when there is more to get.
-    for item in response.get('links', ()):
-        if item['rel'] == 'next':
-            return True
-    return False
-
-
-def _check_ptr_extra_fields(device_or_record):
-    if not (hasattr(device_or_record, 'extra') and
-            isinstance(device_or_record.extra, dict) and
-            device_or_record.extra.get('uri') is not None and
-            device_or_record.extra.get('service_name') is not None):
-        raise LibcloudError("Can't create PTR Record for %s because it "
-                            "doesn't have a 'uri' and 'service_name' in "
-                            "'extra'" % device_or_record)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/route53.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/route53.py b/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/route53.py
deleted file mode 100644
index 040cdbc..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/route53.py
+++ /dev/null
@@ -1,548 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-__all__ = [
-    'Route53DNSDriver'
-]
-
-import base64
-import hmac
-import datetime
-import uuid
-import copy
-from libcloud.utils.py3 import httplib
-
-from hashlib import sha1
-
-try:
-    from lxml import etree as ET
-except ImportError:
-    from xml.etree import ElementTree as ET
-
-from libcloud.utils.py3 import b, urlencode
-
-from libcloud.utils.xml import findtext, findall, fixxpath
-from libcloud.dns.types import Provider, RecordType
-from libcloud.dns.types import ZoneDoesNotExistError, RecordDoesNotExistError
-from libcloud.dns.base import DNSDriver, Zone, Record
-from libcloud.common.types import LibcloudError
-from libcloud.common.aws import AWSGenericResponse
-from libcloud.common.base import ConnectionUserAndKey
-
-
-API_VERSION = '2012-02-29'
-API_HOST = 'route53.amazonaws.com'
-API_ROOT = '/%s/' % (API_VERSION)
-
-NAMESPACE = 'https://%s/doc%s' % (API_HOST, API_ROOT)
-
-
-class InvalidChangeBatch(LibcloudError):
-    pass
-
-
-class Route53DNSResponse(AWSGenericResponse):
-    """
-    Amazon Route53 response class.
-    """
-
-    namespace = NAMESPACE
-    xpath = 'Error'
-
-    exceptions = {
-        'NoSuchHostedZone': ZoneDoesNotExistError,
-        'InvalidChangeBatch': InvalidChangeBatch,
-    }
-
-
-class Route53Connection(ConnectionUserAndKey):
-    host = API_HOST
-    responseCls = Route53DNSResponse
-
-    def pre_connect_hook(self, params, headers):
-        time_string = datetime.datetime.utcnow() \
-                              .strftime('%a, %d %b %Y %H:%M:%S GMT')
-        headers['Date'] = time_string
-        tmp = []
-
-        signature = self._get_aws_auth_b64(self.key, time_string)
-        auth = {'AWSAccessKeyId': self.user_id, 'Signature': signature,
-                'Algorithm': 'HmacSHA1'}
-
-        for k, v in auth.items():
-            tmp.append('%s=%s' % (k, v))
-
-        headers['X-Amzn-Authorization'] = 'AWS3-HTTPS ' + ','.join(tmp)
-
-        return params, headers
-
-    def _get_aws_auth_b64(self, secret_key, time_string):
-        b64_hmac = base64.b64encode(
-            hmac.new(b(secret_key), b(time_string), digestmod=sha1).digest()
-        )
-
-        return b64_hmac.decode('utf-8')
-
-
-class Route53DNSDriver(DNSDriver):
-    type = Provider.ROUTE53
-    name = 'Route53 DNS'
-    website = 'http://aws.amazon.com/route53/'
-    connectionCls = Route53Connection
-
-    RECORD_TYPE_MAP = {
-        RecordType.A: 'A',
-        RecordType.AAAA: 'AAAA',
-        RecordType.CNAME: 'CNAME',
-        RecordType.MX: 'MX',
-        RecordType.NS: 'NS',
-        RecordType.PTR: 'PTR',
-        RecordType.SOA: 'SOA',
-        RecordType.SPF: 'SPF',
-        RecordType.SRV: 'SRV',
-        RecordType.TXT: 'TXT',
-    }
-
-    def iterate_zones(self):
-        return self._get_more('zones')
-
-    def iterate_records(self, zone):
-        return self._get_more('records', zone=zone)
-
-    def get_zone(self, zone_id):
-        self.connection.set_context({'zone_id': zone_id})
-        uri = API_ROOT + 'hostedzone/' + zone_id
-        data = self.connection.request(uri).object
-        elem = findall(element=data, xpath='HostedZone',
-                       namespace=NAMESPACE)[0]
-        return self._to_zone(elem)
-
-    def get_record(self, zone_id, record_id):
-        zone = self.get_zone(zone_id=zone_id)
-        record_type, name = record_id.split(':', 1)
-        if name:
-            full_name = ".".join((name, zone.domain))
-        else:
-            full_name = zone.domain
-        self.connection.set_context({'zone_id': zone_id})
-        params = urlencode({
-            'name': full_name,
-            'type': record_type,
-            'maxitems': '1'
-        })
-        uri = API_ROOT + 'hostedzone/' + zone_id + '/rrset?' + params
-        data = self.connection.request(uri).object
-
-        record = self._to_records(data=data, zone=zone)[0]
-
-        # A cute aspect of the /rrset filters is that they are more pagination
-        # hints than filters!!
-        # So will return a result even if its not what you asked for.
-        record_type_num = self._string_to_record_type(record_type)
-        if record.name != name or record.type != record_type_num:
-            raise RecordDoesNotExistError(value='', driver=self,
-                                          record_id=record_id)
-
-        return record
-
-    def create_zone(self, domain, type='master', ttl=None, extra=None):
-        zone = ET.Element('CreateHostedZoneRequest', {'xmlns': NAMESPACE})
-        ET.SubElement(zone, 'Name').text = domain
-        ET.SubElement(zone, 'CallerReference').text = str(uuid.uuid4())
-
-        if extra and 'Comment' in extra:
-            hzg = ET.SubElement(zone, 'HostedZoneConfig')
-            ET.SubElement(hzg, 'Comment').text = extra['Comment']
-
-        uri = API_ROOT + 'hostedzone'
-        data = ET.tostring(zone)
-        rsp = self.connection.request(uri, method='POST', data=data).object
-
-        elem = findall(element=rsp, xpath='HostedZone', namespace=NAMESPACE)[0]
-        return self._to_zone(elem=elem)
-
-    def delete_zone(self, zone, ex_delete_records=False):
-        self.connection.set_context({'zone_id': zone.id})
-
-        if ex_delete_records:
-            self.ex_delete_all_records(zone=zone)
-
-        uri = API_ROOT + 'hostedzone/%s' % (zone.id)
-        response = self.connection.request(uri, method='DELETE')
-        return response.status in [httplib.OK]
-
-    def create_record(self, name, zone, type, data, extra=None):
-        extra = extra or {}
-        batch = [('CREATE', name, type, data, extra)]
-        self._post_changeset(zone, batch)
-        id = ':'.join((self.RECORD_TYPE_MAP[type], name))
-        return Record(id=id, name=name, type=type, data=data, zone=zone,
-                      driver=self, ttl=extra.get('ttl', None), extra=extra)
-
-    def update_record(self, record, name=None, type=None, data=None,
-                      extra=None):
-        name = name or record.name
-        type = type or record.type
-        extra = extra or record.extra
-
-        if not extra:
-            extra = record.extra
-
-        # Multiple value records need to be handled specially - we need to
-        # pass values for other records as well
-        multiple_value_record = record.extra.get('_multi_value', False)
-        other_records = record.extra.get('_other_records', [])
-
-        if multiple_value_record and other_records:
-            self._update_multi_value_record(record=record, name=name,
-                                            type=type, data=data,
-                                            extra=extra)
-        else:
-            self._update_single_value_record(record=record, name=name,
-                                             type=type, data=data,
-                                             extra=extra)
-
-        id = ':'.join((self.RECORD_TYPE_MAP[type], name))
-        return Record(id=id, name=name, type=type, data=data, zone=record.zone,
-                      driver=self, ttl=extra.get('ttl', None), extra=extra)
-
-    def delete_record(self, record):
-        try:
-            r = record
-            batch = [('DELETE', r.name, r.type, r.data, r.extra)]
-            self._post_changeset(record.zone, batch)
-        except InvalidChangeBatch:
-            raise RecordDoesNotExistError(value='', driver=self,
-                                          record_id=r.id)
-        return True
-
-    def ex_create_multi_value_record(self, name, zone, type, data, extra=None):
-        """
-        Create a record with multiple values with a single call.
-
-        :return: A list of created records.
-        :rtype: ``list`` of :class:`libcloud.dns.base.Record`
-        """
-        extra = extra or {}
-
-        attrs = {'xmlns': NAMESPACE}
-        changeset = ET.Element('ChangeResourceRecordSetsRequest', attrs)
-        batch = ET.SubElement(changeset, 'ChangeBatch')
-        changes = ET.SubElement(batch, 'Changes')
-
-        change = ET.SubElement(changes, 'Change')
-        ET.SubElement(change, 'Action').text = 'CREATE'
-
-        rrs = ET.SubElement(change, 'ResourceRecordSet')
-        ET.SubElement(rrs, 'Name').text = name + '.' + zone.domain
-        ET.SubElement(rrs, 'Type').text = self.RECORD_TYPE_MAP[type]
-        ET.SubElement(rrs, 'TTL').text = str(extra.get('ttl', '0'))
-
-        rrecs = ET.SubElement(rrs, 'ResourceRecords')
-
-        # Value is provided as a multi line string
-        values = [value.strip() for value in data.split('\n') if
-                  value.strip()]
-
-        for value in values:
-            rrec = ET.SubElement(rrecs, 'ResourceRecord')
-            ET.SubElement(rrec, 'Value').text = value
-
-        uri = API_ROOT + 'hostedzone/' + zone.id + '/rrset'
-        data = ET.tostring(changeset)
-        self.connection.set_context({'zone_id': zone.id})
-        self.connection.request(uri, method='POST', data=data)
-
-        id = ':'.join((self.RECORD_TYPE_MAP[type], name))
-
-        records = []
-        for value in values:
-            record = Record(id=id, name=name, type=type, data=value, zone=zone,
-                            driver=self, ttl=extra.get('ttl', None),
-                            extra=extra)
-            records.append(record)
-
-        return records
-
-    def ex_delete_all_records(self, zone):
-        """
-        Remove all the records for the provided zone.
-
-        :param zone: Zone to delete records for.
-        :type  zone: :class:`Zone`
-        """
-        deletions = []
-        for r in zone.list_records():
-            if r.type in (RecordType.NS, RecordType.SOA):
-                continue
-            deletions.append(('DELETE', r.name, r.type, r.data, r.extra))
-
-        if deletions:
-            self._post_changeset(zone, deletions)
-
-    def _update_single_value_record(self, record, name=None, type=None,
-                                    data=None, extra=None):
-        batch = [
-            ('DELETE', record.name, record.type, record.data, record.extra),
-            ('CREATE', name, type, data, extra)
-        ]
-
-        return self._post_changeset(record.zone, batch)
-
-    def _update_multi_value_record(self, record, name=None, type=None,
-                                   data=None, extra=None):
-        other_records = record.extra.get('_other_records', [])
-
-        attrs = {'xmlns': NAMESPACE}
-        changeset = ET.Element('ChangeResourceRecordSetsRequest', attrs)
-        batch = ET.SubElement(changeset, 'ChangeBatch')
-        changes = ET.SubElement(batch, 'Changes')
-
-        # Delete existing records
-        change = ET.SubElement(changes, 'Change')
-        ET.SubElement(change, 'Action').text = 'DELETE'
-
-        rrs = ET.SubElement(change, 'ResourceRecordSet')
-
-        if record.name:
-            record_name = record.name + '.' + record.zone.domain
-        else:
-            record_name = record.zone.domain
-
-        ET.SubElement(rrs, 'Name').text = record_name
-        ET.SubElement(rrs, 'Type').text = self.RECORD_TYPE_MAP[record.type]
-        ET.SubElement(rrs, 'TTL').text = str(record.extra.get('ttl', '0'))
-
-        rrecs = ET.SubElement(rrs, 'ResourceRecords')
-
-        rrec = ET.SubElement(rrecs, 'ResourceRecord')
-        ET.SubElement(rrec, 'Value').text = record.data
-
-        for other_record in other_records:
-            rrec = ET.SubElement(rrecs, 'ResourceRecord')
-            ET.SubElement(rrec, 'Value').text = other_record['data']
-
-        # Re-create new (updated) records. Since we are updating a multi value
-        # record, only a single record is updated and others are left as is.
-        change = ET.SubElement(changes, 'Change')
-        ET.SubElement(change, 'Action').text = 'CREATE'
-
-        rrs = ET.SubElement(change, 'ResourceRecordSet')
-
-        if name:
-            record_name = name + '.' + record.zone.domain
-        else:
-            record_name = record.zone.domain
-
-        ET.SubElement(rrs, 'Name').text = record_name
-        ET.SubElement(rrs, 'Type').text = self.RECORD_TYPE_MAP[type]
-        ET.SubElement(rrs, 'TTL').text = str(extra.get('ttl', '0'))
-
-        rrecs = ET.SubElement(rrs, 'ResourceRecords')
-
-        rrec = ET.SubElement(rrecs, 'ResourceRecord')
-        ET.SubElement(rrec, 'Value').text = data
-
-        for other_record in other_records:
-            rrec = ET.SubElement(rrecs, 'ResourceRecord')
-            ET.SubElement(rrec, 'Value').text = other_record['data']
-        uri = API_ROOT + 'hostedzone/' + record.zone.id + '/rrset'
-        data = ET.tostring(changeset)
-        self.connection.set_context({'zone_id': record.zone.id})
-        response = self.connection.request(uri, method='POST', data=data)
-
-        return response.status == httplib.OK
-
-    def _post_changeset(self, zone, changes_list):
-        attrs = {'xmlns': NAMESPACE}
-        changeset = ET.Element('ChangeResourceRecordSetsRequest', attrs)
-        batch = ET.SubElement(changeset, 'ChangeBatch')
-        changes = ET.SubElement(batch, 'Changes')
-
-        for action, name, type_, data, extra in changes_list:
-            change = ET.SubElement(changes, 'Change')
-            ET.SubElement(change, 'Action').text = action
-
-            rrs = ET.SubElement(change, 'ResourceRecordSet')
-
-            if name:
-                record_name = name + '.' + zone.domain
-            else:
-                record_name = zone.domain
-
-            ET.SubElement(rrs, 'Name').text = record_name
-            ET.SubElement(rrs, 'Type').text = self.RECORD_TYPE_MAP[type_]
-            ET.SubElement(rrs, 'TTL').text = str(extra.get('ttl', '0'))
-
-            rrecs = ET.SubElement(rrs, 'ResourceRecords')
-            rrec = ET.SubElement(rrecs, 'ResourceRecord')
-            if 'priority' in extra:
-                data = '%s %s' % (extra['priority'], data)
-            ET.SubElement(rrec, 'Value').text = data
-
-        uri = API_ROOT + 'hostedzone/' + zone.id + '/rrset'
-        data = ET.tostring(changeset)
-        self.connection.set_context({'zone_id': zone.id})
-        response = self.connection.request(uri, method='POST', data=data)
-
-        return response.status == httplib.OK
-
-    def _to_zones(self, data):
-        zones = []
-        for element in data.findall(fixxpath(xpath='HostedZones/HostedZone',
-                                             namespace=NAMESPACE)):
-            zones.append(self._to_zone(element))
-
-        return zones
-
-    def _to_zone(self, elem):
-        name = findtext(element=elem, xpath='Name', namespace=NAMESPACE)
-        id = findtext(element=elem, xpath='Id',
-                      namespace=NAMESPACE).replace('/hostedzone/', '')
-        comment = findtext(element=elem, xpath='Config/Comment',
-                           namespace=NAMESPACE)
-        resource_record_count = int(findtext(element=elem,
-                                             xpath='ResourceRecordSetCount',
-                                             namespace=NAMESPACE))
-
-        extra = {'Comment': comment, 'ResourceRecordSetCount':
-                 resource_record_count}
-
-        zone = Zone(id=id, domain=name, type='master', ttl=0, driver=self,
-                    extra=extra)
-        return zone
-
-    def _to_records(self, data, zone):
-        records = []
-        elems = data.findall(
-            fixxpath(xpath='ResourceRecordSets/ResourceRecordSet',
-                     namespace=NAMESPACE))
-        for elem in elems:
-            record_set = elem.findall(fixxpath(
-                                      xpath='ResourceRecords/ResourceRecord',
-                                      namespace=NAMESPACE))
-            record_count = len(record_set)
-            multiple_value_record = (record_count > 1)
-
-            record_set_records = []
-
-            for index, record in enumerate(record_set):
-                # Need to special handling for records with multiple values for
-                # update to work correctly
-                record = self._to_record(elem=elem, zone=zone, index=index)
-                record.extra['_multi_value'] = multiple_value_record
-
-                if multiple_value_record:
-                    record.extra['_other_records'] = []
-
-                record_set_records.append(record)
-
-            # Store reference to other records so update works correctly
-            if multiple_value_record:
-                for index in range(0, len(record_set_records)):
-                    record = record_set_records[index]
-
-                    for other_index, other_record in \
-                            enumerate(record_set_records):
-                        if index == other_index:
-                            # Skip current record
-                            continue
-
-                        extra = copy.deepcopy(other_record.extra)
-                        extra.pop('_multi_value')
-                        extra.pop('_other_records')
-
-                        item = {'name': other_record.name,
-                                'data': other_record.data,
-                                'type': other_record.type,
-                                'extra': extra}
-                        record.extra['_other_records'].append(item)
-
-            records.extend(record_set_records)
-
-        return records
-
-    def _to_record(self, elem, zone, index=0):
-        name = findtext(element=elem, xpath='Name',
-                        namespace=NAMESPACE)
-        name = name[:-len(zone.domain) - 1]
-
-        type = self._string_to_record_type(findtext(element=elem, xpath='Type',
-                                                    namespace=NAMESPACE))
-        ttl = findtext(element=elem, xpath='TTL', namespace=NAMESPACE)
-        if ttl is not None:
-            ttl = int(ttl)
-
-        value_elem = elem.findall(
-            fixxpath(xpath='ResourceRecords/ResourceRecord',
-                     namespace=NAMESPACE))[index]
-        data = findtext(element=(value_elem), xpath='Value',
-                        namespace=NAMESPACE)
-
-        extra = {'ttl': ttl}
-
-        if type == 'MX':
-            split = data.split()
-            priority, data = split
-            extra['priority'] = int(priority)
-        elif type == 'SRV':
-            split = data.split()
-            priority, weight, port, data = split
-            extra['priority'] = int(priority)
-            extra['weight'] = int(weight)
-            extra['port'] = int(port)
-
-        id = ':'.join((self.RECORD_TYPE_MAP[type], name))
-        record = Record(id=id, name=name, type=type, data=data, zone=zone,
-                        driver=self, ttl=extra.get('ttl', None), extra=extra)
-        return record
-
-    def _get_more(self, rtype, **kwargs):
-        exhausted = False
-        last_key = None
-        while not exhausted:
-            items, last_key, exhausted = self._get_data(rtype, last_key,
-                                                        **kwargs)
-            for item in items:
-                yield item
-
-    def _get_data(self, rtype, last_key, **kwargs):
-        params = {}
-        if last_key:
-            params['name'] = last_key
-        path = API_ROOT + 'hostedzone'
-
-        if rtype == 'zones':
-            response = self.connection.request(path, params=params)
-            transform_func = self._to_zones
-        elif rtype == 'records':
-            zone = kwargs['zone']
-            path += '/%s/rrset' % (zone.id)
-            self.connection.set_context({'zone_id': zone.id})
-            response = self.connection.request(path, params=params)
-            transform_func = self._to_records
-
-        if response.status == httplib.OK:
-            is_truncated = findtext(element=response.object,
-                                    xpath='IsTruncated',
-                                    namespace=NAMESPACE)
-            exhausted = is_truncated != 'true'
-            last_key = findtext(element=response.object,
-                                xpath='NextRecordName',
-                                namespace=NAMESPACE)
-            items = transform_func(data=response.object, **kwargs)
-            return items, last_key, exhausted
-        else:
-            return [], None, True


[51/56] [abbrv] libcloud git commit: Merge branch 'trunk' of github.com:tonybaloney/libcloud into trunk

Posted by an...@apache.org.
Merge branch 'trunk' of github.com:tonybaloney/libcloud into trunk


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/1a70a26d
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/1a70a26d
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/1a70a26d

Branch: refs/heads/trunk
Commit: 1a70a26d19d5bba475fc1ad991c256796812be4e
Parents: 139278f 363b024
Author: Anthony Shaw <an...@apache.org>
Authored: Sun Oct 9 20:07:37 2016 +1100
Committer: Anthony Shaw <an...@apache.org>
Committed: Sun Oct 9 20:07:37 2016 +1100

----------------------------------------------------------------------
 CHANGES.rst                                     |    2 +-
 docs/compute/drivers/azure.rst                  |   14 +-
 docs/compute/drivers/azure_arm.rst              |   54 +
 docs/examples/compute/azure_arm/instantiate.py  |    7 +
 libcloud/common/azure.py                        |    2 +
 libcloud/common/azure_arm.py                    |  124 ++
 libcloud/common/base.py                         |   17 +-
 libcloud/compute/drivers/azure_arm.py           | 1281 ++++++++++++++++++
 libcloud/compute/providers.py                   |    2 +
 libcloud/compute/types.py                       |    5 +-
 ...777_7777_7777_777777777777_oauth2_token.json |    1 +
 ...99999999999_providers_Microsoft_Compute.json |  200 +++
 ...rosoft_Compute_locations_eastus_vmSizes.json |   28 +
 libcloud/test/compute/test_azure_arm.py         |   69 +
 14 files changed, 1798 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/1a70a26d/CHANGES.rst
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/libcloud/blob/1a70a26d/libcloud/common/base.py
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/libcloud/blob/1a70a26d/libcloud/compute/providers.py
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/libcloud/blob/1a70a26d/libcloud/compute/types.py
----------------------------------------------------------------------


[33/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/cloudsigma.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/cloudsigma.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/cloudsigma.py
deleted file mode 100644
index 02818b3..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/cloudsigma.py
+++ /dev/null
@@ -1,2096 +0,0 @@
-# -*- coding: utf-8 -*-
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-Drivers for CloudSigma API v1.0 and v2.0.
-"""
-
-import re
-import time
-import copy
-import base64
-
-try:
-    import simplejson as json
-except:
-    import json
-
-from libcloud.utils.py3 import b
-from libcloud.utils.py3 import httplib
-
-from libcloud.utils.misc import str2dicts, str2list, dict2str
-from libcloud.common.base import ConnectionUserAndKey, JsonResponse, Response
-from libcloud.common.types import InvalidCredsError, ProviderError
-from libcloud.common.cloudsigma import INSTANCE_TYPES
-from libcloud.common.cloudsigma import API_ENDPOINTS_1_0
-from libcloud.common.cloudsigma import API_ENDPOINTS_2_0
-from libcloud.common.cloudsigma import DEFAULT_API_VERSION, DEFAULT_REGION
-from libcloud.compute.types import NodeState, Provider
-from libcloud.compute.base import NodeDriver, NodeSize, Node
-from libcloud.compute.base import NodeImage
-from libcloud.compute.base import is_private_subnet
-from libcloud.utils.iso8601 import parse_date
-from libcloud.utils.misc import get_secure_random_string
-
-__all__ = [
-    'CloudSigmaNodeDriver',
-    'CloudSigma_1_0_NodeDriver',
-    'CloudSigma_2_0_NodeDriver',
-    'CloudSigmaError',
-
-    'CloudSigmaNodeSize',
-    'CloudSigmaDrive',
-    'CloudSigmaTag',
-    'CloudSigmaSubscription',
-    'CloudSigmaFirewallPolicy',
-    'CloudSigmaFirewallPolicyRule'
-]
-
-
-class CloudSigmaNodeDriver(NodeDriver):
-    name = 'CloudSigma'
-    website = 'http://www.cloudsigma.com/'
-
-    def __new__(cls, key, secret=None, secure=True, host=None, port=None,
-                api_version=DEFAULT_API_VERSION, **kwargs):
-        if cls is CloudSigmaNodeDriver:
-            if api_version == '1.0':
-                cls = CloudSigma_1_0_NodeDriver
-            elif api_version == '2.0':
-                cls = CloudSigma_2_0_NodeDriver
-            else:
-                raise NotImplementedError('Unsupported API version: %s' %
-                                          (api_version))
-        return super(CloudSigmaNodeDriver, cls).__new__(cls)
-
-
-class CloudSigmaException(Exception):
-    def __str__(self):
-        return self.args[0]
-
-    def __repr__(self):
-        return "<CloudSigmaException '%s'>" % (self.args[0])
-
-
-class CloudSigmaInsufficientFundsException(Exception):
-    def __repr__(self):
-        return "<CloudSigmaInsufficientFundsException '%s'>" % (self.args[0])
-
-
-class CloudSigmaNodeSize(NodeSize):
-    def __init__(self, id, name, cpu, ram, disk, bandwidth, price, driver):
-        self.id = id
-        self.name = name
-        self.cpu = cpu
-        self.ram = ram
-        self.disk = disk
-        self.bandwidth = bandwidth
-        self.price = price
-        self.driver = driver
-
-    def __repr__(self):
-        return (('<NodeSize: id=%s, name=%s, cpu=%s, ram=%s disk=%s '
-                 'bandwidth=%s price=%s driver=%s ...>')
-                % (self.id, self.name, self.cpu, self.ram, self.disk,
-                   self.bandwidth, self.price, self.driver.name))
-
-
-class CloudSigma_1_0_Response(Response):
-    def success(self):
-        if self.status == httplib.UNAUTHORIZED:
-            raise InvalidCredsError()
-
-        return self.status >= 200 and self.status <= 299
-
-    def parse_body(self):
-        if not self.body:
-            return self.body
-
-        return str2dicts(self.body)
-
-    def parse_error(self):
-        return 'Error: %s' % (self.body.replace('errors:', '').strip())
-
-
-class CloudSigma_1_0_Connection(ConnectionUserAndKey):
-    host = API_ENDPOINTS_1_0[DEFAULT_REGION]['host']
-    responseCls = CloudSigma_1_0_Response
-
-    def add_default_headers(self, headers):
-        headers['Accept'] = 'application/json'
-        headers['Content-Type'] = 'application/json'
-
-        headers['Authorization'] = 'Basic %s' % (base64.b64encode(
-            b('%s:%s' % (self.user_id, self.key))).decode('utf-8'))
-        return headers
-
-
-class CloudSigma_1_0_NodeDriver(CloudSigmaNodeDriver):
-    type = Provider.CLOUDSIGMA
-    name = 'CloudSigma (API v1.0)'
-    website = 'http://www.cloudsigma.com/'
-    connectionCls = CloudSigma_1_0_Connection
-
-    IMAGING_TIMEOUT = 20 * 60  # Default timeout (in seconds) for the drive
-    # imaging process
-
-    NODE_STATE_MAP = {
-        'active': NodeState.RUNNING,
-        'stopped': NodeState.TERMINATED,
-        'dead': NodeState.TERMINATED,
-        'dumped': NodeState.TERMINATED,
-    }
-
-    def __init__(self, key, secret=None, secure=True, host=None, port=None,
-                 region=DEFAULT_REGION, **kwargs):
-        if region not in API_ENDPOINTS_1_0:
-            raise ValueError('Invalid region: %s' % (region))
-
-        self._host_argument_set = host is not None
-        self.api_name = 'cloudsigma_%s' % (region)
-        super(CloudSigma_1_0_NodeDriver, self).__init__(key=key, secret=secret,
-                                                        secure=secure,
-                                                        host=host,
-                                                        port=port,
-                                                        region=region,
-                                                        **kwargs)
-
-    def reboot_node(self, node):
-        """
-        Reboot a node.
-
-        Because Cloudsigma API does not provide native reboot call,
-        it's emulated using stop and start.
-
-        @inherits: :class:`NodeDriver.reboot_node`
-        """
-        node = self._get_node(node.id)
-        state = node.state
-
-        if state == NodeState.RUNNING:
-            stopped = self.ex_stop_node(node)
-        else:
-            stopped = True
-
-        if not stopped:
-            raise CloudSigmaException(
-                'Could not stop node with id %s' % (node.id))
-
-        success = self.ex_start_node(node)
-
-        return success
-
-    def destroy_node(self, node):
-        """
-        Destroy a node (all the drives associated with it are NOT destroyed).
-
-        If a node is still running, it's stopped before it's destroyed.
-
-        @inherits: :class:`NodeDriver.destroy_node`
-        """
-        node = self._get_node(node.id)
-        state = node.state
-
-        # Node cannot be destroyed while running so it must be stopped first
-        if state == NodeState.RUNNING:
-            stopped = self.ex_stop_node(node)
-        else:
-            stopped = True
-
-        if not stopped:
-            raise CloudSigmaException(
-                'Could not stop node with id %s' % (node.id))
-
-        response = self.connection.request(
-            action='/servers/%s/destroy' % (node.id),
-            method='POST')
-        return response.status == 204
-
-    def list_images(self, location=None):
-        """
-        Return a list of available standard images (this call might take up
-        to 15 seconds to return).
-
-        @inherits: :class:`NodeDriver.list_images`
-        """
-        response = self.connection.request(
-            action='/drives/standard/info').object
-
-        images = []
-        for value in response:
-            if value.get('type'):
-                if value['type'] == 'disk':
-                    image = NodeImage(id=value['drive'], name=value['name'],
-                                      driver=self.connection.driver,
-                                      extra={'size': value['size']})
-                    images.append(image)
-
-        return images
-
-    def list_sizes(self, location=None):
-        sizes = []
-        for value in INSTANCE_TYPES:
-            key = value['id']
-            size = CloudSigmaNodeSize(id=value['id'], name=value['name'],
-                                      cpu=value['cpu'], ram=value['memory'],
-                                      disk=value['disk'],
-                                      bandwidth=value['bandwidth'],
-                                      price=self._get_size_price(size_id=key),
-                                      driver=self.connection.driver)
-            sizes.append(size)
-
-        return sizes
-
-    def list_nodes(self):
-        response = self.connection.request(action='/servers/info').object
-
-        nodes = []
-        for data in response:
-            node = self._to_node(data)
-            if node:
-                nodes.append(node)
-        return nodes
-
-    def create_node(self, **kwargs):
-        """
-        Creates a CloudSigma instance
-
-        @inherits: :class:`NodeDriver.create_node`
-
-        :keyword    name: String with a name for this new node (required)
-        :type       name: ``str``
-
-        :keyword    smp: Number of virtual processors or None to calculate
-                         based on the cpu speed.
-        :type       smp: ``int``
-
-        :keyword    nic_model: e1000, rtl8139 or virtio (is not specified,
-                               e1000 is used)
-        :type       nic_model: ``str``
-
-        :keyword    vnc_password: If not set, VNC access is disabled.
-        :type       vnc_password: ``bool``
-
-        :keyword    drive_type: Drive type (ssd|hdd). Defaults to hdd.
-        :type       drive_type: ``str``
-        """
-        size = kwargs['size']
-        image = kwargs['image']
-        smp = kwargs.get('smp', 'auto')
-        nic_model = kwargs.get('nic_model', 'e1000')
-        vnc_password = kwargs.get('vnc_password', None)
-        drive_type = kwargs.get('drive_type', 'hdd')
-
-        if nic_model not in ['e1000', 'rtl8139', 'virtio']:
-            raise CloudSigmaException('Invalid NIC model specified')
-
-        if drive_type not in ['hdd', 'ssd']:
-            raise CloudSigmaException('Invalid drive type "%s". Valid types'
-                                      ' are: hdd, ssd' % (drive_type))
-
-        drive_data = {}
-        drive_data.update({'name': kwargs['name'],
-                           'size': '%sG' % (kwargs['size'].disk),
-                           'driveType': drive_type})
-
-        response = self.connection.request(
-            action='/drives/%s/clone' % image.id,
-            data=dict2str(drive_data),
-            method='POST').object
-
-        if not response:
-            raise CloudSigmaException('Drive creation failed')
-
-        drive_uuid = response[0]['drive']
-
-        response = self.connection.request(
-            action='/drives/%s/info' % (drive_uuid)).object
-        imaging_start = time.time()
-        while 'imaging' in response[0]:
-            response = self.connection.request(
-                action='/drives/%s/info' % (drive_uuid)).object
-            elapsed_time = time.time() - imaging_start
-            timed_out = elapsed_time >= self.IMAGING_TIMEOUT
-            if 'imaging' in response[0] and timed_out:
-                raise CloudSigmaException('Drive imaging timed out')
-            time.sleep(1)
-
-        node_data = {}
-        node_data.update(
-            {'name': kwargs['name'], 'cpu': size.cpu, 'mem': size.ram,
-             'ide:0:0': drive_uuid, 'boot': 'ide:0:0', 'smp': smp})
-        node_data.update({'nic:0:model': nic_model, 'nic:0:dhcp': 'auto'})
-
-        if vnc_password:
-            node_data.update({'vnc:ip': 'auto', 'vnc:password': vnc_password})
-
-        response = self.connection.request(action='/servers/create',
-                                           data=dict2str(node_data),
-                                           method='POST').object
-
-        if not isinstance(response, list):
-            response = [response]
-
-        node = self._to_node(response[0])
-        if node is None:
-            # Insufficient funds, destroy created drive
-            self.ex_drive_destroy(drive_uuid)
-            raise CloudSigmaInsufficientFundsException(
-                'Insufficient funds, node creation failed')
-
-        # Start the node after it has been created
-        started = self.ex_start_node(node)
-
-        if started:
-            node.state = NodeState.RUNNING
-
-        return node
-
-    def ex_destroy_node_and_drives(self, node):
-        """
-        Destroy a node and all the drives associated with it.
-
-        :param      node: Node which should be used
-        :type       node: :class:`libcloud.compute.base.Node`
-
-        :rtype: ``bool``
-        """
-        node = self._get_node_info(node)
-
-        drive_uuids = []
-        for key, value in node.items():
-            if (key.startswith('ide:') or key.startswith(
-                'scsi') or key.startswith('block')) and\
-                not (key.endswith(':bytes') or
-                     key.endswith(':requests') or key.endswith('media')):
-                drive_uuids.append(value)
-
-        node_destroyed = self.destroy_node(self._to_node(node))
-
-        if not node_destroyed:
-            return False
-
-        for drive_uuid in drive_uuids:
-            self.ex_drive_destroy(drive_uuid)
-
-        return True
-
-    def ex_static_ip_list(self):
-        """
-        Return a list of available static IP addresses.
-
-        :rtype: ``list`` of ``str``
-        """
-        response = self.connection.request(action='/resources/ip/list',
-                                           method='GET')
-
-        if response.status != 200:
-            raise CloudSigmaException('Could not retrieve IP list')
-
-        ips = str2list(response.body)
-        return ips
-
-    def ex_drives_list(self):
-        """
-        Return a list of all the available drives.
-
-        :rtype: ``list`` of ``dict``
-        """
-        response = self.connection.request(action='/drives/info', method='GET')
-
-        result = str2dicts(response.body)
-        return result
-
-    def ex_static_ip_create(self):
-        """
-        Create a new static IP address.p
-
-        :rtype: ``list`` of ``dict``
-        """
-        response = self.connection.request(action='/resources/ip/create',
-                                           method='GET')
-
-        result = str2dicts(response.body)
-        return result
-
-    def ex_static_ip_destroy(self, ip_address):
-        """
-        Destroy a static IP address.
-
-        :param      ip_address: IP address which should be used
-        :type       ip_address: ``str``
-
-        :rtype: ``bool``
-        """
-        response = self.connection.request(
-            action='/resources/ip/%s/destroy' % (ip_address), method='GET')
-
-        return response.status == 204
-
-    def ex_drive_destroy(self, drive_uuid):
-        """
-        Destroy a drive with a specified uuid.
-        If the drive is currently mounted an exception is thrown.
-
-        :param      drive_uuid: Drive uuid which should be used
-        :type       drive_uuid: ``str``
-
-        :rtype: ``bool``
-        """
-        response = self.connection.request(
-            action='/drives/%s/destroy' % (drive_uuid), method='POST')
-
-        return response.status == 204
-
-    def ex_set_node_configuration(self, node, **kwargs):
-        """
-        Update a node configuration.
-        Changing most of the parameters requires node to be stopped.
-
-        :param      node: Node which should be used
-        :type       node: :class:`libcloud.compute.base.Node`
-
-        :param      kwargs: keyword arguments
-        :type       kwargs: ``dict``
-
-        :rtype: ``bool``
-        """
-        valid_keys = ('^name$', '^parent$', '^cpu$', '^smp$', '^mem$',
-                      '^boot$', '^nic:0:model$', '^nic:0:dhcp',
-                      '^nic:1:model$', '^nic:1:vlan$', '^nic:1:mac$',
-                      '^vnc:ip$', '^vnc:password$', '^vnc:tls',
-                      '^ide:[0-1]:[0-1](:media)?$', '^scsi:0:[0-7](:media)?$',
-                      '^block:[0-7](:media)?$')
-
-        invalid_keys = []
-        keys = list(kwargs.keys())
-        for key in keys:
-            matches = False
-            for regex in valid_keys:
-                if re.match(regex, key):
-                    matches = True
-                    break
-            if not matches:
-                invalid_keys.append(key)
-
-        if invalid_keys:
-            raise CloudSigmaException(
-                'Invalid configuration key specified: %s' %
-                (',' .join(invalid_keys)))
-
-        response = self.connection.request(
-            action='/servers/%s/set' % (node.id),
-            data=dict2str(kwargs),
-            method='POST')
-
-        return (response.status == 200 and response.body != '')
-
-    def ex_start_node(self, node):
-        """
-        Start a node.
-
-        :param      node: Node which should be used
-        :type       node: :class:`libcloud.compute.base.Node`
-
-        :rtype: ``bool``
-        """
-        response = self.connection.request(
-            action='/servers/%s/start' % (node.id),
-            method='POST')
-
-        return response.status == 200
-
-    def ex_stop_node(self, node):
-        """
-        Stop (shutdown) a node.
-
-        :param      node: Node which should be used
-        :type       node: :class:`libcloud.compute.base.Node`
-
-        :rtype: ``bool``
-        """
-        response = self.connection.request(
-            action='/servers/%s/stop' % (node.id),
-            method='POST')
-        return response.status == 204
-
-    def ex_shutdown_node(self, node):
-        """
-        Stop (shutdown) a node.
-
-        @inherits: :class:`CloudSigmaBaseNodeDriver.ex_stop_node`
-        """
-        return self.ex_stop_node(node)
-
-    def ex_destroy_drive(self, drive_uuid):
-        """
-        Destroy a drive.
-
-        :param      drive_uuid: Drive uuid which should be used
-        :type       drive_uuid: ``str``
-
-        :rtype: ``bool``
-        """
-        response = self.connection.request(
-            action='/drives/%s/destroy' % (drive_uuid),
-            method='POST')
-        return response.status == 204
-
-    def _ex_connection_class_kwargs(self):
-        """
-        Return the host value based on the user supplied region.
-        """
-        kwargs = {}
-        if not self._host_argument_set:
-            kwargs['host'] = API_ENDPOINTS_1_0[self.region]['host']
-
-        return kwargs
-
-    def _to_node(self, data):
-        if data:
-            try:
-                state = self.NODE_STATE_MAP[data['status']]
-            except KeyError:
-                state = NodeState.UNKNOWN
-
-            if 'server' not in data:
-                # Response does not contain server UUID if the server
-                # creation failed because of insufficient funds.
-                return None
-
-            public_ips = []
-            if 'nic:0:dhcp' in data:
-                if isinstance(data['nic:0:dhcp'], list):
-                    public_ips = data['nic:0:dhcp']
-                else:
-                    public_ips = [data['nic:0:dhcp']]
-
-            extra = {}
-            extra_keys = [('cpu', 'int'), ('smp', 'auto'), ('mem', 'int'),
-                          ('status', 'str')]
-            for key, value_type in extra_keys:
-                if key in data:
-                    value = data[key]
-
-                    if value_type == 'int':
-                        value = int(value)
-                    elif value_type == 'auto':
-                        try:
-                            value = int(value)
-                        except ValueError:
-                            pass
-
-                    extra.update({key: value})
-
-            if 'vnc:ip' in data and 'vnc:password' in data:
-                extra.update({'vnc_ip': data['vnc:ip'],
-                              'vnc_password': data['vnc:password']})
-
-            node = Node(id=data['server'], name=data['name'], state=state,
-                        public_ips=public_ips, private_ips=None,
-                        driver=self.connection.driver,
-                        extra=extra)
-
-            return node
-        return None
-
-    def _get_node(self, node_id):
-        nodes = self.list_nodes()
-        node = [node for node in nodes if node.id == node.id]
-
-        if not node:
-            raise CloudSigmaException(
-                'Node with id %s does not exist' % (node_id))
-
-        return node[0]
-
-    def _get_node_info(self, node):
-        response = self.connection.request(
-            action='/servers/%s/info' % (node.id))
-
-        result = str2dicts(response.body)
-        return result[0]
-
-
-class CloudSigmaZrhConnection(CloudSigma_1_0_Connection):
-    """
-    Connection class for the CloudSigma driver for the Zurich end-point
-    """
-    host = API_ENDPOINTS_1_0['zrh']['host']
-
-
-class CloudSigmaZrhNodeDriver(CloudSigma_1_0_NodeDriver):
-    """
-    CloudSigma node driver for the Zurich end-point
-    """
-    connectionCls = CloudSigmaZrhConnection
-    api_name = 'cloudsigma_zrh'
-
-
-class CloudSigmaLvsConnection(CloudSigma_1_0_Connection):
-    """
-    Connection class for the CloudSigma driver for the Las Vegas end-point
-    """
-    host = API_ENDPOINTS_1_0['lvs']['host']
-
-
-class CloudSigmaLvsNodeDriver(CloudSigma_1_0_NodeDriver):
-    """
-    CloudSigma node driver for the Las Vegas end-point
-    """
-    connectionCls = CloudSigmaLvsConnection
-    api_name = 'cloudsigma_lvs'
-
-
-class CloudSigmaError(ProviderError):
-    """
-    Represents CloudSigma API error.
-    """
-
-    def __init__(self, http_code, error_type, error_msg, error_point, driver):
-        """
-        :param http_code: HTTP status code.
-        :type http_code: ``int``
-
-        :param error_type: Type of error (validation / notexist / backend /
-                           permissions  database / concurrency / billing /
-                           payment)
-        :type error_type: ``str``
-
-        :param error_msg: A description of the error that occurred.
-        :type error_msg: ``str``
-
-        :param error_point: Point at which the error occurred. Can be None.
-        :type error_point: ``str`` or ``None``
-        """
-        super(CloudSigmaError, self).__init__(http_code=http_code,
-                                              value=error_msg, driver=driver)
-        self.error_type = error_type
-        self.error_msg = error_msg
-        self.error_point = error_point
-
-
-class CloudSigmaSubscription(object):
-    """
-    Represents CloudSigma subscription.
-    """
-
-    def __init__(self, id, resource, amount, period, status, price, start_time,
-                 end_time, auto_renew, subscribed_object=None):
-        """
-        :param id: Subscription ID.
-        :type id: ``str``
-
-        :param resource: Resource (e.g vlan, ip, etc.).
-        :type resource: ``str``
-
-        :param period: Subscription period.
-        :type period: ``str``
-
-        :param status: Subscription status (active / inactive).
-        :type status: ``str``
-
-        :param price: Subscription price.
-        :type price: ``str``
-
-        :param start_time: Start time for this subscription.
-        :type start_time: ``datetime.datetime``
-
-        :param end_time: End time for this subscription.
-        :type end_time: ``datetime.datetime``
-
-        :param auto_renew: True if the subscription is auto renewed.
-        :type auto_renew: ``bool``
-
-        :param subscribed_object: Optional UUID of the subscribed object.
-        :type subscribed_object: ``str``
-        """
-        self.id = id
-        self.resource = resource
-        self.amount = amount
-        self.period = period
-        self.status = status
-        self.price = price
-        self.start_time = start_time
-        self.end_time = end_time
-        self.auto_renew = auto_renew
-        self.subscribed_object = subscribed_object
-
-    def __str__(self):
-        return self.__repr__()
-
-    def __repr__(self):
-        return ('<CloudSigmaSubscription id=%s, resource=%s, amount=%s, '
-                'period=%s, object_uuid=%s>' %
-                (self.id, self.resource, self.amount, self.period,
-                 self.subscribed_object))
-
-
-class CloudSigmaTag(object):
-    """
-    Represents a CloudSigma tag object.
-    """
-
-    def __init__(self, id, name, resources=None):
-        """
-        :param id: Tag ID.
-        :type id: ``str``
-
-        :param name: Tag name.
-        :type name: ``str``
-
-        :param resource: IDs of resources which are associated with this tag.
-        :type resources: ``list`` of ``str``
-        """
-        self.id = id
-        self.name = name
-        self.resources = resources if resources else []
-
-    def __str__(self):
-        return self.__repr__()
-
-    def __repr__(self):
-        return ('<CloudSigmaTag id=%s, name=%s, resources=%s>' %
-                (self.id, self.name, repr(self.resources)))
-
-
-class CloudSigmaDrive(NodeImage):
-    """
-    Represents a CloudSigma drive.
-    """
-
-    def __init__(self, id, name, size, media, status, driver, extra=None):
-        """
-        :param id: Drive ID.
-        :type id: ``str``
-
-        :param name: Drive name.
-        :type name: ``str``
-
-        :param size: Drive size (in bytes).
-        :type size: ``int``
-
-        :param media: Drive media (cdrom / disk).
-        :type media: ``str``
-
-        :param status: Drive status (unmounted / mounted).
-        :type status: ``str``
-        """
-        super(CloudSigmaDrive, self).__init__(id=id, name=name, driver=driver,
-                                              extra=extra)
-        self.size = size
-        self.media = media
-        self.status = status
-
-    def __str__(self):
-        return self.__repr__()
-
-    def __repr__(self):
-        return (('<CloudSigmaSize id=%s, name=%s size=%s, media=%s, '
-                'status=%s>') %
-                (self.id, self.name, self.size, self.media, self.status))
-
-
-class CloudSigmaFirewallPolicy(object):
-    """
-    Represents a CloudSigma firewall policy.
-    """
-
-    def __init__(self, id, name, rules):
-        """
-        :param id: Policy ID.
-        :type id: ``str``
-
-        :param name: Policy name.
-        :type name: ``str``
-
-        :param rules: Rules associated with this policy.
-        :type rules: ``list`` of :class:`.CloudSigmaFirewallPolicyRule` objects
-        """
-        self.id = id
-        self.name = name
-        self.rules = rules if rules else []
-
-    def __str__(self):
-        return self.__repr__()
-
-    def __repr__(self):
-        return (('<CloudSigmaFirewallPolicy id=%s, name=%s rules=%s>') %
-                (self.id, self.name, repr(self.rules)))
-
-
-class CloudSigmaFirewallPolicyRule(object):
-    """
-    Represents a CloudSigma firewall policy rule.
-    """
-
-    def __init__(self, action, direction, ip_proto=None, src_ip=None,
-                 src_port=None, dst_ip=None, dst_port=None, comment=None):
-        """
-        :param action: Action (drop / accept).
-        :type action: ``str``
-
-        :param direction: Rule direction (in / out / both)>
-        :type direction: ``str``
-
-        :param ip_proto: IP protocol (tcp / udp).
-        :type ip_proto: ``str``.
-
-        :param src_ip: Source IP in CIDR notation.
-        :type src_ip: ``str``
-
-        :param src_port: Source port or a port range.
-        :type src_port: ``str``
-
-        :param dst_ip: Destination IP in CIDR notation.
-        :type dst_ip: ``str``
-
-        :param src_port: Destination port or a port range.
-        :type src_port: ``str``
-
-        :param comment: Comment associated with the policy.
-        :type comment: ``str``
-        """
-        self.action = action
-        self.direction = direction
-        self.ip_proto = ip_proto
-        self.src_ip = src_ip
-        self.src_port = src_port
-        self.dst_ip = dst_ip
-        self.dst_port = dst_port
-        self.comment = comment
-
-    def __str__(self):
-        return self.__repr__()
-
-    def __repr__(self):
-        return (('<CloudSigmaFirewallPolicyRule action=%s, direction=%s>') %
-                (self.action, self.direction))
-
-
-class CloudSigma_2_0_Response(JsonResponse):
-    success_status_codes = [
-        httplib.OK,
-        httplib.ACCEPTED,
-        httplib.NO_CONTENT,
-        httplib.CREATED
-    ]
-
-    def success(self):
-        return self.status in self.success_status_codes
-
-    def parse_error(self):
-        if int(self.status) == httplib.UNAUTHORIZED:
-            raise InvalidCredsError('Invalid credentials')
-
-        body = self.parse_body()
-        errors = self._parse_errors_from_body(body=body)
-
-        if errors:
-            # Throw first error
-            raise errors[0]
-
-        return body
-
-    def _parse_errors_from_body(self, body):
-        """
-        Parse errors from the response body.
-
-        :return: List of error objects.
-        :rtype: ``list`` of :class:`.CloudSigmaError` objects
-        """
-        errors = []
-
-        if not isinstance(body, list):
-            return None
-
-        for item in body:
-            if 'error_type' not in item:
-                # Unrecognized error
-                continue
-
-            error = CloudSigmaError(http_code=self.status,
-                                    error_type=item['error_type'],
-                                    error_msg=item['error_message'],
-                                    error_point=item['error_point'],
-                                    driver=self.connection.driver)
-            errors.append(error)
-
-        return errors
-
-
-class CloudSigma_2_0_Connection(ConnectionUserAndKey):
-    host = API_ENDPOINTS_2_0[DEFAULT_REGION]['host']
-    responseCls = CloudSigma_2_0_Response
-    api_prefix = '/api/2.0'
-
-    def add_default_headers(self, headers):
-        headers['Accept'] = 'application/json'
-        headers['Content-Type'] = 'application/json'
-
-        headers['Authorization'] = 'Basic %s' % (base64.b64encode(
-            b('%s:%s' % (self.user_id, self.key))).decode('utf-8'))
-        return headers
-
-    def encode_data(self, data):
-        data = json.dumps(data)
-        return data
-
-    def request(self, action, params=None, data=None, headers=None,
-                method='GET', raw=False):
-        params = params or {}
-        action = self.api_prefix + action
-
-        if method == 'GET':
-            params['limit'] = 0  # we want all the items back
-
-        return super(CloudSigma_2_0_Connection, self).request(action=action,
-                                                              params=params,
-                                                              data=data,
-                                                              headers=headers,
-                                                              method=method,
-                                                              raw=raw)
-
-
-class CloudSigma_2_0_NodeDriver(CloudSigmaNodeDriver):
-    """
-    Driver for CloudSigma API v2.0.
-    """
-    name = 'CloudSigma (API v2.0)'
-    api_name = 'cloudsigma_zrh'
-    website = 'http://www.cloudsigma.com/'
-    connectionCls = CloudSigma_2_0_Connection
-
-    # Default drive transition timeout in seconds
-    DRIVE_TRANSITION_TIMEOUT = 500
-
-    # How long to sleep between different polling periods while waiting for
-    # drive transition
-    DRIVE_TRANSITION_SLEEP_INTERVAL = 5
-
-    NODE_STATE_MAP = {
-        'starting': NodeState.PENDING,
-        'stopping': NodeState.PENDING,
-        'unavailable': NodeState.ERROR,
-        'running': NodeState.RUNNING,
-        'stopped': NodeState.STOPPED,
-        'paused': NodeState.PAUSED
-    }
-
-    def __init__(self, key, secret, secure=True, host=None, port=None,
-                 region=DEFAULT_REGION, **kwargs):
-        if region not in API_ENDPOINTS_2_0:
-            raise ValueError('Invalid region: %s' % (region))
-
-        if not secure:
-            # CloudSigma drive uses Basic Auth authentication and we don't want
-            # to allow user to accidentally send credentials over the wire in
-            # plain-text
-            raise ValueError('CloudSigma driver only supports a '
-                             'secure connection')
-
-        self._host_argument_set = host is not None
-        super(CloudSigma_2_0_NodeDriver, self).__init__(key=key, secret=secret,
-                                                        secure=secure,
-                                                        host=host, port=port,
-                                                        region=region,
-                                                        **kwargs)
-
-    def list_nodes(self, ex_tag=None):
-        """
-        List available nodes.
-
-        :param ex_tag: If specified, only return servers tagged with the
-                       provided tag.
-        :type ex_tag: :class:`CloudSigmaTag`
-        """
-        if ex_tag:
-            action = '/tags/%s/servers/detail/' % (ex_tag.id)
-        else:
-            action = '/servers/detail/'
-
-        response = self.connection.request(action=action, method='GET').object
-        nodes = [self._to_node(data=item) for item in response['objects']]
-        return nodes
-
-    def list_sizes(self):
-        """
-        List available sizes.
-        """
-        sizes = []
-        for value in INSTANCE_TYPES:
-            key = value['id']
-            size = CloudSigmaNodeSize(id=value['id'], name=value['name'],
-                                      cpu=value['cpu'], ram=value['memory'],
-                                      disk=value['disk'],
-                                      bandwidth=value['bandwidth'],
-                                      price=self._get_size_price(size_id=key),
-                                      driver=self.connection.driver)
-            sizes.append(size)
-
-        return sizes
-
-    def list_images(self):
-        """
-        Return a list of available pre-installed library drives.
-
-        Note: If you want to list all the available library drives (both
-        pre-installed and installation CDs), use :meth:`ex_list_library_drives`
-        method.
-        """
-        response = self.connection.request(action='/libdrives/').object
-        images = [self._to_image(data=item) for item in response['objects']]
-
-        # We filter out non pre-installed library drives by default because
-        # they can't be used directly following a default Libcloud server
-        # creation flow.
-        images = [image for image in images if
-                  image.extra['image_type'] == 'preinst']
-        return images
-
-    def create_node(self, name, size, image, ex_metadata=None,
-                    ex_vnc_password=None, ex_avoid=None, ex_vlan=None):
-        """
-        Create a new server.
-
-        Server creation consists multiple steps depending on the type of the
-        image used.
-
-        1. Installation CD:
-
-            1. Create a server and attach installation cd
-            2. Start a server
-
-        2. Pre-installed image:
-
-            1. Clone provided library drive so we can use it
-            2. Resize cloned drive to the desired size
-            3. Create a server and attach cloned drive
-            4. Start a server
-
-        :param ex_metadata: Key / value pairs to associate with the
-                            created node. (optional)
-        :type ex_metadata: ``dict``
-
-        :param ex_vnc_password: Password to use for VNC access. If not
-                                provided, random password is generated.
-        :type ex_vnc_password: ``str``
-
-        :param ex_avoid: A list of server UUIDs to avoid when starting this
-                         node. (optional)
-        :type ex_avoid: ``list``
-
-        :param ex_vlan: Optional UUID of a VLAN network to use. If specified,
-                        server will have two nics assigned - 1 with a public ip
-                        and 1 with the provided VLAN.
-        :type ex_vlan: ``str``
-        """
-        is_installation_cd = self._is_installation_cd(image=image)
-
-        if ex_vnc_password:
-            vnc_password = ex_vnc_password
-        else:
-            # VNC password is not provided, generate a random one.
-            vnc_password = get_secure_random_string(size=12)
-
-        drive_name = '%s-drive' % (name)
-
-        # size is specified in GB
-        drive_size = (size.disk * 1024 * 1024 * 1024)
-
-        if not is_installation_cd:
-            # 1. Clone library drive so we can use it
-            drive = self.ex_clone_drive(drive=image, name=drive_name)
-
-            # Wait for drive clone to finish
-            drive = self._wait_for_drive_state_transition(drive=drive,
-                                                          state='unmounted')
-
-            # 2. Resize drive to the desired disk size if the desired disk size
-            # is larger than the cloned drive size.
-            if drive_size > drive.size:
-                drive = self.ex_resize_drive(drive=drive, size=drive_size)
-
-            # Wait for drive resize to finish
-            drive = self._wait_for_drive_state_transition(drive=drive,
-                                                          state='unmounted')
-        else:
-            # No need to clone installation CDs
-            drive = image
-
-        # 3. Create server and attach cloned drive
-        # ide 0:0
-        data = {}
-        data['name'] = name
-        data['cpu'] = size.cpu
-        data['mem'] = (size.ram * 1024 * 1024)
-        data['vnc_password'] = vnc_password
-
-        if ex_metadata:
-            data['meta'] = ex_metadata
-
-        # Assign 1 public interface (DHCP) to the node
-        nic = {
-            'boot_order': None,
-            'ip_v4_conf': {
-                'conf': 'dhcp',
-            },
-            'ip_v6_conf': None
-        }
-
-        nics = [nic]
-
-        if ex_vlan:
-            # Assign another interface for VLAN
-            nic = {
-                'boot_order': None,
-                'ip_v4_conf': None,
-                'ip_v6_conf': None,
-                'vlan': ex_vlan
-            }
-            nics.append(nic)
-
-        # Need to use IDE for installation CDs
-        if is_installation_cd:
-            device_type = 'ide'
-        else:
-            device_type = 'virtio'
-
-        drive = {
-            'boot_order': 1,
-            'dev_channel': '0:0',
-            'device': device_type,
-            'drive': drive.id
-        }
-
-        drives = [drive]
-
-        data['nics'] = nics
-        data['drives'] = drives
-
-        action = '/servers/'
-        response = self.connection.request(action=action, method='POST',
-                                           data=data)
-        node = self._to_node(response.object['objects'][0])
-
-        # 4. Start server
-        self.ex_start_node(node=node, ex_avoid=ex_avoid)
-
-        return node
-
-    def destroy_node(self, node):
-        """
-        Destroy the node and all the associated drives.
-
-        :return: ``True`` on success, ``False`` otherwise.
-        :rtype: ``bool``
-        """
-        action = '/servers/%s/' % (node.id)
-        params = {'recurse': 'all_drives'}
-        response = self.connection.request(action=action, method='DELETE',
-                                           params=params)
-        return response.status == httplib.NO_CONTENT
-
-    # Server extension methods
-
-    def ex_edit_node(self, node, params):
-        """
-        Edit a node.
-
-        :param node: Node to edit.
-        :type node: :class:`libcloud.compute.base.Node`
-
-        :param params: Node parameters to update.
-        :type params: ``dict``
-
-        :return Edited node.
-        :rtype: :class:`libcloud.compute.base.Node`
-        """
-        data = {}
-
-        # name, cpu, mem and vnc_password attributes must always be present so
-        # we just copy them from the to-be-edited node
-        data['name'] = node.name
-        data['cpu'] = node.extra['cpu']
-        data['mem'] = node.extra['mem']
-        data['vnc_password'] = node.extra['vnc_password']
-
-        nics = copy.deepcopy(node.extra.get('nics', []))
-
-        data['nics'] = nics
-
-        data.update(params)
-
-        action = '/servers/%s/' % (node.id)
-        response = self.connection.request(action=action, method='PUT',
-                                           data=data).object
-        node = self._to_node(data=response)
-        return node
-
-    def ex_start_node(self, node, ex_avoid=None):
-        """
-        Start a node.
-
-        :param node: Node to start.
-        :type node: :class:`libcloud.compute.base.Node`
-
-        :param ex_avoid: A list of other server uuids to avoid when
-                         starting this node. If provided, node will
-                         attempt to be started on a different
-                         physical infrastructure from other servers
-                         specified using this argument. (optional)
-        :type ex_avoid: ``list``
-        """
-        params = {}
-
-        if ex_avoid:
-            params['avoid'] = ','.join(ex_avoid)
-
-        path = '/servers/%s/action/' % (node.id)
-        response = self._perform_action(path=path, action='start',
-                                        params=params,
-                                        method='POST')
-        return response.status == httplib.ACCEPTED
-
-    def ex_stop_node(self, node):
-        """
-        Stop a node.
-        """
-        path = '/servers/%s/action/' % (node.id)
-        response = self._perform_action(path=path, action='stop',
-                                        method='POST')
-        return response.status == httplib.ACCEPTED
-
-    def ex_clone_node(self, node, name=None, random_vnc_password=None):
-        """
-        Clone the provided node.
-
-        :param name: Optional name for the cloned node.
-        :type name: ``str``
-        :param random_vnc_password: If True, a new random VNC password will be
-                                    generated for the cloned node. Otherwise
-                                    password from the cloned node will be
-                                    reused.
-        :type random_vnc_password: ``bool``
-
-        :return: Cloned node.
-        :rtype: :class:`libcloud.compute.base.Node`
-        """
-        data = {}
-
-        data['name'] = name
-        data['random_vnc_password'] = random_vnc_password
-
-        path = '/servers/%s/action/' % (node.id)
-        response = self._perform_action(path=path, action='clone',
-                                        method='POST', data=data).object
-        node = self._to_node(data=response)
-        return node
-
-    def ex_open_vnc_tunnel(self, node):
-        """
-        Open a VNC tunnel to the provided node and return the VNC url.
-
-        :param node: Node to open the VNC tunnel to.
-        :type node: :class:`libcloud.compute.base.Node`
-
-        :return: URL of the opened VNC tunnel.
-        :rtype: ``str``
-        """
-        path = '/servers/%s/action/' % (node.id)
-        response = self._perform_action(path=path, action='open_vnc',
-                                        method='POST').object
-        vnc_url = response['vnc_url']
-        return vnc_url
-
-    def ex_close_vnc_tunnel(self, node):
-        """
-        Close a VNC server to the provided node.
-
-        :param node: Node to close the VNC tunnel to.
-        :type node: :class:`libcloud.compute.base.Node`
-
-        :return: ``True`` on success, ``False`` otherwise.
-        :rtype: ``bool``
-        """
-        path = '/servers/%s/action/' % (node.id)
-        response = self._perform_action(path=path, action='close_vnc',
-                                        method='POST')
-        return response.status == httplib.ACCEPTED
-
-    # Drive extension methods
-
-    def ex_list_library_drives(self):
-        """
-        Return a list of all the available library drives (pre-installed and
-        installation CDs).
-
-        :rtype: ``list`` of :class:`.CloudSigmaDrive` objects
-        """
-        response = self.connection.request(action='/libdrives/').object
-        drives = [self._to_drive(data=item) for item in response['objects']]
-        return drives
-
-    def ex_list_user_drives(self):
-        """
-        Return a list of all the available user's drives.
-
-        :rtype: ``list`` of :class:`.CloudSigmaDrive` objects
-        """
-        response = self.connection.request(action='/drives/detail/').object
-        drives = [self._to_drive(data=item) for item in response['objects']]
-        return drives
-
-    def ex_create_drive(self, name, size, media='disk', ex_avoid=None):
-        """
-        Create a new drive.
-
-        :param name: Drive name.
-        :type name: ``str``
-
-        :param size: Drive size in bytes.
-        :type size: ``int``
-
-        :param media: Drive media type (cdrom, disk).
-        :type media: ``str``
-
-        :param ex_avoid: A list of other drive uuids to avoid when
-                         creating this drive. If provided, drive will
-                         attempt to be created on a different
-                         physical infrastructure from other drives
-                         specified using this argument. (optional)
-        :type ex_avoid: ``list``
-
-        :return: Created drive object.
-        :rtype: :class:`.CloudSigmaDrive`
-        """
-        params = {}
-        data = {
-            'name': name,
-            'size': size,
-            'media': media
-        }
-
-        if ex_avoid:
-            params['avoid'] = ','.join(ex_avoid)
-
-        action = '/drives/'
-        response = self.connection.request(action=action, method='POST',
-                                           params=params, data=data).object
-        drive = self._to_drive(data=response['objects'][0])
-        return drive
-
-    def ex_clone_drive(self, drive, name=None, ex_avoid=None):
-        """
-        Clone a library or a standard drive.
-
-        :param drive: Drive to clone.
-        :type drive: :class:`libcloud.compute.base.NodeImage` or
-                     :class:`.CloudSigmaDrive`
-
-        :param name: Optional name for the cloned drive.
-        :type name: ``str``
-
-        :param ex_avoid: A list of other drive uuids to avoid when
-                         creating this drive. If provided, drive will
-                         attempt to be created on a different
-                         physical infrastructure from other drives
-                         specified using this argument. (optional)
-        :type ex_avoid: ``list``
-
-        :return: New cloned drive.
-        :rtype: :class:`.CloudSigmaDrive`
-        """
-        params = {}
-        data = {}
-
-        if ex_avoid:
-            params['avoid'] = ','.join(ex_avoid)
-
-        if name:
-            data['name'] = name
-
-        path = '/drives/%s/action/' % (drive.id)
-        response = self._perform_action(path=path, action='clone',
-                                        params=params, data=data,
-                                        method='POST')
-        drive = self._to_drive(data=response.object['objects'][0])
-        return drive
-
-    def ex_resize_drive(self, drive, size):
-        """
-        Resize a drive.
-
-        :param drive: Drive to resize.
-
-        :param size: New drive size in bytes.
-        :type size: ``int``
-
-        :return: Drive object which is being resized.
-        :rtype: :class:`.CloudSigmaDrive`
-        """
-        path = '/drives/%s/action/' % (drive.id)
-        data = {'name': drive.name, 'size': size, 'media': 'disk'}
-        response = self._perform_action(path=path, action='resize',
-                                        method='POST', data=data)
-
-        drive = self._to_drive(data=response.object['objects'][0])
-        return drive
-
-    def ex_attach_drive(self, node):
-        """
-        Attach a drive to the provided node.
-        """
-        # TODO
-        pass
-
-    def ex_get_drive(self, drive_id):
-        """
-        Retrieve information about a single drive.
-
-        :param drive_id: ID of the drive to retrieve.
-        :type drive_id: ``str``
-
-        :return: Drive object.
-        :rtype: :class:`.CloudSigmaDrive`
-        """
-        action = '/drives/%s/' % (drive_id)
-        response = self.connection.request(action=action).object
-        drive = self._to_drive(data=response)
-        return drive
-
-    # Firewall policies extension methods
-
-    def ex_list_firewall_policies(self):
-        """
-        List firewall policies.
-
-        :rtype: ``list`` of :class:`.CloudSigmaFirewallPolicy`
-        """
-        action = '/fwpolicies/detail/'
-        response = self.connection.request(action=action, method='GET').object
-        policies = [self._to_firewall_policy(data=item) for item
-                    in response['objects']]
-        return policies
-
-    def ex_create_firewall_policy(self, name, rules=None):
-        """
-        Create a firewall policy.
-
-        :param name: Policy name.
-        :type name: ``str``
-
-        :param rules: List of firewall policy rules to associate with this
-                      policy. (optional)
-        :type rules: ``list`` of ``dict``
-
-        :return: Created firewall policy object.
-        :rtype: :class:`.CloudSigmaFirewallPolicy`
-        """
-        data = {}
-        obj = {}
-        obj['name'] = name
-
-        if rules:
-            obj['rules'] = rules
-
-        data['objects'] = [obj]
-
-        action = '/fwpolicies/'
-        response = self.connection.request(action=action, method='POST',
-                                           data=data).object
-        policy = self._to_firewall_policy(data=response['objects'][0])
-        return policy
-
-    def ex_attach_firewall_policy(self, policy, node, nic_mac=None):
-        """
-        Attach firewall policy to a public NIC interface on the server.
-
-        :param policy: Firewall policy to attach.
-        :type policy: :class:`.CloudSigmaFirewallPolicy`
-
-        :param node: Node to attach policy to.
-        :type node: :class:`libcloud.compute.base.Node`
-
-        :param nic_mac: Optional MAC address of the NIC to add the policy to.
-                        If not specified, first public interface is used
-                        instead.
-        :type nic_mac: ``str``
-
-        :return: Node object to which the policy was attached to.
-        :rtype: :class:`libcloud.compute.base.Node`
-        """
-        nics = copy.deepcopy(node.extra.get('nics', []))
-
-        if nic_mac:
-            nic = [n for n in nics if n['mac'] == nic_mac]
-        else:
-            nic = nics
-
-        if len(nic) == 0:
-            raise ValueError('Cannot find the NIC interface to attach '
-                             'a policy to')
-
-        nic = nic[0]
-        nic['firewall_policy'] = policy.id
-
-        params = {'nics': nics}
-        node = self.ex_edit_node(node=node, params=params)
-        return node
-
-    def ex_delete_firewall_policy(self, policy):
-        """
-        Delete a firewall policy.
-
-        :param policy: Policy to delete to.
-        :type policy: :class:`.CloudSigmaFirewallPolicy`
-
-        :return: ``True`` on success, ``False`` otherwise.
-        :rtype: ``bool``
-        """
-        action = '/fwpolicies/%s/' % (policy.id)
-        response = self.connection.request(action=action, method='DELETE')
-        return response.status == httplib.NO_CONTENT
-
-    # Availability groups extension methods
-
-    def ex_list_servers_availability_groups(self):
-        """
-        Return which running servers share the same physical compute host.
-
-        :return: A list of server UUIDs which share the same physical compute
-                 host. Servers which share the same host will be stored under
-                 the same list index.
-        :rtype: ``list`` of ``list``
-        """
-        action = '/servers/availability_groups/'
-        response = self.connection.request(action=action, method='GET')
-        return response.object
-
-    def ex_list_drives_availability_groups(self):
-        """
-        Return which drives share the same physical storage host.
-
-        :return: A list of drive UUIDs which share the same physical storage
-                 host. Drives which share the same host will be stored under
-                 the same list index.
-        :rtype: ``list`` of ``list``
-        """
-        action = '/drives/availability_groups/'
-        response = self.connection.request(action=action, method='GET')
-        return response.object
-
-    # Tag extension methods
-
-    def ex_list_tags(self):
-        """
-        List all the available tags.
-
-        :rtype: ``list`` of :class:`.CloudSigmaTag` objects
-        """
-        action = '/tags/detail/'
-        response = self.connection.request(action=action, method='GET').object
-        tags = [self._to_tag(data=item) for item in response['objects']]
-
-        return tags
-
-    def ex_get_tag(self, tag_id):
-        """
-        Retrieve a single tag.
-
-        :param tag_id: ID of the tag to retrieve.
-        :type tag_id: ``str``
-
-        :rtype: ``list`` of :class:`.CloudSigmaTag` objects
-        """
-        action = '/tags/%s/' % (tag_id)
-        response = self.connection.request(action=action, method='GET').object
-        tag = self._to_tag(data=response)
-        return tag
-
-    def ex_create_tag(self, name, resource_uuids=None):
-        """
-        Create a tag.
-
-        :param name: Tag name.
-        :type name: ``str``
-
-        :param resource_uuids: Optional list of resource UUIDs to assign this
-                               tag go.
-        :type resource_uuids: ``list`` of ``str``
-
-        :return: Created tag object.
-        :rtype: :class:`.CloudSigmaTag`
-        """
-        data = {}
-        data['objects'] = [
-            {
-                'name': name
-            }
-        ]
-
-        if resource_uuids:
-            data['resources'] = resource_uuids
-
-        action = '/tags/'
-        response = self.connection.request(action=action, method='POST',
-                                           data=data).object
-        tag = self._to_tag(data=response['objects'][0])
-        return tag
-
-    def ex_tag_resource(self, resource, tag):
-        """
-        Associate tag with the provided resource.
-
-        :param resource: Resource to associate a tag with.
-        :type resource: :class:`libcloud.compute.base.Node` or
-                        :class:`.CloudSigmaDrive`
-
-        :param tag: Tag to associate with the resources.
-        :type tag: :class:`.CloudSigmaTag`
-
-        :return: Updated tag object.
-        :rtype: :class:`.CloudSigmaTag`
-        """
-        if not hasattr(resource, 'id'):
-            raise ValueError('Resource doesn\'t have id attribute')
-
-        return self.ex_tag_resources(resources=[resource], tag=tag)
-
-    def ex_tag_resources(self, resources, tag):
-        """
-        Associate tag with the provided resources.
-
-        :param resources: Resources to associate a tag with.
-        :type resources: ``list`` of :class:`libcloud.compute.base.Node` or
-                        :class:`.CloudSigmaDrive`
-
-        :param tag: Tag to associate with the resources.
-        :type tag: :class:`.CloudSigmaTag`
-
-        :return: Updated tag object.
-        :rtype: :class:`.CloudSigmaTag`
-        """
-
-        resources = tag.resources[:]
-
-        for resource in resources:
-            if not hasattr(resource, 'id'):
-                raise ValueError('Resource doesn\'t have id attribute')
-
-            resources.append(resource.id)
-
-        resources = list(set(resources))
-
-        data = {
-            'name': tag.name,
-            'resources': resources
-        }
-
-        action = '/tags/%s/' % (tag.id)
-        response = self.connection.request(action=action, method='PUT',
-                                           data=data).object
-        tag = self._to_tag(data=response)
-        return tag
-
-    def ex_delete_tag(self, tag):
-        """
-        Delete a tag.
-
-        :param tag: Tag to delete.
-        :type tag: :class:`.CloudSigmaTag`
-
-        :return: ``True`` on success, ``False`` otherwise.
-        :rtype: ``bool``
-        """
-        action = '/tags/%s/' % (tag.id)
-        response = self.connection.request(action=action, method='DELETE')
-        return response.status == httplib.NO_CONTENT
-
-    # Account extension methods
-
-    def ex_get_balance(self):
-        """
-        Retrieve account balance information.
-
-        :return: Dictionary with two items ("balance" and "currency").
-        :rtype: ``dict``
-        """
-        action = '/balance/'
-        response = self.connection.request(action=action, method='GET')
-        return response.object
-
-    def ex_get_pricing(self):
-        """
-        Retrieve pricing information that are applicable to the cloud.
-
-        :return: Dictionary with pricing information.
-        :rtype: ``dict``
-        """
-        action = '/pricing/'
-        response = self.connection.request(action=action, method='GET')
-        return response.object
-
-    def ex_get_usage(self):
-        """
-        Retrieve account current usage information.
-
-        :return: Dictionary with two items ("balance" and "usage").
-        :rtype: ``dict``
-        """
-        action = '/currentusage/'
-        response = self.connection.request(action=action, method='GET')
-        return response.object
-
-    def ex_list_subscriptions(self, status='all', resources=None):
-        """
-        List subscriptions for this account.
-
-        :param status: Only return subscriptions with the provided status
-                       (optional).
-        :type status: ``str``
-        :param resources: Only return subscriptions for the provided resources
-                          (optional).
-        :type resources: ``list``
-
-        :rtype: ``list``
-        """
-        params = {}
-
-        if status:
-            params['status'] = status
-
-        if resources:
-            params['resource'] = ','.join(resources)
-
-        response = self.connection.request(action='/subscriptions/',
-                                           params=params).object
-        subscriptions = self._to_subscriptions(data=response)
-        return subscriptions
-
-    def ex_toggle_subscription_auto_renew(self, subscription):
-        """
-        Toggle subscription auto renew status.
-
-        :param subscription: Subscription to toggle the auto renew flag for.
-        :type subscription: :class:`.CloudSigmaSubscription`
-
-        :return: ``True`` on success, ``False`` otherwise.
-        :rtype: ``bool``
-        """
-        path = '/subscriptions/%s/action/' % (subscription.id)
-        response = self._perform_action(path=path, action='auto_renew',
-                                        method='POST')
-        return response.status == httplib.OK
-
-    def ex_create_subscription(self, amount, period, resource,
-                               auto_renew=False):
-        """
-        Create a new subscription.
-
-        :param amount: Subscription amount. For example, in dssd case this
-                       would be disk size in gigabytes.
-        :type amount: ``int``
-
-        :param period: Subscription period. For example: 30 days, 1 week, 1
-                                            month, ...
-        :type period: ``str``
-
-        :param resource: Resource the purchase the subscription for.
-        :type resource: ``str``
-
-        :param auto_renew: True to automatically renew the subscription.
-        :type auto_renew: ``bool``
-        """
-        data = [
-            {
-                'amount': amount,
-                'period': period,
-                'auto_renew': auto_renew,
-                'resource': resource
-            }
-        ]
-
-        response = self.connection.request(action='/subscriptions/',
-                                           data=data, method='POST')
-        data = response.object['objects'][0]
-        subscription = self._to_subscription(data=data)
-        return subscription
-
-    # Misc extension methods
-
-    def ex_list_capabilities(self):
-        """
-        Retrieve all the basic and sensible limits of the API.
-
-        :rtype: ``dict``
-        """
-        action = '/capabilities/'
-        response = self.connection.request(action=action,
-                                           method='GET')
-        capabilities = response.object
-        return capabilities
-
-    def _parse_ips_from_nic(self, nic):
-        """
-        Parse private and public IP addresses from the provided network
-        interface object.
-
-        :param nic: NIC object.
-        :type nic: ``dict``
-
-        :return: (public_ips, private_ips) tuple.
-        :rtype: ``tuple``
-        """
-        public_ips, private_ips = [], []
-
-        ipv4_conf = nic['ip_v4_conf']
-        ipv6_conf = nic['ip_v6_conf']
-
-        ip_v4 = ipv4_conf['ip'] if ipv4_conf else None
-        ip_v6 = ipv6_conf['ip'] if ipv6_conf else None
-
-        ipv4 = ip_v4['uuid'] if ip_v4 else None
-        ipv6 = ip_v4['uuid'] if ip_v6 else None
-
-        ips = []
-
-        if ipv4:
-            ips.append(ipv4)
-
-        if ipv6:
-            ips.append(ipv6)
-
-        runtime = nic['runtime']
-
-        ip_v4 = runtime['ip_v4'] if nic['runtime'] else None
-        ip_v6 = runtime['ip_v6'] if nic['runtime'] else None
-
-        ipv4 = ip_v4['uuid'] if ip_v4 else None
-        ipv6 = ip_v4['uuid'] if ip_v6 else None
-
-        if ipv4:
-            ips.append(ipv4)
-
-        if ipv6:
-            ips.append(ipv6)
-
-        ips = set(ips)
-
-        for ip in ips:
-            if is_private_subnet(ip):
-                private_ips.append(ip)
-            else:
-                public_ips.append(ip)
-
-        return public_ips, private_ips
-
-    def _to_node(self, data):
-        extra_keys = ['cpu', 'mem', 'nics', 'vnc_password', 'meta']
-
-        id = data['uuid']
-        name = data['name']
-        state = self.NODE_STATE_MAP.get(data['status'], NodeState.UNKNOWN)
-
-        public_ips = []
-        private_ips = []
-        extra = self._extract_values(obj=data, keys=extra_keys)
-
-        for nic in data['nics']:
-            _public_ips, _private_ips = self._parse_ips_from_nic(nic=nic)
-
-            public_ips.extend(_public_ips)
-            private_ips.extend(_private_ips)
-
-        node = Node(id=id, name=name, state=state, public_ips=public_ips,
-                    private_ips=private_ips, driver=self, extra=extra)
-        return node
-
-    def _to_image(self, data):
-        extra_keys = ['description', 'arch', 'image_type', 'os', 'licenses',
-                      'media', 'meta']
-
-        id = data['uuid']
-        name = data['name']
-        extra = self._extract_values(obj=data, keys=extra_keys)
-
-        image = NodeImage(id=id, name=name, driver=self, extra=extra)
-        return image
-
-    def _to_drive(self, data):
-        id = data['uuid']
-        name = data['name']
-        size = data['size']
-        media = data['media']
-        status = data['status']
-        extra = {}
-
-        drive = CloudSigmaDrive(id=id, name=name, size=size, media=media,
-                                status=status, driver=self, extra=extra)
-
-        return drive
-
-    def _to_tag(self, data):
-        resources = data['resources']
-        resources = [resource['uuid'] for resource in resources]
-
-        tag = CloudSigmaTag(id=data['uuid'], name=data['name'],
-                            resources=resources)
-        return tag
-
-    def _to_subscriptions(self, data):
-        subscriptions = []
-
-        for item in data['objects']:
-            subscription = self._to_subscription(data=item)
-            subscriptions.append(subscription)
-
-        return subscriptions
-
-    def _to_subscription(self, data):
-        start_time = parse_date(data['start_time'])
-        end_time = parse_date(data['end_time'])
-        obj_uuid = data['subscribed_object']
-
-        subscription = CloudSigmaSubscription(id=data['id'],
-                                              resource=data['resource'],
-                                              amount=int(data['amount']),
-                                              period=data['period'],
-                                              status=data['status'],
-                                              price=data['price'],
-                                              start_time=start_time,
-                                              end_time=end_time,
-                                              auto_renew=data['auto_renew'],
-                                              subscribed_object=obj_uuid)
-        return subscription
-
-    def _to_firewall_policy(self, data):
-        rules = []
-
-        for item in data.get('rules', []):
-            rule = CloudSigmaFirewallPolicyRule(action=item['action'],
-                                                direction=item['direction'],
-                                                ip_proto=item['ip_proto'],
-                                                src_ip=item['src_ip'],
-                                                src_port=item['src_port'],
-                                                dst_ip=item['dst_ip'],
-                                                dst_port=item['dst_port'],
-                                                comment=item['comment'])
-            rules.append(rule)
-
-        policy = CloudSigmaFirewallPolicy(id=data['uuid'], name=data['name'],
-                                          rules=rules)
-        return policy
-
-    def _perform_action(self, path, action, method='POST', params=None,
-                        data=None):
-        """
-        Perform API action and return response object.
-        """
-        if params:
-            params = params.copy()
-        else:
-            params = {}
-
-        params['do'] = action
-        response = self.connection.request(action=path, method=method,
-                                           params=params, data=data)
-        return response
-
-    def _is_installation_cd(self, image):
-        """
-        Detect if the provided image is an installation CD.
-
-        :rtype: ``bool``
-        """
-        if isinstance(image, CloudSigmaDrive) and image.media == 'cdrom':
-            return True
-
-        return False
-
-    def _extract_values(self, obj, keys):
-        """
-        Extract values from a dictionary and return a new dictionary with
-        extracted values.
-
-        :param obj: Dictionary to extract values from.
-        :type obj: ``dict``
-
-        :param keys: Keys to extract.
-        :type keys: ``list``
-
-        :return: Dictionary with extracted values.
-        :rtype: ``dict``
-        """
-        result = {}
-
-        for key in keys:
-            result[key] = obj[key]
-
-        return result
-
-    def _wait_for_drive_state_transition(self, drive, state,
-                                         timeout=DRIVE_TRANSITION_TIMEOUT):
-        """
-        Wait for a drive to transition to the provided state.
-
-        Note: This function blocks and periodically calls "GET drive" endpoint
-        to check if the drive has already transitioned to the desired state.
-
-        :param drive: Drive to wait for.
-        :type drive: :class:`.CloudSigmaDrive`
-
-        :param state: Desired drive state.
-        :type state: ``str``
-
-        :param timeout: How long to wait for the transition (in seconds) before
-                        timing out.
-        :type timeout: ``int``
-
-        :return: Drive object.
-        :rtype: :class:`.CloudSigmaDrive`
-        """
-
-        start_time = time.time()
-
-        while drive.status != state:
-            drive = self.ex_get_drive(drive_id=drive.id)
-
-            if drive.status == state:
-                break
-
-            current_time = time.time()
-            delta = (current_time - start_time)
-
-            if delta >= timeout:
-                msg = ('Timed out while waiting for drive transition '
-                       '(timeout=%s seconds)' % (timeout))
-                raise Exception(msg)
-
-            time.sleep(self.DRIVE_TRANSITION_SLEEP_INTERVAL)
-
-        return drive
-
-    def _ex_connection_class_kwargs(self):
-        """
-        Return the host value based on the user supplied region.
-        """
-        kwargs = {}
-
-        if not self._host_argument_set:
-            kwargs['host'] = API_ENDPOINTS_2_0[self.region]['host']
-
-        return kwargs


[25/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/gce.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/gce.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/gce.py
deleted file mode 100644
index 4aa92ac..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/gce.py
+++ /dev/null
@@ -1,5860 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-Module for Google Compute Engine Driver.
-"""
-from __future__ import with_statement
-
-import datetime
-import time
-import sys
-
-from libcloud.common.base import LazyObject
-from libcloud.common.google import GoogleOAuth2Credential
-from libcloud.common.google import GoogleResponse
-from libcloud.common.google import GoogleBaseConnection
-from libcloud.common.google import GoogleBaseError
-from libcloud.common.google import ResourceNotFoundError
-from libcloud.common.google import ResourceExistsError
-from libcloud.common.types import ProviderError
-
-from libcloud.compute.base import Node, NodeDriver, NodeImage, NodeLocation
-from libcloud.compute.base import NodeSize, StorageVolume, VolumeSnapshot
-from libcloud.compute.base import UuidMixin
-from libcloud.compute.providers import Provider
-from libcloud.compute.types import NodeState
-from libcloud.utils.iso8601 import parse_date
-
-API_VERSION = 'v1'
-DEFAULT_TASK_COMPLETION_TIMEOUT = 180
-
-
-def timestamp_to_datetime(timestamp):
-    """
-    Return a datetime object that corresponds to the time in an RFC3339
-    timestamp.
-
-    :param  timestamp: RFC3339 timestamp string
-    :type   timestamp: ``str``
-
-    :return:  Datetime object corresponding to timestamp
-    :rtype:   :class:`datetime.datetime`
-    """
-    # We remove timezone offset and microseconds (Python 2.5 strptime doesn't
-    # support %f)
-    ts = datetime.datetime.strptime(timestamp[:-10], '%Y-%m-%dT%H:%M:%S')
-    tz_hours = int(timestamp[-5:-3])
-    tz_mins = int(timestamp[-2:]) * int(timestamp[-6:-5] + '1')
-    tz_delta = datetime.timedelta(hours=tz_hours, minutes=tz_mins)
-    return ts + tz_delta
-
-
-class GCEResponse(GoogleResponse):
-    pass
-
-
-class GCEConnection(GoogleBaseConnection):
-    """
-    Connection class for the GCE driver.
-
-    GCEConnection extends :class:`google.GoogleBaseConnection` for 2 reasons:
-      1. modify request_path for GCE URI.
-      2. Implement gce_params functionality described below.
-
-    If the parameter gce_params is set to a dict prior to calling request(),
-    the URL parameters will be updated to include those key/values FOR A
-    SINGLE REQUEST. If the response contains a nextPageToken,
-    gce_params['pageToken'] will be set to its value. This can be used to
-    implement paging in list:
-
-    >>> params, more_results = {'maxResults': 2}, True
-    >>> while more_results:
-    ...     driver.connection.gce_params=params
-    ...     driver.ex_list_urlmaps()
-    ...     more_results = 'pageToken' in params
-    ...
-    [<GCEUrlMap id="..." name="cli-map">, <GCEUrlMap id="..." name="lc-map">]
-    [<GCEUrlMap id="..." name="web-map">]
-    """
-    host = 'www.googleapis.com'
-    responseCls = GCEResponse
-
-    def __init__(self, user_id, key, secure, auth_type=None,
-                 credential_file=None, project=None, **kwargs):
-        super(GCEConnection, self).__init__(user_id, key, secure=secure,
-                                            auth_type=auth_type,
-                                            credential_file=credential_file,
-                                            **kwargs)
-        self.request_path = '/compute/%s/projects/%s' % (API_VERSION, project)
-        self.gce_params = None
-
-    def pre_connect_hook(self, params, headers):
-        """
-        Update URL parameters with values from self.gce_params.
-
-        @inherits: :class:`GoogleBaseConnection.pre_connect_hook`
-        """
-        params, headers = super(GCEConnection, self).pre_connect_hook(params,
-                                                                      headers)
-        if self.gce_params:
-            params.update(self.gce_params)
-        return params, headers
-
-    def request(self, *args, **kwargs):
-        """
-        Perform request then do GCE-specific processing of URL params.
-
-        @inherits: :class:`GoogleBaseConnection.request`
-        """
-        response = super(GCEConnection, self).request(*args, **kwargs)
-
-        # If gce_params has been set, then update the pageToken with the
-        # nextPageToken so it can be used in the next request.
-        if self.gce_params:
-            if 'nextPageToken' in response.object:
-                self.gce_params['pageToken'] = response.object['nextPageToken']
-            elif 'pageToken' in self.gce_params:
-                del self.gce_params['pageToken']
-            self.gce_params = None
-
-        return response
-
-
-class GCEList(object):
-    """
-    An Iterator that wraps list functions to provide additional features.
-
-    GCE enforces a limit on the number of objects returned by a list operation,
-    so users with more than 500 objects of a particular type will need to use
-    filter(), page() or both.
-
-    >>> l=GCEList(driver, driver.ex_list_urlmaps)
-    >>> for sublist in l.filter('name eq ...-map').page(1):
-    ...   sublist
-    ...
-    [<GCEUrlMap id="..." name="cli-map">]
-    [<GCEUrlMap id="..." name="web-map">]
-
-    One can create a GCEList manually, but it's slightly easier to use the
-    ex_list() method of :class:`GCENodeDriver`.
-    """
-
-    def __init__(self, driver, list_fn, **kwargs):
-        """
-        :param  driver: An initialized :class:``GCENodeDriver``
-        :type   driver: :class:``GCENodeDriver``
-
-        :param  list_fn: A bound list method from :class:`GCENodeDriver`.
-        :type   list_fn: ``instancemethod``
-        """
-        self.driver = driver
-        self.list_fn = list_fn
-        self.kwargs = kwargs
-        self.params = {}
-
-    def __iter__(self):
-        list_fn = self.list_fn
-        more_results = True
-        while more_results:
-            self.driver.connection.gce_params = self.params
-            yield list_fn(**self.kwargs)
-            more_results = 'pageToken' in self.params
-
-    def __repr__(self):
-        return '<GCEList list="%s" params="%s">' % (
-            self.list_fn.__name__, repr(self.params))
-
-    def filter(self, expression):
-        """
-        Filter results of a list operation.
-
-        GCE supports server-side filtering of resources returned by a list
-        operation. Syntax of the filter expression is fully described in the
-        GCE API reference doc, but in brief it is::
-
-            FIELD_NAME COMPARISON_STRING LITERAL_STRING
-
-        where FIELD_NAME is the resource's property name, COMPARISON_STRING is
-        'eq' or 'ne', and LITERAL_STRING is a regular expression in RE2 syntax.
-
-        >>> for sublist in l.filter('name eq ...-map'):
-        ...   sublist
-        ...
-        [<GCEUrlMap id="..." name="cli-map">, \
-                <GCEUrlMap id="..." name="web-map">]
-
-        API reference: https://cloud.google.com/compute/docs/reference/latest/
-        RE2 syntax: https://github.com/google/re2/blob/master/doc/syntax.txt
-
-        :param  expression: Filter expression described above.
-        :type   expression: ``str``
-
-        :return: This :class:`GCEList` instance
-        :rtype:  :class:`GCEList`
-        """
-        self.params['filter'] = expression
-        return self
-
-    def page(self, max_results=500):
-        """
-        Limit the number of results by each iteration.
-
-        This implements the paging functionality of the GCE list methods and
-        returns this GCEList instance so that results can be chained:
-
-        >>> for sublist in GCEList(driver, driver.ex_list_urlmaps).page(2):
-        ...   sublist
-        ...
-        [<GCEUrlMap id="..." name="cli-map">, \
-                <GCEUrlMap id="..." name="lc-map">]
-        [<GCEUrlMap id="..." name="web-map">]
-
-        :keyword  max_results: Maximum number of results to return per
-                               iteration. Defaults to the GCE default of 500.
-        :type     max_results: ``int``
-
-        :return: This :class:`GCEList` instance
-        :rtype:  :class:`GCEList`
-        """
-        self.params['maxResults'] = max_results
-        return self
-
-
-class GCELicense(UuidMixin, LazyObject):
-    """A GCE License used to track software usage in GCE nodes."""
-    def __init__(self, name, project, driver):
-        UuidMixin.__init__(self)
-        self.id = name
-        self.name = name
-        self.project = project
-        self.driver = driver
-        self.charges_use_fee = None  # init in _request
-        self.extra = None  # init in _request
-
-        self._request()
-
-    def _request(self):
-        # TODO(crunkleton@google.com): create new connection? or make
-        # connection thread-safe? Saving, modifying, and restoring
-        # driver.connection.request_path is really hacky and thread-unsafe.
-        saved_request_path = self.driver.connection.request_path
-        new_request_path = saved_request_path.replace(self.driver.project,
-                                                      self.project)
-        self.driver.connection.request_path = new_request_path
-
-        request = '/global/licenses/%s' % self.name
-        response = self.driver.connection.request(request, method='GET').object
-        self.driver.connection.request_path = saved_request_path
-
-        self.extra = {
-            'selfLink': response.get('selfLink'),
-            'kind': response.get('kind')
-        }
-        self.charges_use_fee = response['chargesUseFee']
-
-    def destroy(self):
-        raise ProviderError("Can not destroy a License resource.")
-
-    def __repr__(self):
-        return '<GCELicense id="%s" name="%s" charges_use_fee="%s">' % (
-            self.id, self.name, self.charges_use_fee)
-
-
-class GCEDiskType(UuidMixin):
-    """A GCE DiskType resource."""
-    def __init__(self, id, name, zone, driver, extra=None):
-        self.id = str(id)
-        self.name = name
-        self.zone = zone
-        self.driver = driver
-        self.extra = extra
-        UuidMixin.__init__(self)
-
-    def destroy(self):
-        raise ProviderError("Can not destroy a DiskType resource.")
-
-    def __repr__(self):
-        return '<GCEDiskType id="%s" name="%s" zone="%s">' % (
-            self.id, self.name, self.zone)
-
-
-class GCEAddress(UuidMixin):
-    """A GCE Static address."""
-    def __init__(self, id, name, address, region, driver, extra=None):
-        self.id = str(id)
-        self.name = name
-        self.address = address
-        self.region = region
-        self.driver = driver
-        self.extra = extra
-        UuidMixin.__init__(self)
-
-    def destroy(self):
-        """
-        Destroy this address.
-
-        :return: True if successful
-        :rtype:  ``bool``
-        """
-        return self.driver.ex_destroy_address(address=self)
-
-    def __repr__(self):
-        return '<GCEAddress id="%s" name="%s" address="%s" region="%s">' % (
-            self.id, self.name, self.address,
-            (hasattr(self.region, "name") and self.region.name or self.region))
-
-
-class GCEBackendService(UuidMixin):
-    """A GCE Backend Service."""
-
-    def __init__(self, id, name, backends, healthchecks, port, port_name,
-                 protocol, timeout, driver, extra=None):
-        self.id = str(id)
-        self.name = name
-        self.backends = backends or []
-        self.healthchecks = healthchecks or []
-        self.port = port
-        self.port_name = port_name
-        self.protocol = protocol
-        self.timeout = timeout
-        self.driver = driver
-        self.extra = extra or {}
-        UuidMixin.__init__(self)
-
-    def __repr__(self):
-        return '<GCEBackendService id="%s" name="%s">' % (
-            self.id, self.name)
-
-    def destroy(self):
-        """
-        Destroy this Backend Service.
-
-        :return: True if successful
-        :rtype:  ``bool``
-        """
-        return self.driver.ex_destroy_backendservice(backendservice=self)
-
-
-class GCEFailedDisk(object):
-    """Dummy Node object for disks that are not created."""
-    def __init__(self, name, error, code):
-        self.name = name
-        self.error = error
-        self.code = code
-
-    def __repr__(self):
-        return '<GCEFailedDisk name="%s" error_code="%s">' % (
-            self.name, self.code)
-
-
-class GCEFailedNode(object):
-    """Dummy Node object for nodes that are not created."""
-    def __init__(self, name, error, code):
-        self.name = name
-        self.error = error
-        self.code = code
-
-    def __repr__(self):
-        return '<GCEFailedNode name="%s" error_code="%s">' % (
-            self.name, self.code)
-
-
-class GCEHealthCheck(UuidMixin):
-    """A GCE Http Health Check class."""
-    def __init__(self, id, name, path, port, interval, timeout,
-                 unhealthy_threshold, healthy_threshold, driver, extra=None):
-        self.id = str(id)
-        self.name = name
-        self.path = path
-        self.port = port
-        self.interval = interval
-        self.timeout = timeout
-        self.unhealthy_threshold = unhealthy_threshold
-        self.healthy_threshold = healthy_threshold
-        self.driver = driver
-        self.extra = extra or {}
-        UuidMixin.__init__(self)
-
-    def destroy(self):
-        """
-        Destroy this Health Check.
-
-        :return:  True if successful
-        :rtype:   ``bool``
-        """
-        return self.driver.ex_destroy_healthcheck(healthcheck=self)
-
-    def update(self):
-        """
-        Commit updated healthcheck values.
-
-        :return:  Updated Healthcheck object
-        :rtype:   :class:`GCEHealthcheck`
-        """
-        return self.driver.ex_update_healthcheck(healthcheck=self)
-
-    def __repr__(self):
-        return '<GCEHealthCheck id="%s" name="%s" path="%s" port="%s">' % (
-            self.id, self.name, self.path, self.port)
-
-
-class GCEFirewall(UuidMixin):
-    """A GCE Firewall rule class."""
-    def __init__(self, id, name, allowed, network, source_ranges, source_tags,
-                 target_tags, driver, extra=None):
-        self.id = str(id)
-        self.name = name
-        self.network = network
-        self.allowed = allowed
-        self.source_ranges = source_ranges
-        self.source_tags = source_tags
-        self.target_tags = target_tags
-        self.driver = driver
-        self.extra = extra
-        UuidMixin.__init__(self)
-
-    def destroy(self):
-        """
-        Destroy this firewall.
-
-        :return: True if successful
-        :rtype:  ``bool``
-        """
-        return self.driver.ex_destroy_firewall(firewall=self)
-
-    def update(self):
-        """
-        Commit updated firewall values.
-
-        :return:  Updated Firewall object
-        :rtype:   :class:`GCEFirewall`
-        """
-        return self.driver.ex_update_firewall(firewall=self)
-
-    def __repr__(self):
-        return '<GCEFirewall id="%s" name="%s" network="%s">' % (
-            self.id, self.name, self.network.name)
-
-
-class GCEForwardingRule(UuidMixin):
-    def __init__(self, id, name, region, address, protocol, targetpool, driver,
-                 extra=None):
-        self.id = str(id)
-        self.name = name
-        self.region = region
-        self.address = address
-        self.protocol = protocol
-        # TODO: 'targetpool' should more correctly be 'target' since a
-        # forwarding rule's target can be something besides a targetpool
-        self.targetpool = targetpool
-        self.driver = driver
-        self.extra = extra
-        UuidMixin.__init__(self)
-
-    def destroy(self):
-        """
-        Destroy this Forwarding Rule
-
-        :return:  True if successful
-        :rtype:   ``bool``
-        """
-        return self.driver.ex_destroy_forwarding_rule(forwarding_rule=self)
-
-    def __repr__(self):
-        return '<GCEForwardingRule id="%s" name="%s" address="%s">' % (
-            self.id, self.name, self.address)
-
-
-class GCENodeImage(NodeImage):
-    """A GCE Node Image class."""
-    def __init__(self, id, name, driver, extra=None):
-        super(GCENodeImage, self).__init__(id, name, driver, extra=extra)
-
-    def delete(self):
-        """
-        Delete this image
-
-        :return: True if successful
-        :rtype:  ``bool``
-        """
-        return self.driver.ex_delete_image(image=self)
-
-    def deprecate(self, replacement, state, deprecated=None, obsolete=None,
-                  deleted=None):
-        """
-        Deprecate this image
-
-        :param  replacement: Image to use as a replacement
-        :type   replacement: ``str`` or :class: `GCENodeImage`
-
-        :param  state: Deprecation state of this image. Possible values include
-                       \'DELETED\', \'DEPRECATED\' or \'OBSOLETE\'.
-        :type   state: ``str``
-
-        :param  deprecated: RFC3339 timestamp to mark DEPRECATED
-        :type   deprecated: ``str`` or ``None``
-
-        :param  obsolete: RFC3339 timestamp to mark OBSOLETE
-        :type   obsolete: ``str`` or ``None``
-
-        :param  deleted: RFC3339 timestamp to mark DELETED
-        :type   deleted: ``str`` or ``None``
-
-        :return: True if successful
-        :rtype:  ``bool``
-        """
-        return self.driver.ex_deprecate_image(self, replacement, state,
-                                              deprecated, obsolete, deleted)
-
-
-class GCENetwork(UuidMixin):
-    """A GCE Network object class."""
-    def __init__(self, id, name, cidr, driver, extra=None):
-        self.id = str(id)
-        self.name = name
-        self.cidr = cidr
-        self.driver = driver
-        self.extra = extra
-        UuidMixin.__init__(self)
-
-    def destroy(self):
-        """
-        Destroy this network
-
-        :return: True if successful
-        :rtype:  ``bool``
-        """
-        return self.driver.ex_destroy_network(network=self)
-
-    def __repr__(self):
-        return '<GCENetwork id="%s" name="%s" cidr="%s">' % (
-            self.id, self.name, self.cidr)
-
-
-class GCERoute(UuidMixin):
-    """A GCE Route object class."""
-    def __init__(self, id, name, dest_range, priority, network="default",
-                 tags=None, driver=None, extra=None):
-        self.id = str(id)
-        self.name = name
-        self.dest_range = dest_range
-        self.priority = priority
-        self.network = network
-        self.tags = tags
-        self.driver = driver
-        self.extra = extra
-        UuidMixin.__init__(self)
-
-    def destroy(self):
-        """
-        Destroy this route
-
-        :return: True if successful
-        :rtype:  ``bool``
-        """
-        return self.driver.ex_destroy_route(route=self)
-
-    def __repr__(self):
-        return '<GCERoute id="%s" name="%s" dest_range="%s" network="%s">' % (
-            self.id, self.name, self.dest_range,
-            hasattr(self.network, 'name') and self.network.name or
-            self.network)
-
-
-class GCENodeSize(NodeSize):
-    """A GCE Node Size (MachineType) class."""
-    def __init__(self, id, name, ram, disk, bandwidth, price, driver,
-                 extra=None):
-        self.extra = extra
-        super(GCENodeSize, self).__init__(id, name, ram, disk, bandwidth,
-                                          price, driver, extra=extra)
-
-
-class GCEProject(UuidMixin):
-    """GCE Project information."""
-    def __init__(self, id, name, metadata, quotas, driver, extra=None):
-        self.id = str(id)
-        self.name = name
-        self.metadata = metadata
-        self.quotas = quotas
-        self.driver = driver
-        self.extra = extra
-        UuidMixin.__init__(self)
-
-    def set_common_instance_metadata(self, metadata=None, force=False):
-        """
-        Set common instance metadata for the project. Common uses
-        are for setting 'sshKeys', or setting a project-wide
-        'startup-script' for all nodes (instances).  Passing in
-        ``None`` for the 'metadata' parameter will clear out all common
-        instance metadata *except* for 'sshKeys'. If you also want to
-        update 'sshKeys', set the 'force' parameter to ``True``.
-
-        :param  metadata: Dictionary of metadata. Can be either a standard
-                          python dictionary, or the format expected by
-                          GCE (e.g. {'items': [{'key': k1, 'value': v1}, ...}]
-        :type   metadata: ``dict`` or ``None``
-
-        :param  force: Force update of 'sshKeys'. If force is ``False`` (the
-                       default), existing sshKeys will be retained. Setting
-                       force to ``True`` will either replace sshKeys if a new
-                       a new value is supplied, or deleted if no new value
-                       is supplied.
-        :type   force: ``bool``
-
-        :return: True if successful
-        :rtype:  ``bool``
-        """
-        return self.driver.ex_set_common_instance_metadata(self, metadata)
-
-    def set_usage_export_bucket(self, bucket, prefix=None):
-        """
-        Used to retain Compute Engine resource usage, storing the CSV data in
-        a Google Cloud Storage bucket. See the
-        `docs <https://cloud.google.com/compute/docs/usage-export>`_ for more
-        information. Please ensure you have followed the necessary setup steps
-        prior to enabling this feature (e.g. bucket exists, ACLs are in place,
-        etc.)
-
-        :param  bucket: Name of the Google Cloud Storage bucket. Specify the
-                        name in either 'gs://<bucket_name>' or the full URL
-                        'https://storage.googleapis.com/<bucket_name>'.
-        :type   bucket: ``str``
-
-        :param  prefix: Optional prefix string for all reports.
-        :type   prefix: ``str`` or ``None``
-
-        :return: True if successful
-        :rtype:  ``bool``
-        """
-        return self.driver.ex_set_usage_export_bucket(self, bucket, prefix)
-
-    def __repr__(self):
-        return '<GCEProject id="%s" name="%s">' % (self.id, self.name)
-
-
-class GCERegion(UuidMixin):
-    def __init__(self, id, name, status, zones, quotas, deprecated, driver,
-                 extra=None):
-        self.id = str(id)
-        self.name = name
-        self.status = status
-        self.zones = zones
-        self.quotas = quotas
-        self.deprecated = deprecated
-        self.driver = driver
-        self.extra = extra
-        UuidMixin.__init__(self)
-
-    def __repr__(self):
-        return '<GCERegion id="%s" name="%s", status="%s">' % (
-            self.id, self.name, self.status)
-
-
-class GCESnapshot(VolumeSnapshot):
-    def __init__(self, id, name, size, status, driver, extra=None,
-                 created=None):
-        self.name = name
-        self.status = status
-        super(GCESnapshot, self).__init__(id, driver, size, extra, created)
-
-
-class GCETargetHttpProxy(UuidMixin):
-    def __init__(self, id, name, urlmap, driver, extra=None):
-        self.id = str(id)
-        self.name = name
-        self.urlmap = urlmap
-        self.driver = driver
-        self.extra = extra or {}
-        UuidMixin.__init__(self)
-
-    def __repr__(self):
-        return '<GCETargetHttpProxy id="%s" name="%s">' % (
-            self.id, self.name)
-
-    def destroy(self):
-        """
-        Destroy this Target HTTP Proxy.
-
-        :return:  True if successful
-        :rtype:   ``bool``
-        """
-        return self.driver.ex_destroy_targethttpproxy(targethttpproxy=self)
-
-
-class GCETargetInstance(UuidMixin):
-    def __init__(self, id, name, zone, node, driver, extra=None):
-        self.id = str(id)
-        self.name = name
-        self.zone = zone
-        self.node = node
-        self.driver = driver
-        self.extra = extra
-        UuidMixin.__init__(self)
-
-    def destroy(self):
-        """
-        Destroy this Target Instance
-
-        :return:  True if successful
-        :rtype:   ``bool``
-        """
-        return self.driver.ex_destroy_targetinstance(targetinstance=self)
-
-    def __repr__(self):
-        return '<GCETargetInstance id="%s" name="%s" zone="%s" node="%s">' % (
-            self.id, self.name, self.zone.name,
-            (hasattr(self.node, 'name') and self.node.name or self.node))
-
-
-class GCETargetPool(UuidMixin):
-    def __init__(self, id, name, region, healthchecks, nodes, driver,
-                 extra=None):
-        self.id = str(id)
-        self.name = name
-        self.region = region
-        self.healthchecks = healthchecks
-        self.nodes = nodes
-        self.driver = driver
-        self.extra = extra
-        UuidMixin.__init__(self)
-
-    def add_node(self, node):
-        """
-        Add a node to this target pool.
-
-        :param  node: Node to add
-        :type   node: ``str`` or :class:`Node`
-
-        :return:  True if successful
-        :rtype:   ``bool``
-        """
-        return self.driver.ex_targetpool_add_node(targetpool=self, node=node)
-
-    def remove_node(self, node):
-        """
-        Remove a node from this target pool.
-
-        :param  node: Node to remove
-        :type   node: ``str`` or :class:`Node`
-
-        :return:  True if successful
-        :rtype:   ``bool``
-        """
-        return self.driver.ex_targetpool_remove_node(targetpool=self,
-                                                     node=node)
-
-    def add_healthcheck(self, healthcheck):
-        """
-        Add a healthcheck to this target pool.
-
-        :param  healthcheck: Healthcheck to add
-        :type   healthcheck: ``str`` or :class:`GCEHealthCheck`
-
-        :return:  True if successful
-        :rtype:   ``bool``
-        """
-        return self.driver.ex_targetpool_add_healthcheck(
-            targetpool=self, healthcheck=healthcheck)
-
-    def remove_healthcheck(self, healthcheck):
-        """
-        Remove a healthcheck from this target pool.
-
-        :param  healthcheck: Healthcheck to remove
-        :type   healthcheck: ``str`` or :class:`GCEHealthCheck`
-
-        :return:  True if successful
-        :rtype:   ``bool``
-        """
-        return self.driver.ex_targetpool_remove_healthcheck(
-            targetpool=self, healthcheck=healthcheck)
-
-    def set_backup_targetpool(self, backup_targetpool, failover_ratio=0.1):
-        """
-        Set a backup targetpool.
-
-        :param  backup_targetpool: The existing targetpool to use for
-                                   failover traffic.
-        :type   backup_targetpool: :class:`GCETargetPool`
-
-        :param  failover_ratio: The percentage of healthy VMs must fall at or
-                                below this value before traffic will be sent
-                                to the backup targetpool (default 0.10)
-        :type   failover_ratio: ``float``
-
-        :return:  True if successful
-        :rtype:   ``bool``
-        """
-        return self.driver.ex_targetpool_set_backup_targetpool(
-            targetpool=self, backup_targetpool=backup_targetpool,
-            failover_ratio=failover_ratio)
-
-    def get_health(self, node=None):
-        """
-        Return a hash of target pool instances and their health.
-
-        :param  node: Optional node to specify if only a specific node's
-                      health status should be returned
-        :type   node: ``str``, ``Node``, or ``None``
-
-        :return: List of hashes of nodes and their respective health
-        :rtype:  ``list`` of ``dict``
-        """
-        return self.driver.ex_targetpool_get_health(targetpool=self, node=node)
-
-    def destroy(self):
-        """
-        Destroy this Target Pool
-
-        :return:  True if successful
-        :rtype:   ``bool``
-        """
-        return self.driver.ex_destroy_targetpool(targetpool=self)
-
-    def __repr__(self):
-        return '<GCETargetPool id="%s" name="%s" region="%s">' % (
-            self.id, self.name, self.region.name)
-
-
-class GCEUrlMap(UuidMixin):
-    """A GCE URL Map."""
-
-    def __init__(self, id, name, default_service, host_rules, path_matchers,
-                 tests, driver, extra=None):
-        self.id = str(id)
-        self.name = name
-        self.default_service = default_service
-        self.host_rules = host_rules or []
-        self.path_matchers = path_matchers or []
-        self.tests = tests or []
-        self.driver = driver
-        self.extra = extra or {}
-        UuidMixin.__init__(self)
-
-    def __repr__(self):
-        return '<GCEUrlMap id="%s" name="%s">' % (
-            self.id, self.name)
-
-    def destroy(self):
-        """
-        Destroy this URL Map
-
-        :return:  True if successful
-        :rtype:   ``bool``
-        """
-        return self.driver.ex_destroy_urlmap(urlmap=self)
-
-
-class GCEZone(NodeLocation):
-    """Subclass of NodeLocation to provide additional information."""
-    def __init__(self, id, name, status, maintenance_windows, deprecated,
-                 driver, extra=None):
-        self.status = status
-        self.maintenance_windows = maintenance_windows
-        self.deprecated = deprecated
-        self.extra = extra
-        country = name.split('-')[0]
-        super(GCEZone, self).__init__(id=str(id), name=name, country=country,
-                                      driver=driver)
-
-    @property
-    def time_until_mw(self):
-        """
-        Returns the time until the next Maintenance Window as a
-        datetime.timedelta object.
-        """
-        return self._get_time_until_mw()
-
-    @property
-    def next_mw_duration(self):
-        """
-        Returns the duration of the next Maintenance Window as a
-        datetime.timedelta object.
-        """
-        return self._get_next_mw_duration()
-
-    def _now(self):
-        """
-        Returns current UTC time.
-
-        Can be overridden in unittests.
-        """
-        return datetime.datetime.utcnow()
-
-    def _get_next_maint(self):
-        """
-        Returns the next Maintenance Window.
-
-        :return:  A dictionary containing maintenance window info (or None if
-                  no maintenance windows are scheduled)
-                  The dictionary contains 4 keys with values of type ``str``
-                      - name: The name of the maintenance window
-                      - description: Description of the maintenance window
-                      - beginTime: RFC3339 Timestamp
-                      - endTime: RFC3339 Timestamp
-        :rtype:   ``dict`` or ``None``
-        """
-        begin = None
-        next_window = None
-        if not self.maintenance_windows:
-            return None
-        if len(self.maintenance_windows) == 1:
-            return self.maintenance_windows[0]
-        for mw in self.maintenance_windows:
-            begin_next = timestamp_to_datetime(mw['beginTime'])
-            if (not begin) or (begin_next < begin):
-                begin = begin_next
-                next_window = mw
-        return next_window
-
-    def _get_time_until_mw(self):
-        """
-        Returns time until next maintenance window.
-
-        :return:  Time until next maintenance window (or None if no
-                  maintenance windows are scheduled)
-        :rtype:   :class:`datetime.timedelta` or ``None``
-        """
-        next_window = self._get_next_maint()
-        if not next_window:
-            return None
-        now = self._now()
-        next_begin = timestamp_to_datetime(next_window['beginTime'])
-        return next_begin - now
-
-    def _get_next_mw_duration(self):
-        """
-        Returns the duration of the next maintenance window.
-
-        :return:  Duration of next maintenance window (or None if no
-                  maintenance windows are scheduled)
-        :rtype:   :class:`datetime.timedelta` or ``None``
-        """
-        next_window = self._get_next_maint()
-        if not next_window:
-            return None
-        next_begin = timestamp_to_datetime(next_window['beginTime'])
-        next_end = timestamp_to_datetime(next_window['endTime'])
-        return next_end - next_begin
-
-    def __repr__(self):
-        return '<GCEZone id="%s" name="%s" status="%s">' % (self.id, self.name,
-                                                            self.status)
-
-
-class GCENodeDriver(NodeDriver):
-    """
-    GCE Node Driver class.
-
-    This is the primary driver for interacting with Google Compute Engine.  It
-    contains all of the standard libcloud methods, plus additional ex_* methods
-    for more features.
-
-    Note that many methods allow either objects or strings (or lists of
-    objects/strings).  In most cases, passing strings instead of objects will
-    result in additional GCE API calls.
-    """
-    connectionCls = GCEConnection
-    api_name = 'google'
-    name = "Google Compute Engine"
-    type = Provider.GCE
-    website = 'https://cloud.google.com/'
-
-    # Google Compute Engine node states are mapped to Libcloud node states
-    # per the following dict. GCE does not have an actual 'stopped' state
-    # but instead uses a 'terminated' state to indicate the node exists
-    # but is not running. In order to better match libcloud, GCE maps this
-    # 'terminated' state to 'STOPPED'.
-    # Also, when a node is deleted from GCE, it no longer exists and instead
-    # will result in a ResourceNotFound error versus returning a placeholder
-    # node in a 'terminated' state.
-    # For more details, please see GCE's docs,
-    # https://cloud.google.com/compute/docs/instances#checkmachinestatus
-    NODE_STATE_MAP = {
-        "PROVISIONING": NodeState.PENDING,
-        "STAGING": NodeState.PENDING,
-        "RUNNING": NodeState.RUNNING,
-        "STOPPING": NodeState.PENDING,
-        "TERMINATED": NodeState.STOPPED,
-        "UNKNOWN": NodeState.UNKNOWN
-    }
-
-    AUTH_URL = "https://www.googleapis.com/auth/"
-    SA_SCOPES_MAP = {
-        # list derived from 'gcloud compute instances create --help'
-        "bigquery": "bigquery",
-        "cloud-platform": "cloud-platform",
-        "compute-ro": "compute.readonly",
-        "compute-rw": "compute",
-        "datastore": "datastore",
-        "logging-write": "logging.write",
-        "monitoring": "monitoring",
-        "sql": "sqlservice",
-        "sql-admin": "sqlservice.admin",
-        "storage-full": "devstorage.full_control",
-        "storage-ro": "devstorage.read_only",
-        "storage-rw": "devstorage.read_write",
-        "taskqueue": "taskqueue",
-        "useraccounts-ro": "cloud.useraccounts.readonly",
-        "useraccounts-rw": "cloud.useraccounts",
-        "userinfo-email": "userinfo.email"
-    }
-
-    IMAGE_PROJECTS = {
-        "centos-cloud": ["centos"],
-        "coreos-cloud": ["coreos"],
-        "debian-cloud": ["debian", "backports"],
-        "gce-nvme": ["nvme-backports"],
-        "google-containers": ["container-vm"],
-        "opensuse-cloud": ["opensuse"],
-        "rhel-cloud": ["rhel"],
-        "suse-cloud": ["sles", "suse"],
-        "ubuntu-os-cloud": ["ubuntu"],
-        "windows-cloud": ["windows"],
-    }
-
-    def __init__(self, user_id, key=None, datacenter=None, project=None,
-                 auth_type=None, scopes=None, credential_file=None, **kwargs):
-        """
-        :param  user_id: The email address (for service accounts) or Client ID
-                         (for installed apps) to be used for authentication.
-        :type   user_id: ``str``
-
-        :param  key: The RSA Key (for service accounts) or file path containing
-                     key or Client Secret (for installed apps) to be used for
-                     authentication.
-        :type   key: ``str``
-
-        :keyword  datacenter: The name of the datacenter (zone) used for
-                              operations.
-        :type     datacenter: ``str``
-
-        :keyword  project: Your GCE project name. (required)
-        :type     project: ``str``
-
-        :keyword  auth_type: Accepted values are "SA" or "IA" or "GCE"
-                             ("Service Account" or "Installed Application" or
-                             "GCE" if libcloud is being used on a GCE instance
-                             with service account enabled).
-                             If not supplied, auth_type will be guessed based
-                             on value of user_id or if the code is being
-                             executed in a GCE instance.
-        :type     auth_type: ``str``
-
-        :keyword  scopes: List of authorization URLs. Default is empty and
-                          grants read/write to Compute, Storage, DNS.
-        :type     scopes: ``list``
-
-        :keyword  credential_file: Path to file for caching authentication
-                                   information used by GCEConnection.
-        :type     credential_file: ``str``
-        """
-        if not project:
-            raise ValueError('Project name must be specified using '
-                             '"project" keyword.')
-
-        self.auth_type = auth_type
-        self.project = project
-        self.scopes = scopes
-        self.credential_file = credential_file or \
-            GoogleOAuth2Credential.default_credential_file + '.' + self.project
-
-        super(GCENodeDriver, self).__init__(user_id, key, **kwargs)
-
-        # Cache Zone and Region information to reduce API calls and
-        # increase speed
-        self.base_path = '/compute/%s/projects/%s' % (API_VERSION,
-                                                      self.project)
-        self.zone_list = self.ex_list_zones()
-        self.zone_dict = {}
-        for zone in self.zone_list:
-            self.zone_dict[zone.name] = zone
-        if datacenter:
-            self.zone = self.ex_get_zone(datacenter)
-        else:
-            self.zone = None
-
-        self.region_list = self.ex_list_regions()
-        self.region_dict = {}
-        for region in self.region_list:
-            self.region_dict[region.name] = region
-
-        if self.zone:
-            self.region = self._get_region_from_zone(self.zone)
-        else:
-            self.region = None
-
-    def ex_add_access_config(self, node, name, nic, nat_ip=None,
-                             config_type=None):
-        """
-        Add a network interface access configuration to a node.
-
-        :keyword  node: The existing target Node (instance) that will receive
-                        the new access config.
-        :type     node: ``Node``
-
-        :keyword  name: Name of the new access config.
-        :type     node: ``str``
-
-        :keyword  nat_ip: The external existing static IP Address to use for
-                          the access config. If not provided, an ephemeral
-                          IP address will be allocated.
-        :type     nat_ip: ``str`` or ``None``
-
-        :keyword  config_type: The type of access config to create. Currently
-                               the only supported type is 'ONE_TO_ONE_NAT'.
-        :type     config_type: ``str`` or ``None``
-
-        :return: True if successful
-        :rtype:  ``bool``
-        """
-        if not isinstance(node, Node):
-            raise ValueError("Must specify a valid libcloud node object.")
-        node_name = node.name
-        zone_name = node.extra['zone'].name
-
-        config = {'name': name}
-        if config_type is None:
-            config_type = 'ONE_TO_ONE_NAT'
-        config['type'] = config_type
-
-        if nat_ip is not None:
-            config['natIP'] = nat_ip
-        params = {'networkInterface': nic}
-        request = '/zones/%s/instances/%s/addAccessConfig' % (zone_name,
-                                                              node_name)
-        self.connection.async_request(request, method='POST',
-                                      data=config, params=params)
-        return True
-
-    def ex_delete_access_config(self, node, name, nic):
-        """
-        Delete a network interface access configuration from a node.
-
-        :keyword  node: The existing target Node (instance) for the request.
-        :type     node: ``Node``
-
-        :keyword  name: Name of the access config.
-        :type     node: ``str``
-
-        :keyword  nic: Name of the network interface.
-        :type     nic: ``str``
-
-        :return: True if successful
-        :rtype:  ``bool``
-        """
-        if not isinstance(node, Node):
-            raise ValueError("Must specify a valid libcloud node object.")
-        node_name = node.name
-        zone_name = node.extra['zone'].name
-
-        params = {'accessConfig': name, 'networkInterface': nic}
-        request = '/zones/%s/instances/%s/deleteAccessConfig' % (zone_name,
-                                                                 node_name)
-        self.connection.async_request(request, method='POST', params=params)
-        return True
-
-    def ex_set_node_metadata(self, node, metadata):
-        """
-        Set metadata for the specified node.
-
-        :keyword  node: The existing target Node (instance) for the request.
-        :type     node: ``Node``
-
-        :keyword  metadata: Set (or clear with None) metadata for this
-                            particular node.
-        :type     metadata: ``dict`` or ``None``
-
-        :return: True if successful
-        :rtype:  ``bool``
-        """
-        if not isinstance(node, Node):
-            raise ValueError("Must specify a valid libcloud node object.")
-        node_name = node.name
-        zone_name = node.extra['zone'].name
-        if 'metadata' in node.extra and \
-                'fingerprint' in node.extra['metadata']:
-            current_fp = node.extra['metadata']['fingerprint']
-        else:
-            current_fp = 'absent'
-        body = self._format_metadata(current_fp, metadata)
-        request = '/zones/%s/instances/%s/setMetadata' % (zone_name,
-                                                          node_name)
-        self.connection.async_request(request, method='POST', data=body)
-        return True
-
-    def ex_get_serial_output(self, node):
-        """
-        Fetch the console/serial port output from the node.
-
-        :keyword  node: The existing target Node (instance) for the request.
-        :type     node: ``Node``
-
-        :return: A string containing serial port output of the node.
-        :rtype:  ``str``
-        """
-        if not isinstance(node, Node):
-            raise ValueError("Must specify a valid libcloud node object.")
-        node_name = node.name
-        zone_name = node.extra['zone'].name
-        request = '/zones/%s/instances/%s/serialPort' % (zone_name,
-                                                         node_name)
-        response = self.connection.request(request, method='GET').object
-        return response['contents']
-
-    def ex_list(self, list_fn, **kwargs):
-        """
-        Wrap a list method in a :class:`GCEList` iterator.
-
-        >>> for sublist in driver.ex_list(driver.ex_list_urlmaps).page(1):
-        ...   sublist
-        ...
-        [<GCEUrlMap id="..." name="cli-map">]
-        [<GCEUrlMap id="..." name="lc-map">]
-        [<GCEUrlMap id="..." name="web-map">]
-
-        :param  list_fn: A bound list method from :class:`GCENodeDriver`.
-        :type   list_fn: ``instancemethod``
-
-        :return: An iterator that returns sublists from list_fn.
-        :rtype: :class:`GCEList`
-        """
-        return GCEList(driver=self, list_fn=list_fn, **kwargs)
-
-    def ex_list_disktypes(self, zone=None):
-        """
-        Return a list of DiskTypes for a zone or all.
-
-        :keyword  zone: The zone to return DiskTypes from. For example:
-                        'us-central1-a'.  If None, will return DiskTypes from
-                        self.zone.  If 'all', will return all DiskTypes.
-        :type     zone: ``str`` or ``None``
-
-        :return: A list of static DiskType objects.
-        :rtype: ``list`` of :class:`GCEDiskType`
-        """
-        list_disktypes = []
-        zone = self._set_zone(zone)
-        if zone is None:
-            request = '/aggregated/diskTypes'
-        else:
-            request = '/zones/%s/diskTypes' % (zone.name)
-        response = self.connection.request(request, method='GET').object
-
-        if 'items' in response:
-            # The aggregated result returns dictionaries for each region
-            if zone is None:
-                for v in response['items'].values():
-                    zone_disktypes = [self._to_disktype(a) for a in
-                                      v.get('diskTypes', [])]
-                    list_disktypes.extend(zone_disktypes)
-            else:
-                list_disktypes = [self._to_disktype(a) for a in
-                                  response['items']]
-        return list_disktypes
-
-    def ex_set_usage_export_bucket(self, bucket, prefix=None):
-        """
-        Used to retain Compute Engine resource usage, storing the CSV data in
-        a Google Cloud Storage bucket. See the
-        `docs <https://cloud.google.com/compute/docs/usage-export>`_ for more
-        information. Please ensure you have followed the necessary setup steps
-        prior to enabling this feature (e.g. bucket exists, ACLs are in place,
-        etc.)
-
-        :param  bucket: Name of the Google Cloud Storage bucket. Specify the
-                        name in either 'gs://<bucket_name>' or the full URL
-                        'https://storage.googleapis.com/<bucket_name>'.
-        :type   bucket: ``str``
-
-        :param  prefix: Optional prefix string for all reports.
-        :type   prefix: ``str`` or ``None``
-
-        :return: True if successful
-        :rtype:  ``bool``
-        """
-        if bucket.startswith('https://www.googleapis.com/') or \
-                bucket.startswith('gs://'):
-            data = {'bucketName': bucket}
-        else:
-            raise ValueError("Invalid bucket name: %s" % bucket)
-        if prefix:
-            data['reportNamePrefix'] = prefix
-
-        request = '/setUsageExportBucket'
-        self.connection.async_request(request, method='POST', data=data)
-        return True
-
-    def ex_set_common_instance_metadata(self, metadata=None, force=False):
-        """
-        Set common instance metadata for the project. Common uses
-        are for setting 'sshKeys', or setting a project-wide
-        'startup-script' for all nodes (instances).  Passing in
-        ``None`` for the 'metadata' parameter will clear out all common
-        instance metadata *except* for 'sshKeys'. If you also want to
-        update 'sshKeys', set the 'force' parameter to ``True``.
-
-        :param  metadata: Dictionary of metadata. Can be either a standard
-                          python dictionary, or the format expected by
-                          GCE (e.g. {'items': [{'key': k1, 'value': v1}, ...}]
-        :type   metadata: ``dict`` or ``None``
-
-        :param  force: Force update of 'sshKeys'. If force is ``False`` (the
-                       default), existing sshKeys will be retained. Setting
-                       force to ``True`` will either replace sshKeys if a new
-                       a new value is supplied, or deleted if no new value
-                       is supplied.
-        :type   force: ``bool``
-
-        :return: True if successful
-        :rtype:  ``bool``
-        """
-        if metadata:
-            metadata = self._format_metadata('na', metadata)
-
-        request = '/setCommonInstanceMetadata'
-
-        project = self.ex_get_project()
-        current_metadata = project.extra['commonInstanceMetadata']
-        fingerprint = current_metadata['fingerprint']
-        md_items = []
-        if 'items' in current_metadata:
-            md_items = current_metadata['items']
-
-        # grab copy of current 'sshKeys' in case we want to retain them
-        current_keys = ""
-        for md in md_items:
-            if md['key'] == 'sshKeys':
-                current_keys = md['value']
-
-        new_md = self._set_project_metadata(metadata, force, current_keys)
-
-        md = {'fingerprint': fingerprint, 'items': new_md}
-        self.connection.async_request(request, method='POST', data=md)
-        return True
-
-    def ex_list_addresses(self, region=None):
-        """
-        Return a list of static addresses for a region, 'global', or all.
-
-        :keyword  region: The region to return addresses from. For example:
-                          'us-central1'.  If None, will return addresses from
-                          region of self.zone.  If 'all', will return all
-                          addresses. If 'global', it will return addresses in
-                          the global namespace.
-        :type     region: ``str`` or ``None``
-
-        :return: A list of static address objects.
-        :rtype: ``list`` of :class:`GCEAddress`
-        """
-        list_addresses = []
-        if region != 'global':
-            region = self._set_region(region)
-        if region is None:
-            request = '/aggregated/addresses'
-        elif region == 'global':
-            request = '/global/addresses'
-        else:
-            request = '/regions/%s/addresses' % (region.name)
-        response = self.connection.request(request, method='GET').object
-
-        if 'items' in response:
-            # The aggregated result returns dictionaries for each region
-            if region is None:
-                for v in response['items'].values():
-                    region_addresses = [self._to_address(a) for a in
-                                        v.get('addresses', [])]
-                    list_addresses.extend(region_addresses)
-            else:
-                list_addresses = [self._to_address(a) for a in
-                                  response['items']]
-        return list_addresses
-
-    def ex_list_backendservices(self):
-        """
-        Return a list of backend services.
-
-        :return: A list of backend service objects.
-        :rtype: ``list`` of :class:`GCEBackendService`
-        """
-        list_backendservices = []
-        response = self.connection.request('/global/backendServices',
-                                           method='GET').object
-
-        list_backendservices = [self._to_backendservice(d) for d in
-                                response.get('items', [])]
-
-        return list_backendservices
-
-    def ex_list_healthchecks(self):
-        """
-        Return the list of health checks.
-
-        :return: A list of health check objects.
-        :rtype: ``list`` of :class:`GCEHealthCheck`
-        """
-        list_healthchecks = []
-        request = '/global/httpHealthChecks'
-        response = self.connection.request(request, method='GET').object
-        list_healthchecks = [self._to_healthcheck(h) for h in
-                             response.get('items', [])]
-        return list_healthchecks
-
-    def ex_list_firewalls(self):
-        """
-        Return the list of firewalls.
-
-        :return: A list of firewall objects.
-        :rtype: ``list`` of :class:`GCEFirewall`
-        """
-        list_firewalls = []
-        request = '/global/firewalls'
-        response = self.connection.request(request, method='GET').object
-        list_firewalls = [self._to_firewall(f) for f in
-                          response.get('items', [])]
-        return list_firewalls
-
-    def ex_list_forwarding_rules(self, region=None, global_rules=False):
-        """
-        Return the list of forwarding rules for a region or all.
-
-        :keyword  region: The region to return forwarding rules from.  For
-                          example: 'us-central1'.  If None, will return
-                          forwarding rules from the region of self.region
-                          (which is based on self.zone).  If 'all', will
-                          return forwarding rules for all regions, which does
-                          not include the global forwarding rules.
-        :type     region: ``str`` or :class:`GCERegion` or ``None``
-
-        :keyword  global_rules: List global forwarding rules instead of
-                                per-region rules.  Setting True will cause
-                                'region' parameter to be ignored.
-        :type     global_rules: ``bool``
-
-        :return: A list of forwarding rule objects.
-        :rtype: ``list`` of :class:`GCEForwardingRule`
-        """
-        list_forwarding_rules = []
-        if global_rules:
-            region = None
-            request = '/global/forwardingRules'
-        else:
-            region = self._set_region(region)
-            if region is None:
-                request = '/aggregated/forwardingRules'
-            else:
-                request = '/regions/%s/forwardingRules' % (region.name)
-        response = self.connection.request(request, method='GET').object
-
-        if 'items' in response:
-            # The aggregated result returns dictionaries for each region
-            if not global_rules and region is None:
-                for v in response['items'].values():
-                    region_forwarding_rules = [self._to_forwarding_rule(f) for
-                                               f in v.get('forwardingRules',
-                                                          [])]
-                    list_forwarding_rules.extend(region_forwarding_rules)
-            else:
-                list_forwarding_rules = [self._to_forwarding_rule(f) for f in
-                                         response['items']]
-        return list_forwarding_rules
-
-    def list_images(self, ex_project=None, ex_include_deprecated=False):
-        """
-        Return a list of image objects. If no project is specified, a list of
-        all non-deprecated global and vendor images images is returned. By
-        default, only non-deprecated images are returned.
-
-        :keyword  ex_project: Optional alternate project name.
-        :type     ex_project: ``str``, ``list`` of ``str``, or ``None``
-
-        :keyword  ex_include_deprecated: If True, even DEPRECATED images will
-                                         be returned.
-        :type     ex_include_deprecated: ``bool``
-
-        :return:  List of GCENodeImage objects
-        :rtype:   ``list`` of :class:`GCENodeImage`
-        """
-        dep = ex_include_deprecated
-        if ex_project is not None:
-            return self.ex_list_project_images(ex_project=ex_project,
-                                               ex_include_deprecated=dep)
-        image_list = self.ex_list_project_images(ex_project=None,
-                                                 ex_include_deprecated=dep)
-        for img_proj in list(self.IMAGE_PROJECTS.keys()):
-            try:
-                image_list.extend(
-                    self.ex_list_project_images(ex_project=img_proj,
-                                                ex_include_deprecated=dep))
-            except:
-                # do not break if an OS type is invalid
-                pass
-        return image_list
-
-    def ex_list_project_images(self, ex_project=None,
-                               ex_include_deprecated=False):
-        """
-        Return a list of image objects for a project. If no project is
-        specified, only a list of 'global' images is returned.
-
-        :keyword  ex_project: Optional alternate project name.
-        :type     ex_project: ``str``, ``list`` of ``str``, or ``None``
-
-        :keyword  ex_include_deprecated: If True, even DEPRECATED images will
-                                         be returned.
-        :type     ex_include_deprecated: ``bool``
-
-        :return:  List of GCENodeImage objects
-        :rtype:   ``list`` of :class:`GCENodeImage`
-        """
-        list_images = []
-        request = '/global/images'
-        if ex_project is None:
-            response = self.connection.request(request, method='GET').object
-            for img in response.get('items', []):
-                if 'deprecated' not in img:
-                    list_images.append(self._to_node_image(img))
-                else:
-                    if ex_include_deprecated:
-                        list_images.append(self._to_node_image(img))
-        else:
-            list_images = []
-            # Save the connection request_path
-            save_request_path = self.connection.request_path
-            if isinstance(ex_project, str):
-                ex_project = [ex_project]
-            for proj in ex_project:
-                # Override the connection request path
-                new_request_path = save_request_path.replace(self.project,
-                                                             proj)
-                self.connection.request_path = new_request_path
-                try:
-                    response = self.connection.request(request,
-                                                       method='GET').object
-                except:
-                    raise
-                finally:
-                    # Restore the connection request_path
-                    self.connection.request_path = save_request_path
-                for img in response.get('items', []):
-                    if 'deprecated' not in img:
-                        list_images.append(self._to_node_image(img))
-                    else:
-                        if ex_include_deprecated:
-                            list_images.append(self._to_node_image(img))
-        return list_images
-
-    def list_locations(self):
-        """
-        Return a list of locations (zones).
-
-        The :class:`ex_list_zones` method returns more comprehensive results,
-        but this is here for compatibility.
-
-        :return: List of NodeLocation objects
-        :rtype: ``list`` of :class:`NodeLocation`
-        """
-        list_locations = []
-        request = '/zones'
-        response = self.connection.request(request, method='GET').object
-        list_locations = [self._to_node_location(l) for l in response['items']]
-        return list_locations
-
-    def ex_list_routes(self):
-        """
-        Return the list of routes.
-
-        :return: A list of route objects.
-        :rtype: ``list`` of :class:`GCERoute`
-        """
-        list_routes = []
-        request = '/global/routes'
-        response = self.connection.request(request, method='GET').object
-        list_routes = [self._to_route(n) for n in
-                       response.get('items', [])]
-        return list_routes
-
-    def ex_list_networks(self):
-        """
-        Return the list of networks.
-
-        :return: A list of network objects.
-        :rtype: ``list`` of :class:`GCENetwork`
-        """
-        list_networks = []
-        request = '/global/networks'
-        response = self.connection.request(request, method='GET').object
-        list_networks = [self._to_network(n) for n in
-                         response.get('items', [])]
-        return list_networks
-
-    def list_nodes(self, ex_zone=None):
-        """
-        Return a list of nodes in the current zone or all zones.
-
-        :keyword  ex_zone:  Optional zone name or 'all'
-        :type     ex_zone:  ``str`` or :class:`GCEZone` or
-                            :class:`NodeLocation` or ``None``
-
-        :return:  List of Node objects
-        :rtype:   ``list`` of :class:`Node`
-        """
-        list_nodes = []
-        zone = self._set_zone(ex_zone)
-        if zone is None:
-            request = '/aggregated/instances'
-        else:
-            request = '/zones/%s/instances' % (zone.name)
-
-        response = self.connection.request(request, method='GET').object
-
-        if 'items' in response:
-            # The aggregated response returns a dict for each zone
-            if zone is None:
-                for v in response['items'].values():
-                    for i in v.get('instances', []):
-                        try:
-                            list_nodes.append(self._to_node(i))
-                        # If a GCE node has been deleted between
-                        #   - is was listed by `request('.../instances', 'GET')
-                        #   - it is converted by `self._to_node(i)`
-                        # `_to_node()` will raise a ResourceNotFoundError.
-                        #
-                        # Just ignore that node and return the list of the
-                        # other nodes.
-                        except ResourceNotFoundError:
-                            pass
-            else:
-                for i in response['items']:
-                    try:
-                        list_nodes.append(self._to_node(i))
-                    # If a GCE node has been deleted between
-                    #   - is was listed by `request('.../instances', 'GET')
-                    #   - it is converted by `self._to_node(i)`
-                    # `_to_node()` will raise a ResourceNotFoundError.
-                    #
-                    # Just ignore that node and return the list of the
-                    # other nodes.
-                    except ResourceNotFoundError:
-                        pass
-        return list_nodes
-
-    def ex_list_regions(self):
-        """
-        Return the list of regions.
-
-        :return: A list of region objects.
-        :rtype: ``list`` of :class:`GCERegion`
-        """
-        list_regions = []
-        request = '/regions'
-        response = self.connection.request(request, method='GET').object
-        list_regions = [self._to_region(r) for r in response['items']]
-        return list_regions
-
-    def list_sizes(self, location=None):
-        """
-        Return a list of sizes (machineTypes) in a zone.
-
-        :keyword  location: Location or Zone for sizes
-        :type     location: ``str`` or :class:`GCEZone` or
-                            :class:`NodeLocation` or ``None``
-
-        :return:  List of GCENodeSize objects
-        :rtype:   ``list`` of :class:`GCENodeSize`
-        """
-        list_sizes = []
-        zone = self._set_zone(location)
-        if zone is None:
-            request = '/aggregated/machineTypes'
-        else:
-            request = '/zones/%s/machineTypes' % (zone.name)
-
-        response = self.connection.request(request, method='GET').object
-
-        if 'items' in response:
-            # The aggregated response returns a dict for each zone
-            if zone is None:
-                for v in response['items'].values():
-                    zone_sizes = [self._to_node_size(s) for s in
-                                  v.get('machineTypes', [])]
-                    list_sizes.extend(zone_sizes)
-            else:
-                list_sizes = [self._to_node_size(s) for s in response['items']]
-        return list_sizes
-
-    def ex_list_snapshots(self):
-        """
-        Return the list of disk snapshots in the project.
-
-        :return:  A list of snapshot objects
-        :rtype:   ``list`` of :class:`GCESnapshot`
-        """
-        list_snapshots = []
-        request = '/global/snapshots'
-        response = self.connection.request(request, method='GET').object
-        list_snapshots = [self._to_snapshot(s) for s in
-                          response.get('items', [])]
-        return list_snapshots
-
-    def ex_list_targethttpproxies(self):
-        """
-        Return the list of target HTTP proxies.
-
-        :return:  A list of target http proxy objects
-        :rtype:   ``list`` of :class:`GCETargetHttpProxy`
-        """
-        request = '/global/targetHttpProxies'
-        response = self.connection.request(request, method='GET').object
-        return [self._to_targethttpproxy(u) for u in
-                response.get('items', [])]
-
-    def ex_list_targetinstances(self, zone=None):
-        """
-        Return the list of target instances.
-
-        :return:  A list of target instance objects
-        :rtype:   ``list`` of :class:`GCETargetInstance`
-        """
-        list_targetinstances = []
-        zone = self._set_zone(zone)
-        if zone is None:
-            request = '/aggregated/targetInstances'
-        else:
-            request = '/zones/%s/targetInstances' % (zone.name)
-        response = self.connection.request(request, method='GET').object
-
-        if 'items' in response:
-            # The aggregated result returns dictionaries for each region
-            if zone is None:
-                for v in response['items'].values():
-                    zone_targetinstances = [self._to_targetinstance(t) for t in
-                                            v.get('targetInstances', [])]
-                    list_targetinstances.extend(zone_targetinstances)
-            else:
-                list_targetinstances = [self._to_targetinstance(t) for t in
-                                        response['items']]
-        return list_targetinstances
-
-    def ex_list_targetpools(self, region=None):
-        """
-        Return the list of target pools.
-
-        :return:  A list of target pool objects
-        :rtype:   ``list`` of :class:`GCETargetPool`
-        """
-        list_targetpools = []
-        region = self._set_region(region)
-        if region is None:
-            request = '/aggregated/targetPools'
-        else:
-            request = '/regions/%s/targetPools' % (region.name)
-        response = self.connection.request(request, method='GET').object
-
-        if 'items' in response:
-            # The aggregated result returns dictionaries for each region
-            if region is None:
-                for v in response['items'].values():
-                    region_targetpools = [self._to_targetpool(t) for t in
-                                          v.get('targetPools', [])]
-                    list_targetpools.extend(region_targetpools)
-            else:
-                list_targetpools = [self._to_targetpool(t) for t in
-                                    response['items']]
-        return list_targetpools
-
-    def ex_list_urlmaps(self):
-        """
-        Return the list of URL Maps in the project.
-
-        :return:  A list of url map objects
-        :rtype:   ``list`` of :class:`GCEUrlMap`
-        """
-        request = '/global/urlMaps'
-        response = self.connection.request(request, method='GET').object
-        return [self._to_urlmap(u) for u in response.get('items', [])]
-
-    def list_volumes(self, ex_zone=None):
-        """
-        Return a list of volumes for a zone or all.
-
-        Will return list from provided zone, or from the default zone unless
-        given the value of 'all'.
-
-        :keyword  ex_zone: The zone to return volumes from.
-        :type     ex_zone: ``str`` or :class:`GCEZone` or
-                            :class:`NodeLocation` or ``None``
-
-        :return: A list of volume objects.
-        :rtype: ``list`` of :class:`StorageVolume`
-        """
-        list_volumes = []
-        zone = self._set_zone(ex_zone)
-        if zone is None:
-            request = '/aggregated/disks'
-        else:
-            request = '/zones/%s/disks' % (zone.name)
-
-        response = self.connection.request(request, method='GET').object
-        if 'items' in response:
-            # The aggregated response returns a dict for each zone
-            if zone is None:
-                for v in response['items'].values():
-                    zone_volumes = [self._to_storage_volume(d) for d in
-                                    v.get('disks', [])]
-                    list_volumes.extend(zone_volumes)
-            else:
-                list_volumes = [self._to_storage_volume(d) for d in
-                                response['items']]
-        return list_volumes
-
-    def ex_list_zones(self):
-        """
-        Return the list of zones.
-
-        :return: A list of zone objects.
-        :rtype: ``list`` of :class:`GCEZone`
-        """
-        list_zones = []
-        request = '/zones'
-        response = self.connection.request(request, method='GET').object
-        list_zones = [self._to_zone(z) for z in response['items']]
-        return list_zones
-
-    def ex_create_address(self, name, region=None, address=None,
-                          description=None):
-        """
-        Create a static address in a region, or a global address.
-
-        :param  name: Name of static address
-        :type   name: ``str``
-
-        :keyword  region: Name of region for the address (e.g. 'us-central1')
-                          Use 'global' to create a global address.
-        :type     region: ``str`` or :class:`GCERegion`
-
-        :keyword  address: Ephemeral IP address to promote to a static one
-                           (e.g. 'xxx.xxx.xxx.xxx')
-        :type     address: ``str`` or ``None``
-
-        :keyword  description: Optional descriptive comment.
-        :type     description: ``str`` or ``None``
-
-        :return:  Static Address object
-        :rtype:   :class:`GCEAddress`
-        """
-        region = region or self.region
-        if region != 'global' and not hasattr(region, 'name'):
-            region = self.ex_get_region(region)
-        elif region is None:
-            raise ValueError('REGION_NOT_SPECIFIED',
-                             'Region must be provided for an address')
-        address_data = {'name': name}
-        if address:
-            address_data['address'] = address
-        if description:
-            address_data['description'] = description
-        if region == 'global':
-            request = '/global/addresses'
-        else:
-            request = '/regions/%s/addresses' % (region.name)
-        self.connection.async_request(request, method='POST',
-                                      data=address_data)
-        return self.ex_get_address(name, region=region)
-
-    def ex_create_backendservice(self, name, healthchecks):
-        """
-        Create a global backend service.
-
-        :param  name: Name of the backend service
-        :type   name: ``str``
-
-        :keyword  healthchecks: A list of HTTP Health Checks to use for this
-                                service.  There must be at least one.
-        :type     healthchecks: ``list`` of (``str`` or
-                                :class:`GCEHealthCheck`)
-
-        :return:  A Backend Service object
-        :rtype:   :class:`GCEBackendService`
-        """
-        backendservice_data = {'name': name, 'healthChecks': []}
-
-        for hc in healthchecks:
-            if not hasattr(hc, 'extra'):
-                hc = self.ex_get_healthcheck(name=hc)
-            backendservice_data['healthChecks'].append(hc.extra['selfLink'])
-
-        request = '/global/backendServices'
-        self.connection.async_request(request, method='POST',
-                                      data=backendservice_data)
-        return self.ex_get_backendservice(name)
-
-    def ex_create_healthcheck(self, name, host=None, path=None, port=None,
-                              interval=None, timeout=None,
-                              unhealthy_threshold=None,
-                              healthy_threshold=None,
-                              description=None):
-        """
-        Create an Http Health Check.
-
-        :param  name: Name of health check
-        :type   name: ``str``
-
-        :keyword  host: Hostname of health check request.  Defaults to empty
-                        and public IP is used instead.
-        :type     host: ``str``
-
-        :keyword  path: The request path for the check.  Defaults to /.
-        :type     path: ``str``
-
-        :keyword  port: The TCP port number for the check.  Defaults to 80.
-        :type     port: ``int``
-
-        :keyword  interval: How often (in seconds) to check.  Defaults to 5.
-        :type     interval: ``int``
-
-        :keyword  timeout: How long to wait before failing. Defaults to 5.
-        :type     timeout: ``int``
-
-        :keyword  unhealthy_threshold: How many failures before marking
-                                       unhealthy.  Defaults to 2.
-        :type     unhealthy_threshold: ``int``
-
-        :keyword  healthy_threshold: How many successes before marking as
-                                     healthy.  Defaults to 2.
-        :type     healthy_threshold: ``int``
-
-        :keyword  description: The description of the check.  Defaults to None.
-        :type     description: ``str`` or ``None``
-
-        :return:  Health Check object
-        :rtype:   :class:`GCEHealthCheck`
-        """
-        hc_data = {}
-        hc_data['name'] = name
-        if host:
-            hc_data['host'] = host
-        if description:
-            hc_data['description'] = description
-        # As of right now, the 'default' values aren't getting set when called
-        # through the API, so set them explicitly
-        hc_data['requestPath'] = path or '/'
-        hc_data['port'] = port or 80
-        hc_data['checkIntervalSec'] = interval or 5
-        hc_data['timeoutSec'] = timeout or 5
-        hc_data['unhealthyThreshold'] = unhealthy_threshold or 2
-        hc_data['healthyThreshold'] = healthy_threshold or 2
-
-        request = '/global/httpHealthChecks'
-
-        self.connection.async_request(request, method='POST', data=hc_data)
-        return self.ex_get_healthcheck(name)
-
-    def ex_create_firewall(self, name, allowed, network='default',
-                           source_ranges=None, source_tags=None,
-                           target_tags=None):
-        """
-        Create a firewall on a network.
-
-        Firewall rules should be supplied in the "allowed" field.  This is a
-        list of dictionaries formated like so ("ports" is optional)::
-
-            [{"IPProtocol": "<protocol string or number>",
-              "ports": "<port_numbers or ranges>"}]
-
-        For example, to allow tcp on port 8080 and udp on all ports, 'allowed'
-        would be::
-
-            [{"IPProtocol": "tcp",
-              "ports": ["8080"]},
-             {"IPProtocol": "udp"}]
-
-        See `Firewall Reference <https://developers.google.com/compute/docs/
-        reference/latest/firewalls/insert>`_ for more information.
-
-        :param  name: Name of the firewall to be created
-        :type   name: ``str``
-
-        :param  allowed: List of dictionaries with rules
-        :type   allowed: ``list`` of ``dict``
-
-        :keyword  network: The network that the firewall applies to.
-        :type     network: ``str`` or :class:`GCENetwork`
-
-        :keyword  source_ranges: A list of IP ranges in CIDR format that the
-                                 firewall should apply to. Defaults to
-                                 ['0.0.0.0/0']
-        :type     source_ranges: ``list`` of ``str``
-
-        :keyword  source_tags: A list of source instance tags the rules apply
-                               to.
-        :type     source_tags: ``list`` of ``str``
-
-        :keyword  target_tags: A list of target instance tags the rules apply
-                               to.
-        :type     target_tags: ``list`` of ``str``
-
-        :return:  Firewall object
-        :rtype:   :class:`GCEFirewall`
-        """
-        firewall_data = {}
-        if not hasattr(network, 'name'):
-            nw = self.ex_get_network(network)
-        else:
-            nw = network
-
-        firewall_data['name'] = name
-        firewall_data['allowed'] = allowed
-        firewall_data['network'] = nw.extra['selfLink']
-        if source_ranges is None and source_tags is None:
-            source_ranges = ['0.0.0.0/0']
-        if source_ranges is not None:
-            firewall_data['sourceRanges'] = source_ranges
-        if source_tags is not None:
-            firewall_data['sourceTags'] = source_tags
-        if target_tags is not None:
-            firewall_data['targetTags'] = target_tags
-
-        request = '/global/firewalls'
-
-        self.connection.async_request(request, method='POST',
-                                      data=firewall_data)
-        return self.ex_get_firewall(name)
-
-    def ex_create_forwarding_rule(self, name, target=None, region=None,
-                                  protocol='tcp', port_range=None,
-                                  address=None, description=None,
-                                  global_rule=False, targetpool=None):
-        """
-        Create a forwarding rule.
-
-        :param  name: Name of forwarding rule to be created
-        :type   name: ``str``
-
-        :keyword  target: The target of this forwarding rule.  For global
-                          forwarding rules this must be a global
-                          TargetHttpProxy. For regional rules this may be
-                          either a TargetPool or TargetInstance. If passed
-                          a string instead of the object, it will be the name
-                          of a TargetHttpProxy for global rules or a
-                          TargetPool for regional rules.  A TargetInstance
-                          must be passed by object. (required)
-        :type     target: ``str`` or :class:`GCETargetHttpProxy` or
-                          :class:`GCETargetInstance` or :class:`GCETargetPool`
-
-        :keyword  region: Region to create the forwarding rule in.  Defaults to
-                          self.region.  Ignored if global_rule is True.
-        :type     region: ``str`` or :class:`GCERegion`
-
-        :keyword  protocol: Should be 'tcp' or 'udp'
-        :type     protocol: ``str``
-
-        :keyword  port_range: Single port number or range separated by a dash.
-                              Examples: '80', '5000-5999'.  Required for global
-                              forwarding rules, optional for regional rules.
-        :type     port_range: ``str``
-
-        :keyword  address: Optional static address for forwarding rule. Must be
-                           in same region.
-        :type     address: ``str`` or :class:`GCEAddress`
-
-        :keyword  description: The description of the forwarding rule.
-                               Defaults to None.
-        :type     description: ``str`` or ``None``
-
-        :keyword  targetpool: Deprecated parameter for backwards compatibility.
-                              Use target instead.
-        :type     targetpool: ``str`` or :class:`GCETargetPool`
-
-        :return:  Forwarding Rule object
-        :rtype:   :class:`GCEForwardingRule`
-        """
-        forwarding_rule_data = {'name': name}
-        if global_rule:
-            if not hasattr(target, 'name'):
-                target = self.ex_get_targethttpproxy(target)
-        else:
-            region = region or self.region
-            if not hasattr(region, 'name'):
-                region = self.ex_get_region(region)
-            forwarding_rule_data['region'] = region.extra['selfLink']
-
-            if not target:
-                target = targetpool  # Backwards compatibility
-            if not hasattr(target, 'name'):
-                target = self.ex_get_targetpool(target, region)
-
-        forwarding_rule_data['target'] = target.extra['selfLink']
-        forwarding_rule_data['IPProtocol'] = protocol.upper()
-        if address:
-            if not hasattr(address, 'name'):
-                address = self.ex_get_address(
-                    address, 'global' if global_rule else region)
-            forwarding_rule_data['IPAddress'] = address.address
-        if port_range:
-            forwarding_rule_data['portRange'] = port_range
-        if description:
-            forwarding_rule_data['description'] = description
-
-        if global_rule:
-            request = '/global/forwardingRules'
-        else:
-            request = '/regions/%s/forwardingRules' % (region.name)
-
-        self.connection.async_request(request, method='POST',
-                                      data=forwarding_rule_data)
-
-        return self.ex_get_forwarding_rule(name, global_rule=global_rule)
-
-    def ex_create_image(self, name, volume, description=None, family=None,
-                        use_existing=True, wait_for_completion=True):
-        """
-        Create an image from the provided volume.
-
-        :param  name: The name of the image to create.
-        :type   name: ``str``
-
-        :param  volume: The volume to use to create the image, or the
-                        Google Cloud Storage URI
-        :type   volume: ``str`` or :class:`StorageVolume`
-
-        :keyword    description: Description of the new Image
-        :type       description: ``str``
-
-        :keyword    family: The name of the image family to which this image
-                            belongs. If you create resources by specifying an
-                            image family instead of a specific image name, the
-                            resource uses the latest non-deprecated image that
-                            is set with that family name.
-        :type       family: ``str``
-
-        :keyword  use_existing: If True and an image with the given name
-                                already exists, return an object for that
-                                image instead of attempting to create
-                                a new image.
-        :type     use_existing: ``bool``
-
-        :keyword  wait_for_completion: If True, wait until the new image is
-                                       created before returning a new NodeImage
-                                       Otherwise, return a new NodeImage
-                                       instance, and let the user track the
-                                       creation progress
-        :type     wait_for_completion: ``bool``
-
-        :return:    A GCENodeImage object for the new image
-        :rtype:     :class:`GCENodeImage`
-
-        """
-        image_data = {}
-        image_data['name'] = name
-        image_data['description'] = description
-        image_data['family'] = family
-        if isinstance(volume, StorageVolume):
-            image_data['sourceDisk'] = volume.extra['selfLink']
-            image_data['zone'] = volume.extra['zone'].name
-        elif (isinstance(volume, str) and
-              volume.startswith('https://') and
-              volume.endswith('tar.gz')):
-            image_data['rawDisk'] = {'source': volume, 'containerType': 'TAR'}
-        else:
-            raise ValueError('Source must be instance of StorageVolume or URI')
-
-        request = '/global/images'
-
-        try:
-            if wait_for_completion:
-                self.connection.async_request(request, method='POST',
-                                              data=image_data)
-            else:
-                self.connection.request(request, method='POST',
-                                        data=image_data)
-
-        except ResourceExistsError:
-            e = sys.exc_info()[1]
-            if not use_existing:
-                raise e
-
-        return self.ex_get_image(name)
-
-    def ex_create_route(self, name, dest_range, priority=500,
-                        network="default", tags=None, next_hop=None,
-                        description=None):
-        """
-        Create a route.
-
-        :param  name: Name of route to be created
-        :type   name: ``str``
-
-        :param  dest_range: Address range of route in CIDR format.
-        :type   dest_range: ``str``
-
-        :param  priority: Priority value, lower values take precedence
-        :type   priority: ``int``
-
-        :param  network: The network the route belongs to. Can be either the
-                         full URL of the network or a libcloud object.
-        :type   network: ``str`` or ``GCENetwork``
-
-        :param  tags: List of instance-tags for routing, empty for all nodes
-        :type   tags: ``list`` of ``str`` or ``None``
-
-        :param  next_hop: Next traffic hop. Use ``None`` for the default
-                          Internet gateway, or specify an instance or IP
-                          address.
-        :type   next_hop: ``str``, ``Node``, or ``None``
-
-        :param  description: Custom description for the route.
-        :type   description: ``str`` or ``None``
-
-        :return:  Route object
-        :rtype:   :class:`GCERoute`
-        """
-        route_data = {}
-        route_data['name'] = name
-        route_data['destRange'] = dest_range
-        route_data['priority'] = priority
-        route_data['description'] = description
-        if isinstance(network, str) and network.startswith('https://'):
-            network_uri = network
-        elif isinstance(network, str):
-            network = self.ex_get_network(network)
-            network_uri = network.extra['selfLink']
-        else:
-            network_uri = network.extra['selfLink']
-        route_data['network'] = network_uri
-        route_data['tags'] = tags
-        if next_hop is None:
-            url = 'https://www.googleapis.com/compute/%s/projects/%s/%s' % (
-                  API_VERSION, self.project,
-                  "global/gateways/default-internet-gateway")
-            route_data['nextHopGateway'] = url
-        elif isinstance(next_hop, str):
-            route_data['nextHopIp'] = next_hop
-        else:
-            route_data['nextHopInstance'] = next_hop.extra['selfLink']
-
-        request = '/global/routes'
-        self.connection.async_request(request, method='POST',
-                                      data=route_data)
-
-        return self.ex_get_route(name)
-
-    def ex_create_network(self, name, cidr, description=None):
-        """
-        Create a network.
-
-        :param  name: Name of network to be created
-        :type   name: ``str``
-
-        :param  cidr: Address range of network in CIDR format.
-        :type   cidr: ``str``
-
-        :param  description: Custom description for the network.
-        :type   description: ``str`` or ``None``
-
-        :return:  Network object
-        :rtype:   :class:`GCENetwork`
-        """
-        network_data = {}
-        network_data['name'] = name
-        network_data['IPv4Range'] = cidr
-        network_data['description'] = description
-
-        request = '/global/networks'
-
-        self.connection.async_request(request, method='POST',
-                                      data=network_data)
-
-        return self.ex_get_network(name)
-
-    def create_node(self, name, size, image, location=None,
-                    ex_network='default', ex_tags=None, ex_metadata=None,
-                    ex_boot_disk=None, use_existing_disk=True,
-                    external_ip='ephemeral', ex_disk_type='pd-standard',
-                    ex_disk_auto_delete=True, ex_service_accounts=None,
-                    description=None, ex_can_ip_forward=None,
-                    ex_disks_gce_struct=None, ex_nic_gce_struct=None,
-                    ex_on_host_maintenance=None, ex_automatic_restart=None,
-                    ex_preemptible=None):
-        """
-        Create a new node and return a node object for the node.
-
-        :param  name: The name of the node to create.
-        :type   name: ``str``
-
-        :param  size: The machine type to use.
-        :type   size: ``str`` or :class:`GCENodeSize`
-
-        :param  image: The image to use to create the node (or, if attaching
-                       a persistent disk, the image used to create the disk)
-        :type   image: ``str`` or :class:`GCENodeImage` or ``None``
-
-        :keyword  location: The location (zone) to create the node in.
-        :type     location: ``str`` or :class:`NodeLocation` or
-                            :class:`GCEZone` or ``None``
-
-        :keyword  ex_network: The network to associate with the node.
-        

<TRUNCATED>

[35/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/azure.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/azure.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/azure.py
deleted file mode 100644
index 48a0654..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/azure.py
+++ /dev/null
@@ -1,3591 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-Driver for Microsoft Azure Virtual Machines service.
-
-http://azure.microsoft.com/en-us/services/virtual-machines/
-"""
-
-import re
-import time
-import collections
-import random
-import sys
-import copy
-import base64
-
-from datetime import datetime
-from xml.dom import minidom
-from xml.sax.saxutils import escape as xml_escape
-
-try:
-    from lxml import etree as ET
-except ImportError:
-    from xml.etree import ElementTree as ET
-
-from libcloud.common.azure import AzureServiceManagementConnection
-from libcloud.common.azure import AzureRedirectException
-from libcloud.compute.providers import Provider
-from libcloud.compute.base import Node, NodeDriver, NodeLocation, NodeSize
-from libcloud.compute.base import NodeImage, StorageVolume
-from libcloud.compute.types import NodeState
-from libcloud.common.types import LibcloudError
-from libcloud.utils.py3 import _real_unicode
-from libcloud.utils.py3 import httplib
-from libcloud.utils.py3 import urlparse
-from libcloud.utils.py3 import ensure_string
-from libcloud.utils.py3 import urlquote as url_quote
-from libcloud.utils.misc import ReprMixin
-
-HTTPSConnection = httplib.HTTPSConnection
-
-if sys.version_info < (3,):
-    _unicode_type = unicode
-
-    def _str(value):
-        if isinstance(value, unicode):
-            return value.encode('utf-8')
-
-        return str(value)
-else:
-    _str = str
-    _unicode_type = str
-
-
-AZURE_SERVICE_MANAGEMENT_HOST = 'management.core.windows.net'
-X_MS_VERSION = '2013-08-01'
-
-WINDOWS_SERVER_REGEX = re.compile(
-    r'Win|SQL|SharePoint|Visual|Dynamics|DynGP|BizTalk'
-)
-
-"""
-Sizes must be hardcoded because Microsoft doesn't provide an API to fetch them
-From http://msdn.microsoft.com/en-us/library/windowsazure/dn197896.aspx
-
-Prices are for Linux instances in East US data center. To see what pricing will
-actually be, visit:
-http://azure.microsoft.com/en-gb/pricing/details/virtual-machines/
-"""
-AZURE_COMPUTE_INSTANCE_TYPES = {
-    'A0': {
-        'id': 'ExtraSmall',
-        'name': 'Extra Small Instance',
-        'ram': 768,
-        'disk': 127,
-        'bandwidth': None,
-        'price': '0.0211',
-        'max_data_disks': 1,
-        'cores': 'Shared'
-    },
-    'A1': {
-        'id': 'Small',
-        'name': 'Small Instance',
-        'ram': 1792,
-        'disk': 127,
-        'bandwidth': None,
-        'price': '0.0633',
-        'max_data_disks': 2,
-        'cores': 1
-    },
-    'A2': {
-        'id': 'Medium',
-        'name': 'Medium Instance',
-        'ram': 3584,
-        'disk': 127,
-        'bandwidth': None,
-        'price': '0.1266',
-        'max_data_disks': 4,
-        'cores': 2
-    },
-    'A3': {
-        'id': 'Large',
-        'name': 'Large Instance',
-        'ram': 7168,
-        'disk': 127,
-        'bandwidth': None,
-        'price': '0.2531',
-        'max_data_disks': 8,
-        'cores': 4
-    },
-    'A4': {
-        'id': 'ExtraLarge',
-        'name': 'Extra Large Instance',
-        'ram': 14336,
-        'disk': 127,
-        'bandwidth': None,
-        'price': '0.5062',
-        'max_data_disks': 16,
-        'cores': 8
-    },
-    'A5': {
-        'id': 'A5',
-        'name': 'Memory Intensive Instance',
-        'ram': 14336,
-        'disk': 127,
-        'bandwidth': None,
-        'price': '0.2637',
-        'max_data_disks': 4,
-        'cores': 2
-    },
-    'A6': {
-        'id': 'A6',
-        'name': 'A6 Instance',
-        'ram': 28672,
-        'disk': 127,
-        'bandwidth': None,
-        'price': '0.5273',
-        'max_data_disks': 8,
-        'cores': 4
-    },
-    'A7': {
-        'id': 'A7',
-        'name': 'A7 Instance',
-        'ram': 57344,
-        'disk': 127,
-        'bandwidth': None,
-        'price': '1.0545',
-        'max_data_disks': 16,
-        'cores': 8
-    },
-    'A8': {
-        'id': 'A8',
-        'name': 'A8 Instance',
-        'ram': 57344,
-        'disk': 127,
-        'bandwidth': None,
-        'price': '2.0774',
-        'max_data_disks': 16,
-        'cores': 8
-    },
-    'A9': {
-        'id': 'A9',
-        'name': 'A9 Instance',
-        'ram': 114688,
-        'disk': 127,
-        'bandwidth': None,
-        'price': '4.7137',
-        'max_data_disks': 16,
-        'cores': 16
-    },
-    'A10': {
-        'id': 'A10',
-        'name': 'A10 Instance',
-        'ram': 57344,
-        'disk': 127,
-        'bandwidth': None,
-        'price': '1.2233',
-        'max_data_disks': 16,
-        'cores': 8
-    },
-    'A11': {
-        'id': 'A11',
-        'name': 'A11 Instance',
-        'ram': 114688,
-        'disk': 127,
-        'bandwidth': None,
-        'price': '2.1934',
-        'max_data_disks': 16,
-        'cores': 16
-    },
-    'D1': {
-        'id': 'Standard_D1',
-        'name': 'D1 Faster Compute Instance',
-        'ram': 3584,
-        'disk': 127,
-        'bandwidth': None,
-        'price': '0.0992',
-        'max_data_disks': 2,
-        'cores': 1
-    },
-    'D2': {
-        'id': 'Standard_D2',
-        'name': 'D2 Faster Compute Instance',
-        'ram': 7168,
-        'disk': 127,
-        'bandwidth': None,
-        'price': '0.1983',
-        'max_data_disks': 4,
-        'cores': 2
-    },
-    'D3': {
-        'id': 'Standard_D3',
-        'name': 'D3 Faster Compute Instance',
-        'ram': 14336,
-        'disk': 127,
-        'bandwidth': None,
-        'price': '0.3965',
-        'max_data_disks': 8,
-        'cores': 4
-    },
-    'D4': {
-        'id': 'Standard_D4',
-        'name': 'D4 Faster Compute Instance',
-        'ram': 28672,
-        'disk': 127,
-        'bandwidth': None,
-        'price': '0.793',
-        'max_data_disks': 16,
-        'cores': 8
-    },
-    'D11': {
-        'id': 'Standard_D11',
-        'name': 'D11 Faster Compute Instance',
-        'ram': 14336,
-        'disk': 127,
-        'bandwidth': None,
-        'price': '0.251',
-        'max_data_disks': 4,
-        'cores': 2
-    },
-    'D12': {
-        'id': 'Standard_D12',
-        'name': 'D12 Faster Compute Instance',
-        'ram': 28672,
-        'disk': 127,
-        'bandwidth': None,
-        'price': '0.502',
-        'max_data_disks': 8,
-        'cores': 4
-    },
-    'D13': {
-        'id': 'Standard_D13',
-        'name': 'D13 Faster Compute Instance',
-        'ram': 57344,
-        'disk': 127,
-        'bandwidth': None,
-        'price': '0.9038',
-        'max_data_disks': 16,
-        'cores': 8
-    },
-    'D14': {
-        'id': 'Standard_D14',
-        'name': 'D14 Faster Compute Instance',
-        'ram': 114688,
-        'disk': 127,
-        'bandwidth': None,
-        'price': '1.6261',
-        'max_data_disks': 32,
-        'cores': 16
-    }
-}
-
-_KNOWN_SERIALIZATION_XFORMS = {
-    'include_apis': 'IncludeAPIs',
-    'message_id': 'MessageId',
-    'content_md5': 'Content-MD5',
-    'last_modified': 'Last-Modified',
-    'cache_control': 'Cache-Control',
-    'account_admin_live_email_id': 'AccountAdminLiveEmailId',
-    'service_admin_live_email_id': 'ServiceAdminLiveEmailId',
-    'subscription_id': 'SubscriptionID',
-    'fqdn': 'FQDN',
-    'private_id': 'PrivateID',
-    'os_virtual_hard_disk': 'OSVirtualHardDisk',
-    'logical_disk_size_in_gb': 'LogicalDiskSizeInGB',
-    'logical_size_in_gb': 'LogicalSizeInGB',
-    'os': 'OS',
-    'persistent_vm_downtime_info': 'PersistentVMDowntimeInfo',
-    'copy_id': 'CopyId',
-    'os_disk_configuration': 'OSDiskConfiguration',
-    'is_dns_programmed': 'IsDnsProgrammed'
-}
-
-
-class AzureNodeDriver(NodeDriver):
-    connectionCls = AzureServiceManagementConnection
-    name = 'Azure Virtual machines'
-    website = 'http://azure.microsoft.com/en-us/services/virtual-machines/'
-    type = Provider.AZURE
-
-    _instance_types = AZURE_COMPUTE_INSTANCE_TYPES
-    _blob_url = ".blob.core.windows.net"
-    features = {'create_node': ['password']}
-    service_location = collections.namedtuple(
-        'service_location',
-        ['is_affinity_group', 'service_location']
-    )
-
-    NODE_STATE_MAP = {
-        'RoleStateUnknown': NodeState.UNKNOWN,
-        'CreatingVM': NodeState.PENDING,
-        'StartingVM': NodeState.PENDING,
-        'Provisioning': NodeState.PENDING,
-        'CreatingRole': NodeState.PENDING,
-        'StartingRole': NodeState.PENDING,
-        'ReadyRole': NodeState.RUNNING,
-        'BusyRole': NodeState.PENDING,
-        'StoppingRole': NodeState.PENDING,
-        'StoppingVM': NodeState.PENDING,
-        'DeletingVM': NodeState.PENDING,
-        'StoppedVM': NodeState.STOPPED,
-        'RestartingRole': NodeState.REBOOTING,
-        'CyclingRole': NodeState.TERMINATED,
-        'FailedStartingRole': NodeState.TERMINATED,
-        'FailedStartingVM': NodeState.TERMINATED,
-        'UnresponsiveRole': NodeState.TERMINATED,
-        'StoppedDeallocated': NodeState.TERMINATED,
-    }
-
-    def __init__(self, subscription_id=None, key_file=None, **kwargs):
-        """
-        subscription_id contains the Azure subscription id in the form of GUID
-        key_file contains the Azure X509 certificate in .pem form
-        """
-        self.subscription_id = subscription_id
-        self.key_file = key_file
-        self.follow_redirects = kwargs.get('follow_redirects', True)
-        super(AzureNodeDriver, self).__init__(
-            self.subscription_id,
-            self.key_file,
-            secure=True,
-            **kwargs
-        )
-
-    def list_sizes(self):
-        """
-        Lists all sizes
-
-        :rtype: ``list`` of :class:`NodeSize`
-        """
-        sizes = []
-
-        for _, values in self._instance_types.items():
-            node_size = self._to_node_size(copy.deepcopy(values))
-            sizes.append(node_size)
-
-        return sizes
-
-    def list_images(self, location=None):
-        """
-        Lists all images
-
-        :rtype: ``list`` of :class:`NodeImage`
-        """
-        data = self._perform_get(self._get_image_path(), Images)
-
-        custom_image_data = self._perform_get(
-            self._get_vmimage_path(),
-            VMImages
-        )
-
-        images = [self._to_image(i) for i in data]
-        images.extend(self._vm_to_image(j) for j in custom_image_data)
-
-        if location is not None:
-            images = [
-                image
-                for image in images
-                if location in image.extra["location"]
-            ]
-
-        return images
-
-    def list_locations(self):
-        """
-        Lists all locations
-
-        :rtype: ``list`` of :class:`NodeLocation`
-        """
-        data = self._perform_get(
-            '/' + self.subscription_id + '/locations',
-            Locations
-        )
-
-        return [self._to_location(l) for l in data]
-
-    def list_nodes(self, ex_cloud_service_name):
-        """
-        List all nodes
-
-        ex_cloud_service_name parameter is used to scope the request
-        to a specific Cloud Service. This is a required parameter as
-        nodes cannot exist outside of a Cloud Service nor be shared
-        between a Cloud Service within Azure.
-
-        :param      ex_cloud_service_name: Cloud Service name
-        :type       ex_cloud_service_name: ``str``
-
-        :rtype: ``list`` of :class:`Node`
-        """
-        response = self._perform_get(
-            self._get_hosted_service_path(ex_cloud_service_name) +
-            '?embed-detail=True',
-            None
-        )
-        self.raise_for_response(response, 200)
-
-        data = self._parse_response(response, HostedService)
-
-        vips = None
-
-        if (len(data.deployments) > 0 and
-                data.deployments[0].virtual_ips is not None):
-            vips = [vip.address for vip in data.deployments[0].virtual_ips]
-
-        try:
-            return [
-                self._to_node(n, ex_cloud_service_name, vips)
-                for n in data.deployments[0].role_instance_list
-            ]
-        except IndexError:
-            return []
-
-    def reboot_node(self, node, ex_cloud_service_name=None,
-                    ex_deployment_slot=None):
-        """
-        Reboots a node.
-
-        ex_cloud_service_name parameter is used to scope the request
-        to a specific Cloud Service. This is a required parameter as
-        nodes cannot exist outside of a Cloud Service nor be shared
-        between a Cloud Service within Azure.
-
-        :param      ex_cloud_service_name: Cloud Service name
-        :type       ex_cloud_service_name: ``str``
-
-        :param      ex_deployment_slot: Options are "production" (default)
-                                         or "Staging". (Optional)
-        :type       ex_deployment_slot: ``str``
-
-        :rtype: ``bool``
-        """
-        if ex_cloud_service_name is None:
-            if node.extra is not None:
-                ex_cloud_service_name = node.extra.get(
-                    'ex_cloud_service_name'
-                )
-
-        if not ex_cloud_service_name:
-            raise ValueError("ex_cloud_service_name is required.")
-
-        if not ex_deployment_slot:
-            ex_deployment_slot = "Production"
-
-        _deployment_name = self._get_deployment(
-            service_name=ex_cloud_service_name,
-            deployment_slot=ex_deployment_slot
-        ).name
-
-        try:
-            response = self._perform_post(
-                self._get_deployment_path_using_name(
-                    ex_cloud_service_name,
-                    _deployment_name
-                ) + '/roleinstances/' + _str(node.id) + '?comp=reboot',
-                ''
-            )
-
-            self.raise_for_response(response, 202)
-
-            if self._parse_response_for_async_op(response):
-                return True
-            else:
-                return False
-        except Exception:
-            return False
-
-    def list_volumes(self, node=None):
-        """
-        Lists volumes of the disks in the image repository that are
-        associated with the specified subscription.
-
-        Pass Node object to scope the list of volumes to a single
-        instance.
-
-        :rtype: ``list`` of :class:`StorageVolume`
-        """
-
-        data = self._perform_get(self._get_disk_path(), Disks)
-        volumes = [self._to_volume(volume=v, node=node) for v in data]
-        return volumes
-
-    def create_node(self, name, size, image, ex_cloud_service_name,
-                    ex_storage_service_name=None, ex_new_deployment=False,
-                    ex_deployment_slot="Production", ex_deployment_name=None,
-                    ex_admin_user_id="azureuser", ex_custom_data=None,
-                    ex_virtual_network_name=None, ex_network_config=None,
-                    auth=None, **kwargs):
-        """
-        Create Azure Virtual Machine
-
-        Reference: http://bit.ly/1fIsCb7
-        [www.windowsazure.com/en-us/documentation/]
-
-        We default to:
-
-        + 3389/TCP - RDP - 1st Microsoft instance.
-        + RANDOM/TCP - RDP - All succeeding Microsoft instances.
-
-        + 22/TCP - SSH - 1st Linux instance
-        + RANDOM/TCP - SSH - All succeeding Linux instances.
-
-        The above replicates the standard behavior of the Azure UI.
-        You can retrieve the assigned ports to each instance by
-        using the following private function:
-
-        _get_endpoint_ports(service_name)
-        Returns public,private port key pair.
-
-        @inherits: :class:`NodeDriver.create_node`
-
-        :keyword     image: The image to use when creating this node
-        :type        image:  `NodeImage`
-
-        :keyword     size: The size of the instance to create
-        :type        size: `NodeSize`
-
-        :keyword     ex_cloud_service_name: Required.
-                     Name of the Azure Cloud Service.
-        :type        ex_cloud_service_name:  ``str``
-
-        :keyword     ex_storage_service_name: Optional:
-                     Name of the Azure Storage Service.
-        :type        ex_storage_service_name:  ``str``
-
-        :keyword     ex_new_deployment: Optional. Tells azure to create a
-                                        new deployment rather than add to an
-                                        existing one.
-        :type        ex_new_deployment: ``boolean``
-
-        :keyword     ex_deployment_slot: Optional: Valid values: production|
-                                         staging.
-                                         Defaults to production.
-        :type        ex_deployment_slot:  ``str``
-
-        :keyword     ex_deployment_name: Optional. The name of the
-                                         deployment.
-                                         If this is not passed in we default
-                                         to using the Cloud Service name.
-        :type        ex_deployment_name: ``str``
-
-        :type        ex_custom_data: ``str``
-        :keyword     ex_custom_data: Optional script or other data which is
-                                     injected into the VM when it's beginning
-                                     provisioned.
-
-        :keyword     ex_admin_user_id: Optional. Defaults to 'azureuser'.
-        :type        ex_admin_user_id:  ``str``
-
-        :keyword     ex_virtual_network_name: Optional. If this is not passed
-                                              in no virtual network is used.
-        :type        ex_virtual_network_name:  ``str``
-
-        :keyword     ex_network_config: Optional. The ConfigurationSet to use
-                                        for network configuration
-        :type        ex_network_config:  `ConfigurationSet`
-
-        """
-        # TODO: Refactor this method to make it more readable, split it into
-        # multiple smaller methods
-        auth = self._get_and_check_auth(auth)
-        password = auth.password
-
-        if not isinstance(size, NodeSize):
-            raise ValueError('Size must be an instance of NodeSize')
-
-        if not isinstance(image, NodeImage):
-            raise ValueError(
-                "Image must be an instance of NodeImage, "
-                "produced by list_images()"
-            )
-
-        # Retrieve a list of currently available nodes for the provided cloud
-        # service
-        node_list = self.list_nodes(
-            ex_cloud_service_name=ex_cloud_service_name
-        )
-
-        if ex_network_config is None:
-            network_config = ConfigurationSet()
-        else:
-            network_config = ex_network_config
-        network_config.configuration_set_type = 'NetworkConfiguration'
-
-        # Base64 encode custom data if provided
-        if ex_custom_data:
-            ex_custom_data = self._encode_base64(data=ex_custom_data)
-
-        # We do this because we need to pass a Configuration to the
-        # method. This will be either Linux or Windows.
-        if WINDOWS_SERVER_REGEX.search(image.id, re.I):
-            machine_config = WindowsConfigurationSet(
-                computer_name=name,
-                admin_password=password,
-                admin_user_name=ex_admin_user_id
-            )
-
-            machine_config.domain_join = None
-
-            if not node_list or ex_new_deployment:
-                port = "3389"
-            else:
-                port = random.randint(41952, 65535)
-                endpoints = self._get_deployment(
-                    service_name=ex_cloud_service_name,
-                    deployment_slot=ex_deployment_slot
-                )
-
-                for instances in endpoints.role_instance_list:
-                    ports = [ep.public_port for ep in
-                             instances.instance_endpoints]
-
-                    while port in ports:
-                        port = random.randint(41952, 65535)
-
-            endpoint = ConfigurationSetInputEndpoint(
-                name='Remote Desktop',
-                protocol='tcp',
-                port=port,
-                local_port='3389',
-                load_balanced_endpoint_set_name=None,
-                enable_direct_server_return=False
-            )
-        else:
-            if not node_list or ex_new_deployment:
-                port = "22"
-            else:
-                port = random.randint(41952, 65535)
-                endpoints = self._get_deployment(
-                    service_name=ex_cloud_service_name,
-                    deployment_slot=ex_deployment_slot
-                )
-
-                for instances in endpoints.role_instance_list:
-                    ports = []
-                    if instances.instance_endpoints is not None:
-                        for ep in instances.instance_endpoints:
-                            ports += [ep.public_port]
-
-                    while port in ports:
-                        port = random.randint(41952, 65535)
-
-            endpoint = ConfigurationSetInputEndpoint(
-                name='SSH',
-                protocol='tcp',
-                port=port,
-                local_port='22',
-                load_balanced_endpoint_set_name=None,
-                enable_direct_server_return=False
-            )
-            machine_config = LinuxConfigurationSet(
-                name,
-                ex_admin_user_id,
-                password,
-                False,
-                ex_custom_data
-            )
-
-        network_config.input_endpoints.items.append(endpoint)
-
-        _storage_location = self._get_cloud_service_location(
-            service_name=ex_cloud_service_name
-        )
-
-        if ex_storage_service_name is None:
-            ex_storage_service_name = ex_cloud_service_name
-            ex_storage_service_name = re.sub(
-                r'[\W_-]+',
-                '',
-                ex_storage_service_name.lower(),
-                flags=re.UNICODE
-            )
-
-            if self._is_storage_service_unique(
-                    service_name=ex_storage_service_name):
-
-                self._create_storage_account(
-                    service_name=ex_storage_service_name,
-                    location=_storage_location.service_location,
-                    is_affinity_group=_storage_location.is_affinity_group
-                )
-
-        # OK, bit annoying here. You must create a deployment before
-        # you can create an instance; however, the deployment function
-        # creates the first instance, but all subsequent instances
-        # must be created using the add_role function.
-        #
-        # So, yeah, annoying.
-        if not node_list or ex_new_deployment:
-            # This is the first node in this cloud service.
-
-            if not ex_deployment_name:
-                ex_deployment_name = ex_cloud_service_name
-
-            vm_image_id = None
-            disk_config = None
-
-            if image.extra.get('vm_image', False):
-                vm_image_id = image.id
-                #  network_config = None
-            else:
-                blob_url = "http://%s.blob.core.windows.net" % (
-                    ex_storage_service_name)
-
-                # Azure's pattern in the UI.
-                disk_name = "%s-%s-%s.vhd" % (
-                    ex_cloud_service_name,
-                    name,
-                    time.strftime("%Y-%m-%d")
-                )
-
-                media_link = "%s/vhds/%s" % (blob_url, disk_name)
-
-                disk_config = OSVirtualHardDisk(image.id, media_link)
-
-            response = self._perform_post(
-                self._get_deployment_path_using_name(ex_cloud_service_name),
-                AzureXmlSerializer.virtual_machine_deployment_to_xml(
-                    ex_deployment_name,
-                    ex_deployment_slot,
-                    name,
-                    name,
-                    machine_config,
-                    disk_config,
-                    'PersistentVMRole',
-                    network_config,
-                    None,
-                    None,
-                    size.id,
-                    ex_virtual_network_name,
-                    vm_image_id
-                )
-            )
-            self.raise_for_response(response, 202)
-            self._ex_complete_async_azure_operation(response)
-        else:
-            _deployment_name = self._get_deployment(
-                service_name=ex_cloud_service_name,
-                deployment_slot=ex_deployment_slot
-            ).name
-
-            vm_image_id = None
-            disk_config = None
-
-            if image.extra.get('vm_image', False):
-                vm_image_id = image.id
-                #  network_config = None
-            else:
-                blob_url = "http://%s.blob.core.windows.net" % (
-                    ex_storage_service_name
-                )
-                disk_name = "%s-%s-%s.vhd" % (
-                    ex_cloud_service_name,
-                    name,
-                    time.strftime("%Y-%m-%d")
-                )
-                media_link = "%s/vhds/%s" % (blob_url, disk_name)
-                disk_config = OSVirtualHardDisk(image.id, media_link)
-
-            path = self._get_role_path(ex_cloud_service_name, _deployment_name)
-            body = AzureXmlSerializer.add_role_to_xml(
-                name,  # role_name
-                machine_config,  # system_config
-                disk_config,  # os_virtual_hard_disk
-                'PersistentVMRole',  # role_type
-                network_config,  # network_config
-                None,  # availability_set_name
-                None,  # data_virtual_hard_disks
-                vm_image_id,  # vm_image
-                size.id  # role_size
-            )
-
-            response = self._perform_post(path, body)
-            self.raise_for_response(response, 202)
-            self._ex_complete_async_azure_operation(response)
-
-        return Node(
-            id=name,
-            name=name,
-            state=NodeState.PENDING,
-            public_ips=[],
-            private_ips=[],
-            driver=self.connection.driver,
-            extra={
-                'ex_cloud_service_name': ex_cloud_service_name
-            }
-        )
-
-    def destroy_node(self, node, ex_cloud_service_name=None,
-                     ex_deployment_slot="Production"):
-        """
-        Remove Azure Virtual Machine
-
-        This removes the instance, but does not
-        remove the disk. You will need to use destroy_volume.
-        Azure sometimes has an issue where it will hold onto
-        a blob lease for an extended amount of time.
-
-        :keyword     ex_cloud_service_name: Required.
-                     Name of the Azure Cloud Service.
-        :type        ex_cloud_service_name:  ``str``
-
-        :keyword     ex_deployment_slot: Optional: The name of the deployment
-                                         slot. If this is not passed in we
-                                         default to production.
-        :type        ex_deployment_slot:  ``str``
-        """
-
-        if not isinstance(node, Node):
-            raise ValueError("A libcloud Node object is required.")
-
-        if ex_cloud_service_name is None and node.extra is not None:
-            ex_cloud_service_name = node.extra.get('ex_cloud_service_name')
-
-        if not ex_cloud_service_name:
-            raise ValueError("Unable to get ex_cloud_service_name from Node.")
-
-        _deployment = self._get_deployment(
-            service_name=ex_cloud_service_name,
-            deployment_slot=ex_deployment_slot
-        )
-
-        _deployment_name = _deployment.name
-
-        _server_deployment_count = len(_deployment.role_instance_list)
-
-        if _server_deployment_count > 1:
-            path = self._get_role_path(
-                ex_cloud_service_name,
-                _deployment_name,
-                node.id
-            )
-        else:
-            path = self._get_deployment_path_using_name(
-                ex_cloud_service_name,
-                _deployment_name
-            )
-
-        path += '?comp=media'
-
-        self._perform_delete(path)
-
-        return True
-
-    def ex_list_cloud_services(self):
-        return self._perform_get(
-            self._get_hosted_service_path(),
-            HostedServices
-        )
-
-    def ex_create_cloud_service(self, name, location, description=None,
-                                extended_properties=None):
-        """
-        Create an azure cloud service.
-
-        :param      name: Name of the service to create
-        :type       name: ``str``
-
-        :param      location: Standard azure location string
-        :type       location: ``str``
-
-        :param      description: Optional description
-        :type       description: ``str``
-
-        :param      extended_properties: Optional extended_properties
-        :type       extended_properties: ``dict``
-
-        :rtype: ``bool``
-        """
-
-        response = self._perform_cloud_service_create(
-            self._get_hosted_service_path(),
-            AzureXmlSerializer.create_hosted_service_to_xml(
-                name,
-                self._encode_base64(name),
-                description,
-                location,
-                None,
-                extended_properties
-            )
-        )
-
-        self.raise_for_response(response, 201)
-
-        return True
-
-    def ex_destroy_cloud_service(self, name):
-        """
-        Delete an azure cloud service.
-
-        :param      name: Name of the cloud service to destroy.
-        :type       name: ``str``
-
-        :rtype: ``bool``
-        """
-        response = self._perform_cloud_service_delete(
-            self._get_hosted_service_path(name)
-        )
-
-        self.raise_for_response(response, 200)
-
-        return True
-
-    def ex_add_instance_endpoints(self, node, endpoints,
-                                  ex_deployment_slot="Production"):
-        all_endpoints = [
-            {
-                "name": endpoint.name,
-                "protocol": endpoint.protocol,
-                "port": endpoint.public_port,
-                "local_port": endpoint.local_port,
-
-            }
-            for endpoint in node.extra['instance_endpoints']
-        ]
-
-        all_endpoints.extend(endpoints)
-        result = self.ex_set_instance_endpoints(node, all_endpoints,
-                                                ex_deployment_slot)
-        return result
-
-    def ex_set_instance_endpoints(self, node, endpoints,
-                                  ex_deployment_slot="Production"):
-
-        """
-        For example::
-
-            endpoint = ConfigurationSetInputEndpoint(
-                name='SSH',
-                protocol='tcp',
-                port=port,
-                local_port='22',
-                load_balanced_endpoint_set_name=None,
-                enable_direct_server_return=False
-            )
-            {
-                'name': 'SSH',
-                'protocol': 'tcp',
-                'port': port,
-                'local_port': '22'
-            }
-        """
-        ex_cloud_service_name = node.extra['ex_cloud_service_name']
-        vm_role_name = node.name
-
-        network_config = ConfigurationSet()
-        network_config.configuration_set_type = 'NetworkConfiguration'
-
-        for endpoint in endpoints:
-            new_endpoint = ConfigurationSetInputEndpoint(**endpoint)
-            network_config.input_endpoints.items.append(new_endpoint)
-
-        _deployment_name = self._get_deployment(
-            service_name=ex_cloud_service_name,
-            deployment_slot=ex_deployment_slot
-        ).name
-
-        response = self._perform_put(
-            self._get_role_path(
-                ex_cloud_service_name,
-                _deployment_name,
-                vm_role_name
-            ),
-            AzureXmlSerializer.add_role_to_xml(
-                None,  # role_name
-                None,  # system_config
-                None,  # os_virtual_hard_disk
-                'PersistentVMRole',  # role_type
-                network_config,  # network_config
-                None,  # availability_set_name
-                None,  # data_virtual_hard_disks
-                None,  # vm_image
-                None  # role_size
-            )
-        )
-
-        self.raise_for_response(response, 202)
-
-    def ex_create_storage_service(self, name, location,
-                                  description=None, affinity_group=None,
-                                  extended_properties=None):
-        """
-        Create an azure storage service.
-
-        :param      name: Name of the service to create
-        :type       name: ``str``
-
-        :param      location: Standard azure location string
-        :type       location: ``str``
-
-        :param      description: (Optional) Description of storage service.
-        :type       description: ``str``
-
-        :param      affinity_group: (Optional) Azure affinity group.
-        :type       affinity_group: ``str``
-
-        :param      extended_properties: (Optional) Additional configuration
-                                         options support by Azure.
-        :type       extended_properties: ``dict``
-
-        :rtype: ``bool``
-        """
-
-        response = self._perform_storage_service_create(
-            self._get_storage_service_path(),
-            AzureXmlSerializer.create_storage_service_to_xml(
-                service_name=name,
-                label=self._encode_base64(name),
-                description=description,
-                location=location,
-                affinity_group=affinity_group,
-                extended_properties=extended_properties
-            )
-        )
-
-        self.raise_for_response(response, 202)
-
-        return True
-
-    def ex_destroy_storage_service(self, name):
-        """
-        Destroy storage service. Storage service must not have any active
-        blobs. Sometimes Azure likes to hold onto volumes after they are
-        deleted for an inordinate amount of time, so sleep before calling
-        this method after volume deletion.
-
-        :param name: Name of storage service.
-        :type  name: ``str``
-
-        :rtype: ``bool``
-        """
-
-        response = self._perform_storage_service_delete(
-            self._get_storage_service_path(name)
-        )
-        self.raise_for_response(response, 200)
-
-        return True
-
-    """
-    Functions not implemented
-    """
-
-    def create_volume_snapshot(self):
-        raise NotImplementedError(
-            'You cannot create snapshots of '
-            'Azure VMs at this time.'
-        )
-
-    def attach_volume(self):
-        raise NotImplementedError(
-            'attach_volume is not supported '
-            'at this time.'
-        )
-
-    def create_volume(self):
-        raise NotImplementedError(
-            'create_volume is not supported '
-            'at this time.'
-        )
-
-    def detach_volume(self):
-        raise NotImplementedError(
-            'detach_volume is not supported '
-            'at this time.'
-        )
-
-    def destroy_volume(self):
-        raise NotImplementedError(
-            'destroy_volume is not supported '
-            'at this time.'
-        )
-
-    """
-    Private Functions
-    """
-
-    def _perform_cloud_service_create(self, path, data):
-        request = AzureHTTPRequest()
-        request.method = 'POST'
-        request.host = AZURE_SERVICE_MANAGEMENT_HOST
-        request.path = path
-        request.body = data
-        request.path, request.query = self._update_request_uri_query(request)
-        request.headers = self._update_management_header(request)
-        response = self._perform_request(request)
-
-        return response
-
-    def _perform_cloud_service_delete(self, path):
-        request = AzureHTTPRequest()
-        request.method = 'DELETE'
-        request.host = AZURE_SERVICE_MANAGEMENT_HOST
-        request.path = path
-        request.path, request.query = self._update_request_uri_query(request)
-        request.headers = self._update_management_header(request)
-        response = self._perform_request(request)
-
-        return response
-
-    def _perform_storage_service_create(self, path, data):
-        request = AzureHTTPRequest()
-        request.method = 'POST'
-        request.host = AZURE_SERVICE_MANAGEMENT_HOST
-        request.path = path
-        request.body = data
-        request.path, request.query = self._update_request_uri_query(request)
-        request.headers = self._update_management_header(request)
-        response = self._perform_request(request)
-
-        return response
-
-    def _perform_storage_service_delete(self, path):
-        request = AzureHTTPRequest()
-        request.method = 'DELETE'
-        request.host = AZURE_SERVICE_MANAGEMENT_HOST
-        request.path = path
-        request.path, request.query = self._update_request_uri_query(request)
-        request.headers = self._update_management_header(request)
-        response = self._perform_request(request)
-
-        return response
-
-    def _to_node(self, data, ex_cloud_service_name=None, virtual_ips=None):
-        """
-        Convert the data from a Azure response object into a Node
-        """
-
-        remote_desktop_port = ''
-        ssh_port = ''
-        public_ips = virtual_ips or []
-
-        if data.instance_endpoints is not None:
-            if len(data.instance_endpoints) >= 1:
-                public_ips = [data.instance_endpoints[0].vip]
-
-            for port in data.instance_endpoints:
-                if port.name == 'Remote Desktop':
-                    remote_desktop_port = port.public_port
-
-                if port.name == "SSH":
-                    ssh_port = port.public_port
-
-        return Node(
-            id=data.role_name,
-            name=data.role_name,
-            state=self.NODE_STATE_MAP.get(
-                data.instance_status,
-                NodeState.UNKNOWN
-            ),
-            public_ips=public_ips,
-            private_ips=[data.ip_address],
-            driver=self.connection.driver,
-            extra={
-                'instance_endpoints': data.instance_endpoints,
-                'remote_desktop_port': remote_desktop_port,
-                'ssh_port': ssh_port,
-                'power_state': data.power_state,
-                'instance_size': data.instance_size,
-                'ex_cloud_service_name': ex_cloud_service_name
-            }
-        )
-
-    def _to_location(self, data):
-        """
-        Convert the data from a Azure response object into a location
-        """
-        country = data.display_name
-
-        if "Asia" in data.display_name:
-            country = "Asia"
-
-        if "Europe" in data.display_name:
-            country = "Europe"
-
-        if "US" in data.display_name:
-            country = "US"
-
-        if "Japan" in data.display_name:
-            country = "Japan"
-
-        if "Brazil" in data.display_name:
-            country = "Brazil"
-
-        vm_role_sizes = data.compute_capabilities.virtual_machines_role_sizes
-
-        return AzureNodeLocation(
-            id=data.name,
-            name=data.display_name,
-            country=country,
-            driver=self.connection.driver,
-            available_services=data.available_services,
-            virtual_machine_role_sizes=vm_role_sizes
-        )
-
-    def _to_node_size(self, data):
-        """
-        Convert the AZURE_COMPUTE_INSTANCE_TYPES into NodeSize
-        """
-        return NodeSize(
-            id=data["id"],
-            name=data["name"],
-            ram=data["ram"],
-            disk=data["disk"],
-            bandwidth=data["bandwidth"],
-            price=data["price"],
-            driver=self.connection.driver,
-            extra={
-                'max_data_disks': data["max_data_disks"],
-                'cores': data["cores"]
-            }
-        )
-
-    def _to_image(self, data):
-        return NodeImage(
-            id=data.name,
-            name=data.label,
-            driver=self.connection.driver,
-            extra={
-                'os': data.os,
-                'category': data.category,
-                'description': data.description,
-                'location': data.location,
-                'affinity_group': data.affinity_group,
-                'media_link': data.media_link,
-                'vm_image': False
-            }
-        )
-
-    def _vm_to_image(self, data):
-        return NodeImage(
-            id=data.name,
-            name=data.label,
-            driver=self.connection.driver,
-            extra={
-                'os': data.os_disk_configuration.os,
-                'category': data.category,
-                'location': data.location,
-                'media_link': data.os_disk_configuration.media_link,
-                'affinity_group': data.affinity_group,
-                'deployment_name': data.deployment_name,
-                'vm_image': True
-            }
-        )
-
-    def _to_volume(self, volume, node):
-        extra = {
-            'affinity_group': volume.affinity_group,
-            'os': volume.os,
-            'location': volume.location,
-            'media_link': volume.media_link,
-            'source_image_name': volume.source_image_name
-        }
-
-        role_name = getattr(volume.attached_to, 'role_name', None)
-        hosted_service_name = getattr(
-            volume.attached_to,
-            'hosted_service_name',
-            None
-        )
-
-        deployment_name = getattr(
-            volume.attached_to,
-            'deployment_name',
-            None
-        )
-
-        if role_name is not None:
-            extra['role_name'] = role_name
-
-        if hosted_service_name is not None:
-            extra['hosted_service_name'] = hosted_service_name
-
-        if deployment_name is not None:
-            extra['deployment_name'] = deployment_name
-
-        if node:
-            if role_name is not None and role_name == node.id:
-                return StorageVolume(
-                    id=volume.name,
-                    name=volume.name,
-                    size=int(volume.logical_disk_size_in_gb),
-                    driver=self.connection.driver,
-                    extra=extra
-                )
-        else:
-            return StorageVolume(
-                id=volume.name,
-                name=volume.name,
-                size=int(volume.logical_disk_size_in_gb),
-                driver=self.connection.driver,
-                extra=extra
-            )
-
-    def _get_deployment(self, **kwargs):
-        _service_name = kwargs['service_name']
-        _deployment_slot = kwargs['deployment_slot']
-
-        response = self._perform_get(
-            self._get_deployment_path_using_slot(
-                _service_name,
-                _deployment_slot
-            ),
-            None
-        )
-
-        self.raise_for_response(response, 200)
-
-        return self._parse_response(response, Deployment)
-
-    def _get_cloud_service_location(self, service_name=None):
-        if not service_name:
-            raise ValueError("service_name is required.")
-
-        res = self._perform_get(
-            '%s?embed-detail=False' % (
-                self._get_hosted_service_path(service_name)
-            ),
-            HostedService
-        )
-
-        _affinity_group = res.hosted_service_properties.affinity_group
-        _cloud_service_location = res.hosted_service_properties.location
-
-        if _affinity_group is not None and _affinity_group is not '':
-            return self.service_location(True, _affinity_group)
-        elif _cloud_service_location is not None:
-            return self.service_location(False, _cloud_service_location)
-        else:
-            return None
-
-    def _is_storage_service_unique(self, service_name=None):
-        if not service_name:
-            raise ValueError("service_name is required.")
-
-        _check_availability = self._perform_get(
-            '%s/operations/isavailable/%s%s' % (
-                self._get_storage_service_path(),
-                _str(service_name),
-                ''
-            ),
-            AvailabilityResponse
-        )
-
-        self.raise_for_response(_check_availability, 200)
-
-        return _check_availability.result
-
-    def _create_storage_account(self, **kwargs):
-        if kwargs['is_affinity_group'] is True:
-            response = self._perform_post(
-                self._get_storage_service_path(),
-                AzureXmlSerializer.create_storage_service_input_to_xml(
-                    kwargs['service_name'],
-                    kwargs['service_name'],
-                    self._encode_base64(kwargs['service_name']),
-                    kwargs['location'],
-                    None,  # Location
-                    True,  # geo_replication_enabled
-                    None  # extended_properties
-                )
-            )
-
-            self.raise_for_response(response, 202)
-
-        else:
-            response = self._perform_post(
-                self._get_storage_service_path(),
-                AzureXmlSerializer.create_storage_service_input_to_xml(
-                    kwargs['service_name'],
-                    kwargs['service_name'],
-                    self._encode_base64(kwargs['service_name']),
-                    None,  # Affinity Group
-                    kwargs['location'],  # Location
-                    True,  # geo_replication_enabled
-                    None  # extended_properties
-                )
-            )
-
-            self.raise_for_response(response, 202)
-
-        # We need to wait for this to be created before we can
-        # create the storage container and the instance.
-        self._ex_complete_async_azure_operation(
-            response,
-            "create_storage_account"
-        )
-
-    def _get_operation_status(self, request_id):
-        return self._perform_get(
-            '/' + self.subscription_id + '/operations/' + _str(request_id),
-            Operation
-        )
-
-    def _perform_get(self, path, response_type):
-        request = AzureHTTPRequest()
-        request.method = 'GET'
-        request.host = AZURE_SERVICE_MANAGEMENT_HOST
-        request.path = path
-        request.path, request.query = self._update_request_uri_query(request)
-        request.headers = self._update_management_header(request)
-        response = self._perform_request(request)
-
-        if response_type is not None:
-            return self._parse_response(response, response_type)
-
-        return response
-
-    def _perform_post(self, path, body, response_type=None, async=False):
-        request = AzureHTTPRequest()
-        request.method = 'POST'
-        request.host = AZURE_SERVICE_MANAGEMENT_HOST
-        request.path = path
-        request.body = ensure_string(self._get_request_body(body))
-        request.path, request.query = self._update_request_uri_query(request)
-        request.headers = self._update_management_header(request)
-        response = self._perform_request(request)
-
-        return response
-
-    def _perform_put(self, path, body, response_type=None, async=False):
-        request = AzureHTTPRequest()
-        request.method = 'PUT'
-        request.host = AZURE_SERVICE_MANAGEMENT_HOST
-        request.path = path
-        request.body = ensure_string(self._get_request_body(body))
-        request.path, request.query = self._update_request_uri_query(request)
-        request.headers = self._update_management_header(request)
-        response = self._perform_request(request)
-
-        return response
-
-    def _perform_delete(self, path, async=False):
-        request = AzureHTTPRequest()
-        request.method = 'DELETE'
-        request.host = AZURE_SERVICE_MANAGEMENT_HOST
-        request.path = path
-        request.path, request.query = self._update_request_uri_query(request)
-        request.headers = self._update_management_header(request)
-        response = self._perform_request(request)
-
-        self.raise_for_response(response, 202)
-
-        if async:
-            return self._parse_response_for_async_op(response)
-
-    def _perform_request(self, request):
-        try:
-            return self.connection.request(
-                action=request.path,
-                data=request.body,
-                headers=request.headers,
-                method=request.method
-            )
-        except AzureRedirectException:
-            e = sys.exc_info()[1]
-            parsed_url = urlparse.urlparse(e.location)
-            request.host = parsed_url.netloc
-            return self._perform_request(request)
-        except Exception as e:
-            raise e
-
-    def _update_request_uri_query(self, request):
-        """
-        pulls the query string out of the URI and moves it into
-        the query portion of the request object.  If there are already
-        query parameters on the request the parameters in the URI will
-        appear after the existing parameters
-        """
-        if '?' in request.path:
-            request.path, _, query_string = request.path.partition('?')
-            if query_string:
-                query_params = query_string.split('&')
-                for query in query_params:
-                    if '=' in query:
-                        name, _, value = query.partition('=')
-                        request.query.append((name, value))
-
-        request.path = url_quote(request.path, '/()$=\',')
-
-        # add encoded queries to request.path.
-        if request.query:
-            request.path += '?'
-            for name, value in request.query:
-                if value is not None:
-                    request.path += '%s=%s%s' % (
-                        name,
-                        url_quote(value, '/()$=\','),
-                        '&'
-                    )
-            request.path = request.path[:-1]
-
-        return request.path, request.query
-
-    def _update_management_header(self, request):
-        """
-        Add additional headers for management.
-        """
-
-        if request.method in ['PUT', 'POST', 'MERGE', 'DELETE']:
-            request.headers['Content-Length'] = str(len(request.body))
-
-        # append additional headers base on the service
-        #  request.headers.append(('x-ms-version', X_MS_VERSION))
-
-        # if it is not GET or HEAD request, must set content-type.
-        if request.method not in ['GET', 'HEAD']:
-            for key in request.headers:
-                if 'content-type' == key.lower():
-                    break
-            else:
-                request.headers['Content-Type'] = 'application/xml'
-
-        return request.headers
-
-    def _parse_response(self, response, return_type):
-        """
-        Parse the HTTPResponse's body and fill all the data into a class of
-        return_type.
-        """
-
-        return self._parse_response_body_from_xml_text(
-            response=response,
-            return_type=return_type
-        )
-
-    def _parse_response_body_from_xml_text(self, response, return_type):
-        """
-        parse the xml and fill all the data into a class of return_type
-        """
-        respbody = response.body
-
-        doc = minidom.parseString(respbody)
-        return_obj = return_type()
-        for node in self._get_child_nodes(doc, return_type.__name__):
-            self._fill_data_to_return_object(node, return_obj)
-
-        # Note: We always explicitly assign status code to the custom return
-        # type object
-        return_obj.status = response.status
-
-        return return_obj
-
-    def _get_child_nodes(self, node, tag_name):
-        return [childNode for childNode in node.getElementsByTagName(tag_name)
-                if childNode.parentNode == node]
-
-    def _fill_data_to_return_object(self, node, return_obj):
-        members = dict(vars(return_obj))
-        for name, value in members.items():
-            if isinstance(value, _ListOf):
-                setattr(
-                    return_obj,
-                    name,
-                    self._fill_list_of(
-                        node,
-                        value.list_type,
-                        value.xml_element_name
-                    )
-                )
-            elif isinstance(value, ScalarListOf):
-                setattr(
-                    return_obj,
-                    name,
-                    self._fill_scalar_list_of(
-                        node,
-                        value.list_type,
-                        self._get_serialization_name(name),
-                        value.xml_element_name
-                    )
-                )
-            elif isinstance(value, _DictOf):
-                setattr(
-                    return_obj,
-                    name,
-                    self._fill_dict_of(
-                        node,
-                        self._get_serialization_name(name),
-                        value.pair_xml_element_name,
-                        value.key_xml_element_name,
-                        value.value_xml_element_name
-                    )
-                )
-            elif isinstance(value, WindowsAzureData):
-                setattr(
-                    return_obj,
-                    name,
-                    self._fill_instance_child(node, name, value.__class__)
-                )
-            elif isinstance(value, dict):
-                setattr(
-                    return_obj,
-                    name,
-                    self._fill_dict(
-                        node,
-                        self._get_serialization_name(name)
-                    )
-                )
-            elif isinstance(value, _Base64String):
-                value = self._fill_data_minidom(node, name, '')
-                if value is not None:
-                    value = self._decode_base64_to_text(value)
-                # always set the attribute,
-                # so we don't end up returning an object
-                # with type _Base64String
-                setattr(return_obj, name, value)
-            else:
-                value = self._fill_data_minidom(node, name, value)
-                if value is not None:
-                    setattr(return_obj, name, value)
-
-    def _fill_list_of(self, xmldoc, element_type, xml_element_name):
-        xmlelements = self._get_child_nodes(xmldoc, xml_element_name)
-        return [
-            self._parse_response_body_from_xml_node(xmlelement, element_type)
-            for xmlelement in xmlelements
-        ]
-
-    def _parse_response_body_from_xml_node(self, node, return_type):
-        """
-        parse the xml and fill all the data into a class of return_type
-        """
-        return_obj = return_type()
-        self._fill_data_to_return_object(node, return_obj)
-
-        return return_obj
-
-    def _fill_scalar_list_of(self,
-                             xmldoc,
-                             element_type,
-                             parent_xml_element_name,
-                             xml_element_name):
-        xmlelements = self._get_child_nodes(xmldoc, parent_xml_element_name)
-
-        if xmlelements:
-            xmlelements = self._get_child_nodes(
-                xmlelements[0],
-                xml_element_name
-            )
-            return [
-                self._get_node_value(xmlelement, element_type)
-                for xmlelement in xmlelements
-            ]
-
-    def _get_node_value(self, xmlelement, data_type):
-        value = xmlelement.firstChild.nodeValue
-        if data_type is datetime:
-            return self._to_datetime(value)
-        elif data_type is bool:
-            return value.lower() != 'false'
-        else:
-            return data_type(value)
-
-    def _get_serialization_name(self, element_name):
-        """
-        Converts a Python name into a serializable name.
-        """
-
-        known = _KNOWN_SERIALIZATION_XFORMS.get(element_name)
-        if known is not None:
-            return known
-
-        if element_name.startswith('x_ms_'):
-            return element_name.replace('_', '-')
-
-        if element_name.endswith('_id'):
-            element_name = element_name.replace('_id', 'ID')
-
-        for name in ['content_', 'last_modified', 'if_', 'cache_control']:
-            if element_name.startswith(name):
-                element_name = element_name.replace('_', '-_')
-
-        return ''.join(name.capitalize() for name in element_name.split('_'))
-
-    def _fill_dict_of(self, xmldoc, parent_xml_element_name,
-                      pair_xml_element_name, key_xml_element_name,
-                      value_xml_element_name):
-        return_obj = {}
-
-        xmlelements = self._get_child_nodes(xmldoc, parent_xml_element_name)
-
-        if xmlelements:
-            xmlelements = self._get_child_nodes(
-                xmlelements[0],
-                pair_xml_element_name
-            )
-            for pair in xmlelements:
-                keys = self._get_child_nodes(pair, key_xml_element_name)
-                values = self._get_child_nodes(pair, value_xml_element_name)
-                if keys and values:
-                    key = keys[0].firstChild.nodeValue
-                    value = values[0].firstChild.nodeValue
-                    return_obj[key] = value
-
-        return return_obj
-
-    def _fill_instance_child(self, xmldoc, element_name, return_type):
-        """
-        Converts a child of the current dom element to the specified type.
-        """
-        xmlelements = self._get_child_nodes(
-            xmldoc,
-            self._get_serialization_name(element_name)
-        )
-
-        if not xmlelements:
-            return None
-
-        return_obj = return_type()
-        self._fill_data_to_return_object(xmlelements[0], return_obj)
-
-        return return_obj
-
-    def _fill_dict(self, xmldoc, element_name):
-        xmlelements = self._get_child_nodes(xmldoc, element_name)
-
-        if xmlelements:
-            return_obj = {}
-            for child in xmlelements[0].childNodes:
-                if child.firstChild:
-                    return_obj[child.nodeName] = child.firstChild.nodeValue
-            return return_obj
-
-    def _encode_base64(self, data):
-        if isinstance(data, _unicode_type):
-            data = data.encode('utf-8')
-        encoded = base64.b64encode(data)
-        return encoded.decode('utf-8')
-
-    def _decode_base64_to_bytes(self, data):
-        if isinstance(data, _unicode_type):
-            data = data.encode('utf-8')
-        return base64.b64decode(data)
-
-    def _decode_base64_to_text(self, data):
-        decoded_bytes = self._decode_base64_to_bytes(data)
-        return decoded_bytes.decode('utf-8')
-
-    def _fill_data_minidom(self, xmldoc, element_name, data_member):
-        xmlelements = self._get_child_nodes(
-            xmldoc,
-            self._get_serialization_name(element_name)
-        )
-
-        if not xmlelements or not xmlelements[0].childNodes:
-            return None
-
-        value = xmlelements[0].firstChild.nodeValue
-
-        if data_member is None:
-            return value
-        elif isinstance(data_member, datetime):
-            return self._to_datetime(value)
-        elif type(data_member) is bool:
-            return value.lower() != 'false'
-        elif type(data_member) is str:
-            return _real_unicode(value)
-        else:
-            return type(data_member)(value)
-
-    def _to_datetime(self, strtime):
-        return datetime.strptime(strtime, "%Y-%m-%dT%H:%M:%S.%f")
-
-    def _get_request_body(self, request_body):
-        if request_body is None:
-            return b''
-
-        if isinstance(request_body, WindowsAzureData):
-            request_body = self._convert_class_to_xml(request_body)
-
-        if isinstance(request_body, bytes):
-            return request_body
-
-        if isinstance(request_body, _unicode_type):
-            return request_body.encode('utf-8')
-
-        request_body = str(request_body)
-        if isinstance(request_body, _unicode_type):
-            return request_body.encode('utf-8')
-
-        return request_body
-
-    def _convert_class_to_xml(self, source, xml_prefix=True):
-        root = ET.Element()
-        doc = self._construct_element_tree(source, root)
-
-        result = ensure_string(ET.tostring(doc, encoding='utf-8',
-                                           method='xml'))
-        return result
-
-    def _construct_element_tree(self, source, etree):
-        if source is None:
-            return ET.Element()
-
-        if isinstance(source, list):
-            for value in source:
-                etree.append(self._construct_element_tree(value, etree))
-
-        elif isinstance(source, WindowsAzureData):
-            class_name = source.__class__.__name__
-            etree.append(ET.Element(class_name))
-
-            for name, value in vars(source).items():
-                if value is not None:
-                    if (isinstance(value, list) or
-                            isinstance(value, WindowsAzureData)):
-                        etree.append(
-                            self._construct_element_tree(value, etree)
-                        )
-                    else:
-                        ele = ET.Element(self._get_serialization_name(name))
-                        ele.text = xml_escape(str(value))
-                        etree.append(ele)
-
-            etree.append(ET.Element(class_name))
-        return etree
-
-    def _parse_response_for_async_op(self, response):
-        if response is None:
-            return None
-
-        result = AsynchronousOperationResult()
-        if response.headers:
-            for name, value in response.headers.items():
-                if name.lower() == 'x-ms-request-id':
-                    result.request_id = value
-
-        return result
-
-    def _get_deployment_path_using_name(self, service_name,
-                                        deployment_name=None):
-        components = [
-            'services/hostedservices/',
-            _str(service_name),
-            '/deployments'
-        ]
-        resource = ''.join(components)
-        return self._get_path(resource, deployment_name)
-
-    def _get_path(self, resource, name):
-        path = '/' + self.subscription_id + '/' + resource
-        if name is not None:
-            path += '/' + _str(name)
-        return path
-
-    def _get_image_path(self, image_name=None):
-        return self._get_path('services/images', image_name)
-
-    def _get_vmimage_path(self, image_name=None):
-        return self._get_path('services/vmimages', image_name)
-
-    def _get_hosted_service_path(self, service_name=None):
-        return self._get_path('services/hostedservices', service_name)
-
-    def _get_deployment_path_using_slot(self, service_name, slot=None):
-        return self._get_path(
-            'services/hostedservices/%s/deploymentslots' % (
-                _str(service_name)
-            ),
-            slot
-        )
-
-    def _get_disk_path(self, disk_name=None):
-        return self._get_path('services/disks', disk_name)
-
-    def _get_role_path(self, service_name, deployment_name, role_name=None):
-        components = [
-            'services/hostedservices/',
-            _str(service_name),
-            '/deployments/',
-            deployment_name,
-            '/roles'
-        ]
-        resource = ''.join(components)
-        return self._get_path(resource, role_name)
-
-    def _get_storage_service_path(self, service_name=None):
-        return self._get_path('services/storageservices', service_name)
-
-    def _ex_complete_async_azure_operation(self, response=None,
-                                           operation_type='create_node'):
-        request_id = self._parse_response_for_async_op(response)
-        operation_status = self._get_operation_status(request_id.request_id)
-
-        timeout = 60 * 5
-        waittime = 0
-        interval = 5
-
-        while operation_status.status == "InProgress" and waittime < timeout:
-            operation_status = self._get_operation_status(request_id)
-            if operation_status.status == "Succeeded":
-                break
-
-            waittime += interval
-            time.sleep(interval)
-
-        if operation_status.status == 'Failed':
-            raise LibcloudError(
-                'Message: Async request for operation %s has failed' %
-                operation_type,
-                driver=self.connection.driver
-            )
-
-    def raise_for_response(self, response, valid_response):
-        if response.status != valid_response:
-            values = (response.error, response.body, response.status)
-            message = 'Message: %s, Body: %s, Status code: %s' % (values)
-            raise LibcloudError(message, driver=self)
-
-"""
-XML Serializer
-
-Borrowed from the Azure SDK for Python which is licensed under Apache 2.0.
-
-https://github.com/Azure/azure-sdk-for-python
-"""
-
-
-def _lower(text):
-    return text.lower()
-
-
-class AzureXmlSerializer(object):
-
-    @staticmethod
-    def create_storage_service_input_to_xml(service_name,
-                                            description,
-                                            label,
-                                            affinity_group,
-                                            location,
-                                            geo_replication_enabled,
-                                            extended_properties):
-        return AzureXmlSerializer.doc_from_data(
-            'CreateStorageServiceInput',
-            [
-                ('ServiceName', service_name),
-                ('Description', description),
-                ('Label', label),
-                ('AffinityGroup', affinity_group),
-                ('Location', location),
-                ('GeoReplicationEnabled', geo_replication_enabled, _lower)
-            ],
-            extended_properties
-        )
-
-    @staticmethod
-    def update_storage_service_input_to_xml(description,
-                                            label,
-                                            geo_replication_enabled,
-                                            extended_properties):
-        return AzureXmlSerializer.doc_from_data(
-            'UpdateStorageServiceInput',
-            [
-                ('Description', description),
-                ('Label', label, AzureNodeDriver._encode_base64),
-                ('GeoReplicationEnabled', geo_replication_enabled, _lower)
-            ],
-            extended_properties
-        )
-
-    @staticmethod
-    def regenerate_keys_to_xml(key_type):
-        return AzureXmlSerializer.doc_from_data(
-            'RegenerateKeys',
-            [('KeyType', key_type)]
-        )
-
-    @staticmethod
-    def update_hosted_service_to_xml(label, description, extended_properties):
-        return AzureXmlSerializer.doc_from_data(
-            'UpdateHostedService',
-            [
-                ('Label', label, AzureNodeDriver._encode_base64),
-                ('Description', description)
-            ],
-            extended_properties
-        )
-
-    @staticmethod
-    def create_hosted_service_to_xml(service_name,
-                                     label,
-                                     description,
-                                     location,
-                                     affinity_group=None,
-                                     extended_properties=None):
-        if affinity_group:
-            return AzureXmlSerializer.doc_from_data(
-                'CreateHostedService',
-                [
-                    ('ServiceName', service_name),
-                    ('Label', label),
-                    ('Description', description),
-                    ('AffinityGroup', affinity_group),
-                ],
-                extended_properties
-            )
-
-        return AzureXmlSerializer.doc_from_data(
-            'CreateHostedService',
-            [
-                ('ServiceName', service_name),
-                ('Label', label),
-                ('Description', description),
-                ('Location', location),
-            ],
-            extended_properties
-        )
-
-    @staticmethod
-    def create_storage_service_to_xml(service_name,
-                                      label,
-                                      description,
-                                      location,
-                                      affinity_group,
-                                      extended_properties=None):
-
-        return AzureXmlSerializer.doc_from_data(
-            'CreateStorageServiceInput',
-            [
-                ('ServiceName', service_name),
-                ('Label', label),
-                ('Description', description),
-                ('Location', location),
-                ('AffinityGroup', affinity_group)
-            ],
-            extended_properties
-        )
-
-    @staticmethod
-    def create_deployment_to_xml(name,
-                                 package_url,
-                                 label,
-                                 configuration,
-                                 start_deployment,
-                                 treat_warnings_as_error,
-                                 extended_properties):
-        return AzureXmlSerializer.doc_from_data(
-            'CreateDeployment',
-            [
-                ('Name', name),
-                ('PackageUrl', package_url),
-                ('Label', label, AzureNodeDriver._encode_base64),
-                ('Configuration', configuration),
-                ('StartDeployment', start_deployment, _lower),
-                ('TreatWarningsAsError', treat_warnings_as_error, _lower)
-            ],
-            extended_properties
-        )
-
-    @staticmethod
-    def swap_deployment_to_xml(production, source_deployment):
-        return AzureXmlSerializer.doc_from_data(
-            'Swap',
-            [
-                ('Production', production),
-                ('SourceDeployment', source_deployment)
-            ]
-        )
-
-    @staticmethod
-    def update_deployment_status_to_xml(status):
-        return AzureXmlSerializer.doc_from_data(
-            'UpdateDeploymentStatus',
-            [('Status', status)]
-        )
-
-    @staticmethod
-    def change_deployment_to_xml(configuration,
-                                 treat_warnings_as_error,
-                                 mode,
-                                 extended_properties):
-        return AzureXmlSerializer.doc_from_data(
-            'ChangeConfiguration',
-            [
-                ('Configuration', configuration),
-                ('TreatWarningsAsError', treat_warnings_as_error, _lower),
-                ('Mode', mode)
-            ],
-            extended_properties
-        )
-
-    @staticmethod
-    def upgrade_deployment_to_xml(mode,
-                                  package_url,
-                                  configuration,
-                                  label,
-                                  role_to_upgrade,
-                                  force,
-                                  extended_properties):
-        return AzureXmlSerializer.doc_from_data(
-            'UpgradeDeployment',
-            [
-                ('Mode', mode),
-                ('PackageUrl', package_url),
-                ('Configuration', configuration),
-                ('Label', label, AzureNodeDriver._encode_base64),
-                ('RoleToUpgrade', role_to_upgrade),
-                ('Force', force, _lower)
-            ],
-            extended_properties
-        )
-
-    @staticmethod
-    def rollback_upgrade_to_xml(mode, force):
-        return AzureXmlSerializer.doc_from_data(
-            'RollbackUpdateOrUpgrade',
-            [
-                ('Mode', mode),
-                ('Force', force, _lower)
-            ]
-        )
-
-    @staticmethod
-    def walk_upgrade_domain_to_xml(upgrade_domain):
-        return AzureXmlSerializer.doc_from_data(
-            'WalkUpgradeDomain',
-            [('UpgradeDomain', upgrade_domain)]
-        )
-
-    @staticmethod
-    def certificate_file_to_xml(data, certificate_format, password):
-        return AzureXmlSerializer.doc_from_data(
-            'CertificateFile',
-            [
-                ('Data', data),
-                ('CertificateFormat', certificate_format),
-                ('Password', password)
-            ]
-        )
-
-    @staticmethod
-    def create_affinity_group_to_xml(name, label, description, location):
-        return AzureXmlSerializer.doc_from_data(
-            'CreateAffinityGroup',
-            [
-                ('Name', name),
-                ('Label', label, AzureNodeDriver._encode_base64),
-                ('Description', description),
-                ('Location', location)
-            ]
-        )
-
-    @staticmethod
-    def update_affinity_group_to_xml(label, description):
-        return AzureXmlSerializer.doc_from_data(
-            'UpdateAffinityGroup',
-            [
-                ('Label', label, AzureNodeDriver._encode_base64),
-                ('Description', description)
-            ]
-        )
-
-    @staticmethod
-    def subscription_certificate_to_xml(public_key, thumbprint, data):
-        return AzureXmlSerializer.doc_from_data(
-            'SubscriptionCertificate',
-            [
-                ('SubscriptionCertificatePublicKey', public_key),
-                ('SubscriptionCertificateThumbprint', thumbprint),
-                ('SubscriptionCertificateData', data)
-            ]
-        )
-
-    @staticmethod
-    def os_image_to_xml(label, media_link, name, os):
-        return AzureXmlSerializer.doc_from_data(
-            'OSImage',
-            [
-                ('Label', label),
-                ('MediaLink', media_link),
-                ('Name', name),
-                ('OS', os)
-            ]
-        )
-
-    @staticmethod
-    def data_virtual_hard_disk_to_xml(host_caching,
-                                      disk_label,
-                                      disk_name,
-                                      lun,
-                                      logical_disk_size_in_gb,
-                                      media_link,
-                                      source_media_link):
-        return AzureXmlSerializer.doc_from_data(
-            'DataVirtualHardDisk',
-            [
-                ('HostCaching', host_caching),
-                ('DiskLabel', disk_label),
-                ('DiskName', disk_name),
-                ('Lun', lun),
-                ('LogicalDiskSizeInGB', logical_disk_size_in_gb),
-                ('MediaLink', media_link),
-                ('SourceMediaLink', source_media_link)
-            ]
-        )
-
-    @staticmethod
-    def disk_to_xml(has_operating_system, label, media_link, name, os):
-        return AzureXmlSerializer.doc_from_data(
-            'Disk',
-            [
-                ('HasOperatingSystem', has_operating_system, _lower),
-                ('Label', label),
-                ('MediaLink', media_link),
-                ('Name', name),
-                ('OS', os)
-            ]
-        )
-
-    @staticmethod
-    def restart_role_operation_to_xml():
-        xml = ET.Element("OperationType")
-        xml.text = "RestartRoleOperation"
-        doc = AzureXmlSerializer.doc_from_xml(
-            'RestartRoleOperation',
-            xml
-        )
-        result = ensure_string(ET.tostring(doc, encoding='utf-8'))
-        return result
-
-    @staticmethod
-    def shutdown_role_operation_to_xml():
-        xml = ET.Element("OperationType")
-        xml.text = "ShutdownRoleOperation"
-        doc = AzureXmlSerializer.doc_from_xml(
-            'ShutdownRoleOperation',
-            xml
-        )
-        result = ensure_string(ET.tostring(doc, encoding='utf-8'))
-        return result
-
-    @staticmethod
-    def start_role_operation_to_xml():
-        xml = ET.Element("OperationType")
-        xml.text = "StartRoleOperation"
-        doc = AzureXmlSerializer.doc_from_xml(
-            'StartRoleOperation',
-            xml
-        )
-        result = ensure_string(ET.tostring(doc, encoding='utf-8'))
-        return result
-
-    @staticmethod
-    def windows_configuration_to_xml(configuration, xml):
-        AzureXmlSerializer.data_to_xml(
-            [('ConfigurationSetType', configuration.configuration_set_type)],
-            xml
-        )
-        AzureXmlSerializer.data_to_xml(
-            [('ComputerName', configuration.computer_name)],
-            xml
-        )
-        AzureXmlSerializer.data_to_xml(
-            [('AdminPassword', configuration.admin_password)],
-            xml
-        )
-        AzureXmlSerializer.data_to_xml(
-            [
-                (
-                    'ResetPasswordOnFirstLogon',
-                    configuration.reset_password_on_first_logon,
-                    _lower
-                )
-            ],
-            xml
-        )
-
-        AzureXmlSerializer.data_to_xml(
-            [
-                (
-                    'EnableAutomaticUpdates',
-                    configuration.enable_automatic_updates,
-                    _lower
-                )
-            ],
-            xml
-        )
-
-        AzureXmlSerializer.data_to_xml(
-            [('TimeZone', configuration.time_zone)],
-            xml
-        )
-
-        if configuration.domain_join is not None:
-            domain = ET.xml("DomainJoin")
-            creds = ET.xml("Credentials")
-            domain.appemnd(creds)
-            xml.append(domain)
-
-            AzureXmlSerializer.data_to_xml(
-                [('Domain', configuration.domain_join.credentials.domain)],
-                creds
-            )
-
-            AzureXmlSerializer.data_to_xml(
-                [
-                    (
-                        'Username',
-                        configuration.domain_join.credentials.username
-                    )
-                ],
-                creds
-            )
-            AzureXmlSerializer.data_to_xml(
-                [
-                    (
-                        'Password',
-                        configuration.domain_join.credentials.password
-                    )
-                ],
-                creds
-            )
-
-            AzureXmlSerializer.data_to_xml(
-                [('JoinDomain', configuration.domain_join.join_domain)],
-                domain
-            )
-
-            AzureXmlSerializer.data_to_xml(
-                [
-                    (
-                        'MachineObjectOU',
-                        configuration.domain_join.machine_object_ou
-                    )
-                ],
-                domain
-            )
-
-        if configuration.stored_certificate_settings is not None:
-            cert_settings = ET.Element("StoredCertificateSettings")
-            xml.append(cert_settings)
-            for cert in configuration.stored_certificate_settings:
-                cert_setting = ET.Element("CertificateSetting")
-                cert_settings.append(cert_setting)
-
-                cert_setting.append(AzureXmlSerializer.data_to_xml(
-                    [('StoreLocation', cert.store_location)])
-                )
-                AzureXmlSerializer.data_to_xml(
-                    [('StoreName', cert.store_name)],
-                    cert_setting
-                )
-                AzureXmlSerializer.data_to_xml(
-                    [('Thumbprint', cert.thumbprint)],
-                    cert_setting
-                )
-
-        AzureXmlSerializer.data_to_xml(
-            [('AdminUsername', configuration.admin_user_name)],
-            xml
-        )
-        return xml
-
-    @staticmethod
-    def linux_configuration_to_xml(configuration, xml):
-        AzureXmlSerializer.data_to_xml(
-            [('ConfigurationSetType', configuration.configuration_set_type)],
-            xml
-        )
-        AzureXmlSerializer.data_to_xml(
-            [('HostName', configuration.host_name)],
-            xml
-        )
-        AzureXmlSerializer.data_to_xml(
-            [('UserName', configuration.user_name)],
-            xml
-        )
-        AzureXmlSerializer.data_to_xml(
-            [('UserPassword', configuration.user_password)],
-            xml
-        )
-        AzureXmlSerializer.data_to_xml(
-            [
-                (
-                    'DisableSshPasswordAuthentication',
-                    configuration.disable_ssh_password_authentication,
-                    _lower
-                )
-            ],
-            xml
-        )
-
-        if configuration.ssh is not None:
-            ssh = ET.Element("SSH")
-            pkeys = ET.Element("PublicKeys")
-            kpairs = ET.Element("KeyPairs")
-            ssh.append(pkeys)
-            ssh.append(kpairs)
-            xml.append(ssh)
-
-            for key in configuration.ssh.public_keys:
-                pkey = ET.Element("PublicKey")
-                pkeys.append(pkey)
-                AzureXmlSerializer.data_to_xml(
-                    [('Fingerprint', key.fingerprint)],
-                    pkey
-                )
-                AzureXmlSerializer.data_to_xml([('Path', key.path)], pkey)
-
-            for key in configuration.ssh.key_pairs:
-                kpair = ET.Element("KeyPair")
-                kpairs.append(kpair)
-                AzureXmlSerializer.data_to_xml(
-                    [('Fingerprint', key.fingerprint)],
-                    kpair
-                )
-                AzureXmlSerializer.data_to_xml([('Path', key.path)], kpair)
-
-        if configuration.custom_data is not None:
-            AzureXmlSerializer.data_to_xml(
-                [('CustomData', configuration.custom_data)],
-                xml
-            )
-
-        return xml
-
-    @staticmethod
-    def network_configuration_to_xml(configuration, xml):
-        AzureXmlSerializer.data_to_xml(
-            [('ConfigurationSetType', configuration.configuration_set_type)],
-            xml
-        )
-
-        input_endpoints = ET.Element("InputEndpoints")
-        xml.append(input_endpoints)
-
-        for endpoint in configuration.input_endpoints:
-            input_endpoint = ET.Element("InputEndpoint")
-            input_endpoints.append(input_endpoint)
-
-            AzureXmlSerializer.data_to_xml(
-                [
-                    (
-                        'LoadBalancedEndpointSetName',
-                        endpoint.load_balanced_endpoint_set_name
-                    )
-                ],
-                input_endpoint
-            )
-
-            AzureXmlSerializer.data_to_xml(
-                [('LocalPort', endpoint.local_port)],
-                input_endpoint
-            )
-            AzureXmlSerializer.data_to_xml(
-                [('Name', endpoint.name)],
-                input_endpoint
-            )
-            AzureXmlSerializer.data_to_xml(
-                [('Port', endpoint.port)],
-                input_endpoint
-            )
-
-            if (endpoint.load_balancer_probe.path or
-                    endpoint.load_balancer_probe.port or
-                    endpoint.load_balancer_probe.protocol):
-
-                load_balancer_probe = ET.Element("LoadBalancerProbe")
-                input_endpoint.append(load_balancer_probe)
-                AzureXmlSerializer.data_to_xml(
-                    [('Path', endpoint.load_balancer_probe.path)],
-                    load_balancer_probe
-                )
-                AzureXmlSerializer.data_to_xml(
-                    [('Port', endpoint.load_balancer_probe.port)],
-                    load_balancer_probe
-                )
-                AzureXmlSerializer.data_to_xml(
-                    [('Protocol', endpoint.load_balancer_probe.protocol)],
-                    load_balancer_probe
-                )
-
-            AzureXmlSerializer.data_to_xml(
-                [('Protocol', endpoint.protocol)],
-                input_endpoint
-            )
-            AzureXmlSerializer.data_to_xml(
-                [
-                    (
-                        'EnableDirectServerReturn',
-                        endpoint.enable_direct_server_return,
-                        _lower
-                    )
-                ],
-                input_endpoint
-            )
-
-        subnet_names = ET.Element("SubnetNames")
-        xml.append(subnet_names)
-        for name in configuration.subnet_names:
-            AzureXmlSerializer.data_to_xml(
-                [('SubnetName', name)],
-                subnet_names
-            )
-
-        return xml
-
-    @staticmethod
-    def role_to_xml(availability_set_name,
-                    data_virtual_hard_disks,
-                    network_configuration_set,
-                    os_virtual_hard_disk,
-                    vm_image_name,
-                    role_name,
-                    role_size,
-                    role_type,
-                    system_configuration_set,
-                    xml):
-
-        AzureXmlSerializer.data_to_xml([('RoleName', role_name)], xml)
-        AzureXmlSerializer.data_to_xml([('RoleType', role_type)], xml)
-
-        config_sets = ET.Element("ConfigurationSets")
-        xml.append(config_sets)
-
-        if system_configuration_set is not None:
-            config_set = ET.Element("ConfigurationSet")
-            config_sets.append(config_set)
-
-            if isinstance(system_configuration_set, WindowsConfigurationSet):
-                AzureXmlSerializer.windows_configuration_to_xml(
-                    system_configuration_set,
-                    config_set
-                )
-            elif isinstance(system_configuration_set, LinuxConfigurationSet):
-                AzureXmlSerializer.linux_configuration_to_xml(
-                    system_configuration_set,
-                    config_set
-                )
-
-        if network_configuration_set is not None:
-            config_set = ET.Element("ConfigurationSet")
-            config_sets.append(config_set)
-
-            AzureXmlSerializer.network_configuration_to_xml(
-                network_configuration_set,
-                config_set
-            )
-
-        if availability_set_name is not None:
-            AzureXmlSerializer.data_to_xml(
-                [('AvailabilitySetName', availability_set_name)],
-                xml
-            )
-
-        if data_virtual_hard_disks is not None:
-            vhds = ET.Element("DataVirtualHardDisks")
-            xml.append(vhds)
-
-            for hd in data_virtual_hard_disks:
-                vhd = ET.Element("DataVirtualHardDisk")
-                vhds.append(vhd)
-                AzureXmlSerializer.data_to_xml(
-                    [('HostCaching', hd.host_caching)],
-                    vhd
-                )
-                AzureXmlSerializer.data_to_xml(
-                    [('DiskLabel', hd.disk_label)],
-                    vhd
-                )
-                AzureXmlSerializer.data_to_xml(
-                    [('DiskName', hd.disk_name)],
-                    vhd
-                )
-                AzureXmlSerializer.data_to_xml(
-                    [('Lun', hd.lun)],
-                    vhd
-                )
-                AzureXmlSerializer.data_to_xml(
-                    [('LogicalDiskSizeInGB', hd.logical_disk_size_in_gb)],

<TRUNCATED>

[22/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/opennebula.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/opennebula.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/opennebula.py
deleted file mode 100644
index c295cd4..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/opennebula.py
+++ /dev/null
@@ -1,1264 +0,0 @@
-# Copyright 2002-2009, Distributed Systems Architecture Group, Universidad
-# Complutense de Madrid (dsa-research.org)
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-OpenNebula.org driver.
-"""
-
-__docformat__ = 'epytext'
-
-from base64 import b64encode
-import hashlib
-
-try:
-    from lxml import etree as ET
-except ImportError:
-    from xml.etree import ElementTree as ET
-
-from libcloud.utils.py3 import httplib
-from libcloud.utils.py3 import next
-from libcloud.utils.py3 import b
-
-from libcloud.compute.base import NodeState, NodeDriver, Node, NodeLocation
-from libcloud.common.base import ConnectionUserAndKey, XmlResponse
-from libcloud.compute.base import NodeImage, NodeSize, StorageVolume
-from libcloud.common.types import InvalidCredsError
-from libcloud.compute.providers import Provider
-
-__all__ = [
-    'ACTION',
-    'OpenNebulaResponse',
-    'OpenNebulaConnection',
-    'OpenNebulaNodeSize',
-    'OpenNebulaNetwork',
-    'OpenNebulaNodeDriver',
-    'OpenNebula_1_4_NodeDriver',
-    'OpenNebula_2_0_NodeDriver',
-    'OpenNebula_3_0_NodeDriver',
-    'OpenNebula_3_2_NodeDriver',
-    'OpenNebula_3_8_NodeDriver']
-
-API_HOST = ''
-API_PORT = (4567, 443)
-API_SECURE = True
-API_PLAIN_AUTH = False
-DEFAULT_API_VERSION = '3.2'
-
-
-class ACTION(object):
-    """
-    All actions, except RESUME, only apply when the VM is in the "Running"
-    state.
-    """
-
-    STOP = 'STOPPED'
-    """
-    The VM is stopped, and its memory state stored to a checkpoint file. VM
-    state, and disk image, are transferred back to the front-end. Resuming
-    the VM requires the VM instance to be re-scheduled.
-    """
-
-    SUSPEND = 'SUSPENDED'
-    """
-    The VM is stopped, and its memory state stored to a checkpoint file. The VM
-    state, and disk image, are left on the host to be resumed later. Resuming
-    the VM does not require the VM to be re-scheduled. Rather, after
-    suspending, the VM resources are reserved for later resuming.
-    """
-
-    RESUME = 'RESUME'
-    """
-    The VM is resumed using the saved memory state from the checkpoint file,
-    and the VM's disk image. The VM is either started immediately, or
-    re-scheduled depending on how it was suspended.
-    """
-
-    CANCEL = 'CANCEL'
-    """
-    The VM is forcibly shutdown, its memory state is deleted. If a persistent
-    disk image was used, that disk image is transferred back to the front-end.
-    Any non-persistent disk images are deleted.
-    """
-
-    SHUTDOWN = 'SHUTDOWN'
-    """
-    The VM is gracefully shutdown by sending the ACPI signal. If the VM does
-    not shutdown, then it is considered to still be running. If successfully,
-    shutdown, its memory state is deleted. If a persistent disk image was used,
-    that disk image is transferred back to the front-end. Any non-persistent
-    disk images are deleted.
-    """
-
-    REBOOT = 'REBOOT'
-    """
-    Introduced in OpenNebula v3.2.
-
-    The VM is gracefully restarted by sending the ACPI signal.
-    """
-
-    DONE = 'DONE'
-    """
-    The VM is forcibly shutdown, its memory state is deleted. If a persistent
-    disk image was used, that disk image is transferred back to the front-end.
-    Any non-persistent disk images are deleted.
-    """
-
-
-class OpenNebulaResponse(XmlResponse):
-    """
-    XmlResponse class for the OpenNebula.org driver.
-    """
-
-    def success(self):
-        """
-        Check if response has the appropriate HTTP response code to be a
-        success.
-
-        :rtype:  ``bool``
-        :return: True is success, else False.
-        """
-        i = int(self.status)
-        return i >= 200 and i <= 299
-
-    def parse_error(self):
-        """
-        Check if response contains any errors.
-
-        @raise: :class:`InvalidCredsError`
-
-        :rtype:  :class:`ElementTree`
-        :return: Contents of HTTP response body.
-        """
-        if int(self.status) == httplib.UNAUTHORIZED:
-            raise InvalidCredsError(self.body)
-        return self.body
-
-
-class OpenNebulaConnection(ConnectionUserAndKey):
-    """
-    Connection class for the OpenNebula.org driver.
-    with plain_auth support
-    """
-
-    host = API_HOST
-    port = API_PORT
-    secure = API_SECURE
-    plain_auth = API_PLAIN_AUTH
-    responseCls = OpenNebulaResponse
-
-    def __init__(self, *args, **kwargs):
-        if 'plain_auth' in kwargs:
-            self.plain_auth = kwargs.pop('plain_auth')
-        super(OpenNebulaConnection, self).__init__(*args, **kwargs)
-
-    def add_default_headers(self, headers):
-        """
-        Add headers required by the OpenNebula.org OCCI interface.
-
-        Includes adding Basic HTTP Authorization headers for authenticating
-        against the OpenNebula.org OCCI interface.
-
-        :type  headers: ``dict``
-        :param headers: Dictionary containing HTTP headers.
-
-        :rtype:  ``dict``
-        :return: Dictionary containing updated headers.
-        """
-        if self.plain_auth:
-            passwd = self.key
-        else:
-            passwd = hashlib.sha1(b(self.key)).hexdigest()
-        headers['Authorization'] =\
-            ('Basic %s' % b64encode(b('%s:%s' % (self.user_id,
-                                                 passwd))).decode('utf-8'))
-        return headers
-
-
-class OpenNebulaNodeSize(NodeSize):
-    """
-    NodeSize class for the OpenNebula.org driver.
-    """
-
-    def __init__(self, id, name, ram, disk, bandwidth, price, driver,
-                 cpu=None, vcpu=None):
-        super(OpenNebulaNodeSize, self).__init__(id=id, name=name, ram=ram,
-                                                 disk=disk,
-                                                 bandwidth=bandwidth,
-                                                 price=price, driver=driver)
-        self.cpu = cpu
-        self.vcpu = vcpu
-
-    def __repr__(self):
-        return (('<OpenNebulaNodeSize: id=%s, name=%s, ram=%s, disk=%s, '
-                 'bandwidth=%s, price=%s, driver=%s, cpu=%s, vcpu=%s ...>')
-                % (self.id, self.name, self.ram, self.disk, self.bandwidth,
-                   self.price, self.driver.name, self.cpu, self.vcpu))
-
-
-class OpenNebulaNetwork(object):
-    """
-    Provide a common interface for handling networks of all types.
-
-    Network objects are analogous to physical switches connecting two or
-    more physical nodes together. The Network object provides the interface in
-    libcloud through which we can manipulate networks in different cloud
-    providers in the same way. Network objects don't actually do much directly
-    themselves, instead the network driver handles the connection to the
-    network.
-
-    You don't normally create a network object yourself; instead you use
-    a driver and then have that create the network for you.
-
-    >>> from libcloud.compute.drivers.dummy import DummyNodeDriver
-    >>> driver = DummyNodeDriver()
-    >>> network = driver.create_network()
-    >>> network = driver.list_networks()[0]
-    >>> network.name
-    'dummy-1'
-    """
-
-    def __init__(self, id, name, address, size, driver, extra=None):
-        self.id = str(id)
-        self.name = name
-        self.address = address
-        self.size = size
-        self.driver = driver
-        self.uuid = self.get_uuid()
-        self.extra = extra or {}
-
-    def get_uuid(self):
-        """
-        Unique hash for this network.
-
-        The hash is a function of an SHA1 hash of the network's ID and
-        its driver which means that it should be unique between all
-        networks. In some subclasses (e.g. GoGrid) there is no ID
-        available so the public IP address is used. This means that,
-        unlike a properly done system UUID, the same UUID may mean a
-        different system install at a different time
-
-        >>> from libcloud.network.drivers.dummy import DummyNetworkDriver
-        >>> driver = DummyNetworkDriver()
-        >>> network = driver.create_network()
-        >>> network.get_uuid()
-        'd3748461511d8b9b0e0bfa0d4d3383a619a2bb9f'
-
-        Note, for example, that this example will always produce the
-        same UUID!
-
-        :rtype:  ``str``
-        :return: Unique identifier for this instance.
-        """
-        return hashlib.sha1(b("%s:%s" % (self.id,
-                                         self.driver.type))).hexdigest()
-
-    def __repr__(self):
-        return (('<OpenNebulaNetwork: uuid=%s, name=%s, address=%s, size=%s, '
-                 'provider=%s ...>')
-                % (self.uuid, self.name, self.address, self.size,
-                   self.driver.name))
-
-
-class OpenNebulaNodeDriver(NodeDriver):
-    """
-    OpenNebula.org node driver.
-    """
-
-    connectionCls = OpenNebulaConnection
-    name = 'OpenNebula'
-    website = 'http://opennebula.org/'
-    type = Provider.OPENNEBULA
-
-    NODE_STATE_MAP = {
-        'INIT': NodeState.PENDING,
-        'PENDING': NodeState.PENDING,
-        'HOLD': NodeState.PENDING,
-        'ACTIVE': NodeState.RUNNING,
-        'STOPPED': NodeState.TERMINATED,
-        'SUSPENDED': NodeState.PENDING,
-        'DONE': NodeState.TERMINATED,
-        'FAILED': NodeState.TERMINATED}
-
-    def __new__(cls, key, secret=None, api_version=DEFAULT_API_VERSION,
-                **kwargs):
-        if cls is OpenNebulaNodeDriver:
-            if api_version in ['1.4']:
-                cls = OpenNebula_1_4_NodeDriver
-            elif api_version in ['2.0', '2.2']:
-                cls = OpenNebula_2_0_NodeDriver
-            elif api_version in ['3.0']:
-                cls = OpenNebula_3_0_NodeDriver
-            elif api_version in ['3.2']:
-                cls = OpenNebula_3_2_NodeDriver
-            elif api_version in ['3.6']:
-                cls = OpenNebula_3_6_NodeDriver
-            elif api_version in ['3.8']:
-                cls = OpenNebula_3_8_NodeDriver
-                if 'plain_auth' not in kwargs:
-                    kwargs['plain_auth'] = cls.plain_auth
-                else:
-                    cls.plain_auth = kwargs['plain_auth']
-            else:
-                raise NotImplementedError(
-                    "No OpenNebulaNodeDriver found for API version %s" %
-                    (api_version))
-            return super(OpenNebulaNodeDriver, cls).__new__(cls)
-
-    def create_node(self, **kwargs):
-        """
-        Create a new OpenNebula node.
-
-        @inherits: :class:`NodeDriver.create_node`
-
-        :keyword networks: List of virtual networks to which this node should
-                           connect. (optional)
-        :type    networks: :class:`OpenNebulaNetwork` or
-            ``list`` of :class:`OpenNebulaNetwork`
-        """
-        compute = ET.Element('COMPUTE')
-
-        name = ET.SubElement(compute, 'NAME')
-        name.text = kwargs['name']
-
-        instance_type = ET.SubElement(compute, 'INSTANCE_TYPE')
-        instance_type.text = kwargs['size'].name
-
-        storage = ET.SubElement(compute, 'STORAGE')
-        ET.SubElement(storage,
-                      'DISK',
-                      {'image': '%s' % (str(kwargs['image'].id))})
-
-        if 'networks' in kwargs:
-            if not isinstance(kwargs['networks'], list):
-                kwargs['networks'] = [kwargs['networks']]
-
-            networkGroup = ET.SubElement(compute, 'NETWORK')
-            for network in kwargs['networks']:
-                if network.address:
-                    ET.SubElement(networkGroup, 'NIC',
-                                  {'network': '%s' % (str(network.id)),
-                                   'ip': network.address})
-                else:
-                    ET.SubElement(networkGroup, 'NIC',
-                                  {'network': '%s' % (str(network.id))})
-
-        xml = ET.tostring(compute)
-        node = self.connection.request('/compute', method='POST',
-                                       data=xml).object
-
-        return self._to_node(node)
-
-    def destroy_node(self, node):
-        url = '/compute/%s' % (str(node.id))
-        resp = self.connection.request(url, method='DELETE')
-
-        return resp.status == httplib.OK
-
-    def list_nodes(self):
-        return self._to_nodes(self.connection.request('/compute').object)
-
-    def list_images(self, location=None):
-        return self._to_images(self.connection.request('/storage').object)
-
-    def list_sizes(self, location=None):
-        """
-        Return list of sizes on a provider.
-
-        @inherits: :class:`NodeDriver.list_sizes`
-
-        :return: List of compute node sizes supported by the cloud provider.
-        :rtype:  ``list`` of :class:`OpenNebulaNodeSize`
-        """
-        return [
-            NodeSize(id=1,
-                     name='small',
-                     ram=None,
-                     disk=None,
-                     bandwidth=None,
-                     price=None,
-                     driver=self),
-            NodeSize(id=2,
-                     name='medium',
-                     ram=None,
-                     disk=None,
-                     bandwidth=None,
-                     price=None,
-                     driver=self),
-            NodeSize(id=3,
-                     name='large',
-                     ram=None,
-                     disk=None,
-                     bandwidth=None,
-                     price=None,
-                     driver=self),
-        ]
-
-    def list_locations(self):
-        return [NodeLocation(0, '', '', self)]
-
-    def ex_list_networks(self, location=None):
-        """
-        List virtual networks on a provider.
-
-        :param location: Location from which to request a list of virtual
-                         networks. (optional)
-        :type  location: :class:`NodeLocation`
-
-        :return: List of virtual networks available to be connected to a
-                 compute node.
-        :rtype:  ``list`` of :class:`OpenNebulaNetwork`
-        """
-        return self._to_networks(self.connection.request('/network').object)
-
-    def ex_node_action(self, node, action):
-        """
-        Build action representation and instruct node to commit action.
-
-        Build action representation from the compute node ID, and the
-        action which should be carried out on that compute node. Then
-        instruct the node to carry out that action.
-
-        :param node: Compute node instance.
-        :type  node: :class:`Node`
-
-        :param action: Action to be carried out on the compute node.
-        :type  action: ``str``
-
-        :return: False if an HTTP Bad Request is received, else, True is
-                 returned.
-        :rtype:  ``bool``
-        """
-        compute_node_id = str(node.id)
-
-        compute = ET.Element('COMPUTE')
-
-        compute_id = ET.SubElement(compute, 'ID')
-        compute_id.text = compute_node_id
-
-        state = ET.SubElement(compute, 'STATE')
-        state.text = action
-
-        xml = ET.tostring(compute)
-
-        url = '/compute/%s' % compute_node_id
-        resp = self.connection.request(url, method='PUT',
-                                       data=xml)
-
-        if resp.status == httplib.BAD_REQUEST:
-            return False
-        else:
-            return True
-
-    def _to_images(self, object):
-        """
-        Request a list of images and convert that list to a list of NodeImage
-        objects.
-
-        Request a list of images from the OpenNebula web interface, and
-        issue a request to convert each XML object representation of an image
-        to a NodeImage object.
-
-        :rtype:  ``list`` of :class:`NodeImage`
-        :return: List of images.
-        """
-        images = []
-        for element in object.findall('DISK'):
-            image_id = element.attrib['href'].partition('/storage/')[2]
-            image = self.connection.request(
-                ('/storage/%s' % (image_id))).object
-            images.append(self._to_image(image))
-
-        return images
-
-    def _to_image(self, image):
-        """
-        Take XML object containing an image description and convert to
-        NodeImage object.
-
-        :type  image: :class:`ElementTree`
-        :param image: XML representation of an image.
-
-        :rtype:  :class:`NodeImage`
-        :return: The newly extracted :class:`NodeImage`.
-        """
-        return NodeImage(id=image.findtext('ID'),
-                         name=image.findtext('NAME'),
-                         driver=self.connection.driver,
-                         extra={'size': image.findtext('SIZE'),
-                                'url': image.findtext('URL')})
-
-    def _to_networks(self, object):
-        """
-        Request a list of networks and convert that list to a list of
-        OpenNebulaNetwork objects.
-
-        Request a list of networks from the OpenNebula web interface, and
-        issue a request to convert each XML object representation of a network
-        to an OpenNebulaNetwork object.
-
-        :rtype:  ``list`` of :class:`OpenNebulaNetwork`
-        :return: List of virtual networks.
-        """
-        networks = []
-        for element in object.findall('NETWORK'):
-            network_id = element.attrib['href'].partition('/network/')[2]
-            network_element = self.connection.request(
-                ('/network/%s' % (network_id))).object
-            networks.append(self._to_network(network_element))
-
-        return networks
-
-    def _to_network(self, element):
-        """
-        Take XML object containing a network description and convert to
-        OpenNebulaNetwork object.
-
-        Take XML representation containing a network description and
-        convert to OpenNebulaNetwork object.
-
-        :rtype:  :class:`OpenNebulaNetwork`
-        :return: The newly extracted :class:`OpenNebulaNetwork`.
-        """
-        return OpenNebulaNetwork(id=element.findtext('ID'),
-                                 name=element.findtext('NAME'),
-                                 address=element.findtext('ADDRESS'),
-                                 size=element.findtext('SIZE'),
-                                 driver=self.connection.driver)
-
-    def _to_nodes(self, object):
-        """
-        Request a list of compute nodes and convert that list to a list of
-        Node objects.
-
-        Request a list of compute nodes from the OpenNebula web interface, and
-        issue a request to convert each XML object representation of a node
-        to a Node object.
-
-        :rtype:  ``list`` of :class:`Node`
-        :return: A list of compute nodes.
-        """
-        computes = []
-        for element in object.findall('COMPUTE'):
-            compute_id = element.attrib['href'].partition('/compute/')[2]
-            compute = self.connection.request(
-                ('/compute/%s' % (compute_id))).object
-            computes.append(self._to_node(compute))
-
-        return computes
-
-    def _to_node(self, compute):
-        """
-        Take XML object containing a compute node description and convert to
-        Node object.
-
-        Take XML representation containing a compute node description and
-        convert to Node object.
-
-        :type  compute: :class:`ElementTree`
-        :param compute: XML representation of a compute node.
-
-        :rtype:  :class:`Node`
-        :return: The newly extracted :class:`Node`.
-        """
-        try:
-            state = self.NODE_STATE_MAP[compute.findtext('STATE').upper()]
-        except KeyError:
-            state = NodeState.UNKNOWN
-
-        return Node(id=compute.findtext('ID'),
-                    name=compute.findtext('NAME'),
-                    state=state,
-                    public_ips=self._extract_networks(compute),
-                    private_ips=[],
-                    driver=self.connection.driver,
-                    image=self._extract_images(compute))
-
-    def _extract_networks(self, compute):
-        """
-        Extract networks from a compute node XML representation.
-
-        Extract network descriptions from a compute node XML representation,
-        converting each network to an OpenNebulaNetwork object.
-
-        :type  compute: :class:`ElementTree`
-        :param compute: XML representation of a compute node.
-
-        :rtype:  ``list`` of :class:`OpenNebulaNetwork`s.
-        :return: List of virtual networks attached to the compute node.
-        """
-        networks = list()
-
-        network_list = compute.find('NETWORK')
-        for element in network_list.findall('NIC'):
-            networks.append(
-                OpenNebulaNetwork(id=element.attrib.get('network', None),
-                                  name=None,
-                                  address=element.attrib.get('ip', None),
-                                  size=1,
-                                  driver=self.connection.driver))
-
-        return networks
-
-    def _extract_images(self, compute):
-        """
-        Extract image disks from a compute node XML representation.
-
-        Extract image disk descriptions from a compute node XML representation,
-        converting the disks to an NodeImage object.
-
-        :type  compute: :class:`ElementTree`
-        :param compute: XML representation of a compute node.
-
-        :rtype:  :class:`NodeImage`.
-        :return: First disk attached to a compute node.
-        """
-        disks = list()
-
-        disk_list = compute.find('STORAGE')
-        if disk_list is not None:
-            for element in disk_list.findall('DISK'):
-                disks.append(
-                    NodeImage(id=element.attrib.get('image', None),
-                              name=None,
-                              driver=self.connection.driver,
-                              extra={'dev': element.attrib.get('dev', None)}))
-
-        # @TODO: Return all disks when the Node type accepts multiple
-        # attached disks per node.
-        if len(disks) > 0:
-            return disks[0]
-        else:
-            return None
-
-
-class OpenNebula_1_4_NodeDriver(OpenNebulaNodeDriver):
-    """
-    OpenNebula.org node driver for OpenNebula.org v1.4.
-    """
-
-    name = 'OpenNebula (v1.4)'
-
-
-class OpenNebula_2_0_NodeDriver(OpenNebulaNodeDriver):
-    """
-    OpenNebula.org node driver for OpenNebula.org v2.0 through OpenNebula.org
-    v2.2.
-    """
-
-    name = 'OpenNebula (v2.0 - v2.2)'
-
-    def create_node(self, **kwargs):
-        """
-        Create a new OpenNebula node.
-
-        @inherits: :class:`NodeDriver.create_node`
-
-        :keyword networks: List of virtual networks to which this node should
-                           connect. (optional)
-        :type    networks: :class:`OpenNebulaNetwork` or ``list``
-                           of :class:`OpenNebulaNetwork`
-
-        :keyword context: Custom (key, value) pairs to be injected into
-                          compute node XML description. (optional)
-        :type    context: ``dict``
-
-        :return: Instance of a newly created node.
-        :rtype:  :class:`Node`
-        """
-        compute = ET.Element('COMPUTE')
-
-        name = ET.SubElement(compute, 'NAME')
-        name.text = kwargs['name']
-
-        instance_type = ET.SubElement(compute, 'INSTANCE_TYPE')
-        instance_type.text = kwargs['size'].name
-
-        disk = ET.SubElement(compute, 'DISK')
-        ET.SubElement(disk,
-                      'STORAGE',
-                      {'href': '/storage/%s' % (str(kwargs['image'].id))})
-
-        if 'networks' in kwargs:
-            if not isinstance(kwargs['networks'], list):
-                kwargs['networks'] = [kwargs['networks']]
-
-            for network in kwargs['networks']:
-                nic = ET.SubElement(compute, 'NIC')
-                ET.SubElement(nic, 'NETWORK',
-                              {'href': '/network/%s' % (str(network.id))})
-                if network.address:
-                    ip_line = ET.SubElement(nic, 'IP')
-                    ip_line.text = network.address
-
-        if 'context' in kwargs:
-            if isinstance(kwargs['context'], dict):
-                contextGroup = ET.SubElement(compute, 'CONTEXT')
-                for key, value in list(kwargs['context'].items()):
-                    context = ET.SubElement(contextGroup, key.upper())
-                    context.text = value
-
-        xml = ET.tostring(compute)
-        node = self.connection.request('/compute', method='POST',
-                                       data=xml).object
-
-        return self._to_node(node)
-
-    def destroy_node(self, node):
-        url = '/compute/%s' % (str(node.id))
-        resp = self.connection.request(url, method='DELETE')
-
-        return resp.status == httplib.NO_CONTENT
-
-    def list_sizes(self, location=None):
-        """
-        Return list of sizes on a provider.
-
-        @inherits: :class:`NodeDriver.list_sizes`
-
-        :return: List of compute node sizes supported by the cloud provider.
-        :rtype:  ``list`` of :class:`OpenNebulaNodeSize`
-        """
-        return [
-            OpenNebulaNodeSize(id=1,
-                               name='small',
-                               ram=1024,
-                               cpu=1,
-                               disk=None,
-                               bandwidth=None,
-                               price=None,
-                               driver=self),
-            OpenNebulaNodeSize(id=2,
-                               name='medium',
-                               ram=4096,
-                               cpu=4,
-                               disk=None,
-                               bandwidth=None,
-                               price=None,
-                               driver=self),
-            OpenNebulaNodeSize(id=3,
-                               name='large',
-                               ram=8192,
-                               cpu=8,
-                               disk=None,
-                               bandwidth=None,
-                               price=None,
-                               driver=self),
-            OpenNebulaNodeSize(id=4,
-                               name='custom',
-                               ram=0,
-                               cpu=0,
-                               disk=None,
-                               bandwidth=None,
-                               price=None,
-                               driver=self),
-        ]
-
-    def _to_images(self, object):
-        """
-        Request a list of images and convert that list to a list of NodeImage
-        objects.
-
-        Request a list of images from the OpenNebula web interface, and
-        issue a request to convert each XML object representation of an image
-        to a NodeImage object.
-
-        :rtype:  ``list`` of :class:`NodeImage`
-        :return: List of images.
-        """
-        images = []
-        for element in object.findall('STORAGE'):
-            image_id = element.attrib["href"].partition("/storage/")[2]
-            image = self.connection.request(
-                ("/storage/%s" % (image_id))).object
-            images.append(self._to_image(image))
-
-        return images
-
-    def _to_image(self, image):
-        """
-        Take XML object containing an image description and convert to
-        NodeImage object.
-
-        :type  image: :class:`ElementTree`
-        :param image: XML representation of an image.
-
-        :rtype:  :class:`NodeImage`
-        :return: The newly extracted :class:`NodeImage`.
-        """
-        return NodeImage(id=image.findtext('ID'),
-                         name=image.findtext('NAME'),
-                         driver=self.connection.driver,
-                         extra={'description': image.findtext('DESCRIPTION'),
-                                'type': image.findtext('TYPE'),
-                                'size': image.findtext('SIZE'),
-                                'fstype': image.findtext('FSTYPE', None)})
-
-    def _to_node(self, compute):
-        """
-        Take XML object containing a compute node description and convert to
-        Node object.
-
-        Take XML representation containing a compute node description and
-        convert to Node object.
-
-        :type  compute: :class:`ElementTree`
-        :param compute: XML representation of a compute node.
-
-        :rtype:  :class:`Node`
-        :return: The newly extracted :class:`Node`.
-        """
-        try:
-            state = self.NODE_STATE_MAP[compute.findtext('STATE').upper()]
-        except KeyError:
-            state = NodeState.UNKNOWN
-
-        return Node(id=compute.findtext('ID'),
-                    name=compute.findtext('NAME'),
-                    state=state,
-                    public_ips=self._extract_networks(compute),
-                    private_ips=[],
-                    driver=self.connection.driver,
-                    image=self._extract_images(compute),
-                    size=self._extract_size(compute),
-                    extra={'context': self._extract_context(compute)})
-
-    def _extract_networks(self, compute):
-        """
-        Extract networks from a compute node XML representation.
-
-        Extract network descriptions from a compute node XML representation,
-        converting each network to an OpenNebulaNetwork object.
-
-        :type  compute: :class:`ElementTree`
-        :param compute: XML representation of a compute node.
-
-        :rtype:  ``list`` of :class:`OpenNebulaNetwork`
-        :return: List of virtual networks attached to the compute node.
-        """
-        networks = []
-
-        for element in compute.findall('NIC'):
-            network = element.find('NETWORK')
-            network_id = network.attrib['href'].partition('/network/')[2]
-
-            networks.append(
-                OpenNebulaNetwork(id=network_id,
-                                  name=network.attrib.get('name', None),
-                                  address=element.findtext('IP'),
-                                  size=1,
-                                  driver=self.connection.driver,
-                                  extra={'mac': element.findtext('MAC')}))
-
-        return networks
-
-    def _extract_images(self, compute):
-        """
-        Extract image disks from a compute node XML representation.
-
-        Extract image disk descriptions from a compute node XML representation,
-        converting the disks to an NodeImage object.
-
-        :type  compute: :class:`ElementTree`
-        :param compute: XML representation of a compute node.
-
-        :rtype:  ``list`` of :class:`NodeImage`
-        :return: Disks attached to a compute node.
-        """
-        disks = list()
-
-        for element in compute.findall('DISK'):
-            disk = element.find('STORAGE')
-            image_id = disk.attrib['href'].partition('/storage/')[2]
-
-            if 'id' in element.attrib:
-                disk_id = element.attrib['id']
-            else:
-                disk_id = None
-
-            disks.append(
-                NodeImage(id=image_id,
-                          name=disk.attrib.get('name', None),
-                          driver=self.connection.driver,
-                          extra={'type': element.findtext('TYPE'),
-                                 'disk_id': disk_id,
-                                 'target': element.findtext('TARGET')}))
-
-        # Return all disks when the Node type accepts multiple attached disks
-        # per node.
-        if len(disks) > 1:
-            return disks
-        elif len(disks) == 1:
-            return disks[0]
-        else:
-            return None
-
-    def _extract_size(self, compute):
-        """
-        Extract size, or node type, from a compute node XML representation.
-
-        Extract node size, or node type, description from a compute node XML
-        representation, converting the node size to a NodeSize object.
-
-        :type  compute: :class:`ElementTree`
-        :param compute: XML representation of a compute node.
-
-        :rtype:  :class:`OpenNebulaNodeSize`
-        :return: Node type of compute node.
-        """
-        instance_type = compute.find('INSTANCE_TYPE')
-
-        try:
-            return next((node_size for node_size in self.list_sizes()
-                        if node_size.name == instance_type.text))
-        except StopIteration:
-            return None
-
-    def _extract_context(self, compute):
-        """
-        Extract size, or node type, from a compute node XML representation.
-
-        Extract node size, or node type, description from a compute node XML
-        representation, converting the node size to a NodeSize object.
-
-        :type  compute: :class:`ElementTree`
-        :param compute: XML representation of a compute node.
-
-        :rtype:  ``dict``
-        :return: Dictionary containing (key, value) pairs related to
-                 compute node context.
-        """
-        contexts = dict()
-        context = compute.find('CONTEXT')
-
-        if context is not None:
-            for context_element in list(context):
-                contexts[context_element.tag.lower()] = context_element.text
-
-        return contexts
-
-
-class OpenNebula_3_0_NodeDriver(OpenNebula_2_0_NodeDriver):
-    """
-    OpenNebula.org node driver for OpenNebula.org v3.0.
-    """
-
-    name = 'OpenNebula (v3.0)'
-
-    def ex_node_set_save_name(self, node, name):
-        """
-        Build action representation and instruct node to commit action.
-
-        Build action representation from the compute node ID, the disk image
-        which will be saved, and the name under which the image will be saved
-        upon shutting down the compute node.
-
-        :param node: Compute node instance.
-        :type  node: :class:`Node`
-
-        :param name: Name under which the image should be saved after shutting
-                     down the compute node.
-        :type  name: ``str``
-
-        :return: False if an HTTP Bad Request is received, else, True is
-                 returned.
-        :rtype:  ``bool``
-        """
-        compute_node_id = str(node.id)
-
-        compute = ET.Element('COMPUTE')
-
-        compute_id = ET.SubElement(compute, 'ID')
-        compute_id.text = compute_node_id
-
-        disk = ET.SubElement(compute, 'DISK', {'id': str(node.image.id)})
-
-        ET.SubElement(disk, 'STORAGE',
-                      {'href': '/storage/%s' % (str(node.image.id)),
-                       'name': node.image.name})
-
-        ET.SubElement(disk, 'SAVE_AS', {'name': str(name)})
-
-        xml = ET.tostring(compute)
-
-        url = '/compute/%s' % compute_node_id
-        resp = self.connection.request(url, method='PUT',
-                                       data=xml)
-
-        if resp.status == httplib.BAD_REQUEST:
-            return False
-        else:
-            return True
-
-    def _to_network(self, element):
-        """
-        Take XML object containing a network description and convert to
-        OpenNebulaNetwork object.
-
-        Take XML representation containing a network description and
-        convert to OpenNebulaNetwork object.
-
-        :return: The newly extracted :class:`OpenNebulaNetwork`.
-        :rtype:  :class:`OpenNebulaNetwork`
-        """
-        return OpenNebulaNetwork(id=element.findtext('ID'),
-                                 name=element.findtext('NAME'),
-                                 address=element.findtext('ADDRESS'),
-                                 size=element.findtext('SIZE'),
-                                 driver=self.connection.driver,
-                                 extra={'public': element.findtext('PUBLIC')})
-
-
-class OpenNebula_3_2_NodeDriver(OpenNebula_3_0_NodeDriver):
-    """
-    OpenNebula.org node driver for OpenNebula.org v3.2.
-    """
-
-    name = 'OpenNebula (v3.2)'
-
-    def reboot_node(self, node):
-        return self.ex_node_action(node, ACTION.REBOOT)
-
-    def list_sizes(self, location=None):
-        """
-        Return list of sizes on a provider.
-
-        @inherits: :class:`NodeDriver.list_sizes`
-
-        :return: List of compute node sizes supported by the cloud provider.
-        :rtype:  ``list`` of :class:`OpenNebulaNodeSize`
-        """
-        return self._to_sizes(self.connection.request('/instance_type').object)
-
-    def _to_sizes(self, object):
-        """
-        Request a list of instance types and convert that list to a list of
-        OpenNebulaNodeSize objects.
-
-        Request a list of instance types from the OpenNebula web interface,
-        and issue a request to convert each XML object representation of an
-        instance type to an OpenNebulaNodeSize object.
-
-        :return: List of instance types.
-        :rtype:  ``list`` of :class:`OpenNebulaNodeSize`
-        """
-        sizes = []
-        size_id = 1
-
-        attributes = [('name', str, None), ('ram', int, 'MEMORY'),
-                      ('cpu', float, None), ('vcpu', float, None),
-                      ('disk', str, None), ('bandwidth', float, None),
-                      ('price', float, None)]
-
-        for element in object.findall('INSTANCE_TYPE'):
-            size_kwargs = {'id': size_id, 'driver': self}
-            values = self._get_attributes_values(attributes=attributes,
-                                                 element=element)
-            size_kwargs.update(values)
-
-            size = OpenNebulaNodeSize(**size_kwargs)
-            sizes.append(size)
-            size_id += 1
-
-        return sizes
-
-    def _get_attributes_values(self, attributes, element):
-        values = {}
-
-        for attribute_name, attribute_type, alias in attributes:
-                key = alias if alias else attribute_name.upper()
-                value = element.findtext(key)
-
-                if value is not None:
-                    value = attribute_type(value)
-
-                values[attribute_name] = value
-
-        return values
-
-
-class OpenNebula_3_6_NodeDriver(OpenNebula_3_2_NodeDriver):
-    """
-    OpenNebula.org node driver for OpenNebula.org v3.6.
-    """
-
-    name = 'OpenNebula (v3.6)'
-
-    def create_volume(self, size, name, location=None, snapshot=None):
-        storage = ET.Element('STORAGE')
-
-        vol_name = ET.SubElement(storage, 'NAME')
-        vol_name.text = name
-
-        vol_type = ET.SubElement(storage, 'TYPE')
-        vol_type.text = 'DATABLOCK'
-
-        description = ET.SubElement(storage, 'DESCRIPTION')
-        description.text = 'Attached storage'
-
-        public = ET.SubElement(storage, 'PUBLIC')
-        public.text = 'NO'
-
-        persistent = ET.SubElement(storage, 'PERSISTENT')
-        persistent.text = 'YES'
-
-        fstype = ET.SubElement(storage, 'FSTYPE')
-        fstype.text = 'ext3'
-
-        vol_size = ET.SubElement(storage, 'SIZE')
-        vol_size.text = str(size)
-
-        xml = ET.tostring(storage)
-        volume = self.connection.request('/storage',
-                                         {'occixml': xml},
-                                         method='POST').object
-
-        return self._to_volume(volume)
-
-    def destroy_volume(self, volume):
-        url = '/storage/%s' % (str(volume.id))
-        resp = self.connection.request(url, method='DELETE')
-
-        return resp.status == httplib.NO_CONTENT
-
-    def attach_volume(self, node, volume, device):
-        action = ET.Element('ACTION')
-
-        perform = ET.SubElement(action, 'PERFORM')
-        perform.text = 'ATTACHDISK'
-
-        params = ET.SubElement(action, 'PARAMS')
-
-        ET.SubElement(params,
-                      'STORAGE',
-                      {'href': '/storage/%s' % (str(volume.id))})
-
-        target = ET.SubElement(params, 'TARGET')
-        target.text = device
-
-        xml = ET.tostring(action)
-
-        url = '/compute/%s/action' % node.id
-
-        resp = self.connection.request(url, method='POST', data=xml)
-        return resp.status == httplib.ACCEPTED
-
-    def _do_detach_volume(self, node_id, disk_id):
-        action = ET.Element('ACTION')
-
-        perform = ET.SubElement(action, 'PERFORM')
-        perform.text = 'DETACHDISK'
-
-        params = ET.SubElement(action, 'PARAMS')
-
-        ET.SubElement(params,
-                      'DISK',
-                      {'id': disk_id})
-
-        xml = ET.tostring(action)
-
-        url = '/compute/%s/action' % node_id
-
-        resp = self.connection.request(url, method='POST', data=xml)
-        return resp.status == httplib.ACCEPTED
-
-    def detach_volume(self, volume):
-        # We need to find the node using this volume
-        for node in self.list_nodes():
-            if type(node.image) is not list:
-                # This node has only one associated image. It is not the one we
-                # are after.
-                continue
-
-            for disk in node.image:
-                if disk.id == volume.id:
-                    # Node found. We can now detach the volume
-                    disk_id = disk.extra['disk_id']
-                    return self._do_detach_volume(node.id, disk_id)
-
-        return False
-
-    def list_volumes(self):
-        return self._to_volumes(self.connection.request('/storage').object)
-
-    def _to_volume(self, storage):
-        return StorageVolume(id=storage.findtext('ID'),
-                             name=storage.findtext('NAME'),
-                             size=int(storage.findtext('SIZE')),
-                             driver=self.connection.driver)
-
-    def _to_volumes(self, object):
-        volumes = []
-        for storage in object.findall('STORAGE'):
-            storage_id = storage.attrib['href'].partition('/storage/')[2]
-
-            volumes.append(self._to_volume(
-                self.connection.request('/storage/%s' % storage_id).object))
-
-        return volumes
-
-
-class OpenNebula_3_8_NodeDriver(OpenNebula_3_6_NodeDriver):
-    """
-    OpenNebula.org node driver for OpenNebula.org v3.8.
-    """
-
-    name = 'OpenNebula (v3.8)'
-    plain_auth = API_PLAIN_AUTH
-
-    def _to_sizes(self, object):
-        """
-        Request a list of instance types and convert that list to a list of
-        OpenNebulaNodeSize objects.
-
-        Request a list of instance types from the OpenNebula web interface,
-        and issue a request to convert each XML object representation of an
-        instance type to an OpenNebulaNodeSize object.
-
-        :return: List of instance types.
-        :rtype:  ``list`` of :class:`OpenNebulaNodeSize`
-        """
-        sizes = []
-        size_id = 1
-
-        attributes = [('name', str, None), ('ram', int, 'MEMORY'),
-                      ('cpu', float, None), ('vcpu', float, None),
-                      ('disk', str, None), ('bandwidth', float, None),
-                      ('price', float, None)]
-
-        for element in object.findall('INSTANCE_TYPE'):
-            element = self.connection.request(
-                ('/instance_type/%s') % (element.attrib['name'])).object
-
-            size_kwargs = {'id': size_id, 'driver': self}
-            values = self._get_attributes_values(attributes=attributes,
-                                                 element=element)
-            size_kwargs.update(values)
-
-            size = OpenNebulaNodeSize(**size_kwargs)
-            sizes.append(size)
-            size_id += 1
-        return sizes
-
-    def _ex_connection_class_kwargs(self):
-        """
-        Set plain_auth as an extra :class:`OpenNebulaConnection_3_8` argument
-
-        :return: ``dict`` of :class:`OpenNebulaConnection_3_8` input arguments
-        """
-
-        return {'plain_auth': self.plain_auth}


[27/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/ecp.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/ecp.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/ecp.py
deleted file mode 100644
index 380b7af..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/ecp.py
+++ /dev/null
@@ -1,385 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-Enomaly ECP driver
-"""
-import time
-import base64
-import os
-import socket
-import binascii
-
-from libcloud.utils.py3 import httplib
-from libcloud.utils.py3 import b
-
-# JSON is included in the standard library starting with Python 2.6.  For 2.5
-# and 2.4, there's a simplejson egg at: http://pypi.python.org/pypi/simplejson
-try:
-    import simplejson as json
-except ImportError:
-    import json
-
-from libcloud.common.base import Response, ConnectionUserAndKey
-from libcloud.compute.base import NodeDriver, NodeSize, NodeLocation
-from libcloud.compute.base import NodeImage, Node
-from libcloud.compute.types import Provider, NodeState, InvalidCredsError
-from libcloud.utils.networking import is_private_subnet
-
-# Defaults
-API_HOST = ''
-API_PORT = (80, 443)
-
-
-class ECPResponse(Response):
-    def success(self):
-        if self.status == httplib.OK or self.status == httplib.CREATED:
-            try:
-                j_body = json.loads(self.body)
-            except ValueError:
-                self.error = "JSON response cannot be decoded."
-                return False
-            if j_body['errno'] == 0:
-                return True
-            else:
-                self.error = "ECP error: %s" % j_body['message']
-                return False
-        elif self.status == httplib.UNAUTHORIZED:
-            raise InvalidCredsError()
-        else:
-            self.error = "HTTP Error Code: %s" % self.status
-        return False
-
-    def parse_error(self):
-        return self.error
-
-    # Interpret the json responses - no error checking required
-    def parse_body(self):
-        return json.loads(self.body)
-
-    def getheaders(self):
-        return self.headers
-
-
-class ECPConnection(ConnectionUserAndKey):
-    """
-    Connection class for the Enomaly ECP driver
-    """
-
-    responseCls = ECPResponse
-    host = API_HOST
-    port = API_PORT
-
-    def add_default_headers(self, headers):
-        # Authentication
-        username = self.user_id
-        password = self.key
-        base64string = base64.encodestring(
-            b('%s:%s' % (username, password)))[:-1]
-        authheader = "Basic %s" % base64string
-        headers['Authorization'] = authheader
-
-        return headers
-
-    def _encode_multipart_formdata(self, fields):
-        """
-        Based on Wade Leftwich's function:
-        http://code.activestate.com/recipes/146306/
-        """
-        # use a random boundary that does not appear in the fields
-        boundary = ''
-        while boundary in ''.join(fields):
-            boundary = binascii.hexlify(os.urandom(16)).decode('utf-8')
-        L = []
-        for i in fields:
-            L.append('--' + boundary)
-            L.append('Content-Disposition: form-data; name="%s"' % i)
-            L.append('')
-            L.append(fields[i])
-        L.append('--' + boundary + '--')
-        L.append('')
-        body = '\r\n'.join(L)
-        content_type = 'multipart/form-data; boundary=%s' % boundary
-        header = {'Content-Type': content_type}
-        return header, body
-
-
-class ECPNodeDriver(NodeDriver):
-    """
-    Enomaly ECP node driver
-    """
-
-    name = "Enomaly Elastic Computing Platform"
-    website = 'http://www.enomaly.com/'
-    type = Provider.ECP
-    connectionCls = ECPConnection
-
-    def list_nodes(self):
-        """
-        Returns a list of all running Nodes
-
-        :rtype: ``list`` of :class:`Node`
-        """
-
-        # Make the call
-        res = self.connection.request('/rest/hosting/vm/list').parse_body()
-
-        # Put together a list of node objects
-        nodes = []
-        for vm in res['vms']:
-            node = self._to_node(vm)
-            if node is not None:
-                nodes.append(node)
-
-        # And return it
-        return nodes
-
-    def _to_node(self, vm):
-        """
-        Turns a (json) dictionary into a Node object.
-        This returns only running VMs.
-        """
-
-        # Check state
-        if not vm['state'] == "running":
-            return None
-
-        # IPs
-        iplist = [interface['ip'] for interface in vm['interfaces'] if
-                  interface['ip'] != '127.0.0.1']
-
-        public_ips = []
-        private_ips = []
-        for ip in iplist:
-            try:
-                socket.inet_aton(ip)
-            except socket.error:
-                # not a valid ip
-                continue
-            if is_private_subnet(ip):
-                private_ips.append(ip)
-            else:
-                public_ips.append(ip)
-
-        # Create the node object
-        n = Node(
-            id=vm['uuid'],
-            name=vm['name'],
-            state=NodeState.RUNNING,
-            public_ips=public_ips,
-            private_ips=private_ips,
-            driver=self,
-        )
-
-        return n
-
-    def reboot_node(self, node):
-        """
-        Shuts down a VM and then starts it again.
-
-        @inherits: :class:`NodeDriver.reboot_node`
-        """
-
-        # Turn the VM off
-        # Black magic to make the POST requests work
-        d = self.connection._encode_multipart_formdata({'action': 'stop'})
-        self.connection.request(
-            '/rest/hosting/vm/%s' % node.id,
-            method='POST',
-            headers=d[0],
-            data=d[1]
-        ).parse_body()
-
-        node.state = NodeState.REBOOTING
-        # Wait for it to turn off and then continue (to turn it on again)
-        while node.state == NodeState.REBOOTING:
-            # Check if it's off.
-            response = self.connection.request(
-                '/rest/hosting/vm/%s' % node.id
-            ).parse_body()
-            if response['vm']['state'] == 'off':
-                node.state = NodeState.TERMINATED
-            else:
-                time.sleep(5)
-
-        # Turn the VM back on.
-        # Black magic to make the POST requests work
-        d = self.connection._encode_multipart_formdata({'action': 'start'})
-        self.connection.request(
-            '/rest/hosting/vm/%s' % node.id,
-            method='POST',
-            headers=d[0],
-            data=d[1]
-        ).parse_body()
-
-        node.state = NodeState.RUNNING
-        return True
-
-    def destroy_node(self, node):
-        """
-        Shuts down and deletes a VM.
-
-        @inherits: :class:`NodeDriver.destroy_node`
-        """
-
-        # Shut down first
-        # Black magic to make the POST requests work
-        d = self.connection._encode_multipart_formdata({'action': 'stop'})
-        self.connection.request(
-            '/rest/hosting/vm/%s' % node.id,
-            method='POST',
-            headers=d[0],
-            data=d[1]
-        ).parse_body()
-
-        # Ensure there was no application level error
-        node.state = NodeState.PENDING
-        # Wait for the VM to turn off before continuing
-        while node.state == NodeState.PENDING:
-            # Check if it's off.
-            response = self.connection.request(
-                '/rest/hosting/vm/%s' % node.id
-            ).parse_body()
-            if response['vm']['state'] == 'off':
-                node.state = NodeState.TERMINATED
-            else:
-                time.sleep(5)
-
-        # Delete the VM
-        # Black magic to make the POST requests work
-        d = self.connection._encode_multipart_formdata({'action': 'delete'})
-        self.connection.request(
-            '/rest/hosting/vm/%s' % (node.id),
-            method='POST',
-            headers=d[0],
-            data=d[1]
-        ).parse_body()
-
-        return True
-
-    def list_images(self, location=None):
-        """
-        Returns a list of all package templates aka appliances aka images.
-
-        @inherits: :class:`NodeDriver.list_images`
-        """
-
-        # Make the call
-        response = self.connection.request(
-            '/rest/hosting/ptemplate/list').parse_body()
-
-        # Turn the response into an array of NodeImage objects
-        images = []
-        for ptemplate in response['packages']:
-            images.append(NodeImage(
-                id=ptemplate['uuid'],
-                name='%s: %s' % (ptemplate['name'], ptemplate['description']),
-                driver=self,)
-            )
-
-        return images
-
-    def list_sizes(self, location=None):
-        """
-        Returns a list of all hardware templates
-
-        @inherits: :class:`NodeDriver.list_sizes`
-        """
-
-        # Make the call
-        response = self.connection.request(
-            '/rest/hosting/htemplate/list').parse_body()
-
-        # Turn the response into an array of NodeSize objects
-        sizes = []
-        for htemplate in response['templates']:
-            sizes.append(NodeSize(
-                id=htemplate['uuid'],
-                name=htemplate['name'],
-                ram=htemplate['memory'],
-                disk=0,  # Disk is independent of hardware template.
-                bandwidth=0,  # There is no way to keep track of bandwidth.
-                price=0,  # The billing system is external.
-                driver=self,)
-            )
-
-        return sizes
-
-    def list_locations(self):
-        """
-        This feature does not exist in ECP. Returns hard coded dummy location.
-
-        :rtype: ``list`` of :class:`NodeLocation`
-        """
-        return [NodeLocation(id=1,
-                             name="Cloud",
-                             country='',
-                             driver=self),
-                ]
-
-    def create_node(self, **kwargs):
-        """
-        Creates a virtual machine.
-
-        :keyword    name:   String with a name for this new node (required)
-        :type       name:   ``str``
-
-        :keyword    size:   The size of resources allocated to this node .
-                            (required)
-        :type       size:   :class:`NodeSize`
-
-        :keyword    image:  OS Image to boot on node. (required)
-        :type       image:  :class:`NodeImage`
-
-        :rtype: :class:`Node`
-        """
-
-        # Find out what network to put the VM on.
-        res = self.connection.request(
-            '/rest/hosting/network/list').parse_body()
-
-        # Use the first / default network because there is no way to specific
-        # which one
-        network = res['networks'][0]['uuid']
-
-        # Prepare to make the VM
-        data = {
-            'name': str(kwargs['name']),
-            'package': str(kwargs['image'].id),
-            'hardware': str(kwargs['size'].id),
-            'network_uuid': str(network),
-            'disk': ''
-        }
-
-        # Black magic to make the POST requests work
-        d = self.connection._encode_multipart_formdata(data)
-        response = self.connection.request(
-            '/rest/hosting/vm/',
-            method='PUT',
-            headers=d[0],
-            data=d[1]
-        ).parse_body()
-
-        # Create a node object and return it.
-        n = Node(
-            id=response['machine_id'],
-            name=data['name'],
-            state=NodeState.PENDING,
-            public_ips=[],
-            private_ips=[],
-            driver=self,
-        )
-
-        return n

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/ecs.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/ecs.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/ecs.py
deleted file mode 100644
index c9d53f8..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/ecs.py
+++ /dev/null
@@ -1,1533 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-Node driver for Aliyun.
-"""
-
-try:
-    import simplejson as json
-except ImportError:
-    import json
-import time
-
-from libcloud.common.aliyun import AliyunXmlResponse, SignedAliyunConnection
-from libcloud.common.types import LibcloudError
-from libcloud.compute.base import Node, NodeDriver, NodeImage, NodeSize, \
-    StorageVolume, VolumeSnapshot, NodeLocation
-from libcloud.compute.types import NodeState, StorageVolumeState, \
-    VolumeSnapshotState
-from libcloud.utils.py3 import _real_unicode as u
-from libcloud.utils.xml import findall, findattr, findtext
-
-__all__ = [
-    'DiskCategory',
-    'InternetChargeType',
-    'ECS_API_VERSION',
-    'ECSDriver',
-    'ECSSecurityGroup',
-    'ECSZone'
-]
-
-ECS_API_VERSION = '2014-05-26'
-ECS_API_ENDPOINT = 'ecs.aliyuncs.com'
-DEFAULT_SIGNATURE_VERSION = '1.0'
-
-
-def _parse_bool(value):
-    if isinstance(value, bool):
-        return value
-    if u(value).lower() == 'true':
-        return True
-    return False
-
-
-"""
-Define the extra dictionary for specific resources
-"""
-RESOURCE_EXTRA_ATTRIBUTES_MAP = {
-    'node': {
-        'description': {
-            'xpath': 'Description',
-            'transform_func': u
-        },
-        'image_id': {
-            'xpath': 'ImageId',
-            'transform_func': u
-        },
-        'zone_id': {
-            'xpath': 'ZoneId',
-            'transform_func': u
-        },
-        'instance_type': {
-            'xpath': 'InstanceType',
-            'transform_func': u
-        },
-        'instance_type_family': {
-            'xpath': 'InstanceTypeFamily',
-            'transform_func': u
-        },
-        'hostname': {
-            'xpath': 'HostName',
-            'transform_func': u
-        },
-        'serial_number': {
-            'xpath': 'SerialNumber',
-            'transform_func': u
-        },
-        'internet_charge_type': {
-            'xpath': 'InternetChargeType',
-            'transform_func': u
-        },
-        'creation_time': {
-            'xpath': 'CreationTime',
-            'transform_func': u
-        },
-        'instance_network_type': {
-            'xpath': 'InstanceNetworkType',
-            'transform_func': u
-        },
-        'instance_charge_type': {
-            'xpath': 'InstanceChargeType',
-            'transform_func': u
-        },
-        'device_available': {
-            'xpath': 'DeviceAvailable',
-            'transform_func': u
-        },
-        'io_optimized': {
-            'xpath': 'IoOptimized',
-            'transform_func': u
-        },
-        'expired_time': {
-            'xpath': 'ExpiredTime',
-            'transform_func': u
-        }
-    },
-    'vpc_attributes': {
-        'vpc_id': {
-            'xpath': 'VpcId',
-            'transform_func': u
-        },
-        'vswitch_id': {
-            'xpath': 'VSwitchId',
-            'transform_func': u
-        },
-        'private_ip_address': {
-            'xpath': 'PrivateIpAddress/IpAddress',
-            'transform_func': u
-        },
-        'nat_ip_address': {
-            'xpath': 'NatIpAddress',
-            'transform_func': u
-        }
-    },
-    'eip_address_associate': {
-        'allocation_id': {
-            'xpath': 'AllocationId',
-            'transform_func': u
-        },
-        'ip_address': {
-            'xpath': 'IpAddress',
-            'transform_func': u
-        },
-        'bandwidth': {
-            'xpath': 'Bandwidth',
-            'transform_func': int
-        },
-        'internet_charge_type': {
-            'xpath': 'InternetChargeType',
-            'transform_func': u
-        }
-    },
-    'operation_locks': {
-        'lock_reason': {
-            'xpath': 'LockReason',
-            'transform_func': u
-        }
-    },
-    'volume': {
-        'region_id': {
-            'xpath': 'RegionId',
-            'transform_func': u
-        },
-        'zone_id': {
-            'xpath': 'ZoneId',
-            'transform_func': u
-        },
-        'description': {
-            'xpath': 'Description',
-            'transform_func': u
-        },
-        'type': {
-            'xpath': 'Type',
-            'transform_func': u
-        },
-        'category': {
-            'xpath': 'Category',
-            'transform_func': u
-        },
-        'image_id': {
-            'xpath': 'ImageId',
-            'transform_func': u
-        },
-        'source_snapshot_id': {
-            'xpath': 'SourceSnapshotId',
-            'transform_func': u
-        },
-        'product_code': {
-            'xpath': 'ProductCode',
-            'transform_func': u
-        },
-        'portable': {
-            'xpath': 'Portable',
-            'transform_func': _parse_bool
-        },
-        'instance_id': {
-            'xpath': 'InstanceId',
-            'transform_func': u
-        },
-        'device': {
-            'xpath': 'Device',
-            'transform_func': u
-        },
-        'delete_with_instance': {
-            'xpath': 'DeleteWithInstance',
-            'transform_func': _parse_bool
-        },
-        'enable_auto_snapshot': {
-            'xpath': 'EnableAutoSnapshot',
-            'transform_func': _parse_bool
-        },
-        'creation_time': {
-            'xpath': 'CreationTime',
-            'transform_func': u
-        },
-        'attached_time': {
-            'xpath': 'AttachedTime',
-            'transform_func': u
-        },
-        'detached_time': {
-            'xpath': 'DetachedTime',
-            'transform_func': u
-        },
-        'disk_charge_type': {
-            'xpath': 'DiskChargeType',
-            'transform_func': u
-        }
-    },
-    'snapshot': {
-        'snapshot_name': {
-            'xpath': 'SnapshotName',
-            'transform_func': u
-        },
-        'description': {
-            'xpath': 'Description',
-            'transform_func': u
-        },
-        'progress': {
-            'xpath': 'Progress',
-            'transform_func': u
-        },
-        'source_disk_id': {
-            'xpath': 'SourceDiskId',
-            'transform_func': u
-        },
-        'source_disk_size': {
-            'xpath': 'SourceDiskSize',
-            'transform_func': int
-        },
-        'source_disk_type': {
-            'xpath': 'SourceDiskType',
-            'transform_func': u
-        },
-        'product_code': {
-            'xpath': 'ProductCode',
-            'transform_func': u
-        },
-        'usage': {
-            'xpath': 'Usage',
-            'transform_func': u
-        }
-    },
-    'image': {
-        'image_version': {
-            'xpath': 'ImageVersion',
-            'transform_func': u
-        },
-        'os_type': {
-            'xpath': 'OSType',
-            'transform_func': u
-        },
-        'platform': {
-            'xpath': 'Platform',
-            'transform_func': u
-        },
-        'architecture': {
-            'xpath': 'Architecture',
-            'transform_func': u
-        },
-        'description': {
-            'xpath': 'Description',
-            'transform_func': u
-        },
-        'size': {
-            'xpath': 'Size',
-            'transform_func': int
-        },
-        'image_owner_alias': {
-            'xpath': 'ImageOwnerAlias',
-            'transform_func': u
-        },
-        'os_name': {
-            'xpath': 'OSName',
-            'transform_func': u
-        },
-        'product_code': {
-            'xpath': 'ProductCode',
-            'transform_func': u
-        },
-        'is_subscribed': {
-            'xpath': 'IsSubscribed',
-            'transform_func': _parse_bool
-        },
-        'progress': {
-            'xpath': 'Progress',
-            'transform_func': u
-        },
-        'creation_time': {
-            'xpath': 'CreationTime',
-            'transform_func': u
-        },
-        'usage': {
-            'xpath': 'Usage',
-            'transform_func': u
-        },
-        'is_copied': {
-            'xpath': 'IsCopied',
-            'transform_func': _parse_bool
-        }
-    },
-    'disk_device_mapping': {
-        'snapshot_id': {
-            'xpath': 'SnapshotId',
-            'transform_func': u
-        },
-        'size': {
-            'xpath': 'Size',
-            'transform_func': int
-        },
-        'device': {
-            'xpath': 'Device',
-            'transform_func': u
-        },
-        'format': {
-            'xpath': 'Format',
-            'transform_func': u
-        },
-        'import_oss_bucket': {
-            'xpath': 'ImportOSSBucket',
-            'transform_func': u
-        },
-        'import_oss_object': {
-            'xpath': 'ImportOSSObject',
-            'transform_func': u
-        }
-    }
-}
-
-
-class ECSConnection(SignedAliyunConnection):
-    """
-    Represents a single connection to the Aliyun ECS Endpoint.
-    """
-
-    version = ECS_API_VERSION
-    host = ECS_API_ENDPOINT
-    responseCls = AliyunXmlResponse
-    service_name = 'ecs'
-
-
-class ECSSecurityGroup(object):
-    """
-    Security group used to control nodes internet and intranet accessibility.
-    """
-    def __init__(self, id, name, description=None, driver=None, vpc_id=None,
-                 creation_time=None):
-        self.id = id
-        self.name = name
-        self.description = description
-        self.driver = driver
-        self.vpc_id = vpc_id
-        self.creation_time = creation_time
-
-    def __repr__(self):
-        return ('<ECSSecurityGroup: id=%s, name=%s, driver=%s ...>' %
-                (self.id, self.name, self.driver.name))
-
-
-class ECSZone(object):
-    """
-    ECSZone used to represent an availability zone in a region.
-    """
-    def __init__(self, id, name, driver=None,
-                 available_resource_types=None,
-                 available_instance_types=None,
-                 available_disk_categories=None):
-        self.id = id
-        self.name = name
-        self.driver = driver
-        self.available_resource_types = available_resource_types
-        self.available_instance_types = available_instance_types
-        self.available_disk_categories = available_disk_categories
-
-    def __repr__(self):
-        return ('<ECSZone: id=%s, name=%s, driver=%s>' %
-                (self.id, self.name, self.driver))
-
-
-class InternetChargeType(object):
-    """
-    Internet connection billing types for Aliyun Nodes.
-    """
-    BY_BANDWIDTH = 'PayByBandwidth'
-    BY_TRAFFIC = 'PayByTraffic'
-
-
-class DiskCategory(object):
-    """
-    Enum defined disk types supported by Aliyun system and data disks.
-    """
-    CLOUD = 'cloud'
-    CLOUD_EFFICIENCY = 'cloud_efficiency'
-    CLOUD_SSD = 'cloud_ssd'
-    EPHEMERAL_SSD = 'ephemeral_ssd'
-
-
-class Pagination(object):
-    """
-    Pagination used to describe the multiple pages results.
-    """
-    def __init__(self, total, size, current):
-        """
-        Create a pagination.
-
-        :param total: the total count of the results
-        :param size: the page size of each page
-        :param current: the current page number, 1-based
-        """
-        self.total = total
-        self.size = size
-        self.current = current
-
-    def next(self):
-        """
-        Switch to the next page.
-        :return: the new pagination or None when no more page
-        :rtype: ``Pagination``
-        """
-        if self.total is None or (self.size * self.current >= self.total):
-            return None
-        self.current += 1
-        return self
-
-    def to_dict(self):
-        return {'PageNumber': self.current,
-                'PageSize': self.size}
-
-    def __repr__(self):
-        return ('<Pagination total=%d, size=%d, current page=%d>' %
-                (self.total, self.size, self.current))
-
-
-class ECSDriver(NodeDriver):
-    """
-    Aliyun ECS node driver.
-
-    Used for Aliyun ECS service.
-
-    TODO:
-    Create public IP address
-    Get guest OS root password
-    Adjust internet bandwidth settings
-    Manage security groups and rules
-    """
-
-    name = 'Aliyun ECS'
-    website = 'https://www.aliyun.com/product/ecs'
-    connectionCls = ECSConnection
-    features = {'create_node': ['password']}
-    namespace = None
-    path = '/'
-
-    internet_charge_types = InternetChargeType
-    disk_categories = DiskCategory
-
-    NODE_STATE_MAPPING = {
-        'Starting': NodeState.PENDING,
-        'Running': NodeState.RUNNING,
-        'Stopping': NodeState.PENDING,
-        'Stopped': NodeState.STOPPED
-    }
-
-    VOLUME_STATE_MAPPING = {
-        'In_use': StorageVolumeState.INUSE,
-        'Available': StorageVolumeState.AVAILABLE,
-        'Attaching': StorageVolumeState.ATTACHING,
-        'Detaching': StorageVolumeState.INUSE,
-        'Creating': StorageVolumeState.CREATING,
-        'ReIniting': StorageVolumeState.CREATING}
-
-    SNAPSHOT_STATE_MAPPING = {
-        'progressing': VolumeSnapshotState.CREATING,
-        'accomplished': VolumeSnapshotState.AVAILABLE,
-        'failed': VolumeSnapshotState.ERROR}
-
-    def list_nodes(self, ex_node_ids=None, ex_filters=None):
-        """
-        List all nodes.
-
-        @inherits: :class:`NodeDriver.create_node`
-
-        :keyword  ex_node_ids: a list of node's ids used to filter nodes.
-                               Only the nodes which's id in this list
-                               will be returned.
-        :type   ex_node_ids: ``list`` of ``str``
-        :keyword  ex_filters: node attribute and value pairs to filter nodes.
-                              Only the nodes which matchs all the pairs will
-                              be returned.
-                              If the filter attribute need a json array value,
-                              use ``list`` object, the driver will convert it.
-        :type   ex_filters: ``dict``
-        """
-
-        params = {'Action': 'DescribeInstances',
-                  'RegionId': self.region}
-
-        if ex_node_ids:
-            if isinstance(ex_node_ids, list):
-                params['InstanceIds'] = self._list_to_json_array(ex_node_ids)
-            else:
-                raise AttributeError('ex_node_ids should be a list of '
-                                     'node ids.')
-
-        if ex_filters:
-            if isinstance(ex_filters, dict):
-                params.update(ex_filters)
-            else:
-                raise AttributeError('ex_filters should be a dict of '
-                                     'node attributes.')
-
-        nodes = self._request_multiple_pages(self.path, params,
-                                             self._to_nodes)
-        return nodes
-
-    def list_sizes(self, location=None):
-        params = {'Action': 'DescribeInstanceTypes'}
-
-        resp_body = self.connection.request(self.path, params).object
-        size_elements = findall(resp_body, 'InstanceTypes/InstanceType',
-                                namespace=self.namespace)
-        sizes = [self._to_size(each) for each in size_elements]
-        return sizes
-
-    def list_locations(self):
-        params = {'Action': 'DescribeRegions'}
-
-        resp_body = self.connection.request(self.path, params).object
-        location_elements = findall(resp_body, 'Regions/Region',
-                                    namespace=self.namespace)
-        locations = [self._to_location(each) for each in location_elements]
-        return locations
-
-    def create_node(self, name, size, image, auth=None,
-                    ex_security_group_id=None, ex_description=None,
-                    ex_internet_charge_type=None,
-                    ex_internet_max_bandwidth_out=None,
-                    ex_internet_max_bandwidth_in=None,
-                    ex_hostname=None, ex_io_optimized=None,
-                    ex_system_disk=None, ex_data_disks=None,
-                    ex_vswitch_id=None, ex_private_ip_address=None,
-                    ex_client_token=None, **kwargs):
-        """
-        @inherits: :class:`NodeDriver.create_node`
-
-        :param name: The name for this new node (required)
-        :type name: ``str``
-
-        :param image: The image to use when creating this node (required)
-        :type image: `NodeImage`
-
-        :param size: The size of the node to create (required)
-        :type size: `NodeSize`
-
-        :keyword auth: Initial authentication information for the node
-                       (optional)
-        :type auth: :class:`NodeAuthSSHKey` or :class:`NodeAuthPassword`
-
-        :keyword ex_security_group_id: The id of the security group the
-                                       new created node is attached to.
-                                       (required)
-        :type ex_security_group_id: ``str``
-
-        :keyword ex_description: A description string for this node (optional)
-        :type ex_description: ``str``
-
-        :keyword ex_internet_charge_type: The internet charge type (optional)
-        :type ex_internet_charge_type: a ``str`` of 'PayByTraffic'
-                                       or 'PayByBandwidth'
-
-        :keyword ex_internet_max_bandwidth_out: The max output bandwidth,
-                                                in Mbps (optional)
-                                                Required for 'PayByTraffic'
-                                                internet charge type
-        :type ex_internet_max_bandwidth_out: a ``int`` in range [0, 100]
-                                             a ``int`` in range [1, 100] for
-                                             'PayByTraffic' internet charge
-                                             type
-
-        :keyword ex_internet_max_bandwidth_in: The max input bandwidth,
-                                               in Mbps (optional)
-        :type ex_internet_max_bandwidth_in: a ``int`` in range [1, 200]
-                                            default to 200 in server side
-
-        :keyword ex_hostname: The hostname for the node (optional)
-        :type ex_hostname: ``str``
-
-        :keyword ex_io_optimized: Whether the node is IO optimized (optional)
-        :type ex_io_optimized: ``boll``
-
-        :keyword ex_system_disk: The system disk for the node (optional)
-        :type ex_system_disk: ``dict``
-
-        :keyword ex_data_disks: The data disks for the node (optional)
-        :type ex_data_disks: a `list` of `dict`
-
-        :keyword ex_vswitch_id: The id of vswitch for a VPC type node
-                                (optional)
-        :type ex_vswitch_id: ``str``
-
-        :keyword ex_private_ip_address: The IP address in private network
-                                        (optional)
-        :type ex_private_ip_address: ``str``
-
-        :keyword ex_client_token: A token generated by client to keep
-                                  requests idempotency (optional)
-        :type keyword ex_client_token: ``str``
-        """
-
-        params = {'Action': 'CreateInstance',
-                  'RegionId': self.region,
-                  'ImageId': image.id,
-                  'InstanceType': size.id,
-                  'InstanceName': name}
-
-        if not ex_security_group_id:
-            raise AttributeError('ex_security_group_id is mandatory')
-        params['SecurityGroupId'] = ex_security_group_id
-
-        if ex_description:
-            params['Description'] = ex_description
-
-        inet_params = self._get_internet_related_params(
-            ex_internet_charge_type,
-            ex_internet_max_bandwidth_in,
-            ex_internet_max_bandwidth_out)
-        if inet_params:
-            params.update(inet_params)
-
-        if ex_hostname:
-            params['HostName'] = ex_hostname
-
-        if auth:
-            auth = self._get_and_check_auth(auth)
-            params['Password'] = auth.password
-
-        if ex_io_optimized is not None:
-            optimized = ex_io_optimized
-            if not isinstance(optimized, bool):
-                optimized = str(optimized).lower() == 'true'
-            params['IoOptimized'] = 'true' if optimized else 'false'
-
-        if ex_system_disk:
-            system_disk = self._get_system_disk(ex_system_disk)
-            if system_disk:
-                params.update(system_disk)
-
-        if ex_data_disks:
-            data_disks = self._get_data_disks(ex_data_disks)
-            if data_disks:
-                params.update(data_disks)
-
-        if ex_vswitch_id:
-            params['VSwitchId'] = ex_vswitch_id
-
-        if ex_private_ip_address:
-            if not ex_vswitch_id:
-                raise AttributeError('must provide ex_private_ip_address  '
-                                     'and ex_vswitch_id at the same time')
-            else:
-                params['PrivateIpAddress'] = ex_private_ip_address
-
-        if ex_client_token:
-            params['ClientToken'] = ex_client_token
-
-        resp = self.connection.request(self.path, params=params)
-        node_id = findtext(resp.object, xpath='InstanceId',
-                           namespace=self.namespace)
-        nodes = self.list_nodes(ex_node_ids=[node_id])
-        if len(nodes) != 1:
-            raise LibcloudError('could not find the new created node '
-                                'with id %s. ' % node_id,
-                                driver=self)
-        node = nodes[0]
-        self.ex_start_node(node)
-        self._wait_until_state(nodes, NodeState.RUNNING)
-        return node
-
-    def reboot_node(self, node, ex_force_stop=False):
-        """
-        Reboot the given node
-
-        @inherits :class:`NodeDriver.reboot_node`
-
-        :keyword ex_force_stop: if ``True``, stop node force (maybe lose data)
-                                otherwise, stop node normally,
-                                default to ``False``
-        :type ex_force_stop: ``bool``
-        """
-        params = {'Action': 'RebootInstance',
-                  'InstanceId': node.id,
-                  'ForceStop': u(ex_force_stop).lower()}
-        resp = self.connection.request(self.path, params=params)
-        return resp.success() and \
-            self._wait_until_state([node], NodeState.RUNNING)
-
-    def destroy_node(self, node):
-        nodes = self.list_nodes(ex_node_ids=[node.id])
-        if len(nodes) != 1 and node.id != nodes[0].id:
-            raise LibcloudError('could not find the node with id %s.'
-                                % node.id)
-        current = nodes[0]
-        if current.state == NodeState.RUNNING:
-            # stop node first
-            self.ex_stop_node(node)
-            self._wait_until_state(nodes, NodeState.STOPPED)
-        params = {'Action': 'DeleteInstance',
-                  'InstanceId': node.id}
-        resp = self.connection.request(self.path, params)
-        return resp.success()
-
-    def ex_start_node(self, node):
-        """
-        Start node to running state.
-
-        :param node: the ``Node`` object to start
-        :type node: ``Node``
-
-        :return: starting operation result.
-        :rtype: ``bool``
-        """
-        params = {'Action': 'StartInstance',
-                  'InstanceId': node.id}
-        resp = self.connection.request(self.path, params)
-        return resp.success() and \
-            self._wait_until_state([node], NodeState.RUNNING)
-
-    def ex_stop_node(self, node, ex_force_stop=False):
-        """
-        Stop a running node.
-
-        :param node: The node to stop
-        :type node: :class:`Node`
-
-        :keyword ex_force_stop: if ``True``, stop node force (maybe lose data)
-                                otherwise, stop node normally,
-                                default to ``False``
-        :type ex_force_stop: ``bool``
-
-        :return: stopping operation result.
-        :rtype: ``bool``
-        """
-        params = {'Action': 'StopInstance',
-                  'InstanceId': node.id,
-                  'ForceStop': u(ex_force_stop).lower()}
-        resp = self.connection.request(self.path, params)
-        return resp.success() and \
-            self._wait_until_state([node], NodeState.STOPPED)
-
-    def ex_list_security_groups(self, ex_filters=None):
-        """
-        List security groups in the current region.
-
-        :keyword ex_filters: security group attributes to filter results.
-        :type ex_filters: ``dict``
-
-        :return: a list of defined security groups
-        :rtype: ``list`` of ``ECSSecurityGroup``
-        """
-        params = {'Action': 'DescribeSecurityGroups',
-                  'RegionId': self.region}
-
-        if ex_filters and isinstance(ex_filters, dict):
-            ex_filters.update(params)
-            params = ex_filters
-
-        def _parse_response(resp_object):
-            sg_elements = findall(resp_object, 'SecurityGroups/SecurityGroup',
-                                  namespace=self.namespace)
-            sgs = [self._to_security_group(el) for el in sg_elements]
-            return sgs
-        return self._request_multiple_pages(self.path, params,
-                                            _parse_response)
-
-    def ex_list_zones(self, region_id=None):
-        """
-        List availability zones in the given region or the current region.
-
-        :keyword region_id: the id of the region to query zones from
-        :type region_id: ``str``
-
-        :return: list of zones
-        :rtype: ``list`` of ``ECSZone``
-        """
-        params = {'Action': 'DescribeZones'}
-        if region_id:
-            params['RegionId'] = region_id
-        else:
-            params['RegionId'] = self.region
-        resp_body = self.connection.request(self.path, params).object
-        zone_elements = findall(resp_body, 'Zones/Zone',
-                                namespace=self.namespace)
-        zones = [self._to_zone(el) for el in zone_elements]
-        return zones
-
-    ##
-    # Volume and snapshot management methods
-    ##
-
-    def list_volumes(self, ex_volume_ids=None, ex_filters=None):
-        """
-        List all volumes.
-
-        @inherits: :class:`NodeDriver.list_volumes`
-
-        :keyword ex_volume_ids: a list of volume's ids used to filter volumes.
-                                Only the volumes which's id in this list
-                                will be returned.
-        :type ex_volume_ids: ``list`` of ``str``
-
-        :keyword ex_filters: volume attribute and value pairs to filter
-                             volumes. Only the volumes which matchs all will
-                             be returned.
-                             If the filter attribute need a json array value,
-                             use ``list`` object, the driver will convert it.
-        :type ex_filters: ``dict``
-        """
-        params = {'Action': 'DescribeDisks',
-                  'RegionId': self.region}
-
-        if ex_volume_ids:
-            if isinstance(ex_volume_ids, list):
-                params['DiskIds'] = self._list_to_json_array(ex_volume_ids)
-            else:
-                raise AttributeError('ex_volume_ids should be a list of '
-                                     'volume ids.')
-
-        if ex_filters:
-            if not isinstance(ex_filters, dict):
-                raise AttributeError('ex_filters should be a dict of '
-                                     'volume attributes.')
-            else:
-                for key in ex_filters.keys():
-                    params[key] = ex_filters[key]
-
-        def _parse_response(resp_object):
-            disk_elements = findall(resp_object, 'Disks/Disk',
-                                    namespace=self.namespace)
-            volumes = [self._to_volume(each) for each in disk_elements]
-            return volumes
-        return self._request_multiple_pages(self.path, params,
-                                            _parse_response)
-
-    def list_volume_snapshots(self, volume, ex_snapshot_ids=[],
-                              ex_filters=None):
-        """
-        List snapshots for a storage volume.
-
-        @inherites :class:`NodeDriver.list_volume_snapshots`
-
-        :keyword ex_snapshot_ids: a list of snapshot ids to filter the
-                                  snapshots returned.
-        :type ex_snapshot_ids: ``list`` of ``str``
-
-        :keyword ex_filters: snapshot attribute and value pairs to filter
-                             snapshots. Only the snapshot which matchs all
-                             the pairs will be returned.
-                             If the filter attribute need a json array value,
-                             use ``list`` object, the driver will convert it.
-        :type ex_filters: ``dict``
-        """
-        params = {'Action': 'DescribeSnapshots',
-                  'RegionId': self.region}
-
-        if volume:
-            params['DiskId'] = volume.id
-        if ex_snapshot_ids and isinstance(ex_snapshot_ids, list):
-            params['SnapshotIds'] = self._list_to_json_array(ex_snapshot_ids)
-        if ex_filters and isinstance(ex_filters, dict):
-            for key in ex_filters.keys():
-                params[key] = ex_filters[key]
-
-        def _parse_response(resp_body):
-            snapshot_elements = findall(resp_body, 'Snapshots/Snapshot',
-                                        namespace=self.namespace)
-            snapshots = [self._to_snapshot(each) for each in snapshot_elements]
-            return snapshots
-
-        return self._request_multiple_pages(self.path, params,
-                                            _parse_response)
-
-    def create_volume(self, size, name, location=None, snapshot=None,
-                      ex_zone_id=None, ex_description=None,
-                      ex_disk_category=None, ex_client_token=None):
-        """
-        Create a new volume.
-
-        @inherites :class:`NodeDriver.create_volume`
-
-        :keyword ex_zone_id: the availability zone id (required)
-        :type ex_zone_id: ``str``
-
-        :keyword ex_description: volume description
-        :type ex_description: ``unicode``
-
-        :keyword ex_disk_category: disk category for data disk
-        :type ex_disk_category: ``str``
-
-        :keyword ex_client_token: a token generated by client to identify
-                                  each request.
-        :type ex_client_token: ``str``
-        """
-        params = {'Action': 'CreateDisk',
-                  'RegionId': self.region,
-                  'DiskName': name,
-                  'Size': size}
-        if ex_zone_id is None:
-            raise AttributeError('ex_zone_id is required')
-        params['ZoneId'] = ex_zone_id
-
-        if snapshot is not None and isinstance(snapshot, VolumeSnapshot):
-            params['SnapshotId'] = snapshot.id
-        if ex_description:
-            params['Description'] = ex_description
-        if ex_disk_category:
-            params['DiskCategory'] = ex_disk_category
-        if ex_client_token:
-            params['ClientToken'] = ex_client_token
-        resp = self.connection.request(self.path, params).object
-        volume_id = findtext(resp, 'DiskId', namespace=self.namespace)
-        volumes = self.list_volumes(ex_volume_ids=[volume_id])
-        if len(volumes) != 1:
-            raise LibcloudError('could not find the new create volume '
-                                'with id %s.' % volume_id,
-                                driver=self)
-        return volumes[0]
-
-    def create_volume_snapshot(self, volume, name=None, ex_description=None,
-                               ex_client_token=None):
-        """
-        Creates a snapshot of the storage volume.
-
-        @inherits :class:`NodeDriver.create_volume_snapshot`
-
-        :keyword ex_description: description of the snapshot.
-        :type ex_description: ``unicode``
-
-        :keyword ex_client_token: a token generated by client to identify
-                                  each request.
-        :type ex_client_token: ``str``
-        """
-        params = {'Action': 'CreateSnapshot',
-                  'DiskId': volume.id}
-        if name:
-            params['SnapshotName'] = name
-        if ex_description:
-            params['Description'] = ex_description
-        if ex_client_token:
-            params['ClientToken'] = ex_client_token
-
-        snapshot_elements = self.connection.request(self.path, params).object
-        snapshot_id = findtext(snapshot_elements, 'SnapshotId',
-                               namespace=self.namespace)
-        snapshots = self.list_volume_snapshots(volume=None,
-                                               ex_snapshot_ids=[snapshot_id])
-        if len(snapshots) != 1:
-            raise LibcloudError('could not find new created snapshot with '
-                                'id %s.' % snapshot_id, driver=self)
-        return snapshots[0]
-
-    def attach_volume(self, node, volume, device=None,
-                      ex_delete_with_instance=None):
-        """
-        Attaches volume to node.
-
-        @inherits :class:`NodeDriver.attach_volume`
-
-        :keyword device: device path allocated for this attached volume
-        :type device: ``str`` between /dev/xvdb to xvdz,
-                      if empty, allocated by the system
-        :keyword ex_delete_with_instance: if to delete this volume when the
-                                          instance is deleted.
-        :type ex_delete_with_instance: ``bool``
-        """
-        params = {'Action': 'AttachDisk',
-                  'InstanceId': node.id,
-                  'DiskId': volume.id}
-
-        if device:
-            params['Device'] = device
-        if ex_delete_with_instance:
-            params['DeleteWithInstance'] = \
-                str(bool(ex_delete_with_instance)).lower()
-        resp = self.connection.request(self.path, params)
-        return resp.success()
-
-    def detach_volume(self, volume, ex_instance_id=None):
-        """
-        Detaches a volume from a node.
-
-        @inherits :class:`NodeDriver.detach_volume`
-
-        :keyword ex_instance_id: the id of the instance from which the volume
-                                 is detached.
-        :type ex_instance_id: ``str``
-        """
-        params = {'Action': 'DetachDisk',
-                  'DiskId': volume.id}
-
-        if ex_instance_id:
-            params['InstanceId'] = ex_instance_id
-        else:
-            volumes = self.list_volumes(ex_volume_ids=[volume.id])
-            if len(volumes) != 1:
-                raise AttributeError('could not find the instance id '
-                                     'the volume %s attached to, '
-                                     'ex_instance_id is required.' %
-                                     volume.id)
-            params['InstanceId'] = volumes[0].extra['instance_id']
-
-        resp = self.connection.request(self.path, params)
-        return resp.success()
-
-    def destroy_volume(self, volume):
-        params = {'Action': 'DeleteDisk',
-                  'DiskId': volume.id}
-        volumes = self.list_volumes(ex_volume_ids=[volume.id])
-        if len(volumes) != 1:
-            raise LibcloudError('could not find the volume with id %s.' %
-                                volume.id,
-                                driver=self)
-        if volumes[0].state != StorageVolumeState.AVAILABLE:
-            raise LibcloudError('only volume in AVAILABLE state could be '
-                                'destroyed.', driver=self)
-        resp = self.connection.request(self.path, params)
-        return resp.success()
-
-    def destroy_volume_snapshot(self, snapshot):
-        params = {'Action': 'DeleteSnapshot'}
-
-        if snapshot and isinstance(snapshot, VolumeSnapshot):
-            params['SnapshotId'] = snapshot.id
-        else:
-            raise AttributeError('snapshot is required and must be a '
-                                 'VolumeSnapshot')
-        resp = self.connection.request(self.path, params)
-        return resp.success()
-
-    ##
-    # Image management methods
-    ##
-
-    def list_images(self, location=None, ex_image_ids=None, ex_filters=None):
-        """
-        List images on a provider.
-
-        @inherits :class:`NodeDriver.list_images`
-
-        :keyword ex_image_ids: a list of image ids to filter the images to
-                               be returned.
-        :type ex_image_ids: ``list`` of ``str``
-
-        :keyword ex_filters: image attribute and value pairs to filter
-                             images. Only the image which matchs all
-                             the pairs will be returned.
-                             If the filter attribute need a json array value,
-                             use ``list`` object, the driver will convert it.
-        :type ex_filters: ``dict``
-        """
-
-        if location and isinstance(location, NodeLocation):
-            region = location.id
-        else:
-            region = self.region
-        params = {'Action': 'DescribeImages',
-                  'RegionId': region}
-        if ex_image_ids:
-            if isinstance(ex_image_ids, list):
-                params['ImageId'] = ','.join(ex_image_ids)
-            else:
-                raise AttributeError('ex_image_ids should be a list of '
-                                     'image ids')
-        if ex_filters and isinstance(ex_filters, dict):
-            for key in ex_filters.keys():
-                params[key] = ex_filters[key]
-
-        def _parse_response(resp_body):
-            image_elements = findall(resp_body, 'Images/Image',
-                                     namespace=self.namespace)
-            images = [self._to_image(each) for each in image_elements]
-            return images
-        return self._request_multiple_pages(self.path, params,
-                                            _parse_response)
-
-    def create_image(self, node, name, description=None, ex_snapshot_id=None,
-                     ex_image_version=None, ex_client_token=None):
-        """
-        Creates an image from a system disk snapshot.
-
-        @inherits :class:`NodeDriver.create_image`
-
-        :keyword ex_snapshot_id: the id of the snapshot to create the image.
-                                 (required)
-        :type ex_snapshot_id: ``str``
-
-        :keyword ex_image_version: the version number of the image
-        :type ex_image_version: ``str``
-
-        :keyword ex_client_token: a token generated by client to identify
-                                  each request.
-        :type ex_client_token: ``str``
-        """
-        params = {'Action': 'CreateImage',
-                  'RegionId': self.region}
-        if name:
-            params['ImageName'] = name
-        if description:
-            params['Description'] = description
-        if ex_snapshot_id:
-            params['SnapshotId'] = ex_snapshot_id
-        else:
-            raise AttributeError('ex_snapshot_id is required')
-        if ex_image_version:
-            params['ImageVersion'] = ex_image_version
-        if ex_client_token:
-            params['ClientToken'] = ex_client_token
-
-        resp = self.connection.request(self.path, params)
-        image_id = findtext(resp.object, 'ImageId', namespace=self.namespace)
-        return self.get_image(image_id=image_id)
-
-    def delete_image(self, node_image):
-        params = {'Action': 'DeleteImage',
-                  'RegionId': self.region,
-                  'ImageId': node_image.id}
-        resp = self.connection.request(self.path, params)
-        return resp.success()
-
-    def get_image(self, image_id, ex_region_id=None):
-        if ex_region_id:
-            region = ex_region_id
-        else:
-            region = self.region
-        location = NodeLocation(id=region, name=None, country=None,
-                                driver=self)
-        images = self.list_images(location, ex_image_ids=[image_id])
-        if len(images) != 1:
-            raise LibcloudError('could not find the image with id %s' %
-                                image_id,
-                                driver=self)
-        return images[0]
-
-    def copy_image(self, source_region, node_image, name, description=None,
-                   ex_destination_region_id=None, ex_client_token=None):
-        """
-        Copies an image from a source region to the destination region.
-        If not provide a destination region, default to the current region.
-
-        @inherits :class:`NodeDriver.copy_image`
-
-        :keyword ex_destination_region_id: id of the destination region
-        :type ex_destination_region_id: ``str``
-
-        :keyword ex_client_token: a token generated by client to identify
-                                  each request.
-        :type ex_client_token: ``str``
-        """
-        params = {'Action': 'CopyImage',
-                  'RegionId': source_region,
-                  'ImageId': node_image.id}
-        if ex_destination_region_id is not None:
-            params['DestinationRegionId'] = ex_destination_region_id
-        else:
-            params['DestinationRegionId'] = self.region
-        if name:
-            params['DestinationImageName'] = name
-        if description:
-            params['DestinationDescription'] = description
-        if ex_client_token:
-            params['ClientToken'] = ex_client_token
-        resp = self.connection.request(self.path, params)
-        image_id = findtext(resp.object, 'ImageId', namespace=self.namespace)
-        return self.get_image(image_id=image_id)
-
-    def _to_nodes(self, object):
-        """
-        Convert response to Node object list
-
-        :param object: parsed response object
-        :return: a list of ``Node``
-        :rtype: ``list``
-        """
-        node_elements = findall(object, 'Instances/Instance', self.namespace)
-        return [self._to_node(el) for el in node_elements]
-
-    def _to_node(self, instance):
-        """
-        Convert an InstanceAttributesType object to ``Node`` object
-
-        :param instance: a xml element represents an instance
-        :return: a ``Node`` object
-        :rtype: ``Node``
-        """
-        _id = findtext(element=instance, xpath='InstanceId',
-                       namespace=self.namespace)
-        name = findtext(element=instance, xpath='InstanceName',
-                        namespace=self.namespace)
-        instance_status = findtext(element=instance, xpath='Status',
-                                   namespace=self.namespace)
-        state = self.NODE_STATE_MAPPING.get(instance_status, NodeState.UNKNOWN)
-
-        def _get_ips(ip_address_els):
-            return [each.text for each in ip_address_els]
-
-        public_ip_els = findall(element=instance,
-                                xpath='PublicIpAddress/IpAddress',
-                                namespace=self.namespace)
-        public_ips = _get_ips(public_ip_els)
-        private_ip_els = findall(element=instance,
-                                 xpath='InnerIpAddress/IpAddress',
-                                 namespace=self.namespace)
-        private_ips = _get_ips(private_ip_els)
-
-        # Extra properties
-        extra = self._get_extra_dict(instance,
-                                     RESOURCE_EXTRA_ATTRIBUTES_MAP['node'])
-        extra['vpc_attributes'] = self._get_vpc_attributes(instance)
-        extra['eip_address'] = self._get_eip_address(instance)
-        extra['operation_locks'] = self._get_operation_locks(instance)
-
-        node = Node(id=_id, name=name, state=state,
-                    public_ips=public_ips, private_ips=private_ips,
-                    driver=self.connection.driver, extra=extra)
-        return node
-
-    def _get_extra_dict(self, element, mapping):
-        """
-        Extract attributes from the element based on rules provided in the
-        mapping dictionary.
-
-        :param      element: Element to parse the values from.
-        :type       element: xml.etree.ElementTree.Element.
-
-        :param      mapping: Dictionary with the extra layout
-        :type       node: :class:`Node`
-
-        :rtype: ``dict``
-        """
-        extra = {}
-        for attribute, values in mapping.items():
-            transform_func = values['transform_func']
-            value = findattr(element=element,
-                             xpath=values['xpath'],
-                             namespace=self.namespace)
-            if value:
-                try:
-                    extra[attribute] = transform_func(value)
-                except Exception:
-                    extra[attribute] = None
-            else:
-                extra[attribute] = value
-
-        return extra
-
-    def _get_internet_related_params(self, ex_internet_charge_type,
-                                     ex_internet_max_bandwidth_in,
-                                     ex_internet_max_bandwidth_out):
-        params = {}
-        if ex_internet_charge_type:
-            params['InternetChargeType'] = ex_internet_charge_type
-            if ex_internet_charge_type.lower() == 'paybytraffic':
-                if ex_internet_max_bandwidth_out:
-                    params['InternetMaxBandwidthOut'] = \
-                        ex_internet_max_bandwidth_out
-                else:
-                    raise AttributeError('ex_internet_max_bandwidth_out is '
-                                         'mandatory for PayByTraffic internet'
-                                         ' charge type.')
-
-        if ex_internet_max_bandwidth_in:
-            params['InternetMaxBandwidthIn'] = \
-                ex_internet_max_bandwidth_in
-        return params
-
-    def _get_system_disk(self, ex_system_disk):
-        if not isinstance(ex_system_disk, dict):
-            raise AttributeError('ex_system_disk is not a dict')
-        sys_disk_dict = ex_system_disk
-        key_base = 'SystemDisk.'
-        # TODO(samsong8610): Use a type instead of dict
-        mappings = {'category': 'Category',
-                    'disk_name': 'DiskName',
-                    'description': 'Description'}
-        params = {}
-        for attr in mappings.keys():
-            if attr in sys_disk_dict:
-                params[key_base + mappings[attr]] = sys_disk_dict[attr]
-        return params
-
-    def _get_data_disks(self, ex_data_disks):
-        if isinstance(ex_data_disks, dict):
-            data_disks = [ex_data_disks]
-        elif isinstance(ex_data_disks, list):
-            data_disks = ex_data_disks
-        else:
-            raise AttributeError('ex_data_disks should be a list of dict')
-        # TODO(samsong8610): Use a type instead of dict
-        mappings = {'size': 'Size',
-                    'category': 'Category',
-                    'snapshot_id': 'SnapshotId',
-                    'disk_name': 'DiskName',
-                    'description': 'Description',
-                    'device': 'Device',
-                    'delete_with_instance': 'DeleteWithInstance'}
-        params = {}
-        for idx, disk in enumerate(data_disks):
-            key_base = 'DataDisk.{0}.'.format(idx + 1)
-            for attr in mappings.keys():
-                if attr in disk:
-                    if attr == 'delete_with_instance':
-                        # Convert bool value to str
-                        value = str(disk[attr]).lower()
-                    else:
-                        value = disk[attr]
-                    params[key_base + mappings[attr]] = value
-        return params
-
-    def _get_vpc_attributes(self, instance):
-        vpcs = findall(instance, xpath='VpcAttributes',
-                       namespace=self.namespace)
-        if len(vpcs) <= 0:
-            return None
-        return self._get_extra_dict(
-            vpcs[0], RESOURCE_EXTRA_ATTRIBUTES_MAP['vpc_attributes'])
-
-    def _get_eip_address(self, instance):
-        eips = findall(instance, xpath='EipAddress',
-                       namespace=self.namespace)
-        if len(eips) <= 0:
-            return None
-        return self._get_extra_dict(
-            eips[0], RESOURCE_EXTRA_ATTRIBUTES_MAP['eip_address_associate'])
-
-    def _get_operation_locks(self, instance):
-        locks = findall(instance, xpath='OperationLocks',
-                        namespace=self.namespace)
-        if len(locks) <= 0:
-            return None
-        return self._get_extra_dict(
-            locks[0], RESOURCE_EXTRA_ATTRIBUTES_MAP['operation_locks'])
-
-    def _wait_until_state(self, nodes, state, wait_period=3, timeout=600):
-        """
-        Block until the provided nodes are in the desired state.
-        :param nodes: List of nodes to wait for
-        :type nodes: ``list`` of :class:`.Node`
-        :param state: desired state
-        :type state: ``NodeState``
-        :param wait_period: How many seconds to wait between each loop
-                            iteration. (default is 3)
-        :type wait_period: ``int``
-        :param timeout: How many seconds to wait before giving up.
-                        (default is 600)
-        :type timeout: ``int``
-        :return: if the nodes are in the desired state.
-        :rtype: ``bool``
-        """
-        start = time.time()
-        end = start + timeout
-        node_ids = [node.id for node in nodes]
-
-        while(time.time() < end):
-            matched_nodes = self.list_nodes(ex_node_ids=node_ids)
-            if len(matched_nodes) > len(node_ids):
-                found_ids = [node.id for node in matched_nodes]
-                msg = ('found multiple nodes with same ids, '
-                       'desired ids: %(ids)s, found ids: %(found_ids)s' %
-                       {'ids': node_ids, 'found_ids': found_ids})
-                raise LibcloudError(value=msg, driver=self)
-            desired_nodes = [node for node in matched_nodes
-                             if node.state == state]
-
-            if len(desired_nodes) == len(node_ids):
-                return True
-            else:
-                time.sleep(wait_period)
-                continue
-
-        raise LibcloudError(value='Timed out after %s seconds' % (timeout),
-                            driver=self)
-
-    def _to_volume(self, element):
-        _id = findtext(element, 'DiskId', namespace=self.namespace)
-        name = findtext(element, 'DiskName', namespace=self.namespace)
-        size = int(findtext(element, 'Size', namespace=self.namespace))
-        status_str = findtext(element, 'Status', namespace=self.namespace)
-        status = self.VOLUME_STATE_MAPPING.get(status_str,
-                                               StorageVolumeState.UNKNOWN)
-
-        extra = self._get_extra_dict(element,
-                                     RESOURCE_EXTRA_ATTRIBUTES_MAP['volume'])
-        extra['operation_locks'] = self._get_operation_locks(element)
-        return StorageVolume(_id, name, size, self, state=status, extra=extra)
-
-    def _list_to_json_array(self, value):
-        try:
-            return json.dumps(value)
-        except Exception:
-            raise AttributeError('could not convert list to json array')
-
-    def _to_snapshot(self, element):
-        _id = findtext(element, 'SnapshotId', namespace=self.namespace)
-        created = findtext(element, 'CreationTime', namespace=self.namespace)
-        status_str = findtext(element, 'Status', namespace=self.namespace)
-        state = self.SNAPSHOT_STATE_MAPPING.get(status_str,
-                                                VolumeSnapshotState.UNKNOWN)
-        extra = self._get_extra_dict(element,
-                                     RESOURCE_EXTRA_ATTRIBUTES_MAP['snapshot'])
-        return VolumeSnapshot(id=_id, driver=self, extra=extra,
-                              created=created, state=state)
-
-    def _to_size(self, element):
-        _id = findtext(element, 'InstanceTypeId', namespace=self.namespace)
-        ram = float(findtext(element, 'MemorySize', namespace=self.namespace))
-        extra = {}
-        extra['cpu_core_count'] = int(findtext(element, 'CpuCoreCount',
-                                               namespace=self.namespace))
-        extra['instance_type_family'] = findtext(element, 'InstanceTypeFamily',
-                                                 namespace=self.namespace)
-        return NodeSize(id=_id, name=_id, ram=ram, disk=None, bandwidth=None,
-                        price=None, driver=self, extra=extra)
-
-    def _to_location(self, element):
-        _id = findtext(element, 'RegionId', namespace=self.namespace)
-        localname = findtext(element, 'LocalName', namespace=self.namespace)
-        return NodeLocation(id=_id, name=localname, country=None, driver=self)
-
-    def _to_image(self, element):
-        _id = findtext(element, 'ImageId', namespace=self.namespace)
-        name = findtext(element, 'ImageName', namespace=self.namespace)
-        extra = self._get_extra_dict(element,
-                                     RESOURCE_EXTRA_ATTRIBUTES_MAP['image'])
-        extra['disk_device_mappings'] = self._get_disk_device_mappings(
-            element.find('DiskDeviceMappings'))
-        return NodeImage(id=_id, name=name, driver=self, extra=extra)
-
-    def _get_disk_device_mappings(self, element):
-        if element is None:
-            return None
-        mapping_element = element.find('DiskDeviceMapping')
-        if mapping_element is not None:
-            return self._get_extra_dict(
-                mapping_element,
-                RESOURCE_EXTRA_ATTRIBUTES_MAP['disk_device_mapping'])
-        return None
-
-    def _to_security_group(self, element):
-        _id = findtext(element, 'SecurityGroupId', namespace=self.namespace)
-        name = findtext(element, 'SecurityGroupName',
-                        namespace=self.namespace)
-        description = findtext(element, 'Description',
-                               namespace=self.namespace)
-        vpc_id = findtext(element, 'VpcId', namespace=self.namespace)
-        creation_time = findtext(element, 'CreationTime',
-                                 namespace=self.namespace)
-        return ECSSecurityGroup(_id, name, description=description,
-                                driver=self, vpc_id=vpc_id,
-                                creation_time=creation_time)
-
-    def _to_zone(self, element):
-        _id = findtext(element, 'ZoneId', namespace=self.namespace)
-        local_name = findtext(element, 'LocalName', namespace=self.namespace)
-        resource_types = findall(element,
-                                 'AvailableResourceCreation/ResourceTypes',
-                                 namespace=self.namespace)
-        instance_types = findall(element,
-                                 'AvailableInstanceTypes/InstanceTypes',
-                                 namespace=self.namespace)
-        disk_categories = findall(element,
-                                  'AvailableDiskCategories/DiskCategories',
-                                  namespace=self.namespace)
-
-        def _text(element):
-            return element.text
-
-        return ECSZone(id=_id, name=local_name, driver=self,
-                       available_resource_types=list(
-                           map(_text, resource_types)),
-                       available_instance_types=list(
-                           map(_text, instance_types)),
-                       available_disk_categories=list(
-                           map(_text, disk_categories)))
-
-    def _get_pagination(self, element):
-        page_number = int(findtext(element, 'PageNumber'))
-        total_count = int(findtext(element, 'TotalCount'))
-        page_size = int(findtext(element, 'PageSize'))
-        return Pagination(total=total_count, size=page_size,
-                          current=page_number)
-
-    def _request_multiple_pages(self, path, params, parse_func):
-        """
-        Request all resources by multiple pages.
-        :param path: the resource path
-        :type path: ``str``
-        :param params: the query parameters
-        :type params: ``dict``
-        :param parse_func: the function object to parse the response body
-        :param type: ``function``
-        :return: list of resource object, if not found any, return []
-        :rtype: ``list``
-        """
-        results = []
-        while True:
-            one_page = self.connection.request(path, params).object
-            resources = parse_func(one_page)
-            results += resources
-            pagination = self._get_pagination(one_page)
-            if pagination.next() is None:
-                break
-            params.update(pagination.to_dict())
-        return results

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/elastichosts.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/elastichosts.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/elastichosts.py
deleted file mode 100644
index 736ac7f..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/elastichosts.py
+++ /dev/null
@@ -1,236 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-ElasticHosts Driver
-"""
-
-from libcloud.compute.types import Provider
-from libcloud.compute.drivers.elasticstack import ElasticStackBaseNodeDriver
-
-
-# API end-points
-API_ENDPOINTS = {
-    'lon-p': {
-        'name': 'London Peer 1',
-        'country': 'United Kingdom',
-        'host': 'api-lon-p.elastichosts.com'
-    },
-    'lon-b': {
-        'name': 'London BlueSquare',
-        'country': 'United Kingdom',
-        'host': 'api-lon-b.elastichosts.com'
-    },
-    'sat-p': {
-        'name': 'San Antonio Peer 1',
-        'country': 'United States',
-        'host': 'api-sat-p.elastichosts.com'
-    },
-    'lax-p': {
-        'name': 'Los Angeles Peer 1',
-        'country': 'United States',
-        'host': 'api-lax-p.elastichosts.com'
-    },
-    'sjc-c': {
-        'name': 'San Jose (Silicon Valley)',
-        'country': 'United States',
-        'host': 'api-sjc-c.elastichosts.com'
-    },
-    'tor-p': {
-        'name': 'Toronto Peer 1',
-        'country': 'Canada',
-        'host': 'api-tor-p.elastichosts.com'
-    },
-    'syd-y': {
-        'name': 'Sydney',
-        'country': 'Australia',
-        'host': 'api-syd-v.elastichosts.com'
-    },
-    'cn-1': {
-        'name': 'Hong Kong',
-        'country': 'China',
-        'host': 'api-hkg-e.elastichosts.com'
-    }
-}
-
-# Default API end-point for the base connection class.
-DEFAULT_REGION = 'sat-p'
-
-# Retrieved from http://www.elastichosts.com/cloud-hosting/api
-STANDARD_DRIVES = {
-    '38df0986-4d85-4b76-b502-3878ffc80161': {
-        'uuid': '38df0986-4d85-4b76-b502-3878ffc80161',
-        'description': 'CentOS Linux 5.5',
-        'size_gunzipped': '3GB',
-        'supports_deployment': True,
-    },
-    '980cf63c-f21e-4382-997b-6541d5809629': {
-        'uuid': '980cf63c-f21e-4382-997b-6541d5809629',
-        'description': 'Debian Linux 5.0',
-        'size_gunzipped': '1GB',
-        'supports_deployment': True,
-    },
-    'aee5589a-88c3-43ef-bb0a-9cab6e64192d': {
-        'uuid': 'aee5589a-88c3-43ef-bb0a-9cab6e64192d',
-        'description': 'Ubuntu Linux 10.04',
-        'size_gunzipped': '1GB',
-        'supports_deployment': True,
-    },
-    '62f512cd-82c7-498e-88d8-a09ac2ef20e7': {
-        'uuid': '62f512cd-82c7-498e-88d8-a09ac2ef20e7',
-        'description': 'Ubuntu Linux 12.04',
-        'size_gunzipped': '1GB',
-        'supports_deployment': True,
-    },
-    'b9d0eb72-d273-43f1-98e3-0d4b87d372c0': {
-        'uuid': 'b9d0eb72-d273-43f1-98e3-0d4b87d372c0',
-        'description': 'Windows Web Server 2008',
-        'size_gunzipped': '13GB',
-        'supports_deployment': False,
-    },
-    '30824e97-05a4-410c-946e-2ba5a92b07cb': {
-        'uuid': '30824e97-05a4-410c-946e-2ba5a92b07cb',
-        'description': 'Windows Web Server 2008 R2',
-        'size_gunzipped': '13GB',
-        'supports_deployment': False,
-    },
-    '9ecf810e-6ad1-40ef-b360-d606f0444671': {
-        'uuid': '9ecf810e-6ad1-40ef-b360-d606f0444671',
-        'description': 'Windows Web Server 2008 R2 + SQL Server',
-        'size_gunzipped': '13GB',
-        'supports_deployment': False,
-    },
-    '10a88d1c-6575-46e3-8d2c-7744065ea530': {
-        'uuid': '10a88d1c-6575-46e3-8d2c-7744065ea530',
-        'description': 'Windows Server 2008 Standard R2',
-        'size_gunzipped': '13GB',
-        'supports_deployment': False,
-    },
-    '2567f25c-8fb8-45c7-95fc-bfe3c3d84c47': {
-        'uuid': '2567f25c-8fb8-45c7-95fc-bfe3c3d84c47',
-        'description': 'Windows Server 2008 Standard R2 + SQL Server',
-        'size_gunzipped': '13GB',
-        'supports_deployment': False,
-    },
-}
-
-
-class ElasticHostsException(Exception):
-    def __str__(self):
-        return self.args[0]
-
-    def __repr__(self):
-        return "<ElasticHostsException '%s'>" % (self.args[0])
-
-
-class ElasticHostsNodeDriver(ElasticStackBaseNodeDriver):
-    """
-    Node Driver class for ElasticHosts
-    """
-    type = Provider.ELASTICHOSTS
-    api_name = 'elastichosts'
-    name = 'ElasticHosts'
-    website = 'http://www.elastichosts.com/'
-    features = {"create_node": ["generates_password"]}
-    _standard_drives = STANDARD_DRIVES
-
-    def __init__(self, key, secret=None, secure=True, host=None, port=None,
-                 region=DEFAULT_REGION, **kwargs):
-
-        if hasattr(self, '_region'):
-            region = self._region
-
-        if region not in API_ENDPOINTS:
-            raise ValueError('Invalid region: %s' % (region))
-
-        self._host_argument_set = host is not None
-        super(ElasticHostsNodeDriver, self).__init__(key=key, secret=secret,
-                                                     secure=secure, host=host,
-                                                     port=port,
-                                                     region=region, **kwargs)
-
-    def _ex_connection_class_kwargs(self):
-        """
-        Return the host value based on the user supplied region.
-        """
-        kwargs = {}
-        if not self._host_argument_set:
-            kwargs['host'] = API_ENDPOINTS[self.region]['host']
-
-        return kwargs
-
-
-class ElasticHostsUK1NodeDriver(ElasticHostsNodeDriver):
-    """
-    ElasticHosts node driver for the London Peer 1 end-point
-    """
-    name = 'ElasticHosts (lon-p)'
-    _region = 'lon-p'
-
-
-class ElasticHostsUK2NodeDriver(ElasticHostsNodeDriver):
-    """
-    ElasticHosts node driver for the London Bluesquare end-point
-    """
-    name = 'ElasticHosts (lon-b)'
-    _region = 'lon-b'
-
-
-class ElasticHostsUS1NodeDriver(ElasticHostsNodeDriver):
-    """
-    ElasticHosts node driver for the San Antonio Peer 1 end-point
-    """
-    name = 'ElasticHosts (sat-p)'
-    _region = 'sat-p'
-
-
-class ElasticHostsUS2NodeDriver(ElasticHostsNodeDriver):
-    """
-    ElasticHosts node driver for the Los Angeles Peer 1 end-point
-    """
-    name = 'ElasticHosts (lax-p)'
-    _region = 'lax-p'
-
-
-class ElasticHostsUS3NodeDriver(ElasticHostsNodeDriver):
-    """
-    ElasticHosts node driver for the San Jose (Silicon Valley) end-point
-    """
-    name = 'ElasticHosts (sjc-c)'
-    _region = 'sjc-c'
-
-
-class ElasticHostsCA1NodeDriver(ElasticHostsNodeDriver):
-    """
-    ElasticHosts node driver for the Toronto Peer 1 end-point
-    """
-    name = 'ElasticHosts (tor-p)'
-    _region = 'tor-p'
-
-
-class ElasticHostsAU1NodeDriver(ElasticHostsNodeDriver):
-    """
-    ElasticHosts node driver for the Sydney end-point
-    """
-    name = 'ElasticHosts (syd-y)'
-    _region = 'syd-y'
-
-
-class ElasticHostsCN1NodeDriver(ElasticHostsNodeDriver):
-    """
-    ElasticHosts node driver for the Hong Kong end-point
-    """
-    name = 'ElasticHosts (cn-1)'
-    _region = 'cn-1'


[11/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/softlayer.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/softlayer.py b/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/softlayer.py
deleted file mode 100644
index 8a3cf4c..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/softlayer.py
+++ /dev/null
@@ -1,214 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-__all__ = [
-    'SoftLayerDNSDriver'
-]
-
-
-from libcloud.common.softlayer import SoftLayerConnection
-from libcloud.common.softlayer import SoftLayerObjectDoesntExist
-from libcloud.dns.types import Provider, RecordType
-from libcloud.dns.types import ZoneDoesNotExistError, RecordDoesNotExistError
-from libcloud.dns.base import DNSDriver, Zone, Record
-
-
-VALID_RECORD_EXTRA_PARAMS = ['priority', 'ttl']
-
-
-class SoftLayerDNSDriver(DNSDriver):
-    type = Provider.SOFTLAYER
-    name = 'Softlayer DNS'
-    website = 'https://www.softlayer.com'
-    connectionCls = SoftLayerConnection
-
-    RECORD_TYPE_MAP = {
-        RecordType.A: 'a',
-        RecordType.AAAA: 'aaaa',
-        RecordType.CNAME: 'cname',
-        RecordType.MX: 'mx',
-        RecordType.NS: 'ns',
-        RecordType.PTR: 'ptr',
-        RecordType.SOA: 'soa',
-        RecordType.SPF: 'spf',
-        RecordType.SRV: 'srv',
-        RecordType.TXT: 'txt',
-    }
-
-    def create_zone(self, domain, ttl=None, extra=None):
-        self.connection.set_context({'resource': 'zone', 'id': domain})
-        data = {
-            'name': domain,
-            'resourceRecords': []
-        }
-        response = self.connection.request(
-            'SoftLayer_Dns_Domain', 'createObject', data
-        ).object
-        zone = Zone(id=response['id'], domain=domain,
-                    type='master', ttl=3600, driver=self)
-        return zone
-
-    def get_zone(self, zone_id):
-        self.connection.set_context({'resource': 'zone', 'id': zone_id})
-        try:
-            response = self.connection.request(
-                'SoftLayer_Dns_Domain', 'getObject', id=zone_id
-            ).object
-        except SoftLayerObjectDoesntExist:
-            raise ZoneDoesNotExistError(value='', driver=self,
-                                        zone_id=zone_id)
-        return self._to_zone(response)
-
-    def delete_zone(self, zone):
-        self.connection.set_context({'resource': 'zone', 'id': zone.id})
-        try:
-            self.connection.request(
-                'SoftLayer_Dns_Domain', 'deleteObject', id=zone.id
-            ).object
-        except SoftLayerObjectDoesntExist:
-            raise ZoneDoesNotExistError(value='', driver=self,
-                                        zone_id=zone.id)
-        else:
-            return True
-
-    def iterate_zones(self):
-        zones_list = self.connection.request(
-            'SoftLayer_Dns_Domain', 'getByDomainName', '.'
-        ).object
-        for item in zones_list:
-            yield self._to_zone(item)
-
-    def iterate_records(self, zone):
-        self.connection.set_context({'resource': 'zone', 'id': zone.id})
-        records_list = self.connection.request(
-            'SoftLayer_Dns_Domain', 'getResourceRecords', id=zone.id
-        ).object
-        for item in records_list:
-            yield self._to_record(item, zone=zone)
-
-    def get_record(self, zone_id, record_id):
-        try:
-            record = self.connection.request(
-                'SoftLayer_Dns_Domain_ResourceRecord',
-                'getObject',
-                id=record_id
-            ).object
-            return self._to_record(record, zone=self.get_zone(zone_id))
-        except SoftLayerObjectDoesntExist:
-            raise RecordDoesNotExistError(value='', driver=self,
-                                          record_id=record_id)
-
-    def delete_record(self, record):
-        try:
-            self.connection.request(
-                'SoftLayer_Dns_Domain_ResourceRecord',
-                'deleteObject',
-                id=record.id
-            ).object
-        except SoftLayerObjectDoesntExist:
-            raise RecordDoesNotExistError(value='', driver=self,
-                                          record_id=record.id)
-        else:
-            return True
-
-    def create_record(self, name, zone, type, data, extra=None):
-        params = {
-            'domainId': zone.id,
-            'type': self.RECORD_TYPE_MAP[type],
-            'host': name,
-            'data': data
-        }
-        if extra:
-            if extra.get('ttl'):
-                params['ttl'] = extra['ttl']
-            if extra.get('refresh'):
-                params['refresh'] = extra['refresh']
-            if extra.get('retry'):
-                params['retry'] = extra['retry']
-            if extra.get('expire'):
-                params['expire'] = extra['expire']
-            if extra.get('priority'):
-                params['mxPriority'] = extra['priority']
-        response = self.connection.request(
-            'SoftLayer_Dns_Domain_ResourceRecord',
-            'createObject',
-            params
-        ).object
-
-        return self._to_record(response, zone=zone)
-
-    def update_record(
-            self, record, name=None, type=None, data=None, extra=None):
-        params = {}
-        if type:
-            params['type'] = self.RECORD_TYPE_MAP[type]
-        if name:
-            params['host'] = name
-        if data:
-            params['data'] = data
-
-        if extra:
-            if extra.get('ttl'):
-                params['ttl'] = extra['ttl']
-            if extra.get('refresh'):
-                params['refresh'] = extra['refresh']
-            if extra.get('retry'):
-                params['retry'] = extra['retry']
-            if extra.get('expire'):
-                params['expire'] = extra['expire']
-            if extra.get('priority'):
-                params['mxPriority'] = extra['priority']
-
-        response = self.connection.request(
-            'SoftLayer_Dns_Domain_ResourceRecord',
-            'editObject',
-            params,
-            id=record.id,
-        ).object
-
-        if response:
-            changed_record = self.connection.request(
-                'SoftLayer_Dns_Domain_ResourceRecord',
-                'getObject',
-                id=record.id,
-            ).object
-            return self._to_record(changed_record, zone=record.zone)
-        else:
-            return False
-
-    def _to_zone(self, item):
-        ttl = item.get('ttl', 3600)
-        zone = Zone(id=item['id'], domain=item['name'],
-                    type='master', ttl=ttl, driver=self)
-        return zone
-
-    def _to_record(self, item, zone=None):
-        extra = {
-            'ttl': item['ttl'],
-            'expire': item['expire'],
-            'mxPriority': item['mxPriority'],
-            'refresh': item['refresh'],
-            'retry': item['retry'],
-        }
-        record = Record(
-            id=item['id'],
-            name=item['host'],
-            type=self._string_to_record_type(item['type']),
-            data=item['data'],
-            zone=zone,
-            driver=self,
-            ttl=item['ttl'],
-            extra=extra
-        )
-        return record

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/vultr.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/vultr.py b/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/vultr.py
deleted file mode 100644
index f04407f..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/vultr.py
+++ /dev/null
@@ -1,388 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-Vultr DNS Driver
-"""
-
-from libcloud.utils.py3 import urlencode
-from libcloud.common.vultr import VultrConnection, VultrResponse
-from libcloud.dns.base import DNSDriver, Zone, Record
-from libcloud.dns.types import ZoneDoesNotExistError, RecordDoesNotExistError
-from libcloud.dns.types import ZoneAlreadyExistsError, RecordAlreadyExistsError
-from libcloud.dns.types import Provider, RecordType
-
-
-__all__ = [
-    'ZoneRequiredException',
-    'VultrDNSResponse',
-    'VultrDNSConnection',
-    'VultrDNSDriver',
-]
-
-
-class ZoneRequiredException(Exception):
-    pass
-
-
-class VultrDNSResponse(VultrResponse):
-    pass
-
-
-class VultrDNSConnection(VultrConnection):
-    responseCls = VultrDNSResponse
-
-
-class VultrDNSDriver(DNSDriver):
-
-    type = Provider.VULTR
-    name = 'Vultr DNS'
-    website = 'http://www.vultr.com/'
-    connectionCls = VultrDNSConnection
-
-    RECORD_TYPE_MAP = {
-
-        RecordType.A: 'A',
-        RecordType.AAAA: 'AAAA',
-        RecordType.TXT: 'TXT',
-        RecordType.CNAME: 'CNAME',
-        RecordType.MX: 'MX',
-        RecordType.NS: 'NS',
-        RecordType.SRV: 'SRV',
-    }
-
-    def list_zones(self):
-        """
-        Return a list of records for the provided zone.
-
-        :param zone: Zone to list records for.
-        :type zone: :class:`Zone`
-
-        :return: ``list`` of :class:`Record`
-        """
-        action = '/v1/dns/list'
-        params = {'api_key': self.key}
-        response = self.connection.request(action=action,
-                                           params=params)
-        zones = self._to_zones(response.objects[0])
-
-        return zones
-
-    def list_records(self, zone):
-        """
-        Returns a list of records for the provided zone.
-
-        :param zone: zone to list records for
-        :type zone: `Zone`
-
-        :rtype: list of :class: `Record`
-        """
-        if not isinstance(zone, Zone):
-            raise ZoneRequiredException('zone should be of type Zone')
-
-        zones = self.list_zones()
-
-        if not self.ex_zone_exists(zone.domain, zones):
-            raise ZoneDoesNotExistError(value='', driver=self,
-                                        zone_id=zone.domain)
-
-        action = '/v1/dns/records'
-        params = {'domain': zone.domain}
-        response = self.connection.request(action=action,
-                                           params=params)
-        records = self._to_records(response.objects[0], zone=zone)
-
-        return records
-
-    def get_zone(self, zone_id):
-        """
-        Returns a `Zone` instance.
-
-        :param zone_id: name of the zone user wants to get.
-        :type zone_id: ``str``
-
-        :rtype: :class:`Zone`
-        """
-        ret_zone = None
-
-        action = '/v1/dns/list'
-        params = {'api_key': self.key}
-        response = self.connection.request(action=action,
-                                           params=params)
-        zones = self._to_zones(response.objects[0])
-
-        if not self.ex_zone_exists(zone_id, zones):
-            raise ZoneDoesNotExistError(value=None, zone_id=zone_id,
-                                        driver=self)
-
-        for zone in zones:
-            if zone_id == zone.domain:
-                ret_zone = zone
-
-        return ret_zone
-
-    def get_record(self, zone_id, record_id):
-        """
-        Returns a Record instance.
-
-        :param zone_id: name of the required zone
-        :type zone_id: ``str``
-
-        :param record_id: ID of the required record
-        :type record_id: ``str``
-
-        :rtype: :class: `Record`
-        """
-        ret_record = None
-        zone = self.get_zone(zone_id=zone_id)
-        records = self.list_records(zone=zone)
-
-        if not self.ex_record_exists(record_id, records):
-            raise RecordDoesNotExistError(value='', driver=self,
-                                          record_id=record_id)
-
-        for record in records:
-            if record_id == record.id:
-                ret_record = record
-
-        return ret_record
-
-    def create_zone(self, domain, type='master', ttl=None, extra=None):
-        """
-        Returns a `Zone` object.
-
-        :param domain: Zone domain name, (e.g. example.com).
-        :type domain: ``str``
-
-        :param type: Zone type (master / slave).
-        :type  type: ``str``
-
-        :param ttl: TTL for new records. (optional)
-        :type  ttl: ``int``
-
-        :param extra: (optional) Extra attributes (driver specific).
-                      (e.g. {'serverip':'127.0.0.1'})
-        """
-        extra = extra or {}
-        if extra and extra.get('serverip'):
-            serverip = extra['serverip']
-
-        params = {'api_key': self.key}
-        data = urlencode({'domain': domain, 'serverip': serverip})
-        action = '/v1/dns/create_domain'
-        zones = self.list_zones()
-        if self.ex_zone_exists(domain, zones):
-            raise ZoneAlreadyExistsError(value='', driver=self,
-                                         zone_id=domain)
-
-        self.connection.request(params=params, action=action, data=data,
-                                method='POST')
-        zone = Zone(id=domain, domain=domain, type=type, ttl=ttl,
-                    driver=self, extra=extra)
-
-        return zone
-
-    def create_record(self, name, zone, type, data, extra=None):
-        """
-        Create a new record.
-
-        :param name: Record name without the domain name (e.g. www).
-                     Note: If you want to create a record for a base domain
-                     name, you should specify empty string ('') for this
-                     argument.
-        :type  name: ``str``
-
-        :param zone: Zone where the requested record is created.
-        :type  zone: :class:`Zone`
-
-        :param type: DNS record type (A, AAAA, ...).
-        :type  type: :class:`RecordType`
-
-        :param data: Data for the record (depends on the record type).
-        :type  data: ``str``
-
-        :param extra: Extra attributes (driver specific). (optional)
-        :type extra: ``dict``
-
-        :rtype: :class:`Record`
-        """
-        extra = extra or {}
-
-        ret_record = None
-        old_records_list = self.list_records(zone=zone)
-        # check if record already exists
-        # if exists raise RecordAlreadyExistsError
-        for record in old_records_list:
-            if record.name == name and record.data == data:
-                raise RecordAlreadyExistsError(value='', driver=self,
-                                               record_id=record.id)
-
-        MX = self.RECORD_TYPE_MAP.get('MX')
-        SRV = self.RECORD_TYPE_MAP.get('SRV')
-
-        if extra and extra.get('priority'):
-            priority = int(extra['priority'])
-
-        post_data = {'domain': zone.domain, 'name': name,
-                     'type': self.RECORD_TYPE_MAP.get(type), 'data': data}
-
-        if type == MX or type == SRV:
-            post_data['priority'] = priority
-
-        encoded_data = urlencode(post_data)
-        params = {'api_key': self.key}
-        action = '/v1/dns/create_record'
-
-        self.connection.request(action=action, params=params,
-                                data=encoded_data, method='POST')
-        updated_zone_records = zone.list_records()
-
-        for record in updated_zone_records:
-            if record.name == name and record.data == data:
-                ret_record = record
-
-        return ret_record
-
-    def delete_zone(self, zone):
-        """
-        Delete a zone.
-
-        Note: This will delete all the records belonging to this zone.
-
-        :param zone: Zone to delete.
-        :type  zone: :class:`Zone`
-
-        :rtype: ``bool``
-        """
-        action = '/v1/dns/delete_domain'
-        params = {'api_key': self.key}
-        data = urlencode({'domain': zone.domain})
-        zones = self.list_zones()
-        if not self.ex_zone_exists(zone.domain, zones):
-            raise ZoneDoesNotExistError(value='', driver=self,
-                                        zone_id=zone.domain)
-
-        response = self.connection.request(params=params, action=action,
-                                           data=data, method='POST')
-
-        return response.status == 200
-
-    def delete_record(self, record):
-        """
-        Delete a record.
-
-        :param record: Record to delete.
-        :type  record: :class:`Record`
-
-        :rtype: ``bool``
-        """
-        action = '/v1/dns/delete_record'
-        params = {'api_key': self.key}
-        data = urlencode({'RECORDID': record.id,
-                         'domain': record.zone.domain})
-
-        zone_records = self.list_records(record.zone)
-        if not self.ex_record_exists(record.id, zone_records):
-            raise RecordDoesNotExistError(value='', driver=self,
-                                          record_id=record.id)
-
-        response = self.connection.request(action=action, params=params,
-                                           data=data, method='POST')
-
-        return response.status == 200
-
-    def ex_zone_exists(self, zone_id, zones_list):
-        """
-        Function to check if a `Zone` object exists.
-
-        :param zone_id: Name of the `Zone` object.
-        :type zone_id: ``str``
-
-        :param zones_list: A list containing `Zone` objects
-        :type zones_list: ``list``
-
-        :rtype: Returns `True` or `False`
-        """
-
-        zone_ids = []
-        for zone in zones_list:
-            zone_ids.append(zone.domain)
-
-        return zone_id in zone_ids
-
-    def ex_record_exists(self, record_id, records_list):
-        """
-        :param record_id: Name of the `Record` object.
-        :type record_id: ``str``
-
-        :param records_list: A list containing `Record` objects
-        :type records_list: ``list``
-
-        :rtype: ``bool``
-        """
-        record_ids = []
-        for record in records_list:
-            record_ids.append(record.id)
-
-        return record_id in record_ids
-
-    def _to_zone(self, item):
-        """
-        Build an object `Zone` from the item dictionary
-
-        :param item: item to build the zone from
-        :type item: `dictionary`
-
-        :rtype: :instance: `Zone`
-        """
-        type = 'master'
-        extra = {'date_created': item['date_created']}
-
-        zone = Zone(id=item['domain'], domain=item['domain'], driver=self,
-                    type=type, ttl=None, extra=extra)
-
-        return zone
-
-    def _to_zones(self, items):
-        """
-        Returns a list of `Zone` objects.
-
-        :param: items: a list that contains dictionary objects to be passed
-        to the _to_zone function.
-        :type items: ``list``
-        """
-        zones = []
-        for item in items:
-            zones.append(self._to_zone(item))
-
-        return zones
-
-    def _to_record(self, item, zone):
-        extra = {}
-
-        if item.get('priority'):
-            extra['priority'] = item['priority']
-
-        type = self._string_to_record_type(item['type'])
-        record = Record(id=item['RECORDID'], name=item['name'], type=type,
-                        data=item['data'], zone=zone, driver=self, extra=extra)
-
-        return record
-
-    def _to_records(self, items, zone):
-        records = []
-        for item in items:
-            records.append(self._to_record(item, zone=zone))
-
-        return records

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/worldwidedns.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/worldwidedns.py b/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/worldwidedns.py
deleted file mode 100644
index 8b0f90c..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/worldwidedns.py
+++ /dev/null
@@ -1,536 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-World Wide DNS Driver
-"""
-
-__all__ = [
-    'WorldWideDNSDriver'
-]
-
-import re
-
-from libcloud.common.types import LibcloudError
-from libcloud.common.worldwidedns import WorldWideDNSConnection
-from libcloud.dns.types import Provider, RecordType
-from libcloud.dns.types import ZoneDoesNotExistError
-from libcloud.dns.types import RecordError
-from libcloud.dns.types import RecordDoesNotExistError
-from libcloud.dns.base import DNSDriver, Zone, Record
-
-
-MAX_RECORD_ENTRIES = 40  # Maximum record entries for zone
-
-
-class WorldWideDNSError(LibcloudError):
-
-    def __repr__(self):
-        return ("<WorldWideDNSError in " +
-                repr(self.driver) +
-                " " +
-                repr(self.value) + ">")
-
-
-class WorldWideDNSDriver(DNSDriver):
-    type = Provider.WORLDWIDEDNS
-    name = 'World Wide DNS'
-    website = 'https://www.worldwidedns.net/'
-    connectionCls = WorldWideDNSConnection
-
-    RECORD_TYPE_MAP = {
-        RecordType.MX: 'MX',
-        RecordType.CNAME: 'CNAME',
-        RecordType.A: 'A',
-        RecordType.NS: 'NS',
-        RecordType.SRV: 'SRV',
-        RecordType.TXT: 'TXT',
-    }
-
-    def __init__(self, key, secret=None, reseller_id=None, secure=True,
-                 host=None, port=None, **kwargs):
-        """
-        :param    key: API key or username to used (required)
-        :type     key: ``str``
-
-        :param    secret: Secret password to be used (required)
-        :type     secret: ``str``
-
-        :param    reseller_id: Reseller ID for reseller accounts
-        :type     reseller_id: ``str``
-
-        :param    secure: Whether to use HTTPS or HTTP. Note: Some providers
-                          only support HTTPS, and it is on by default.
-        :type     secure: ``bool``
-
-        :param    host: Override hostname used for connections.
-        :type     host: ``str``
-
-        :param    port: Override port used for connections.
-        :type     port: ``int``
-
-        :return: ``None``
-        """
-        super(WorldWideDNSDriver, self).__init__(key=key, secret=secret,
-                                                 secure=secure, host=host,
-                                                 port=port, **kwargs)
-        self.reseller_id = reseller_id
-
-    def list_zones(self):
-        """
-        Return a list of zones.
-
-        :return: ``list`` of :class:`Zone`
-
-        For more info, please see:
-        https://www.worldwidedns.net/dns_api_protocol_list.asp
-        or
-        https://www.worldwidedns.net/dns_api_protocol_list_reseller.asp
-        """
-        action = '/api_dns_list.asp'
-        if self.reseller_id is not None:
-            action = '/api_dns_list_reseller.asp'
-        zones = self.connection.request(action)
-        if len(zones.body) == 0:
-            return []
-        else:
-            return self._to_zones(zones.body)
-
-    def iterate_records(self, zone):
-        """
-        Return a generator to iterate over records for the provided zone.
-
-        :param zone: Zone to list records for.
-        :type zone: :class:`Zone`
-
-        :rtype: ``generator`` of :class:`Record`
-        """
-        records = self._to_records(zone)
-        for record in records:
-            yield record
-
-    def get_zone(self, zone_id):
-        """
-        Return a Zone instance.
-
-        :param zone_id: ID of the required zone
-        :type  zone_id: ``str``
-
-        :rtype: :class:`Zone`
-        """
-        zones = self.list_zones()
-        zone = [zone for zone in zones if zone.id == zone_id]
-        if len(zone) == 0:
-            raise ZoneDoesNotExistError(driver=self,
-                                        value="The zone doesn't exists",
-                                        zone_id=zone_id)
-        return zone[0]
-
-    def get_record(self, zone_id, record_id):
-        """
-        Return a Record instance.
-
-        :param zone_id: ID of the required zone
-        :type  zone_id: ``str``
-
-        :param record_id: ID number of the required record.
-        :type  record_id: ``str``
-
-        :rtype: :class:`Record`
-        """
-        zone = self.get_zone(zone_id)
-        try:
-            if int(record_id) not in range(1, MAX_RECORD_ENTRIES + 1):
-                raise RecordDoesNotExistError(value="Record doesn't exists",
-                                              driver=zone.driver,
-                                              record_id=record_id)
-        except ValueError:
-            raise WorldWideDNSError(
-                value="Record id should be a string number", driver=self)
-        subdomain = zone.extra.get('S%s' % record_id)
-        type = zone.extra.get('T%s' % record_id)
-        data = zone.extra.get('D%s' % record_id)
-        record = self._to_record(record_id, subdomain, type, data, zone)
-        return record
-
-    def update_zone(self, zone, domain, type='master', ttl=None, extra=None,
-                    ex_raw=False):
-        """
-        Update en existing zone.
-
-        :param zone: Zone to update.
-        :type  zone: :class:`Zone`
-
-        :param domain: Zone domain name (e.g. example.com)
-        :type  domain: ``str``
-
-        :param type: Zone type (master / slave).
-        :type  type: ``str``
-
-        :param ttl: TTL for new records. (optional)
-        :type  ttl: ``int``
-
-        :param extra: Extra attributes (driver specific) (optional). Values not
-                      specified such as *SECURE*, *IP*, *FOLDER*, *HOSTMASTER*,
-                      *REFRESH*, *RETRY* and *EXPIRE* will be kept as already
-                      is. The same will be for *S(1 to 40)*, *T(1 to 40)* and
-                      *D(1 to 40)* if not in raw mode and for *ZONENS* and
-                      *ZONEDATA* if it is.
-        :type  extra: ``dict``
-
-        :param ex_raw: Mode we use to do the update using zone file or not.
-        :type  ex_raw: ``bool``
-
-        :rtype: :class:`Zone`
-
-        For more info, please see
-        https://www.worldwidedns.net/dns_api_protocol_list_domain.asp
-        or
-        https://www.worldwidedns.net/dns_api_protocol_list_domain_raw.asp
-        or
-        https://www.worldwidedns.net/dns_api_protocol_list_domain_reseller.asp
-        or
-        https://www.worldwidedns.net/dns_api_protocol_list_domain_raw_reseller.asp
-        """
-        if extra is not None:
-            not_specified = [key for key in zone.extra.keys() if key not in
-                             extra.keys()]
-        else:
-            not_specified = zone.extra.keys()
-
-        if ttl is None:
-            ttl = zone.ttl
-
-        params = {'DOMAIN': domain,
-                  'TTL': ttl}
-
-        for key in not_specified:
-            params[key] = zone.extra[key]
-        if extra is not None:
-            params.update(extra)
-        if ex_raw:
-            action = '/api_dns_modify_raw.asp'
-            if self.reseller_id is not None:
-                action = '/api_dns_modify_raw_reseller.asp'
-            method = 'POST'
-        else:
-            action = '/api_dns_modify.asp'
-            if self.reseller_id is not None:
-                action = '/api_dns_modify_reseller.asp'
-            method = 'GET'
-        response = self.connection.request(action, params=params,  # noqa
-                                           method=method)
-        zone = self.get_zone(zone.id)
-        return zone
-
-    def update_record(self, record, name, type, data, extra=None):
-        """
-        Update an existing record.
-
-        :param record: Record to update.
-        :type  record: :class:`Record`
-
-        :param name: Record name without the domain name (e.g. www).
-                     Note: If you want to create a record for a base domain
-                     name, you should specify empty string ('') for this
-                     argument.
-        :type  name: ``str``
-
-        :param type: DNS record type (MX, CNAME, A, NS, SRV, TXT).
-        :type  type: :class:`RecordType`
-
-        :param data: Data for the record (depends on the record type).
-        :type  data: ``str``
-
-        :param extra: Contains 'entry' Entry position (1 thru 40)
-        :type extra: ``dict``
-
-        :rtype: :class:`Record`
-        """
-        if (extra is None) or ('entry' not in extra):
-            raise WorldWideDNSError(value="You must enter 'entry' parameter",
-                                    driver=self)
-        record_id = extra.get('entry')
-        if name == '':
-            name = '@'
-        if type not in self.RECORD_TYPE_MAP:
-            raise RecordError(value="Record type is not allowed",
-                              driver=record.zone.driver,
-                              record_id=name)
-        zone = record.zone
-        extra = {'S%s' % record_id: name,
-                 'T%s' % record_id: type,
-                 'D%s' % record_id: data}
-        zone = self.update_zone(zone, zone.domain, extra=extra)
-        record = self.get_record(zone.id, record_id)
-        return record
-
-    def create_zone(self, domain, type='master', ttl=None, extra=None):
-        """
-        Create a new zone.
-
-        :param domain: Zone domain name (e.g. example.com)
-        :type domain: ``str``
-
-        :param type: Zone type (master / slave).
-        :type  type: ``str``
-
-        :param ttl: TTL for new records. (optional)
-        :type  ttl: ``int``
-
-        :param extra: Extra attributes (driver specific). (optional). Possible
-                      parameter in here should be *DYN* which values should be
-                      1 for standart and 2 for dynamic. Default is 1.
-        :type extra: ``dict``
-
-        :rtype: :class:`Zone`
-
-        For more info, please see
-        https://www.worldwidedns.net/dns_api_protocol_new_domain.asp
-        or
-        https://www.worldwidedns.net/dns_api_protocol_new_domain_reseller.asp
-        """
-        if type == 'master':
-            _type = 0
-        elif type == 'slave':
-            _type = 1
-        if extra:
-            dyn = extra.get('DYN') or 1
-        else:
-            dyn = 1
-        params = {'DOMAIN': domain,
-                  'TYPE': _type}
-        action = '/api_dns_new_domain.asp'
-        if self.reseller_id is not None:
-            params['DYN'] = dyn
-            action = '/api_dns_new_domain_reseller.asp'
-        self.connection.request(action, params=params)
-        zone = self.get_zone(domain)
-        if ttl is not None:
-            zone = self.update_zone(zone, zone.domain, ttl=ttl)
-        return zone
-
-    def create_record(self, name, zone, type, data, extra=None):
-        """
-        Create a new record.
-
-        We can create 40 record per domain. If all slots are full, we can
-        replace one of them by choosing a specific entry in ``extra`` argument.
-
-        :param name: Record name without the domain name (e.g. www).
-                     Note: If you want to create a record for a base domain
-                     name, you should specify empty string ('') for this
-                     argument.
-        :type  name: ``str``
-
-        :param zone: Zone where the requested record is created.
-        :type  zone: :class:`Zone`
-
-        :param type: DNS record type (MX, CNAME, A, NS, SRV, TXT).
-        :type  type: :class:`RecordType`
-
-        :param data: Data for the record (depends on the record type).
-        :type  data: ``str``
-
-        :param extra: Contains 'entry' Entry position (1 thru 40)
-        :type extra: ``dict``
-
-        :rtype: :class:`Record`
-        """
-        if (extra is None) or ('entry' not in extra):
-            # If no entry is specified, we look for an available one. If all
-            # are full, raise error.
-            record_id = self._get_available_record_entry(zone)
-            if not record_id:
-                raise WorldWideDNSError(value="All record entries are full",
-                                        driver=zone.driver)
-        else:
-            record_id = extra.get('entry')
-        if name == '':
-            name = '@'
-        if type not in self.RECORD_TYPE_MAP:
-            raise RecordError(value="Record type is not allowed",
-                              driver=zone.driver,
-                              record_id=record_id)
-        extra = {'S%s' % record_id: name,
-                 'T%s' % record_id: type,
-                 'D%s' % record_id: data}
-        zone = self.update_zone(zone, zone.domain, extra=extra)
-        record = self.get_record(zone.id, record_id)
-        return record
-
-    def delete_zone(self, zone):
-        """
-        Delete a zone.
-
-        Note: This will delete all the records belonging to this zone.
-
-        :param zone: Zone to delete.
-        :type  zone: :class:`Zone`
-
-        :rtype: ``bool``
-
-        For more information, please see
-        https://www.worldwidedns.net/dns_api_protocol_delete_domain.asp
-        or
-        https://www.worldwidedns.net/dns_api_protocol_delete_domain_reseller.asp
-        """
-        params = {'DOMAIN': zone.domain}
-        action = '/api_dns_delete_domain.asp'
-        if self.reseller_id is not None:
-            action = '/api_dns_delete_domain_reseller.asp'
-        response = self.connection.request(action, params=params)
-        return response.success()
-
-    def delete_record(self, record):
-        """
-        Delete a record.
-
-        :param record: Record to delete.
-        :type  record: :class:`Record`
-
-        :rtype: ``bool``
-        """
-        zone = record.zone
-        for index in range(MAX_RECORD_ENTRIES):
-            if record.name == zone.extra['S%s' % (index + 1)]:
-                entry = index + 1
-                break
-        extra = {'S%s' % entry: '',
-                 'T%s' % entry: 'NONE',
-                 'D%s' % entry: ''}
-        self.update_zone(zone, zone.domain, extra=extra)
-        return True
-
-    def ex_view_zone(self, domain, name_server):
-        """
-        View zone file from a name server
-
-        :param domain: Domain name.
-        :type  domain: ``str``
-
-        :param name_server: Name server to check. (1, 2 or 3)
-        :type  name_server: ``int``
-
-        :rtype: ``str``
-
-        For more info, please see:
-        https://www.worldwidedns.net/dns_api_protocol_viewzone.asp
-        or
-        https://www.worldwidedns.net/dns_api_protocol_viewzone_reseller.asp
-        """
-        params = {'DOMAIN': domain,
-                  'NS': name_server}
-        action = '/api_dns_viewzone.asp'
-        if self.reseller_id is not None:
-            action = '/api_dns_viewzone_reseller.asp'
-        response = self.connection.request(action, params=params)
-        return response.object
-
-    def ex_transfer_domain(self, domain, user_id):
-        """
-        This command will allow you, if you are a reseller, to change the
-        userid on a domain name to another userid in your account ONLY if that
-        new userid is already created.
-
-        :param domain: Domain name.
-        :type  domain: ``str``
-
-        :param user_id: The new userid to connect to the domain name.
-        :type  user_id: ``str``
-
-        :rtype: ``bool``
-
-        For more info, please see:
-        https://www.worldwidedns.net/dns_api_protocol_transfer.asp
-        """
-        if self.reseller_id is None:
-            raise WorldWideDNSError("This is not a reseller account",
-                                    driver=self)
-        params = {'DOMAIN': domain,
-                  'NEW_ID': user_id}
-        response = self.connection.request('/api_dns_transfer.asp',
-                                           params=params)
-        return response.success()
-
-    def _get_available_record_entry(self, zone):
-        """Return an available entry to store a record."""
-        entries = zone.extra
-        for entry in range(1, MAX_RECORD_ENTRIES + 1):
-            subdomain = entries.get('S%s' % entry)
-            _type = entries.get('T%s' % entry)
-            data = entries.get('D%s' % entry)
-            if not any([subdomain, _type, data]):
-                return entry
-        return None
-
-    def _to_zones(self, data):
-        domain_list = re.split('\r?\n', data)
-        zones = []
-        for line in domain_list:
-            zone = self._to_zone(line)
-            zones.append(zone)
-
-        return zones
-
-    def _to_zone(self, line):
-        data = line.split('\x1f')
-        name = data[0]
-        if data[1] == "P":
-            type = "master"
-            domain_data = self._get_domain_data(name)
-            resp_lines = re.split('\r?\n', domain_data.body)
-            soa_block = resp_lines[:6]
-            zone_data = resp_lines[6:]
-            extra = {'HOSTMASTER': soa_block[0], 'REFRESH': soa_block[1],
-                     'RETRY': soa_block[2], 'EXPIRE': soa_block[3],
-                     'SECURE': soa_block[5]}
-            ttl = soa_block[4]
-            for line in range(MAX_RECORD_ENTRIES):
-                line_data = zone_data[line].split('\x1f')
-                extra['S%s' % (line + 1)] = line_data[0]
-                _type = line_data[1]
-                extra['T%s' % (line + 1)] = _type if _type != 'NONE' else ''
-                try:
-                    extra['D%s' % (line + 1)] = line_data[2]
-                except IndexError:
-                    extra['D%s' % (line + 1)] = ''
-        elif data[1] == 'S':
-            type = 'slave'
-            extra = {}
-            ttl = 0
-        return Zone(id=name, domain=name, type=type,
-                    ttl=ttl, driver=self, extra=extra)
-
-    def _get_domain_data(self, name):
-        params = {'DOMAIN': name}
-        data = self.connection.request('/api_dns_list_domain.asp',
-                                       params=params)
-        return data
-
-    def _to_records(self, zone):
-        records = []
-        for record_id in range(1, MAX_RECORD_ENTRIES + 1):
-            subdomain = zone.extra['S%s' % (record_id)]
-            type = zone.extra['T%s' % (record_id)]
-            data = zone.extra['D%s' % (record_id)]
-            if subdomain and type and data:
-                record = self._to_record(
-                    record_id, subdomain, type, data, zone)
-                records.append(record)
-        return records
-
-    def _to_record(self, _id, subdomain, type, data, zone):
-        return Record(id=_id, name=subdomain, type=type, data=data, zone=zone,
-                      driver=zone.driver)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/zerigo.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/zerigo.py b/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/zerigo.py
deleted file mode 100644
index dacdd75..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/zerigo.py
+++ /dev/null
@@ -1,484 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-__all__ = [
-    'ZerigoDNSDriver'
-]
-
-
-import copy
-import base64
-
-from libcloud.utils.py3 import httplib
-from libcloud.utils.py3 import b
-
-try:
-    from lxml import etree as ET
-except ImportError:
-    from xml.etree import ElementTree as ET
-
-from libcloud.utils.misc import merge_valid_keys, get_new_obj
-from libcloud.utils.xml import findtext, findall
-from libcloud.common.base import XmlResponse, ConnectionUserAndKey
-from libcloud.common.types import InvalidCredsError, LibcloudError
-from libcloud.common.types import MalformedResponseError
-from libcloud.dns.types import Provider, RecordType
-from libcloud.dns.types import ZoneDoesNotExistError, RecordDoesNotExistError
-from libcloud.dns.base import DNSDriver, Zone, Record
-
-API_HOST = 'ns.zerigo.com'
-API_VERSION = '1.1'
-API_ROOT = '/api/%s/' % (API_VERSION)
-
-VALID_ZONE_EXTRA_PARAMS = ['notes', 'tag-list', 'ns1', 'slave-nameservers']
-VALID_RECORD_EXTRA_PARAMS = ['notes', 'ttl', 'priority']
-
-# Number of items per page (maximum limit is 1000)
-ITEMS_PER_PAGE = 100
-
-
-class ZerigoError(LibcloudError):
-    def __init__(self, code, errors):
-        self.code = code
-        self.errors = errors or []
-
-    def __str__(self):
-        return 'Errors: %s' % (', '.join(self.errors))
-
-    def __repr__(self):
-        return ('<ZerigoError response code=%s, errors count=%s>' % (
-            self.code, len(self.errors)))
-
-
-class ZerigoDNSResponse(XmlResponse):
-    def success(self):
-        return self.status in [httplib.OK, httplib.CREATED, httplib.ACCEPTED]
-
-    def parse_error(self):
-        status = int(self.status)
-
-        if status == 401:
-            if not self.body:
-                raise InvalidCredsError(str(self.status) + ': ' + self.error)
-            else:
-                raise InvalidCredsError(self.body)
-        elif status == 404:
-            context = self.connection.context
-            if context['resource'] == 'zone':
-                raise ZoneDoesNotExistError(value='', driver=self,
-                                            zone_id=context['id'])
-            elif context['resource'] == 'record':
-                raise RecordDoesNotExistError(value='', driver=self,
-                                              record_id=context['id'])
-        elif status != 503:
-            try:
-                body = ET.XML(self.body)
-            except:
-                raise MalformedResponseError('Failed to parse XML',
-                                             body=self.body)
-
-            errors = []
-            for error in findall(element=body, xpath='error'):
-                errors.append(error.text)
-
-            raise ZerigoError(code=status, errors=errors)
-
-        return self.body
-
-
-class ZerigoDNSConnection(ConnectionUserAndKey):
-    host = API_HOST
-    secure = True
-    responseCls = ZerigoDNSResponse
-
-    def add_default_headers(self, headers):
-        auth_b64 = base64.b64encode(b('%s:%s' % (self.user_id, self.key)))
-        headers['Authorization'] = 'Basic %s' % (auth_b64.decode('utf-8'))
-        return headers
-
-    def request(self, action, params=None, data='', headers=None,
-                method='GET'):
-        if not headers:
-            headers = {}
-        if not params:
-            params = {}
-
-        if method in ("POST", "PUT"):
-            headers = {'Content-Type': 'application/xml; charset=UTF-8'}
-        return super(ZerigoDNSConnection, self).request(action=action,
-                                                        params=params,
-                                                        data=data,
-                                                        method=method,
-                                                        headers=headers)
-
-
-class ZerigoDNSDriver(DNSDriver):
-    type = Provider.ZERIGO
-    name = 'Zerigo DNS'
-    website = 'http://www.zerigo.com/'
-    connectionCls = ZerigoDNSConnection
-
-    RECORD_TYPE_MAP = {
-        RecordType.A: 'A',
-        RecordType.AAAA: 'AAAA',
-        RecordType.CNAME: 'CNAME',
-        RecordType.GEO: 'GEO',
-        RecordType.MX: 'MX',
-        RecordType.NAPTR: 'NAPTR',
-        RecordType.NS: 'NS',
-        RecordType.PTR: 'PTR',
-        RecordType.REDIRECT: 'REDIRECT',
-        RecordType.SPF: 'SPF',
-        RecordType.SRV: 'SRV',
-        RecordType.TXT: 'TXT',
-        RecordType.URL: 'URL',
-    }
-
-    def iterate_zones(self):
-        return self._get_more('zones')
-
-    def iterate_records(self, zone):
-        return self._get_more('records', zone=zone)
-
-    def get_zone(self, zone_id):
-        path = API_ROOT + 'zones/%s.xml' % (zone_id)
-        self.connection.set_context({'resource': 'zone', 'id': zone_id})
-        data = self.connection.request(path).object
-        zone = self._to_zone(elem=data)
-        return zone
-
-    def get_record(self, zone_id, record_id):
-        zone = self.get_zone(zone_id=zone_id)
-        self.connection.set_context({'resource': 'record', 'id': record_id})
-        path = API_ROOT + 'hosts/%s.xml' % (record_id)
-        data = self.connection.request(path).object
-        record = self._to_record(elem=data, zone=zone)
-        return record
-
-    def create_zone(self, domain, type='master', ttl=None, extra=None):
-        """
-        Create a new zone.
-
-        Provider API docs:
-        https://www.zerigo.com/docs/apis/dns/1.1/zones/create
-
-        @inherits: :class:`DNSDriver.create_zone`
-        """
-        path = API_ROOT + 'zones.xml'
-        zone_elem = self._to_zone_elem(domain=domain, type=type, ttl=ttl,
-                                       extra=extra)
-        data = self.connection.request(action=path,
-                                       data=ET.tostring(zone_elem),
-                                       method='POST').object
-        zone = self._to_zone(elem=data)
-        return zone
-
-    def update_zone(self, zone, domain=None, type=None, ttl=None, extra=None):
-        """
-        Update an existing zone.
-
-        Provider API docs:
-        https://www.zerigo.com/docs/apis/dns/1.1/zones/update
-
-        @inherits: :class:`DNSDriver.update_zone`
-        """
-        if domain:
-            raise LibcloudError('Domain cannot be changed', driver=self)
-
-        path = API_ROOT + 'zones/%s.xml' % (zone.id)
-        zone_elem = self._to_zone_elem(domain=domain, type=type, ttl=ttl,
-                                       extra=extra)
-        response = self.connection.request(action=path,
-                                           data=ET.tostring(zone_elem),
-                                           method='PUT')
-        assert response.status == httplib.OK
-
-        merged = merge_valid_keys(params=copy.deepcopy(zone.extra),
-                                  valid_keys=VALID_ZONE_EXTRA_PARAMS,
-                                  extra=extra)
-        updated_zone = get_new_obj(obj=zone, klass=Zone,
-                                   attributes={'type': type,
-                                               'ttl': ttl,
-                                               'extra': merged})
-        return updated_zone
-
-    def create_record(self, name, zone, type, data, extra=None):
-        """
-        Create a new record.
-
-        Provider API docs:
-        https://www.zerigo.com/docs/apis/dns/1.1/hosts/create
-
-        @inherits: :class:`DNSDriver.create_record`
-        """
-        path = API_ROOT + 'zones/%s/hosts.xml' % (zone.id)
-        record_elem = self._to_record_elem(name=name, type=type, data=data,
-                                           extra=extra)
-        response = self.connection.request(action=path,
-                                           data=ET.tostring(record_elem),
-                                           method='POST')
-        assert response.status == httplib.CREATED
-        record = self._to_record(elem=response.object, zone=zone)
-        return record
-
-    def update_record(self, record, name=None, type=None, data=None,
-                      extra=None):
-        path = API_ROOT + 'hosts/%s.xml' % (record.id)
-        record_elem = self._to_record_elem(name=name, type=type, data=data,
-                                           extra=extra)
-        response = self.connection.request(action=path,
-                                           data=ET.tostring(record_elem),
-                                           method='PUT')
-        assert response.status == httplib.OK
-
-        merged = merge_valid_keys(params=copy.deepcopy(record.extra),
-                                  valid_keys=VALID_RECORD_EXTRA_PARAMS,
-                                  extra=extra)
-        updated_record = get_new_obj(obj=record, klass=Record,
-                                     attributes={'type': type,
-                                                 'data': data,
-                                                 'extra': merged})
-        return updated_record
-
-    def delete_zone(self, zone):
-        path = API_ROOT + 'zones/%s.xml' % (zone.id)
-        self.connection.set_context({'resource': 'zone', 'id': zone.id})
-        response = self.connection.request(action=path, method='DELETE')
-        return response.status == httplib.OK
-
-    def delete_record(self, record):
-        path = API_ROOT + 'hosts/%s.xml' % (record.id)
-        self.connection.set_context({'resource': 'record', 'id': record.id})
-        response = self.connection.request(action=path, method='DELETE')
-        return response.status == httplib.OK
-
-    def ex_get_zone_by_domain(self, domain):
-        """
-        Retrieve a zone object by the domain name.
-
-        :param domain: The domain which should be used
-        :type  domain: ``str``
-
-        :rtype: :class:`Zone`
-        """
-        path = API_ROOT + 'zones/%s.xml' % (domain)
-        self.connection.set_context({'resource': 'zone', 'id': domain})
-        data = self.connection.request(path).object
-        zone = self._to_zone(elem=data)
-        return zone
-
-    def ex_force_slave_axfr(self, zone):
-        """
-        Force a zone transfer.
-
-        :param zone: Zone which should be used.
-        :type  zone: :class:`Zone`
-
-        :rtype: :class:`Zone`
-        """
-        path = API_ROOT + 'zones/%s/force_slave_axfr.xml' % (zone.id)
-        self.connection.set_context({'resource': 'zone', 'id': zone.id})
-        response = self.connection.request(path, method='POST')
-        assert response.status == httplib.ACCEPTED
-        return zone
-
-    def _to_zone_elem(self, domain=None, type=None, ttl=None, extra=None):
-        zone_elem = ET.Element('zone', {})
-
-        if domain:
-            domain_elem = ET.SubElement(zone_elem, 'domain')
-            domain_elem.text = domain
-
-        if type:
-            ns_type_elem = ET.SubElement(zone_elem, 'ns-type')
-
-            if type == 'master':
-                ns_type_elem.text = 'pri_sec'
-            elif type == 'slave':
-                if not extra or 'ns1' not in extra:
-                    raise LibcloudError('ns1 extra attribute is required ' +
-                                        'when zone type is slave', driver=self)
-
-                ns_type_elem.text = 'sec'
-                ns1_elem = ET.SubElement(zone_elem, 'ns1')
-                ns1_elem.text = extra['ns1']
-            elif type == 'std_master':
-                # TODO: Each driver should provide supported zone types
-                # Slave name servers are elsewhere
-                if not extra or 'slave-nameservers' not in extra:
-                    raise LibcloudError('slave-nameservers extra ' +
-                                        'attribute is required whenzone ' +
-                                        'type is std_master', driver=self)
-
-                ns_type_elem.text = 'pri'
-                slave_nameservers_elem = ET.SubElement(zone_elem,
-                                                       'slave-nameservers')
-                slave_nameservers_elem.text = extra['slave-nameservers']
-
-        if ttl:
-            default_ttl_elem = ET.SubElement(zone_elem, 'default-ttl')
-            default_ttl_elem.text = str(ttl)
-
-        if extra and 'tag-list' in extra:
-            tags = extra['tag-list']
-
-            tags_elem = ET.SubElement(zone_elem, 'tag-list')
-            tags_elem.text = ' '.join(tags)
-
-        return zone_elem
-
-    def _to_record_elem(self, name=None, type=None, data=None, extra=None):
-        record_elem = ET.Element('host', {})
-
-        if name:
-            name_elem = ET.SubElement(record_elem, 'hostname')
-            name_elem.text = name
-
-        if type is not None:
-            type_elem = ET.SubElement(record_elem, 'host-type')
-            type_elem.text = self.RECORD_TYPE_MAP[type]
-
-        if data:
-            data_elem = ET.SubElement(record_elem, 'data')
-            data_elem.text = data
-
-        if extra:
-            if 'ttl' in extra:
-                ttl_elem = ET.SubElement(record_elem, 'ttl',
-                                         {'type': 'integer'})
-                ttl_elem.text = str(extra['ttl'])
-
-            if 'priority' in extra:
-                # Only MX and SRV records support priority
-                priority_elem = ET.SubElement(record_elem, 'priority',
-                                              {'type': 'integer'})
-
-                priority_elem.text = str(extra['priority'])
-
-            if 'notes' in extra:
-                notes_elem = ET.SubElement(record_elem, 'notes')
-                notes_elem.text = extra['notes']
-
-        return record_elem
-
-    def _to_zones(self, elem):
-        zones = []
-
-        for item in findall(element=elem, xpath='zone'):
-            zone = self._to_zone(elem=item)
-            zones.append(zone)
-
-        return zones
-
-    def _to_zone(self, elem):
-        id = findtext(element=elem, xpath='id')
-        domain = findtext(element=elem, xpath='domain')
-        type = findtext(element=elem, xpath='ns-type')
-        type = 'master' if type.find('pri') == 0 else 'slave'
-        ttl = findtext(element=elem, xpath='default-ttl')
-
-        hostmaster = findtext(element=elem, xpath='hostmaster')
-        custom_ns = findtext(element=elem, xpath='custom-ns')
-        custom_nameservers = findtext(element=elem, xpath='custom-nameservers')
-        notes = findtext(element=elem, xpath='notes')
-        nx_ttl = findtext(element=elem, xpath='nx-ttl')
-        slave_nameservers = findtext(element=elem, xpath='slave-nameservers')
-        tags = findtext(element=elem, xpath='tag-list')
-        tags = tags.split(' ') if tags else []
-
-        extra = {'hostmaster': hostmaster, 'custom-ns': custom_ns,
-                 'custom-nameservers': custom_nameservers, 'notes': notes,
-                 'nx-ttl': nx_ttl, 'slave-nameservers': slave_nameservers,
-                 'tags': tags}
-        zone = Zone(id=str(id), domain=domain, type=type, ttl=int(ttl),
-                    driver=self, extra=extra)
-        return zone
-
-    def _to_records(self, elem, zone):
-        records = []
-
-        for item in findall(element=elem, xpath='host'):
-            record = self._to_record(elem=item, zone=zone)
-            records.append(record)
-
-        return records
-
-    def _to_record(self, elem, zone):
-        id = findtext(element=elem, xpath='id')
-        name = findtext(element=elem, xpath='hostname')
-        type = findtext(element=elem, xpath='host-type')
-        type = self._string_to_record_type(type)
-        data = findtext(element=elem, xpath='data')
-
-        notes = findtext(element=elem, xpath='notes', no_text_value=None)
-        state = findtext(element=elem, xpath='state', no_text_value=None)
-        fqdn = findtext(element=elem, xpath='fqdn', no_text_value=None)
-        priority = findtext(element=elem, xpath='priority', no_text_value=None)
-        ttl = findtext(element=elem, xpath='ttl', no_text_value=None)
-
-        if not name:
-            name = None
-
-        if ttl:
-            ttl = int(ttl)
-
-        extra = {'notes': notes, 'state': state, 'fqdn': fqdn,
-                 'priority': priority, 'ttl': ttl}
-
-        record = Record(id=id, name=name, type=type, data=data,
-                        zone=zone, driver=self, ttl=ttl, extra=extra)
-        return record
-
-    def _get_more(self, rtype, **kwargs):
-        exhausted = False
-        last_key = None
-
-        while not exhausted:
-            items, last_key, exhausted = self._get_data(rtype, last_key,
-                                                        **kwargs)
-
-            for item in items:
-                yield item
-
-    def _get_data(self, rtype, last_key, **kwargs):
-        # Note: last_key in this case really is a "last_page".
-        # TODO: Update base driver and change last_key to something more
-        # generic - e.g. marker
-        params = {}
-        params['per_page'] = ITEMS_PER_PAGE
-        params['page'] = last_key + 1 if last_key else 1
-
-        if rtype == 'zones':
-            path = API_ROOT + 'zones.xml'
-            response = self.connection.request(path)
-            transform_func = self._to_zones
-        elif rtype == 'records':
-            zone = kwargs['zone']
-            path = API_ROOT + 'zones/%s/hosts.xml' % (zone.id)
-            self.connection.set_context({'resource': 'zone', 'id': zone.id})
-            response = self.connection.request(path, params=params)
-            transform_func = self._to_records
-
-        exhausted = False
-        result_count = int(response.headers.get('x-query-count', 0))
-
-        if (params['page'] * ITEMS_PER_PAGE) >= result_count:
-            exhausted = True
-
-        if response.status == httplib.OK:
-            items = transform_func(elem=response.object, **kwargs)
-            return items, params['page'], exhausted
-        else:
-            return [], None, True

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/zonomi.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/zonomi.py b/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/zonomi.py
deleted file mode 100644
index 003de6d..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/zonomi.py
+++ /dev/null
@@ -1,351 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-Zonomi DNS Driver
-"""
-import sys
-
-from libcloud.common.zonomi import ZonomiConnection, ZonomiResponse
-from libcloud.common.zonomi import ZonomiException
-from libcloud.dns.base import DNSDriver, Zone, Record
-from libcloud.dns.types import ZoneDoesNotExistError, ZoneAlreadyExistsError
-from libcloud.dns.types import RecordAlreadyExistsError
-from libcloud.dns.types import RecordDoesNotExistError
-from libcloud.dns.types import Provider, RecordType
-
-
-__all__ = [
-    'ZonomiDNSDriver',
-]
-
-
-class ZonomiDNSResponse(ZonomiResponse):
-    pass
-
-
-class ZonomiDNSConnection(ZonomiConnection):
-    responseCls = ZonomiDNSResponse
-
-
-class ZonomiDNSDriver(DNSDriver):
-    type = Provider.ZONOMI
-    name = 'Zonomi DNS'
-    website = 'https://zonomi.com'
-    connectionCls = ZonomiDNSConnection
-
-    RECORD_TYPE_MAP = {
-        RecordType.A: 'A',
-        RecordType.MX: 'MX',
-        RecordType.TXT: 'TXT'
-    }
-
-    def list_zones(self):
-        """
-        Return a list of zones.
-
-        :return: ``list`` of :class:`Zone`
-        """
-        action = '/app/dns/dyndns.jsp?'
-        params = {'action': 'QUERYZONES', 'api_key': self.key}
-
-        response = self.connection.request(action=action, params=params)
-        zones = self._to_zones(response.objects)
-
-        return zones
-
-    def list_records(self, zone):
-        """
-        Return a list of records for the provided zone.
-
-        :param zone: Zone to list records for.
-        :type zone: :class:`Zone`
-
-        :return: ``list`` of :class:`Record`
-        """
-        action = '/app/dns/dyndns.jsp?'
-        params = {'action': 'QUERY', 'name': '**.' + zone.id}
-        try:
-            response = self.connection.request(action=action, params=params)
-        except ZonomiException:
-            e = sys.exc_info()[1]
-            if e.code == '404':
-                raise ZoneDoesNotExistError(zone_id=zone.id, driver=self,
-                                            value=e.message)
-            raise e
-
-        records = self._to_records(response.objects, zone)
-
-        return records
-
-    def get_zone(self, zone_id):
-        """
-        Return a Zone instance.
-
-        :param zone_id: ID of the required zone
-        :type  zone_id: ``str``
-
-        :rtype: :class:`Zone`
-        """
-        zone = None
-        zones = self.list_zones()
-        for z in zones:
-            if z.id == zone_id:
-                zone = z
-
-        if zone is None:
-            raise ZoneDoesNotExistError(zone_id=zone_id, driver=self, value='')
-
-        return zone
-
-    def get_record(self, zone_id, record_id):
-        """
-        Return a Record instance.
-
-        :param zone_id: ID of the required zone
-        :type  zone_id: ``str``
-
-        :param record_id: ID of the required record
-        :type  record_id: ``str``
-
-        :rtype: :class:`Record`
-        """
-        record = None
-        zone = self.get_zone(zone_id=zone_id)
-        records = self.list_records(zone=zone)
-
-        for r in records:
-            if r.id == record_id:
-                record = r
-
-        if record is None:
-            raise RecordDoesNotExistError(record_id=record_id, driver=self,
-                                          value='')
-
-        return record
-
-    def create_zone(self, domain, type='master', ttl=None, extra=None):
-        """
-        Create a new zone.
-
-        :param zone_id: Zone domain name (e.g. example.com)
-        :type zone_id: ``str``
-
-        :rtype: :class:`Zone`
-        """
-        action = '/app/dns/addzone.jsp?'
-        params = {'name': domain}
-        try:
-            self.connection.request(action=action, params=params)
-        except ZonomiException:
-            e = sys.exc_info()[1]
-            if e.message == 'ERROR: This zone is already in your zone list.':
-                raise ZoneAlreadyExistsError(zone_id=domain, driver=self,
-                                             value=e.message)
-            raise e
-
-        zone = Zone(id=domain, domain=domain, type='master', ttl=ttl,
-                    driver=self, extra=extra)
-        return zone
-
-    def create_record(self, name, zone, type, data, extra=None):
-        """
-        Create a new record.
-
-        :param name: Record name without the domain name (e.g. www).
-                     Note: If you want to create a record for a base domain
-                     name, you should specify empty string ('') for this
-                     argument.
-        :type  name: ``str``
-
-        :param zone: Zone where the requested record is created.
-        :type  zone: :class:`Zone`
-
-        :param type: DNS record type (A, MX, TXT).
-        :type  type: :class:`RecordType`
-
-        :param data: Data for the record (depends on the record type).
-        :type  data: ``str``
-
-        :param extra: Extra attributes (driver specific, e.g. 'prio' or 'ttl').
-                      (optional)
-        :type extra: ``dict``
-
-        :rtype: :class:`Record`
-        """
-        action = '/app/dns/dyndns.jsp?'
-        if name:
-            record_name = name + '.' + zone.domain
-        else:
-            record_name = zone.domain
-        params = {'action': 'SET', 'name': record_name, 'value': data,
-                  'type': type}
-
-        if type == 'MX' and extra is not None:
-            params['prio'] = extra.get('prio')
-        try:
-            response = self.connection.request(action=action, params=params)
-        except ZonomiException:
-            e = sys.exc_info()[1]
-            if ('ERROR: No zone found for %s' % record_name) in e.message:
-                raise ZoneDoesNotExistError(zone_id=zone.id, driver=self,
-                                            value=e.message)
-            raise e
-
-        # we determine if an A or MX record already exists
-        # by looking at the response.If the key 'skipped' is present in the
-        # response, it means record already exists. If this is True,
-        # then raise RecordAlreadyExistsError
-        if len(response.objects) != 0 and \
-           response.objects[0].get('skipped') == 'unchanged':
-            raise RecordAlreadyExistsError(record_id=name, driver=self,
-                                           value='')
-
-        if 'DELETED' in response.objects:
-            for el in response.objects[:2]:
-                if el.get('content') == data:
-                    response.objects = [el]
-        records = self._to_records(response.objects, zone=zone)
-        return records[0]
-
-    def delete_zone(self, zone):
-        """
-        Delete a zone.
-
-        Note: This will delete all the records belonging to this zone.
-
-        :param zone: Zone to delete.
-        :type  zone: :class:`Zone`
-
-        :rtype: ``bool``
-        """
-        action = '/app/dns/dyndns.jsp?'
-        params = {'action': 'DELETEZONE', 'name': zone.id}
-        try:
-            response = self.connection.request(action=action, params=params)
-        except ZonomiException:
-            e = sys.exc_info()[1]
-            if e.code == '404':
-                raise ZoneDoesNotExistError(zone_id=zone.id, driver=self,
-                                            value=e.message)
-            raise e
-
-        return 'DELETED' in response.objects
-
-    def delete_record(self, record):
-        """
-        Use this method to delete a record.
-
-        :param record: record to delete
-        :type record: `Record`
-
-        :rtype: Bool
-        """
-        action = '/app/dns/dyndns.jsp?'
-        params = {'action': 'DELETE', 'name': record.name, 'type': record.type}
-        try:
-            response = self.connection.request(action=action, params=params)
-        except ZonomiException:
-            e = sys.exc_info()[1]
-            if e.message == 'Record not deleted.':
-                raise RecordDoesNotExistError(record_id=record.id, driver=self,
-                                              value=e.message)
-            raise e
-
-        return 'DELETED' in response.objects
-
-    def ex_convert_to_secondary(self, zone, master):
-        """
-        Convert existent zone to slave.
-
-        :param zone: Zone to convert.
-        :type  zone: :class:`Zone`
-
-        :param master: the specified master name server IP address.
-        :type  master: ``str``
-
-        :rtype: Bool
-        """
-        action = '/app/dns/converttosecondary.jsp?'
-        params = {'name': zone.domain, 'master': master}
-        try:
-            self.connection.request(action=action, params=params)
-        except ZonomiException:
-            e = sys.exc_info()[1]
-            if 'ERROR: Could not find' in e.message:
-                raise ZoneDoesNotExistError(zone_id=zone.id, driver=self,
-                                            value=e.message)
-        return True
-
-    def ex_convert_to_master(self, zone):
-        """
-        Convert existent zone to master.
-
-        :param zone: Zone to convert.
-        :type  zone: :class:`Zone`
-
-        :rtype: Bool
-        """
-        action = '/app/dns/converttomaster.jsp?'
-        params = {'name': zone.domain}
-        try:
-            self.connection.request(action=action, params=params)
-        except ZonomiException:
-            e = sys.exc_info()[1]
-            if 'ERROR: Could not find' in e.message:
-                raise ZoneDoesNotExistError(zone_id=zone.id, driver=self,
-                                            value=e.message)
-        return True
-
-    def _to_zone(self, item):
-        if item['type'] == 'NATIVE':
-            type = 'master'
-        elif item['type'] == 'SLAVE':
-            type = 'slave'
-        zone = Zone(id=item['name'], domain=item['name'], type=type,
-                    driver=self, extra={}, ttl=None)
-
-        return zone
-
-    def _to_zones(self, items):
-        zones = []
-        for item in items:
-            zones.append(self._to_zone(item))
-
-        return zones
-
-    def _to_record(self, item, zone):
-        if len(item.get('ttl')) > 0:
-            ttl = item.get('ttl').split(' ')[0]
-        else:
-            ttl = None
-        extra = {'ttl': ttl,
-                 'prio': item.get('prio')}
-        if len(item['name']) > len(zone.domain):
-            full_domain = item['name']
-            index = full_domain.index('.' + zone.domain)
-            record_name = full_domain[:index]
-        else:
-            record_name = zone.domain
-        record = Record(id=record_name, name=record_name,
-                        data=item['content'], type=item['type'], zone=zone,
-                        driver=self, ttl=ttl, extra=extra)
-
-        return record
-
-    def _to_records(self, items, zone):
-        records = []
-        for item in items:
-            records.append(self._to_record(item, zone))
-
-        return records

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/providers.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/providers.py b/apache-libcloud-1.0.0rc2/libcloud/dns/providers.py
deleted file mode 100644
index ad55385..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/dns/providers.py
+++ /dev/null
@@ -1,93 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from libcloud.dns.types import Provider
-from libcloud.dns.types import OLD_CONSTANT_TO_NEW_MAPPING
-from libcloud.common.providers import get_driver as _get_provider_driver
-from libcloud.common.providers import set_driver as _set_provider_driver
-
-__all__ = [
-    'DRIVERS',
-
-    'get_driver',
-    'set_driver'
-]
-
-DRIVERS = {
-    Provider.DUMMY:
-    ('libcloud.dns.drivers.dummy', 'DummyDNSDriver'),
-    Provider.LINODE:
-    ('libcloud.dns.drivers.linode', 'LinodeDNSDriver'),
-    Provider.ZERIGO:
-    ('libcloud.dns.drivers.zerigo', 'ZerigoDNSDriver'),
-    Provider.RACKSPACE:
-    ('libcloud.dns.drivers.rackspace', 'RackspaceDNSDriver'),
-    Provider.HOSTVIRTUAL:
-    ('libcloud.dns.drivers.hostvirtual', 'HostVirtualDNSDriver'),
-    Provider.ROUTE53:
-    ('libcloud.dns.drivers.route53', 'Route53DNSDriver'),
-    Provider.GANDI:
-    ('libcloud.dns.drivers.gandi', 'GandiDNSDriver'),
-    Provider.GOOGLE: ('libcloud.dns.drivers.google', 'GoogleDNSDriver'),
-    Provider.SOFTLAYER:
-    ('libcloud.dns.drivers.softlayer', 'SoftLayerDNSDriver'),
-    Provider.DIGITAL_OCEAN:
-    ('libcloud.dns.drivers.digitalocean', 'DigitalOceanDNSDriver'),
-    Provider.WORLDWIDEDNS:
-    ('libcloud.dns.drivers.worldwidedns', 'WorldWideDNSDriver'),
-    Provider.DNSIMPLE:
-    ('libcloud.dns.drivers.dnsimple', 'DNSimpleDNSDriver'),
-    Provider.POINTDNS:
-    ('libcloud.dns.drivers.pointdns', 'PointDNSDriver'),
-    Provider.VULTR:
-    ('libcloud.dns.drivers.vultr', 'VultrDNSDriver'),
-    Provider.LIQUIDWEB:
-    ('libcloud.dns.drivers.liquidweb', 'LiquidWebDNSDriver'),
-    Provider.ZONOMI:
-    ('libcloud.dns.drivers.zonomi', 'ZonomiDNSDriver'),
-    Provider.DURABLEDNS:
-    ('libcloud.dns.drivers.durabledns', 'DurableDNSDriver'),
-    Provider.AURORADNS:
-    ('libcloud.dns.drivers.auroradns', 'AuroraDNSDriver'),
-    Provider.GODADDY:
-    ('libcloud.dns.drivers.godaddy', 'GoDaddyDNSDriver'),
-    Provider.CLOUDFLARE:
-    ('libcloud.dns.drivers.cloudflare', 'CloudFlareDNSDriver'),
-    Provider.NFSN:
-    ('libcloud.dns.drivers.nfsn', 'NFSNDNSDriver'),
-    Provider.NSONE:
-    ('libcloud.dns.drivers.nsone', 'NsOneDNSDriver'),
-    Provider.LUADNS:
-    ('libcloud.dns.drivers.luadns', 'LuadnsDNSDriver'),
-    Provider.BUDDYNS:
-    ('libcloud.dns.drivers.buddyns', 'BuddyNSDNSDriver'),
-
-    # Deprecated
-    Provider.RACKSPACE_US:
-    ('libcloud.dns.drivers.rackspace', 'RackspaceUSDNSDriver'),
-    Provider.RACKSPACE_UK:
-    ('libcloud.dns.drivers.rackspace', 'RackspaceUKDNSDriver')
-}
-
-
-def get_driver(provider):
-    deprecated_constants = OLD_CONSTANT_TO_NEW_MAPPING
-    return _get_provider_driver(drivers=DRIVERS, provider=provider,
-                                deprecated_constants=deprecated_constants)
-
-
-def set_driver(provider, module, klass):
-    return _set_provider_driver(drivers=DRIVERS, provider=provider,
-                                module=module, klass=klass)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/types.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/types.py b/apache-libcloud-1.0.0rc2/libcloud/dns/types.py
deleted file mode 100644
index 35994e7..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/dns/types.py
+++ /dev/null
@@ -1,141 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from libcloud.common.types import LibcloudError
-
-__all__ = [
-    'Provider',
-    'RecordType',
-    'ZoneError',
-    'ZoneDoesNotExistError',
-    'ZoneAlreadyExistsError',
-    'RecordError',
-    'RecordDoesNotExistError',
-    'RecordAlreadyExistsError',
-
-    'OLD_CONSTANT_TO_NEW_MAPPING'
-]
-
-
-class Provider(object):
-    DUMMY = 'dummy'
-    AURORADNS = 'auroradns'
-    BUDDYNS = 'buddyns'
-    CLOUDFLARE = 'cloudflare'
-    DIGITAL_OCEAN = 'digitalocean'
-    DNSIMPLE = 'dnsimple'
-    DURABLEDNS = 'durabledns'
-    GANDI = 'gandi'
-    GODADDY = 'godaddy'
-    GOOGLE = 'google'
-    HOSTVIRTUAL = 'hostvirtual'
-    LINODE = 'linode'
-    LIQUIDWEB = 'liquidweb'
-    LUADNS = 'luadns'
-    NFSN = 'nfsn'
-    NSONE = 'nsone'
-    POINTDNS = 'pointdns'
-    RACKSPACE = 'rackspace'
-    ROUTE53 = 'route53'
-    SOFTLAYER = 'softlayer'
-    VULTR = 'vultr'
-    WORLDWIDEDNS = 'worldwidedns'
-    ZERIGO = 'zerigo'
-    ZONOMI = 'zonomi'
-    # Deprecated
-    RACKSPACE_US = 'rackspace_us'
-    RACKSPACE_UK = 'rackspace_uk'
-
-
-OLD_CONSTANT_TO_NEW_MAPPING = {
-    Provider.RACKSPACE_US: Provider.RACKSPACE,
-    Provider.RACKSPACE_UK: Provider.RACKSPACE,
-}
-
-
-class RecordType(object):
-    """
-    DNS record type.
-    """
-    A = 'A'
-    AAAA = 'AAAA'
-    ALIAS = 'ALIAS'
-    CNAME = 'CNAME'
-    DNAME = 'DNAME'
-    GEO = 'GEO'
-    HINFO = 'HINFO'
-    LOC = 'LOC'
-    MX = 'MX'
-    NAPTR = 'NAPTR'
-    NS = 'NS'
-    PTR = 'PTR'
-    REDIRECT = 'REDIRECT'
-    RP = 'RP'
-    SOA = 'SOA'
-    SPF = 'SPF'
-    SRV = 'SRV'
-    SSHFP = 'SSHFP'
-    TXT = 'TXT'
-    URL = 'URL'
-    WKS = 'WKS'
-
-
-class ZoneError(LibcloudError):
-    error_type = 'ZoneError'
-    kwargs = ('zone_id', )
-
-    def __init__(self, value, driver, zone_id):
-        self.zone_id = zone_id
-        super(ZoneError, self).__init__(value=value, driver=driver)
-
-    def __str__(self):
-        return self.__repr__()
-
-    def __repr__(self):
-        return ('<%s in %s, zone_id=%s, value=%s>' %
-                (self.error_type, repr(self.driver),
-                 self.zone_id, self.value))
-
-
-class ZoneDoesNotExistError(ZoneError):
-    error_type = 'ZoneDoesNotExistError'
-
-
-class ZoneAlreadyExistsError(ZoneError):
-    error_type = 'ZoneAlreadyExistsError'
-
-
-class RecordError(LibcloudError):
-    error_type = 'RecordError'
-
-    def __init__(self, value, driver, record_id):
-        self.record_id = record_id
-        super(RecordError, self).__init__(value=value, driver=driver)
-
-    def __str__(self):
-        return self.__repr__()
-
-    def __repr__(self):
-        return ('<%s in %s, record_id=%s, value=%s>' %
-                (self.error_type, repr(self.driver),
-                 self.record_id, self.value))
-
-
-class RecordDoesNotExistError(RecordError):
-    error_type = 'RecordDoesNotExistError'
-
-
-class RecordAlreadyExistsError(RecordError):
-    error_type = 'RecordAlreadyExistsError'


[42/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/backup/drivers/dimensiondata.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/backup/drivers/dimensiondata.py b/apache-libcloud-1.0.0rc2/libcloud/backup/drivers/dimensiondata.py
deleted file mode 100644
index fc83a55..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/backup/drivers/dimensiondata.py
+++ /dev/null
@@ -1,688 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-try:
-    from lxml import etree as ET
-except ImportError:
-    from xml.etree import ElementTree as ET
-
-from libcloud.backup.base import BackupDriver, BackupTarget, BackupTargetJob
-from libcloud.backup.types import BackupTargetType
-from libcloud.backup.types import Provider
-from libcloud.common.dimensiondata import dd_object_to_id
-from libcloud.common.dimensiondata import DimensionDataConnection
-from libcloud.common.dimensiondata import DimensionDataBackupClient
-from libcloud.common.dimensiondata import DimensionDataBackupClientAlert
-from libcloud.common.dimensiondata import DimensionDataBackupClientType
-from libcloud.common.dimensiondata import DimensionDataBackupDetails
-from libcloud.common.dimensiondata import DimensionDataBackupSchedulePolicy
-from libcloud.common.dimensiondata import DimensionDataBackupStoragePolicy
-from libcloud.common.dimensiondata import API_ENDPOINTS, DEFAULT_REGION
-from libcloud.common.dimensiondata import TYPES_URN
-from libcloud.common.dimensiondata import GENERAL_NS, BACKUP_NS
-from libcloud.utils.xml import fixxpath, findtext, findall
-
-DEFAULT_BACKUP_PLAN = 'Advanced'
-
-
-class DimensionDataBackupDriver(BackupDriver):
-    """
-    DimensionData backup driver.
-    """
-
-    selected_region = None
-    connectionCls = DimensionDataConnection
-    name = 'Dimension Data Backup'
-    website = 'https://cloud.dimensiondata.com/'
-    type = Provider.DIMENSIONDATA
-    api_version = 1.0
-
-    network_domain_id = None
-
-    def __init__(self, key, secret=None, secure=True, host=None, port=None,
-                 api_version=None, region=DEFAULT_REGION, **kwargs):
-
-        if region not in API_ENDPOINTS:
-            raise ValueError('Invalid region: %s' % (region))
-
-        self.selected_region = API_ENDPOINTS[region]
-
-        super(DimensionDataBackupDriver, self).__init__(
-            key=key, secret=secret,
-            secure=secure, host=host,
-            port=port,
-            api_version=api_version,
-            region=region,
-            **kwargs)
-
-    def _ex_connection_class_kwargs(self):
-        """
-            Add the region to the kwargs before the connection is instantiated
-        """
-
-        kwargs = super(DimensionDataBackupDriver,
-                       self)._ex_connection_class_kwargs()
-        kwargs['region'] = self.selected_region
-        return kwargs
-
-    def get_supported_target_types(self):
-        """
-        Get a list of backup target types this driver supports
-
-        :return: ``list`` of :class:``BackupTargetType``
-        """
-        return [BackupTargetType.VIRTUAL]
-
-    def list_targets(self):
-        """
-        List all backuptargets
-
-        :rtype: ``list`` of :class:`BackupTarget`
-        """
-        targets = self._to_targets(
-            self.connection.request_with_orgId_api_2('server/server').object)
-        return targets
-
-    def create_target(self, name, address,
-                      type=BackupTargetType.VIRTUAL, extra=None):
-        """
-        Creates a new backup target
-
-        :param name: Name of the target (not used)
-        :type name: ``str``
-
-        :param address: The ID of the node in Dimension Data Cloud
-        :type address: ``str``
-
-        :param type: Backup target type, only Virtual supported
-        :type type: :class:`BackupTargetType`
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type extra: ``dict``
-
-        :rtype: Instance of :class:`BackupTarget`
-        """
-        if extra is not None:
-            service_plan = extra.get('servicePlan', DEFAULT_BACKUP_PLAN)
-        else:
-            service_plan = DEFAULT_BACKUP_PLAN
-            extra = {'servicePlan': service_plan}
-
-        create_node = ET.Element('NewBackup',
-                                 {'xmlns': BACKUP_NS})
-        create_node.set('servicePlan', service_plan)
-
-        response = self.connection.request_with_orgId_api_1(
-            'server/%s/backup' % (address),
-            method='POST',
-            data=ET.tostring(create_node)).object
-
-        asset_id = None
-        for info in findall(response,
-                            'additionalInformation',
-                            GENERAL_NS):
-            if info.get('name') == 'assetId':
-                asset_id = findtext(info, 'value', GENERAL_NS)
-
-        return BackupTarget(
-            id=asset_id,
-            name=name,
-            address=address,
-            type=type,
-            extra=extra,
-            driver=self
-        )
-
-    def create_target_from_node(self, node, type=BackupTargetType.VIRTUAL,
-                                extra=None):
-        """
-        Creates a new backup target from an existing node
-
-        :param node: The Node to backup
-        :type  node: ``Node``
-
-        :param type: Backup target type (Physical, Virtual, ...).
-        :type type: :class:`BackupTargetType`
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type extra: ``dict``
-
-        :rtype: Instance of :class:`BackupTarget`
-        """
-        return self.create_target(name=node.name,
-                                  address=node.id,
-                                  type=BackupTargetType.VIRTUAL,
-                                  extra=extra)
-
-    def create_target_from_container(self, container,
-                                     type=BackupTargetType.OBJECT,
-                                     extra=None):
-        """
-        Creates a new backup target from an existing storage container
-
-        :param node: The Container to backup
-        :type  node: ``Container``
-
-        :param type: Backup target type (Physical, Virtual, ...).
-        :type type: :class:`BackupTargetType`
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type extra: ``dict``
-
-        :rtype: Instance of :class:`BackupTarget`
-        """
-        return NotImplementedError(
-            'create_target_from_container not supported for this driver')
-
-    def update_target(self, target, name=None, address=None, extra=None):
-        """
-        Update the properties of a backup target, only changing the serviceplan
-        is supported.
-
-        :param target: Backup target to update
-        :type  target: Instance of :class:`BackupTarget` or ``str``
-
-        :param name: Name of the target
-        :type name: ``str``
-
-        :param address: Hostname, FQDN, IP, file path etc.
-        :type address: ``str``
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type extra: ``dict``
-
-        :rtype: Instance of :class:`BackupTarget`
-        """
-        if extra is not None:
-            service_plan = extra.get('servicePlan', DEFAULT_BACKUP_PLAN)
-        else:
-            service_plan = DEFAULT_BACKUP_PLAN
-        request = ET.Element('ModifyBackup',
-                             {'xmlns': BACKUP_NS})
-        request.set('servicePlan', service_plan)
-        server_id = self._target_to_target_address(target)
-        self.connection.request_with_orgId_api_1(
-            'server/%s/backup/modify' % (server_id),
-            method='POST',
-            data=ET.tostring(request)).object
-        if isinstance(target, BackupTarget):
-            target.extra = extra
-        else:
-            target = self.ex_get_target_by_id(server_id)
-        return target
-
-    def delete_target(self, target):
-        """
-        Delete a backup target
-
-        :param target: Backup target to delete
-        :type  target: Instance of :class:`BackupTarget` or ``str``
-
-        :rtype: ``bool``
-        """
-        server_id = self._target_to_target_address(target)
-        response = self.connection.request_with_orgId_api_1(
-            'server/%s/backup?disable' % (server_id),
-            method='GET').object
-        response_code = findtext(response, 'result', GENERAL_NS)
-        return response_code in ['IN_PROGRESS', 'SUCCESS']
-
-    def list_recovery_points(self, target, start_date=None, end_date=None):
-        """
-        List the recovery points available for a target
-
-        :param target: Backup target to delete
-        :type  target: Instance of :class:`BackupTarget`
-
-        :param start_date: The start date to show jobs between (optional)
-        :type  start_date: :class:`datetime.datetime`
-
-        :param end_date: The end date to show jobs between (optional)
-        :type  end_date: :class:`datetime.datetime``
-
-        :rtype: ``list`` of :class:`BackupTargetRecoveryPoint`
-        """
-        raise NotImplementedError(
-            'list_recovery_points not implemented for this driver')
-
-    def recover_target(self, target, recovery_point, path=None):
-        """
-        Recover a backup target to a recovery point
-
-        :param target: Backup target to delete
-        :type  target: Instance of :class:`BackupTarget`
-
-        :param recovery_point: Backup target with the backup data
-        :type  recovery_point: Instance of :class:`BackupTarget`
-
-        :param path: The part of the recovery point to recover (optional)
-        :type  path: ``str``
-
-        :rtype: Instance of :class:`BackupTargetJob`
-        """
-        raise NotImplementedError(
-            'recover_target not implemented for this driver')
-
-    def recover_target_out_of_place(self, target, recovery_point,
-                                    recovery_target, path=None):
-        """
-        Recover a backup target to a recovery point out-of-place
-
-        :param target: Backup target with the backup data
-        :type  target: Instance of :class:`BackupTarget`
-
-        :param recovery_point: Backup target with the backup data
-        :type  recovery_point: Instance of :class:`BackupTarget`
-
-        :param recovery_target: Backup target with to recover the data to
-        :type  recovery_target: Instance of :class:`BackupTarget`
-
-        :param path: The part of the recovery point to recover (optional)
-        :type  path: ``str``
-
-        :rtype: Instance of :class:`BackupTargetJob`
-        """
-        raise NotImplementedError(
-            'recover_target_out_of_place not implemented for this driver')
-
-    def get_target_job(self, target, id):
-        """
-        Get a specific backup job by ID
-
-        :param target: Backup target with the backup data
-        :type  target: Instance of :class:`BackupTarget`
-
-        :param id: Backup target with the backup data
-        :type  id: Instance of :class:`BackupTarget`
-
-        :rtype: :class:`BackupTargetJob`
-        """
-        jobs = self.list_target_jobs(target)
-        return list(filter(lambda x: x.id == id, jobs))[0]
-
-    def list_target_jobs(self, target):
-        """
-        List the backup jobs on a target
-
-        :param target: Backup target with the backup data
-        :type  target: Instance of :class:`BackupTarget`
-
-        :rtype: ``list`` of :class:`BackupTargetJob`
-        """
-        raise NotImplementedError(
-            'list_target_jobs not implemented for this driver')
-
-    def create_target_job(self, target, extra=None):
-        """
-        Create a new backup job on a target
-
-        :param target: Backup target with the backup data
-        :type  target: Instance of :class:`BackupTarget`
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type extra: ``dict``
-
-        :rtype: Instance of :class:`BackupTargetJob`
-        """
-        raise NotImplementedError(
-            'create_target_job not implemented for this driver')
-
-    def resume_target_job(self, target, job):
-        """
-        Resume a suspended backup job on a target
-
-        :param target: Backup target with the backup data
-        :type  target: Instance of :class:`BackupTarget`
-
-        :param job: Backup target job to resume
-        :type  job: Instance of :class:`BackupTargetJob`
-
-        :rtype: ``bool``
-        """
-        raise NotImplementedError(
-            'resume_target_job not implemented for this driver')
-
-    def suspend_target_job(self, target, job):
-        """
-        Suspend a running backup job on a target
-
-        :param target: Backup target with the backup data
-        :type  target: Instance of :class:`BackupTarget`
-
-        :param job: Backup target job to suspend
-        :type  job: Instance of :class:`BackupTargetJob`
-
-        :rtype: ``bool``
-        """
-        raise NotImplementedError(
-            'suspend_target_job not implemented for this driver')
-
-    def cancel_target_job(self, job, ex_client=None, ex_target=None):
-        """
-        Cancel a backup job on a target
-
-        :param job: Backup target job to cancel.  If it is ``None``
-                    ex_client and ex_target must be set
-        :type  job: Instance of :class:`BackupTargetJob` or ``None``
-
-        :param ex_client: Client of the job to cancel.
-                          Not necessary if job is specified.
-                          DimensionData only has 1 job per client
-        :type  ex_client: Instance of :class:`DimensionDataBackupClient`
-                          or ``str``
-
-        :param ex_target: Target to cancel a job from.
-                          Not necessary if job is specified.
-        :type  ex_target: Instance of :class:`BackupTarget` or ``str``
-
-        :rtype: ``bool``
-        """
-        if job is None:
-            if ex_client is None or ex_target is None:
-                raise ValueError("Either job or ex_client and "
-                                 "ex_target have to be set")
-            server_id = self._target_to_target_address(ex_target)
-            client_id = self._client_to_client_id(ex_client)
-        else:
-            server_id = job.target.address
-            client_id = job.extra['clientId']
-
-        response = self.connection.request_with_orgId_api_1(
-            'server/%s/backup/client/%s?cancelJob' % (server_id,
-                                                      client_id),
-            method='GET').object
-        response_code = findtext(response, 'result', GENERAL_NS)
-        return response_code in ['IN_PROGRESS', 'SUCCESS']
-
-    def ex_get_target_by_id(self, id):
-        """
-        Get a target by server id
-
-        :param id: The id of the target you want to get
-        :type  id: ``str``
-
-        :rtype: :class:`BackupTarget`
-        """
-        node = self.connection.request_with_orgId_api_2(
-            'server/server/%s' % id).object
-        return self._to_target(node)
-
-    def ex_add_client_to_target(self, target, client_type, storage_policy,
-                                schedule_policy, trigger, email):
-        """
-        Add a client to a target
-
-        :param target: Backup target with the backup data
-        :type  target: Instance of :class:`BackupTarget` or ``str``
-
-        :param client: Client to add to the target
-        :type  client: Instance of :class:`DimensionDataBackupClientType`
-                       or ``str``
-
-        :param storage_policy: The storage policy for the client
-        :type  storage_policy: Instance of
-                               :class:`DimensionDataBackupStoragePolicy`
-                               or ``str``
-
-        :param schedule_policy: The schedule policy for the client
-        :type  schedule_policy: Instance of
-                                :class:`DimensionDataBackupSchedulePolicy`
-                                or ``str``
-
-        :param trigger: The notify trigger for the client
-        :type  trigger: ``str``
-
-        :param email: The notify email for the client
-        :type  email: ``str``
-
-        :rtype: ``bool``
-        """
-        server_id = self._target_to_target_address(target)
-
-        backup_elm = ET.Element('NewBackupClient',
-                                {'xmlns': BACKUP_NS})
-        if isinstance(client_type, DimensionDataBackupClientType):
-            ET.SubElement(backup_elm, "type").text = client_type.type
-        else:
-            ET.SubElement(backup_elm, "type").text = client_type
-
-        if isinstance(storage_policy, DimensionDataBackupStoragePolicy):
-            ET.SubElement(backup_elm,
-                          "storagePolicyName").text = storage_policy.name
-        else:
-            ET.SubElement(backup_elm,
-                          "storagePolicyName").text = storage_policy
-
-        if isinstance(schedule_policy, DimensionDataBackupSchedulePolicy):
-            ET.SubElement(backup_elm,
-                          "schedulePolicyName").text = schedule_policy.name
-        else:
-            ET.SubElement(backup_elm,
-                          "schedulePolicyName").text = schedule_policy
-
-        alerting_elm = ET.SubElement(backup_elm, "alerting")
-        alerting_elm.set('trigger', trigger)
-        ET.SubElement(alerting_elm, "emailAddress").text = email
-
-        response = self.connection.request_with_orgId_api_1(
-            'server/%s/backup/client' % (server_id),
-            method='POST',
-            data=ET.tostring(backup_elm)).object
-        response_code = findtext(response, 'result', GENERAL_NS)
-        return response_code in ['IN_PROGRESS', 'SUCCESS']
-
-    def ex_remove_client_from_target(self, target, backup_client):
-        """
-        Removes a client from a backup target
-
-        :param  target: The backup target to remove the client from
-        :type   target: :class:`BackupTarget` or ``str``
-
-        :param  backup_client: The backup client to remove
-        :type   backup_client: :class:`DimensionDataBackupClient` or ``str``
-
-        :rtype: ``bool``
-        """
-        server_id = self._target_to_target_address(target)
-        client_id = self._client_to_client_id(backup_client)
-        response = self.connection.request_with_orgId_api_1(
-            'server/%s/backup/client/%s?disable' % (server_id, client_id),
-            method='GET').object
-        response_code = findtext(response, 'result', GENERAL_NS)
-        return response_code in ['IN_PROGRESS', 'SUCCESS']
-
-    def ex_get_backup_details_for_target(self, target):
-        """
-        Returns a backup details object for a target
-
-        :param  target: The backup target to get details for
-        :type   target: :class:`BackupTarget` or ``str``
-
-        :rtype: :class:`DimensionDataBackupDetails`
-        """
-        if not isinstance(target, BackupTarget):
-            target = self.ex_get_target_by_id(target)
-        response = self.connection.request_with_orgId_api_1(
-            'server/%s/backup' % (target.address),
-            method='GET').object
-        return self._to_backup_details(response, target)
-
-    def ex_list_available_client_types(self, target):
-        """
-        Returns a list of available backup client types
-
-        :param  target: The backup target to list available types for
-        :type   target: :class:`BackupTarget` or ``str``
-
-        :rtype: ``list`` of :class:`DimensionDataBackupClientType`
-        """
-        server_id = self._target_to_target_address(target)
-        response = self.connection.request_with_orgId_api_1(
-            'server/%s/backup/client/type' % (server_id),
-            method='GET').object
-        return self._to_client_types(response)
-
-    def ex_list_available_storage_policies(self, target):
-        """
-        Returns a list of available backup storage policies
-
-        :param  target: The backup target to list available policies for
-        :type   target: :class:`BackupTarget` or ``str``
-
-        :rtype: ``list`` of :class:`DimensionDataBackupStoragePolicy`
-        """
-        server_id = self._target_to_target_address(target)
-        response = self.connection.request_with_orgId_api_1(
-            'server/%s/backup/client/storagePolicy' % (server_id),
-            method='GET').object
-        return self._to_storage_policies(response)
-
-    def ex_list_available_schedule_policies(self, target):
-        """
-        Returns a list of available backup schedule policies
-
-        :param  target: The backup target to list available policies for
-        :type   target: :class:`BackupTarget` or ``str``
-
-        :rtype: ``list`` of :class:`DimensionDataBackupSchedulePolicy`
-        """
-        server_id = self._target_to_target_address(target)
-        response = self.connection.request_with_orgId_api_1(
-            'server/%s/backup/client/schedulePolicy' % (server_id),
-            method='GET').object
-        return self._to_schedule_policies(response)
-
-    def _to_storage_policies(self, object):
-        elements = object.findall(fixxpath('storagePolicy', BACKUP_NS))
-
-        return [self._to_storage_policy(el) for el in elements]
-
-    def _to_storage_policy(self, element):
-        return DimensionDataBackupStoragePolicy(
-            retention_period=int(element.get('retentionPeriodInDays')),
-            name=element.get('name'),
-            secondary_location=element.get('secondaryLocation')
-        )
-
-    def _to_schedule_policies(self, object):
-        elements = object.findall(fixxpath('schedulePolicy', BACKUP_NS))
-
-        return [self._to_schedule_policy(el) for el in elements]
-
-    def _to_schedule_policy(self, element):
-        return DimensionDataBackupSchedulePolicy(
-            name=element.get('name'),
-            description=element.get('description')
-        )
-
-    def _to_client_types(self, object):
-        elements = object.findall(fixxpath('backupClientType', BACKUP_NS))
-
-        return [self._to_client_type(el) for el in elements]
-
-    def _to_client_type(self, element):
-        description = element.get('description')
-        if description is None:
-            description = findtext(element, 'description', BACKUP_NS)
-        return DimensionDataBackupClientType(
-            type=element.get('type'),
-            description=description,
-            is_file_system=bool(element.get('isFileSystem') == 'true')
-        )
-
-    def _to_backup_details(self, object, target):
-        return DimensionDataBackupDetails(
-            asset_id=object.get('assetId'),
-            service_plan=object.get('servicePlan'),
-            status=object.get('state'),
-            clients=self._to_clients(object, target)
-        )
-
-    def _to_clients(self, object, target):
-        elements = object.findall(fixxpath('backupClient', BACKUP_NS))
-
-        return [self._to_client(el, target) for el in elements]
-
-    def _to_client(self, element, target):
-        client_id = element.get('id')
-        return DimensionDataBackupClient(
-            id=client_id,
-            type=self._to_client_type(element),
-            status=element.get('status'),
-            schedule_policy=findtext(element, 'schedulePolicyName', BACKUP_NS),
-            storage_policy=findtext(element, 'storagePolicyName', BACKUP_NS),
-            download_url=findtext(element, 'downloadUrl', BACKUP_NS),
-            running_job=self._to_backup_job(element, target, client_id),
-            alert=self._to_alert(element)
-        )
-
-    def _to_alert(self, element):
-        alert = element.find(fixxpath('alerting', BACKUP_NS))
-        if alert is not None:
-            notify_list = [
-                email_addr.text for email_addr
-                in alert.findall(fixxpath('emailAddress', BACKUP_NS))
-            ]
-            return DimensionDataBackupClientAlert(
-                trigger=element.get('trigger'),
-                notify_list=notify_list
-            )
-        return None
-
-    def _to_backup_job(self, element, target, client_id):
-        running_job = element.find(fixxpath('runningJob', BACKUP_NS))
-        if running_job is not None:
-            return BackupTargetJob(
-                id=running_job.get('id'),
-                status=running_job.get('status'),
-                progress=int(running_job.get('percentageComplete')),
-                driver=self.connection.driver,
-                target=target,
-                extra={'clientId': client_id}
-            )
-        return None
-
-    def _to_targets(self, object):
-        node_elements = object.findall(fixxpath('server', TYPES_URN))
-
-        return [self._to_target(el) for el in node_elements]
-
-    def _to_target(self, element):
-        backup = findall(element, 'backup', TYPES_URN)
-        if len(backup) == 0:
-            return
-        extra = {
-            'description': findtext(element, 'description', TYPES_URN),
-            'sourceImageId': findtext(element, 'sourceImageId', TYPES_URN),
-            'datacenterId': element.get('datacenterId'),
-            'deployedTime': findtext(element, 'createTime', TYPES_URN),
-            'servicePlan': backup[0].get('servicePlan')
-        }
-
-        n = BackupTarget(id=backup[0].get('assetId'),
-                         name=findtext(element, 'name', TYPES_URN),
-                         address=element.get('id'),
-                         driver=self.connection.driver,
-                         type=BackupTargetType.VIRTUAL,
-                         extra=extra)
-        return n
-
-    @staticmethod
-    def _client_to_client_id(backup_client):
-        return dd_object_to_id(backup_client, DimensionDataBackupClient)
-
-    @staticmethod
-    def _target_to_target_address(target):
-        return dd_object_to_id(target, BackupTarget, id_value='address')

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/backup/drivers/dummy.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/backup/drivers/dummy.py b/apache-libcloud-1.0.0rc2/libcloud/backup/drivers/dummy.py
deleted file mode 100644
index 2b28d66..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/backup/drivers/dummy.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from libcloud.backup.base import BackupDriver
-
-
-class DummyBackupDriver(BackupDriver):
-    """
-    Dummy Backup driver.
-
-    >>> from libcloud.backup.drivers.dummy import DummyBackupDriver
-    >>> driver = DummyBackupDriver('key', 'secret')
-    >>> driver.name
-    'Dummy Backup Provider'
-    """
-
-    name = 'Dummy Backup Provider'
-    website = 'http://example.com'
-
-    def __init__(self, api_key, api_secret):
-        """
-        :param    api_key:    API key or username to used (required)
-        :type     api_key:    ``str``
-
-        :param    api_secret: Secret password to be used (required)
-        :type     api_secret: ``str``
-
-        :rtype: ``None``
-        """

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/backup/drivers/ebs.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/backup/drivers/ebs.py b/apache-libcloud-1.0.0rc2/libcloud/backup/drivers/ebs.py
deleted file mode 100644
index fbeddb1..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/backup/drivers/ebs.py
+++ /dev/null
@@ -1,413 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-__all__ = [
-    'EBSBackupDriver'
-]
-
-
-from libcloud.utils.xml import findtext, findall
-from libcloud.utils.iso8601 import parse_date
-from libcloud.backup.base import BackupDriver, BackupTargetRecoveryPoint,\
-    BackupTargetJob, BackupTarget
-from libcloud.backup.types import BackupTargetType, BackupTargetJobStatusType
-from libcloud.common.aws import AWSGenericResponse, SignedAWSConnection
-
-
-VERSION = '2015-10-01'
-HOST = 'ec2.amazonaws.com'
-ROOT = '/%s/' % (VERSION)
-NS = 'http://ec2.amazonaws.com/doc/%s/' % (VERSION, )
-
-
-class EBSResponse(AWSGenericResponse):
-    """
-    Amazon EBS response class.
-    """
-    namespace = NS
-    exceptions = {}
-    xpath = 'Error'
-
-
-class EBSConnection(SignedAWSConnection):
-    version = VERSION
-    host = HOST
-    responseCls = EBSResponse
-    service_name = 'backup'
-
-
-class EBSBackupDriver(BackupDriver):
-    name = 'Amazon EBS Backup Driver'
-    website = 'http://aws.amazon.com/ebs/'
-    connectionCls = EBSConnection
-
-    def __init__(self, access_id, secret, region):
-        super(EBSBackupDriver, self).__init__(access_id, secret)
-        self.region = region
-        self.connection.host = HOST % (region)
-
-    def get_supported_target_types(self):
-        """
-        Get a list of backup target types this driver supports
-
-        :return: ``list`` of :class:``BackupTargetType``
-        """
-        return [BackupTargetType.VOLUME]
-
-    def list_targets(self):
-        """
-        List all backuptargets
-
-        :rtype: ``list`` of :class:`BackupTarget`
-        """
-        raise NotImplementedError(
-            'list_targets not implemented for this driver')
-
-    def create_target(self, name, address,
-                      type=BackupTargetType.VOLUME, extra=None):
-        """
-        Creates a new backup target
-
-        :param name: Name of the target
-        :type name: ``str``
-
-        :param address: The volume ID.
-        :type address: ``str``
-
-        :param type: Backup target type (Physical, Virtual, ...).
-        :type type: :class:`BackupTargetType`
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type extra: ``dict``
-
-        :rtype: Instance of :class:`BackupTarget`
-        """
-        # Does nothing since any volume can be snapped at anytime.
-        return self.ex_get_target_by_volume_id(address)
-
-    def create_target_from_node(self, node, type=BackupTargetType.VIRTUAL,
-                                extra=None):
-        """
-        Creates a new backup target from an existing node
-
-        :param node: The Node to backup
-        :type  node: ``Node``
-
-        :param type: Backup target type (Physical, Virtual, ...).
-        :type type: :class:`BackupTargetType`
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type extra: ``dict``
-
-        :rtype: Instance of :class:`BackupTarget`
-        """
-        # Get the first EBS volume.
-        device_mapping = node.extra['block_device_mapping']
-        if device_mapping is not None:
-            return self.create_target(
-                name=node.name,
-                address=device_mapping['ebs'][0]['volume_id'],
-                type=BackupTargetType.VOLUME,
-                extra=None)
-        else:
-            raise RuntimeError("Node does not have any block devices")
-
-    def create_target_from_container(self, container,
-                                     type=BackupTargetType.OBJECT,
-                                     extra=None):
-        """
-        Creates a new backup target from an existing storage container
-
-        :param node: The Container to backup
-        :type  node: ``Container``
-
-        :param type: Backup target type (Physical, Virtual, ...).
-        :type type: :class:`BackupTargetType`
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type extra: ``dict``
-
-        :rtype: Instance of :class:`BackupTarget`
-        """
-        raise NotImplementedError(
-            'create_target_from_container not implemented for this driver')
-
-    def update_target(self, target, name, address, extra):
-        """
-        Update the properties of a backup target
-
-        :param target: Backup target to update
-        :type  target: Instance of :class:`BackupTarget`
-
-        :param name: Name of the target
-        :type name: ``str``
-
-        :param address: Hostname, FQDN, IP, file path etc.
-        :type address: ``str``
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type extra: ``dict``
-
-        :rtype: Instance of :class:`BackupTarget`
-        """
-        # Does nothing since any volume can be snapped at anytime.
-        return self.ex_get_target_by_volume_id(address)
-
-    def delete_target(self, target):
-        """
-        Delete a backup target
-
-        :param target: Backup target to delete
-        :type  target: Instance of :class:`BackupTarget`
-        """
-        raise NotImplementedError(
-            'delete_target not implemented for this driver')
-
-    def list_recovery_points(self, target, start_date=None, end_date=None):
-        """
-        List the recovery points available for a target
-
-        :param target: Backup target to delete
-        :type  target: Instance of :class:`BackupTarget`
-
-        :param start_date: The start date to show jobs between (optional)
-        :type  start_date: :class:`datetime.datetime`
-
-        :param end_date: The end date to show jobs between (optional)
-        :type  end_date: :class:`datetime.datetime``
-
-        :rtype: ``list`` of :class:`BackupTargetRecoveryPoint`
-        """
-        params = {
-            'Action': 'DescribeSnapshots',
-            'Filter.1.Name': 'volume-id',
-            'Filter.1.Value': target.extra['volume-id']
-        }
-        data = self.connection.request(ROOT, params=params).object
-        return self._to_recovery_points(data, target)
-
-    def recover_target(self, target, recovery_point, path=None):
-        """
-        Recover a backup target to a recovery point
-
-        :param target: Backup target to delete
-        :type  target: Instance of :class:`BackupTarget`
-
-        :param recovery_point: Backup target with the backup data
-        :type  recovery_point: Instance of :class:`BackupTarget`
-
-        :param path: The part of the recovery point to recover (optional)
-        :type  path: ``str``
-
-        :rtype: Instance of :class:`BackupTargetJob`
-        """
-        raise NotImplementedError(
-            'delete_target not implemented for this driver')
-
-    def recover_target_out_of_place(self, target, recovery_point,
-                                    recovery_target, path=None):
-        """
-        Recover a backup target to a recovery point out-of-place
-
-        :param target: Backup target with the backup data
-        :type  target: Instance of :class:`BackupTarget`
-
-        :param recovery_point: Backup target with the backup data
-        :type  recovery_point: Instance of :class:`BackupTarget`
-
-        :param recovery_target: Backup target with to recover the data to
-        :type  recovery_target: Instance of :class:`BackupTarget`
-
-        :param path: The part of the recovery point to recover (optional)
-        :type  path: ``str``
-
-        :rtype: Instance of :class:`BackupTargetJob`
-        """
-        raise NotImplementedError(
-            'delete_target not implemented for this driver')
-
-    def get_target_job(self, target, id):
-        """
-        Get a specific backup job by ID
-
-        :param target: Backup target with the backup data
-        :type  target: Instance of :class:`BackupTarget`
-
-        :param id: Backup target with the backup data
-        :type  id: Instance of :class:`BackupTarget`
-
-        :rtype: :class:`BackupTargetJob`
-        """
-        jobs = self.list_target_jobs(target)
-        return list(filter(lambda x: x.id == id, jobs))[0]
-
-    def list_target_jobs(self, target):
-        """
-        List the backup jobs on a target
-
-        :param target: Backup target with the backup data
-        :type  target: Instance of :class:`BackupTarget`
-
-        :rtype: ``list`` of :class:`BackupTargetJob`
-        """
-        params = {
-            'Action': 'DescribeSnapshots',
-            'Filter.1.Name': 'volume-id',
-            'Filter.1.Value': target.extra['volume-id'],
-            'Filter.2.Name': 'status',
-            'Filter.2.Value': 'pending'
-        }
-        data = self.connection.request(ROOT, params=params).object
-        return self._to_jobs(data)
-
-    def create_target_job(self, target, extra=None):
-        """
-        Create a new backup job on a target
-
-        :param target: Backup target with the backup data
-        :type  target: Instance of :class:`BackupTarget`
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type extra: ``dict``
-
-        :rtype: Instance of :class:`BackupTargetJob`
-        """
-        params = {
-            'Action': 'CreateSnapshot',
-            'VolumeId': target.extra['volume-id']
-        }
-        data = self.connection.request(ROOT, params=params).object
-        xpath = 'CreateSnapshotResponse'
-        return self._to_job(findall(element=data,
-                                    xpath=xpath, namespace=NS)[0])
-
-    def resume_target_job(self, job):
-        """
-        Resume a suspended backup job on a target
-
-        :param job: Backup target job to resume
-        :type  job: Instance of :class:`BackupTargetJob`
-
-        :rtype: ``bool``
-        """
-        raise NotImplementedError(
-            'resume_target_job not supported for this driver')
-
-    def suspend_target_job(self, job):
-        """
-        Suspend a running backup job on a target
-
-        :param job: Backup target job to suspend
-        :type  job: Instance of :class:`BackupTargetJob`
-
-        :rtype: ``bool``
-        """
-        raise NotImplementedError(
-            'suspend_target_job not supported for this driver')
-
-    def cancel_target_job(self, job):
-        """
-        Cancel a backup job on a target
-
-        :param job: Backup target job to cancel
-        :type  job: Instance of :class:`BackupTargetJob`
-
-        :rtype: ``bool``
-        """
-        raise NotImplementedError(
-            'cancel_target_job not supported for this driver')
-
-    def _to_recovery_points(self, data, target):
-        xpath = 'DescribeSnapshotsResponse/snapshotSet/item'
-        return [self._to_recovery_point(el, target)
-                for el in findall(element=data, xpath=xpath, namespace=NS)]
-
-    def _to_recovery_point(self, el, target):
-        id = findtext(element=el, xpath='snapshotId', namespace=NS)
-        date = parse_date(
-            findtext(element=el, xpath='startTime', namespace=NS))
-        tags = self._get_resource_tags(el)
-        point = BackupTargetRecoveryPoint(
-            id=id,
-            date=date,
-            target=target,
-            driver=self.connection.driver,
-            extra={
-                'snapshot-id': id,
-                'tags': tags
-            },
-        )
-        return point
-
-    def _to_jobs(self, data):
-        xpath = 'DescribeSnapshotsResponse/snapshotSet/item'
-        return [self._to_job(el)
-                for el in findall(element=data, xpath=xpath, namespace=NS)]
-
-    def _to_job(self, el):
-        id = findtext(element=el, xpath='snapshotId', namespace=NS)
-        progress = findtext(element=el, xpath='progress', namespace=NS)\
-            .replace('%', '')
-        volume_id = findtext(element=el, xpath='volumeId', namespace=NS)
-        target = self.ex_get_target_by_volume_id(volume_id)
-        job = BackupTargetJob(
-            id=id,
-            status=BackupTargetJobStatusType.PENDING,
-            progress=int(progress),
-            target=target,
-            driver=self.connection.driver,
-            extra={
-            },
-        )
-        return job
-
-    def ex_get_target_by_volume_id(self, volume_id):
-        return BackupTarget(
-            id=volume_id,
-            name=volume_id,
-            address=volume_id,
-            type=BackupTargetType.VOLUME,
-            driver=self.connection.driver,
-            extra={
-                "volume-id": volume_id
-            }
-        )
-
-    def _get_resource_tags(self, element):
-        """
-        Parse tags from the provided element and return a dictionary with
-        key/value pairs.
-
-        :rtype: ``dict``
-        """
-        tags = {}
-
-        # Get our tag set by parsing the element
-        tag_set = findall(element=element,
-                          xpath='tagSet/item',
-                          namespace=NS)
-
-        for tag in tag_set:
-            key = findtext(element=tag,
-                           xpath='key',
-                           namespace=NS)
-
-            value = findtext(element=tag,
-                             xpath='value',
-                             namespace=NS)
-
-            tags[key] = value
-
-        return tags

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/backup/drivers/gce.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/backup/drivers/gce.py b/apache-libcloud-1.0.0rc2/libcloud/backup/drivers/gce.py
deleted file mode 100644
index 151f734..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/backup/drivers/gce.py
+++ /dev/null
@@ -1,478 +0,0 @@
-
-
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-__all__ = [
-    'GCEBackupDriver'
-]
-
-from libcloud.utils.iso8601 import parse_date
-from libcloud.backup.base import BackupDriver, BackupTargetRecoveryPoint,\
-    BackupTargetJob, BackupTarget
-from libcloud.backup.types import BackupTargetType, BackupTargetJobStatusType
-
-from libcloud.common.google import GoogleResponse, GoogleBaseConnection
-
-API_VERSION = 'v1'
-DEFAULT_TASK_COMPLETION_TIMEOUT = 180
-
-
-class GCEResponse(GoogleResponse):
-    pass
-
-
-class GCEConnection(GoogleBaseConnection):
-    """
-    Connection class for the GCE driver.
-
-    GCEConnection extends :class:`google.GoogleBaseConnection` for 2 reasons:
-      1. modify request_path for GCE URI.
-      2. Implement gce_params functionality described below.
-
-    If the parameter gce_params is set to a dict prior to calling request(),
-    the URL parameters will be updated to include those key/values FOR A
-    SINGLE REQUEST. If the response contains a nextPageToken,
-    gce_params['pageToken'] will be set to its value. This can be used to
-    implement paging in list:
-
-    >>> params, more_results = {'maxResults': 2}, True
-    >>> while more_results:
-    ...     driver.connection.gce_params=params
-    ...     driver.ex_list_urlmaps()
-    ...     more_results = 'pageToken' in params
-    ...
-    [<GCEUrlMap id="..." name="cli-map">, <GCEUrlMap id="..." name="lc-map">]
-    [<GCEUrlMap id="..." name="web-map">]
-    """
-    host = 'www.googleapis.com'
-    responseCls = GCEResponse
-
-    def __init__(self, user_id, key, secure, auth_type=None,
-                 credential_file=None, project=None, **kwargs):
-        super(GCEConnection, self).__init__(user_id, key, secure=secure,
-                                            auth_type=auth_type,
-                                            credential_file=credential_file,
-                                            **kwargs)
-        self.request_path = '/compute/%s/projects/%s' % (API_VERSION,
-                                                         project)
-        self.gce_params = None
-
-    def pre_connect_hook(self, params, headers):
-        """
-        Update URL parameters with values from self.gce_params.
-
-        @inherits: :class:`GoogleBaseConnection.pre_connect_hook`
-        """
-        params, headers = super(GCEConnection, self).pre_connect_hook(params,
-                                                                      headers)
-        if self.gce_params:
-            params.update(self.gce_params)
-        return params, headers
-
-    def request(self, *args, **kwargs):
-        """
-        Perform request then do GCE-specific processing of URL params.
-
-        @inherits: :class:`GoogleBaseConnection.request`
-        """
-        response = super(GCEConnection, self).request(*args, **kwargs)
-
-        # If gce_params has been set, then update the pageToken with the
-        # nextPageToken so it can be used in the next request.
-        if self.gce_params:
-            if 'nextPageToken' in response.object:
-                self.gce_params['pageToken'] = response.object['nextPageToken']
-            elif 'pageToken' in self.gce_params:
-                del self.gce_params['pageToken']
-            self.gce_params = None
-
-        return response
-
-
-class GCEBackupDriver(BackupDriver):
-    name = 'Google Compute Engine Backup Driver'
-    website = 'http://cloud.google.com/'
-    connectionCls = GCEConnection
-
-    def __init__(self, user_id, key=None, project=None,
-                 auth_type=None, scopes=None, credential_file=None, **kwargs):
-        """
-        :param  user_id: The email address (for service accounts) or Client ID
-                         (for installed apps) to be used for authentication.
-        :type   user_id: ``str``
-
-        :param  key: The RSA Key (for service accounts) or file path containing
-                     key or Client Secret (for installed apps) to be used for
-                     authentication.
-        :type   key: ``str``
-
-        :keyword  project: Your GCE project name. (required)
-        :type     project: ``str``
-
-        :keyword  auth_type: Accepted values are "SA" or "IA" or "GCE"
-                             ("Service Account" or "Installed Application" or
-                             "GCE" if libcloud is being used on a GCE instance
-                             with service account enabled).
-                             If not supplied, auth_type will be guessed based
-                             on value of user_id or if the code is being
-                             executed in a GCE instance.
-        :type     auth_type: ``str``
-
-        :keyword  scopes: List of authorization URLs. Default is empty and
-                          grants read/write to Compute, Storage, DNS.
-        :type     scopes: ``list``
-
-        :keyword  credential_file: Path to file for caching authentication
-                                   information used by GCEConnection.
-        :type     credential_file: ``str``
-        """
-        if not project:
-            raise ValueError('Project name must be specified using '
-                             '"project" keyword.')
-
-        self.auth_type = auth_type
-        self.project = project
-        self.scopes = scopes
-        self.credential_file = credential_file or \
-            '~/.gce_libcloud_auth' + '.' + self.project
-
-        super(GCEBackupDriver, self).__init__(user_id, key, **kwargs)
-
-        # Cache Zone and Region information to reduce API calls and
-        # increase speed
-        self.base_path = '/compute/%s/projects/%s' % (API_VERSION,
-                                                      self.project)
-
-    def get_supported_target_types(self):
-        """
-        Get a list of backup target types this driver supports
-
-        :return: ``list`` of :class:``BackupTargetType``
-        """
-        return [BackupTargetType.VOLUME]
-
-    def list_targets(self):
-        """
-        List all backuptargets
-
-        :rtype: ``list`` of :class:`BackupTarget`
-        """
-        raise NotImplementedError(
-            'list_targets not implemented for this driver')
-
-    def create_target(self, name, address,
-                      type=BackupTargetType.VOLUME, extra=None):
-        """
-        Creates a new backup target
-
-        :param name: Name of the target
-        :type name: ``str``
-
-        :param address: The volume ID.
-        :type address: ``str``
-
-        :param type: Backup target type (Physical, Virtual, ...).
-        :type type: :class:`BackupTargetType`
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type extra: ``dict``
-
-        :rtype: Instance of :class:`BackupTarget`
-        """
-        # Does nothing since any volume can be snapped at anytime.
-        return self.ex_get_target_by_source(address)
-
-    def create_target_from_node(self, node, type=BackupTargetType.VIRTUAL,
-                                extra=None):
-        """
-        Creates a new backup target from an existing node
-
-        :param node: The Node to backup
-        :type  node: ``Node``
-
-        :param type: Backup target type (Physical, Virtual, ...).
-        :type type: :class:`BackupTargetType`
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type extra: ``dict``
-
-        :rtype: Instance of :class:`BackupTarget`
-        """
-        # Get the first persistent disk
-        disks = node.extra['disks']
-        if disks is not None:
-            return self.create_target(
-                name=node.name,
-                address=disks[0]['source'],
-                type=BackupTargetType.VOLUME,
-                extra=None)
-        else:
-            raise RuntimeError("Node does not have any block devices")
-
-    def create_target_from_container(self, container,
-                                     type=BackupTargetType.OBJECT,
-                                     extra=None):
-        """
-        Creates a new backup target from an existing storage container
-
-        :param node: The Container to backup
-        :type  node: ``Container``
-
-        :param type: Backup target type (Physical, Virtual, ...).
-        :type type: :class:`BackupTargetType`
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type extra: ``dict``
-
-        :rtype: Instance of :class:`BackupTarget`
-        """
-        raise NotImplementedError(
-            'create_target_from_container not implemented for this driver')
-
-    def update_target(self, target, name, address, extra):
-        """
-        Update the properties of a backup target
-
-        :param target: Backup target to update
-        :type  target: Instance of :class:`BackupTarget`
-
-        :param name: Name of the target
-        :type name: ``str``
-
-        :param address: Hostname, FQDN, IP, file path etc.
-        :type address: ``str``
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type extra: ``dict``
-
-        :rtype: Instance of :class:`BackupTarget`
-        """
-        # Does nothing since any volume can be snapped at anytime.
-        return self.ex_get_target_by_source(address)
-
-    def delete_target(self, target):
-        """
-        Delete a backup target
-
-        :param target: Backup target to delete
-        :type  target: Instance of :class:`BackupTarget`
-        """
-        raise NotImplementedError(
-            'delete_target not implemented for this driver')
-
-    def list_recovery_points(self, target, start_date=None, end_date=None):
-        """
-        List the recovery points available for a target
-
-        :param target: Backup target to delete
-        :type  target: Instance of :class:`BackupTarget`
-
-        :param start_date: The start date to show jobs between (optional)
-        :type  start_date: :class:`datetime.datetime`
-
-        :param end_date: The end date to show jobs between (optional)
-        :type  end_date: :class:`datetime.datetime``
-
-        :rtype: ``list`` of :class:`BackupTargetRecoveryPoint`
-        """
-        request = '/global/snapshots'
-        response = self.connection.request(request, method='GET').object
-        return self._to_recovery_points(response, target)
-
-    def recover_target(self, target, recovery_point, path=None):
-        """
-        Recover a backup target to a recovery point
-
-        :param target: Backup target to delete
-        :type  target: Instance of :class:`BackupTarget`
-
-        :param recovery_point: Backup target with the backup data
-        :type  recovery_point: Instance of :class:`BackupTarget`
-
-        :param path: The part of the recovery point to recover (optional)
-        :type  path: ``str``
-
-        :rtype: Instance of :class:`BackupTargetJob`
-        """
-        raise NotImplementedError(
-            'recover_target not implemented for this driver')
-
-    def recover_target_out_of_place(self, target, recovery_point,
-                                    recovery_target, path=None):
-        """
-        Recover a backup target to a recovery point out-of-place
-
-        :param target: Backup target with the backup data
-        :type  target: Instance of :class:`BackupTarget`
-
-        :param recovery_point: Backup target with the backup data
-        :type  recovery_point: Instance of :class:`BackupTarget`
-
-        :param recovery_target: Backup target with to recover the data to
-        :type  recovery_target: Instance of :class:`BackupTarget`
-
-        :param path: The part of the recovery point to recover (optional)
-        :type  path: ``str``
-
-        :rtype: Instance of :class:`BackupTargetJob`
-        """
-        raise NotImplementedError(
-            'recover_target_out_of_place not implemented for this driver')
-
-    def get_target_job(self, target, id):
-        """
-        Get a specific backup job by ID
-
-        :param target: Backup target with the backup data
-        :type  target: Instance of :class:`BackupTarget`
-
-        :param id: Backup target with the backup data
-        :type  id: Instance of :class:`BackupTarget`
-
-        :rtype: :class:`BackupTargetJob`
-        """
-        jobs = self.list_target_jobs(target)
-        return list(filter(lambda x: x.id == id, jobs))[0]
-
-    def list_target_jobs(self, target):
-        """
-        List the backup jobs on a target
-
-        :param target: Backup target with the backup data
-        :type  target: Instance of :class:`BackupTarget`
-
-        :rtype: ``list`` of :class:`BackupTargetJob`
-        """
-        return []
-
-    def create_target_job(self, target, extra=None):
-        """
-        Create a new backup job on a target
-
-        :param target: Backup target with the backup data
-        :type  target: Instance of :class:`BackupTarget`
-
-        :param extra: (optional) Extra attributes (driver specific).
-        :type extra: ``dict``
-
-        :rtype: Instance of :class:`BackupTargetJob`
-        """
-        name = target.name
-        request = '/zones/%s/disks/%s/createSnapshot' % (
-            target.extra['zone'].name, target.name)
-        snapshot_data = {
-            'source': target.extra['source']
-        }
-        self.connection.async_request(request, method='POST',
-                                      data=snapshot_data)
-        return self._to_job(self.ex_get_snapshot(name), target)
-
-    def resume_target_job(self, target, job):
-        """
-        Resume a suspended backup job on a target
-
-        :param target: Backup target with the backup data
-        :type  target: Instance of :class:`BackupTarget`
-
-        :param job: Backup target job to resume
-        :type  job: Instance of :class:`BackupTargetJob`
-
-        :rtype: ``bool``
-        """
-        raise NotImplementedError(
-            'resume_target_job not supported for this driver')
-
-    def suspend_target_job(self, target, job):
-        """
-        Suspend a running backup job on a target
-
-        :param target: Backup target with the backup data
-        :type  target: Instance of :class:`BackupTarget`
-
-        :param job: Backup target job to suspend
-        :type  job: Instance of :class:`BackupTargetJob`
-
-        :rtype: ``bool``
-        """
-        raise NotImplementedError(
-            'suspend_target_job not supported for this driver')
-
-    def cancel_target_job(self, target, job):
-        """
-        Cancel a backup job on a target
-
-        :param target: Backup target with the backup data
-        :type  target: Instance of :class:`BackupTarget`
-
-        :param job: Backup target job to cancel
-        :type  job: Instance of :class:`BackupTargetJob`
-
-        :rtype: ``bool``
-        """
-        raise NotImplementedError(
-            'cancel_target_job not supported for this driver')
-
-    def _to_recovery_points(self, data, target):
-        return [self._to_recovery_point(item, target)
-                for item in data.items]
-
-    def _to_recovery_point(self, item, target):
-        id = item.id
-        date = parse_date(item.creationTimestamp)
-        point = BackupTargetRecoveryPoint(
-            id=id,
-            date=date,
-            target=target,
-            driver=self.connection.driver,
-            extra={
-                'snapshot-id': id,
-            },
-        )
-        return point
-
-    def _to_jobs(self, data, target):
-        return [self._to_job(item, target)
-                for item in data.items]
-
-    def _to_job(self, item, target):
-        id = item.id
-        job = BackupTargetJob(
-            id=id,
-            status=BackupTargetJobStatusType.PENDING,
-            progress=0,
-            target=target,
-            driver=self.connection.driver,
-            extra={
-            },
-        )
-        return job
-
-    def ex_get_snapshot(self, name):
-        request = '/global/snapshots/%s' % (name)
-        response = self.connection.request(request, method='GET').object
-        return response
-
-    def ex_get_target_by_source(self, source):
-        return BackupTarget(
-            id=source,
-            name=source,
-            address=source,
-            type=BackupTargetType.VOLUME,
-            driver=self.connection.driver,
-            extra={
-                "source": source
-            }
-        )

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/backup/providers.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/backup/providers.py b/apache-libcloud-1.0.0rc2/libcloud/backup/providers.py
deleted file mode 100644
index 16cd610..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/backup/providers.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-from libcloud.backup.types import Provider
-from libcloud.common.providers import get_driver as _get_provider_driver
-from libcloud.common.providers import set_driver as _set_provider_driver
-
-DRIVERS = {
-    Provider.DUMMY:
-    ('libcloud.backup.drivers.dummy', 'DummyBackupDriver'),
-    Provider.EBS:
-    ('libcloud.backup.drivers.ebs', 'EBSBackupDriver'),
-    Provider.GCE:
-    ('libcloud.backup.drivers.gce', 'GCEBackupDriver'),
-    Provider.DIMENSIONDATA:
-    ('libcloud.backup.drivers.dimensiondata', 'DimensionDataBackupDriver')
-}
-
-
-def get_driver(provider):
-    return _get_provider_driver(drivers=DRIVERS, provider=provider)
-
-
-def set_driver(provider, module, klass):
-    return _set_provider_driver(drivers=DRIVERS, provider=provider,
-                                module=module, klass=klass)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/backup/types.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/backup/types.py b/apache-libcloud-1.0.0rc2/libcloud/backup/types.py
deleted file mode 100644
index 0264268..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/backup/types.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-__all__ = [
-    'Provider',
-    'BackupTargetType',
-    'BackupTargetJobStatusType'
-]
-
-
-class Provider(object):
-    DUMMY = 'dummy'
-    EBS = 'ebs'
-    GCE = 'gce'
-    DIMENSIONDATA = 'dimensiondata'
-
-
-class BackupTargetType(object):
-    """
-    Backup Target type.
-    """
-
-    VIRTUAL = 'Virtual'
-    """ Denotes a virtual host """
-
-    PHYSICAL = 'Physical'
-    """ Denotes a physical host """
-
-    FILESYSTEM = 'Filesystem'
-    """ Denotes a file system (e.g. NAS) """
-
-    DATABASE = 'Database'
-    """ Denotes a database target """
-
-    OBJECT = 'Object'
-    """ Denotes an object based file system """
-
-    VOLUME = 'Volume'
-    """ Denotes a block storage volume """
-
-
-class BackupTargetJobStatusType(object):
-    """
-    The status of a backup target job
-    """
-
-    RUNNING = 'Running'
-    CANCELLED = 'Cancelled'
-    FAILED = 'Failed'
-    COMPLETED = 'Completed'
-    PENDING = 'Pending'

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/__init__.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/__init__.py b/apache-libcloud-1.0.0rc2/libcloud/common/__init__.py
deleted file mode 100644
index e69de29..0000000

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/abiquo.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/abiquo.py b/apache-libcloud-1.0.0rc2/libcloud/common/abiquo.py
deleted file mode 100644
index a972243..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/abiquo.py
+++ /dev/null
@@ -1,274 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-Abiquo Utilities Module for the Abiquo Driver.
-
-Common utilities needed by the :class:`AbiquoNodeDriver`.
-"""
-import base64
-
-from libcloud.common.base import ConnectionUserAndKey, PollingConnection
-from libcloud.common.base import XmlResponse
-from libcloud.common.types import InvalidCredsError, LibcloudError
-from libcloud.utils.py3 import httplib
-from libcloud.utils.py3 import urlparse
-from libcloud.utils.py3 import b
-from libcloud.compute.base import NodeState
-
-
-def get_href(element, rel):
-    """
-    Search a RESTLink element in the :class:`AbiquoResponse`.
-
-    Abiquo, as a REST API, it offers self-discovering functionality.
-    That means that you could walk through the whole API only
-    navigating from the links offered by the entities.
-
-    This is a basic method to find the 'relations' of an entity searching into
-    its links.
-
-    For instance, a Rack entity serialized as XML as the following::
-
-        <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-        <rack>
-         <link href="http://host/api/admin/datacenters/1"
-            type="application/vnd.abiquo.datacenter+xml" rel="datacenter"/>
-         <link href="http://host/api/admin/datacenters/1/racks/1"
-            type="application/vnd.abiquo.rack+xml" rel="edit"/>
-         <link href="http://host/api/admin/datacenters/1/racks/1/machines"
-            type="application/vnd.abiquo.machines+xml" rel="machines"/>
-         <haEnabled>false</haEnabled>
-         <id>1</id>
-         <longDescription></longDescription>
-         <name>racacaca</name>
-         <nrsq>10</nrsq>
-         <shortDescription></shortDescription>
-         <vlanIdMax>4094</vlanIdMax>
-         <vlanIdMin>2</vlanIdMin>
-         <vlanPerVdcReserved>1</vlanPerVdcReserved>
-         <vlansIdAvoided></vlansIdAvoided>
-        </rack>
-
-    offers link to datacenters (rel='datacenter'), to itself (rel='edit') and
-    to the machines defined in it (rel='machines')
-
-    A call to this method with the 'rack' element using 'datacenter' as 'rel'
-    will return:
-
-    'http://10.60.12.7:80/api/admin/datacenters/1'
-
-    :type  element: :class:`xml.etree.ElementTree`
-    :param element: Xml Entity returned by Abiquo API (required)
-    :type      rel: ``str``
-    :param     rel: relation link name
-    :rtype:         ``str``
-    :return:        the 'href' value according to the 'rel' input parameter
-    """
-    links = element.findall('link')
-    for link in links:
-        if link.attrib['rel'] == rel:
-            href = link.attrib['href']
-            # href is something like:
-            #
-            # 'http://localhost:80/api/admin/enterprises'
-            #
-            # we are only interested in '/admin/enterprises/' part
-            needle = '/api/'
-            url_path = urlparse.urlparse(href).path
-            index = url_path.find(needle)
-            result = url_path[index + len(needle) - 1:]
-            return result
-
-
-class AbiquoResponse(XmlResponse):
-    """
-    Abiquo XML Response.
-
-    Wraps the response in XML bodies or extract the error data in
-    case of error.
-    """
-
-    # Map between abiquo state and Libcloud State
-    NODE_STATE_MAP = {
-        'NOT_ALLOCATED': NodeState.TERMINATED,
-        'ALLOCATED': NodeState.PENDING,
-        'CONFIGURED': NodeState.PENDING,
-        'ON': NodeState.RUNNING,
-        'PAUSED': NodeState.PENDING,
-        'OFF': NodeState.PENDING,
-        'LOCKED': NodeState.PENDING,
-        'UNKNOWN': NodeState.UNKNOWN
-    }
-
-    def parse_error(self):
-        """
-        Parse the error messages.
-
-        Response body can easily be handled by this class parent
-        :class:`XmlResponse`, but there are use cases which Abiquo API
-        does not respond an XML but an HTML. So we need to
-        handle these special cases.
-        """
-        if self.status == httplib.UNAUTHORIZED:
-            raise InvalidCredsError(driver=self.connection.driver)
-        elif self.status == httplib.FORBIDDEN:
-            raise ForbiddenError(self.connection.driver)
-        elif self.status == httplib.NOT_ACCEPTABLE:
-            raise LibcloudError('Not Acceptable')
-        else:
-            parsebody = self.parse_body()
-            if parsebody is not None and hasattr(parsebody, 'findall'):
-                errors = self.parse_body().findall('error')
-                # Most of the exceptions only have one error
-                raise LibcloudError(errors[0].findtext('message'))
-            else:
-                raise LibcloudError(self.body)
-
-    def success(self):
-        """
-        Determine if the request was successful.
-
-        Any of the 2XX HTTP response codes are accepted as successful requests
-
-        :rtype:  ``bool``
-        :return: successful request or not.
-        """
-        return self.status in [httplib.OK, httplib.CREATED, httplib.NO_CONTENT,
-                               httplib.ACCEPTED]
-
-    def async_success(self):
-        """
-        Determinate if async request was successful.
-
-        An async_request retrieves for a task object that can be successfully
-        retrieved (self.status == OK), but the asynchronous task (the body of
-        the HTTP response) which we are asking for has finished with an error.
-        So this method checks if the status code is 'OK' and if the task
-        has finished successfully.
-
-        :rtype:  ``bool``
-        :return: successful asynchronous request or not
-        """
-        if self.success():
-            # So we have a 'task' object in the body
-            task = self.parse_body()
-            return task.findtext('state') == 'FINISHED_SUCCESSFULLY'
-        else:
-            return False
-
-
-class AbiquoConnection(ConnectionUserAndKey, PollingConnection):
-    """
-    A Connection to Abiquo API.
-
-    Basic :class:`ConnectionUserAndKey` connection with
-    :class:`PollingConnection` features for asynchronous tasks.
-    """
-
-    responseCls = AbiquoResponse
-
-    def __init__(self, user_id, key, secure=True, host=None, port=None,
-                 url=None, timeout=None,
-                 retry_delay=None, backoff=None, proxy_url=None):
-        super(AbiquoConnection, self).__init__(user_id=user_id, key=key,
-                                               secure=secure,
-                                               host=host, port=port,
-                                               url=url, timeout=timeout,
-                                               retry_delay=retry_delay,
-                                               backoff=backoff,
-                                               proxy_url=proxy_url)
-
-        # This attribute stores data cached across multiple request
-        self.cache = {}
-
-    def add_default_headers(self, headers):
-        """
-        Add Basic Authentication header to all the requests.
-
-        It injects the 'Authorization: Basic Base64String===' header
-        in each request
-
-        :type  headers: ``dict``
-        :param headers: Default input headers
-
-        :rtype:         ``dict``
-        :return:        Default input headers with the 'Authorization'
-                        header
-        """
-        b64string = b('%s:%s' % (self.user_id, self.key))
-        encoded = base64.b64encode(b64string).decode('utf-8')
-
-        authorization = 'Basic ' + encoded
-
-        headers['Authorization'] = authorization
-        return headers
-
-    def get_poll_request_kwargs(self, response, context, request_kwargs):
-        """
-        Manage polling request arguments.
-
-        Return keyword arguments which are passed to the
-        :class:`NodeDriver.request` method when polling for the job status. The
-        Abiquo Asynchronous Response returns and 'acceptedrequest' XmlElement
-        as the following::
-
-            <acceptedrequest>
-                <link href="http://uri/to/task" rel="status"/>
-                <message>You can follow the progress in the link</message>
-            </acceptedrequest>
-
-        We need to extract the href URI to poll.
-
-        :type    response:       :class:`xml.etree.ElementTree`
-        :keyword response:       Object returned by poll request.
-        :type    request_kwargs: ``dict``
-        :keyword request_kwargs: Default request arguments and headers
-        :rtype:                  ``dict``
-        :return:                 Modified keyword arguments
-        """
-        accepted_request_obj = response.object
-        link_poll = get_href(accepted_request_obj, 'status')
-        hdr_poll = {'Accept': 'application/vnd.abiquo.task+xml'}
-
-        # Override the 'action', 'method' and 'headers'
-        # keys of the previous dict
-        request_kwargs['action'] = link_poll
-        request_kwargs['method'] = 'GET'
-        request_kwargs['headers'] = hdr_poll
-        return request_kwargs
-
-    def has_completed(self, response):
-        """
-        Decide if the asynchronous job has ended.
-
-        :type  response: :class:`xml.etree.ElementTree`
-        :param response: Response object returned by poll request
-        :rtype:          ``bool``
-        :return:         Whether the job has completed
-        """
-        task = response.object
-        task_state = task.findtext('state')
-        return task_state in ['FINISHED_SUCCESSFULLY', 'ABORTED',
-                              'FINISHED_UNSUCCESSFULLY']
-
-
-class ForbiddenError(LibcloudError):
-    """
-    Exception used when credentials are ok but user has not permissions.
-    """
-
-    def __init__(self, driver):
-        message = 'User has not permission to perform this task.'
-        super(LibcloudError, self).__init__(message, driver)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/common/aliyun.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/common/aliyun.py b/apache-libcloud-1.0.0rc2/libcloud/common/aliyun.py
deleted file mode 100644
index 4e91dbb..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/common/aliyun.py
+++ /dev/null
@@ -1,239 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 base64
-import hashlib
-import hmac
-import sys
-import time
-import uuid
-
-try:
-    from lxml import etree as ET
-except ImportError:
-    from xml.etree import ElementTree as ET
-
-from libcloud.common.base import ConnectionUserAndKey, XmlResponse
-from libcloud.common.types import MalformedResponseError
-from libcloud.utils.py3 import b, u, urlquote, PY3
-from libcloud.utils.xml import findtext
-
-__all__ = [
-    'AliyunXmlResponse',
-    'AliyunRequestSigner',
-    'AliyunRequestSignerAlgorithmV1_0',
-    'SignedAliyunConnection',
-    'AliyunConnection',
-
-    'SIGNATURE_VERSION_1_0',
-    'DEFAULT_SIGNATURE_VERSION'
-]
-
-SIGNATURE_VERSION_1_0 = '1.0'
-DEFAULT_SIGNATURE_VERSION = SIGNATURE_VERSION_1_0
-
-
-class AliyunXmlResponse(XmlResponse):
-    namespace = None
-
-    def success(self):
-        return self.status >= 200 and self.status < 300
-
-    def parse_body(self):
-        """
-        Each response from Aliyun contains a request id and a host id.
-        The response body is in utf-8 encoding.
-        """
-        if len(self.body) == 0 and not self.parse_zero_length_body:
-            return self.body
-
-        try:
-            if PY3:
-                parser = ET.XMLParser(encoding='utf-8')
-                body = ET.XML(self.body.encode('utf-8'), parser=parser)
-            else:
-                body = ET.XML(self.body)
-        except:
-            raise MalformedResponseError('Failed to parse XML',
-                                         body=self.body,
-                                         driver=self.connection.driver)
-        self.request_id = findtext(element=body, xpath='RequestId',
-                                   namespace=self.namespace)
-        self.host_id = findtext(element=body, xpath='HostId',
-                                namespace=self.namespace)
-        return body
-
-    def parse_error(self):
-        """
-        Parse error responses from Aliyun.
-        """
-        body = super(AliyunXmlResponse, self).parse_error()
-        code, message = self._parse_error_details(element=body)
-        request_id = findtext(element=body, xpath='RequestId',
-                              namespace=self.namespace)
-        host_id = findtext(element=body, xpath='HostId',
-                           namespace=self.namespace)
-        error = {'code': code,
-                 'message': message,
-                 'request_id': request_id,
-                 'host_id': host_id}
-        return u(error)
-
-    def _parse_error_details(self, element):
-        """
-        Parse error code and message from the provided error element.
-
-        :return: ``tuple`` with two elements: (code, message)
-        :rtype: ``tuple``
-        """
-        code = findtext(element=element, xpath='Code',
-                        namespace=self.namespace)
-        message = findtext(element=element, xpath='Message',
-                           namespace=self.namespace)
-
-        return (code, message)
-
-
-class AliyunRequestSigner(object):
-    """
-    Class handles signing the outgoing Aliyun requests.
-    """
-
-    def __init__(self, access_key, access_secret, version):
-        """
-        :param access_key: Access key.
-        :type access_key: ``str``
-
-        :param access_secret: Access secret.
-        :type access_secret: ``str``
-
-        :param version: API version.
-        :type version: ``str``
-        """
-        self.access_key = access_key
-        self.access_secret = access_secret
-        self.version = version
-
-    def get_request_params(self, params, method='GET', path='/'):
-        return params
-
-    def get_request_headers(self, params, headers, method='GET', path='/'):
-        return params, headers
-
-
-class AliyunRequestSignerAlgorithmV1_0(AliyunRequestSigner):
-    """Aliyun request signer using signature version 1.0."""
-    def get_request_params(self, params, method='GET', path='/'):
-        params['Format'] = 'XML'
-        params['Version'] = self.version
-        params['AccessKeyId'] = self.access_key
-        params['SignatureMethod'] = 'HMAC-SHA1'
-        params['SignatureVersion'] = SIGNATURE_VERSION_1_0
-        params['SignatureNonce'] = _get_signature_nonce()
-        # TODO: Support 'ResourceOwnerAccount'
-        params['Timestamp'] = time.strftime('%Y-%m-%dT%H:%M:%SZ',
-                                            time.gmtime())
-        params['Signature'] = self._sign_request(params, method, path)
-        return params
-
-    def _sign_request(self, params, method, path):
-        """
-        Sign Aliyun requests parameters and get the signature.
-
-        StringToSign = HTTPMethod + '&' +
-                       percentEncode('/') + '&' +
-                       percentEncode(CanonicalizedQueryString)
-        """
-        keys = list(params.keys())
-        keys.sort()
-        pairs = []
-        for key in keys:
-            pairs.append('%s=%s' % (_percent_encode(key),
-                                    _percent_encode(params[key])))
-        qs = urlquote('&'.join(pairs), safe='-_.~')
-        string_to_sign = '&'.join((method, urlquote(path, safe=''), qs))
-        b64_hmac = base64.b64encode(
-            hmac.new(b(self._get_access_secret()), b(string_to_sign),
-                     digestmod=hashlib.sha1).digest()
-        )
-
-        return b64_hmac.decode('utf8')
-
-    def _get_access_secret(self):
-        return '%s&' % self.access_secret
-
-
-class AliyunConnection(ConnectionUserAndKey):
-    pass
-
-
-class SignedAliyunConnection(AliyunConnection):
-    def __init__(self, user_id, key, secure=True, host=None, port=None,
-                 url=None, timeout=None, proxy_url=None, retry_delay=None,
-                 backoff=None, signature_version=DEFAULT_SIGNATURE_VERSION):
-        super(SignedAliyunConnection, self).__init__(user_id=user_id, key=key,
-                                                     secure=secure,
-                                                     host=host, port=port,
-                                                     url=url, timeout=timeout,
-                                                     proxy_url=proxy_url,
-                                                     retry_delay=retry_delay,
-                                                     backoff=backoff)
-        self.signature_version = str(signature_version)
-
-        if self.signature_version == '1.0':
-            signer_cls = AliyunRequestSignerAlgorithmV1_0
-        else:
-            raise ValueError('Unsupported signature_version: %s' %
-                             signature_version)
-
-        self.signer = signer_cls(access_key=self.user_id,
-                                 access_secret=self.key,
-                                 version=self.version)
-
-    def add_default_params(self, params):
-        params = self.signer.get_request_params(params=params,
-                                                method=self.method,
-                                                path=self.action)
-        return params
-
-
-def _percent_encode(encode_str):
-    """
-    Encode string to utf8, quote for url and replace '+' with %20,
-    '*' with %2A and keep '~' not converted.
-
-    :param src_str: ``str`` in the same encoding with sys.stdin,
-                    default to encoding cp936.
-    :return: ``str`` represents the encoded result
-    :rtype: ``str``
-    """
-    encoding = sys.stdin.encoding or 'cp936'
-    decoded = str(encode_str)
-    if PY3:
-        if isinstance(encode_str, bytes):
-            decoded = encode_str.decode(encoding)
-    else:
-        decoded = str(encode_str).decode(encoding)
-
-    res = urlquote(
-        decoded.encode('utf8'), '')
-    res = res.replace('+', '%20')
-    res = res.replace('*', '%2A')
-    res = res.replace('%7E', '~')
-    return res
-
-
-def _get_signature_nonce():
-    return str(uuid.uuid4())


[29/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/dummy.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/dummy.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/dummy.py
deleted file mode 100644
index 9824335..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/dummy.py
+++ /dev/null
@@ -1,349 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-Dummy Driver
-
-@note: This driver is out of date
-"""
-import uuid
-import socket
-import struct
-
-from libcloud.common.base import ConnectionKey
-from libcloud.compute.base import NodeImage, NodeSize, Node
-from libcloud.compute.base import NodeDriver, NodeLocation
-from libcloud.compute.base import KeyPair
-from libcloud.compute.types import Provider, NodeState
-
-
-class DummyConnection(ConnectionKey):
-    """
-    Dummy connection class
-    """
-
-    def connect(self, host=None, port=None):
-        pass
-
-
-class DummyNodeDriver(NodeDriver):
-    """
-    Dummy node driver
-
-    This is a fake driver which appears to always create or destroy
-    nodes successfully.
-
-    >>> from libcloud.compute.drivers.dummy import DummyNodeDriver
-    >>> driver = DummyNodeDriver(0)
-    >>> node=driver.create_node()
-    >>> node.public_ips[0]
-    '127.0.0.3'
-    >>> node.name
-    'dummy-3'
-
-    If the credentials you give convert to an integer then the next
-    node to be created will be one higher.
-
-    Each time you create a node you will get a different IP address.
-
-    >>> driver = DummyNodeDriver(22)
-    >>> node=driver.create_node()
-    >>> node.name
-    'dummy-23'
-
-    """
-
-    name = "Dummy Node Provider"
-    website = 'http://example.com'
-    type = Provider.DUMMY
-
-    def __init__(self, creds):
-        """
-        :param  creds: Credentials
-        :type   creds: ``str``
-
-        :rtype: ``None``
-        """
-        self.creds = creds
-        try:
-            num = int(creds)
-        except ValueError:
-            num = None
-        if num:
-            self.nl = []
-            startip = _ip_to_int('127.0.0.1')
-            for i in range(num):
-                ip = _int_to_ip(startip + i)
-                self.nl.append(
-                    Node(id=i,
-                         name='dummy-%d' % (i),
-                         state=NodeState.RUNNING,
-                         public_ips=[ip],
-                         private_ips=[],
-                         driver=self,
-                         extra={'foo': 'bar'})
-                )
-        else:
-            self.nl = [
-                Node(id=1,
-                     name='dummy-1',
-                     state=NodeState.RUNNING,
-                     public_ips=['127.0.0.1'],
-                     private_ips=[],
-                     driver=self,
-                     extra={'foo': 'bar'}),
-                Node(id=2,
-                     name='dummy-2',
-                     state=NodeState.RUNNING,
-                     public_ips=['127.0.0.1'],
-                     private_ips=[],
-                     driver=self,
-                     extra={'foo': 'bar'}),
-            ]
-        self.connection = DummyConnection(self.creds)
-
-    def get_uuid(self, unique_field=None):
-        """
-
-        :param  unique_field: Unique field
-        :type   unique_field: ``bool``
-        :rtype: :class:`UUID`
-        """
-        return str(uuid.uuid4())
-
-    def list_nodes(self):
-        """
-        List the nodes known to a particular driver;
-        There are two default nodes created at the beginning
-
-        >>> from libcloud.compute.drivers.dummy import DummyNodeDriver
-        >>> driver = DummyNodeDriver(0)
-        >>> node_list=driver.list_nodes()
-        >>> sorted([node.name for node in node_list ])
-        ['dummy-1', 'dummy-2']
-
-        each item in the list returned is a node object from which you
-        can carry out any node actions you wish
-
-        >>> node_list[0].reboot()
-        True
-
-        As more nodes are added, list_nodes will return them
-
-        >>> node=driver.create_node()
-        >>> node.size.id
-        's1'
-        >>> node.image.id
-        'i2'
-        >>> sorted([n.name for n in driver.list_nodes()])
-        ['dummy-1', 'dummy-2', 'dummy-3']
-
-        @inherits: :class:`NodeDriver.list_nodes`
-        """
-        return self.nl
-
-    def reboot_node(self, node):
-        """
-        Sets the node state to rebooting; in this dummy driver always
-        returns True as if the reboot had been successful.
-
-        >>> from libcloud.compute.drivers.dummy import DummyNodeDriver
-        >>> driver = DummyNodeDriver(0)
-        >>> node=driver.create_node()
-        >>> from libcloud.compute.types import NodeState
-        >>> node.state == NodeState.RUNNING
-        True
-        >>> node.state == NodeState.REBOOTING
-        False
-        >>> driver.reboot_node(node)
-        True
-        >>> node.state == NodeState.REBOOTING
-        True
-
-        Please note, dummy nodes never recover from the reboot.
-
-        @inherits: :class:`NodeDriver.reboot_node`
-        """
-
-        node.state = NodeState.REBOOTING
-        return True
-
-    def destroy_node(self, node):
-        """
-        Sets the node state to terminated and removes it from the node list
-
-        >>> from libcloud.compute.drivers.dummy import DummyNodeDriver
-        >>> driver = DummyNodeDriver(0)
-        >>> from libcloud.compute.types import NodeState
-        >>> node = [node for node in driver.list_nodes() if
-        ...         node.name == 'dummy-1'][0]
-        >>> node.state == NodeState.RUNNING
-        True
-        >>> driver.destroy_node(node)
-        True
-        >>> node.state == NodeState.RUNNING
-        False
-        >>> [n for n in driver.list_nodes() if n.name == 'dummy-1']
-        []
-
-        @inherits: :class:`NodeDriver.destroy_node`
-        """
-
-        node.state = NodeState.TERMINATED
-        self.nl.remove(node)
-        return True
-
-    def list_images(self, location=None):
-        """
-        Returns a list of images as a cloud provider might have
-
-        >>> from libcloud.compute.drivers.dummy import DummyNodeDriver
-        >>> driver = DummyNodeDriver(0)
-        >>> sorted([image.name for image in driver.list_images()])
-        ['Slackware 4', 'Ubuntu 9.04', 'Ubuntu 9.10']
-
-        @inherits: :class:`NodeDriver.list_images`
-        """
-        return [
-            NodeImage(id=1, name="Ubuntu 9.10", driver=self),
-            NodeImage(id=2, name="Ubuntu 9.04", driver=self),
-            NodeImage(id=3, name="Slackware 4", driver=self),
-        ]
-
-    def list_sizes(self, location=None):
-        """
-        Returns a list of node sizes as a cloud provider might have
-
-        >>> from libcloud.compute.drivers.dummy import DummyNodeDriver
-        >>> driver = DummyNodeDriver(0)
-        >>> sorted([size.ram for size in driver.list_sizes()])
-        [128, 512, 4096, 8192]
-
-        @inherits: :class:`NodeDriver.list_images`
-        """
-
-        return [
-            NodeSize(id=1,
-                     name="Small",
-                     ram=128,
-                     disk=4,
-                     bandwidth=500,
-                     price=4,
-                     driver=self),
-            NodeSize(id=2,
-                     name="Medium",
-                     ram=512,
-                     disk=16,
-                     bandwidth=1500,
-                     price=8,
-                     driver=self),
-            NodeSize(id=3,
-                     name="Big",
-                     ram=4096,
-                     disk=32,
-                     bandwidth=2500,
-                     price=32,
-                     driver=self),
-            NodeSize(id=4,
-                     name="XXL Big",
-                     ram=4096 * 2,
-                     disk=32 * 4,
-                     bandwidth=2500 * 3,
-                     price=32 * 2,
-                     driver=self),
-        ]
-
-    def list_locations(self):
-        """
-        Returns a list of locations of nodes
-
-        >>> from libcloud.compute.drivers.dummy import DummyNodeDriver
-        >>> driver = DummyNodeDriver(0)
-        >>> sorted([loc.name + " in " + loc.country for loc in
-        ...         driver.list_locations()])
-        ['Island Datacenter in FJ', 'London Loft in GB', "Paul's Room in US"]
-
-        @inherits: :class:`NodeDriver.list_locations`
-        """
-        return [
-            NodeLocation(id=1,
-                         name="Paul's Room",
-                         country='US',
-                         driver=self),
-            NodeLocation(id=2,
-                         name="London Loft",
-                         country='GB',
-                         driver=self),
-            NodeLocation(id=3,
-                         name="Island Datacenter",
-                         country='FJ',
-                         driver=self),
-        ]
-
-    def create_node(self, **kwargs):
-        """
-        Creates a dummy node; the node id is equal to the number of
-        nodes in the node list
-
-        >>> from libcloud.compute.drivers.dummy import DummyNodeDriver
-        >>> driver = DummyNodeDriver(0)
-        >>> sorted([node.name for node in driver.list_nodes()])
-        ['dummy-1', 'dummy-2']
-        >>> nodeA = driver.create_node()
-        >>> sorted([node.name for node in driver.list_nodes()])
-        ['dummy-1', 'dummy-2', 'dummy-3']
-        >>> driver.create_node().name
-        'dummy-4'
-        >>> driver.destroy_node(nodeA)
-        True
-        >>> sorted([node.name for node in driver.list_nodes()])
-        ['dummy-1', 'dummy-2', 'dummy-4']
-
-        @inherits: :class:`NodeDriver.create_node`
-        """
-        l = len(self.nl) + 1
-        n = Node(id=l,
-                 name='dummy-%d' % l,
-                 state=NodeState.RUNNING,
-                 public_ips=['127.0.0.%d' % l],
-                 private_ips=[],
-                 driver=self,
-                 size=NodeSize(id='s1', name='foo', ram=2048,
-                               disk=160, bandwidth=None, price=0.0,
-                               driver=self),
-                 image=NodeImage(id='i2', name='image', driver=self),
-                 extra={'foo': 'bar'})
-        self.nl.append(n)
-        return n
-
-    def import_key_pair_from_string(self, name, key_material):
-        key_pair = KeyPair(name=name,
-                           public_key=key_material,
-                           fingerprint='fingerprint',
-                           private_key='private_key',
-                           driver=self)
-        return key_pair
-
-
-def _ip_to_int(ip):
-    return socket.htonl(struct.unpack('I', socket.inet_aton(ip))[0])
-
-
-def _int_to_ip(ip):
-    return socket.inet_ntoa(struct.pack('I', socket.ntohl(ip)))
-
-if __name__ == "__main__":
-    import doctest
-
-    doctest.testmod()


[28/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/ec2.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/ec2.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/ec2.py
deleted file mode 100644
index f21b49e..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/ec2.py
+++ /dev/null
@@ -1,6773 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-Amazon EC2, Eucalyptus, Nimbus and Outscale drivers.
-"""
-
-import re
-import sys
-import base64
-import copy
-import warnings
-
-try:
-    from lxml import etree as ET
-except ImportError:
-    from xml.etree import ElementTree as ET
-
-from libcloud.utils.py3 import b, basestring, ensure_string
-
-from libcloud.utils.xml import fixxpath, findtext, findattr, findall
-from libcloud.utils.publickey import get_pubkey_ssh2_fingerprint
-from libcloud.utils.publickey import get_pubkey_comment
-from libcloud.utils.iso8601 import parse_date
-from libcloud.common.aws import AWSBaseResponse, SignedAWSConnection
-from libcloud.common.aws import DEFAULT_SIGNATURE_VERSION
-from libcloud.common.types import (InvalidCredsError, MalformedResponseError,
-                                   LibcloudError)
-from libcloud.compute.providers import Provider
-from libcloud.compute.base import Node, NodeDriver, NodeLocation, NodeSize
-from libcloud.compute.base import NodeImage, StorageVolume, VolumeSnapshot
-from libcloud.compute.base import KeyPair
-from libcloud.compute.types import NodeState, KeyPairDoesNotExistError, \
-    StorageVolumeState, VolumeSnapshotState
-
-__all__ = [
-    'API_VERSION',
-    'NAMESPACE',
-    'INSTANCE_TYPES',
-    'OUTSCALE_INSTANCE_TYPES',
-    'OUTSCALE_SAS_REGION_DETAILS',
-    'OUTSCALE_INC_REGION_DETAILS',
-    'DEFAULT_EUCA_API_VERSION',
-    'EUCA_NAMESPACE',
-
-    'EC2NodeDriver',
-    'BaseEC2NodeDriver',
-
-    'NimbusNodeDriver',
-    'EucNodeDriver',
-
-    'OutscaleSASNodeDriver',
-    'OutscaleINCNodeDriver',
-
-    'EC2NodeLocation',
-    'EC2ReservedNode',
-    'EC2SecurityGroup',
-    'EC2PlacementGroup',
-    'EC2Network',
-    'EC2NetworkSubnet',
-    'EC2NetworkInterface',
-    'EC2RouteTable',
-    'EC2Route',
-    'EC2SubnetAssociation',
-    'ExEC2AvailabilityZone',
-
-    'IdempotentParamError'
-]
-
-API_VERSION = '2013-10-15'
-NAMESPACE = 'http://ec2.amazonaws.com/doc/%s/' % (API_VERSION)
-
-# Eucalyptus Constants
-DEFAULT_EUCA_API_VERSION = '3.3.0'
-EUCA_NAMESPACE = 'http://msgs.eucalyptus.com/%s' % (DEFAULT_EUCA_API_VERSION)
-
-"""
-Sizes must be hardcoded, because Amazon doesn't provide an API to fetch them.
-From http://aws.amazon.com/ec2/instance-types/
-and <http://aws.amazon.com/ec2/previous-generation/>
-ram = [MiB], disk = [GB]
-"""
-
-
-def GiB(value):
-    return int(value * 1024)
-
-
-INSTANCE_TYPES = {
-    't1.micro': {
-        'id': 't1.micro',
-        'name': 'Micro Instance',
-        'ram': GiB(0.613),
-        'disk': 15,  # GB
-        'bandwidth': None
-    },
-    'm1.small': {
-        'id': 'm1.small',
-        'name': 'Small Instance',
-        'ram': GiB(1.7),
-        'disk': 160,  # GB
-        'bandwidth': None
-    },
-    'm1.medium': {
-        'id': 'm1.medium',
-        'name': 'Medium Instance',
-        'ram': GiB(3.75),
-        'disk': 410,  # GB
-        'bandwidth': None
-    },
-    'm1.large': {
-        'id': 'm1.large',
-        'name': 'Large Instance',
-        'ram': GiB(7.5),
-        'disk': 2 * 420,  # GB
-        'bandwidth': None,
-        'extra': {
-            'cpu': 2
-        }
-    },
-    'm1.xlarge': {
-        'id': 'm1.xlarge',
-        'name': 'Extra Large Instance',
-        'ram': GiB(15),
-        'disk': 4 * 420,  # GB
-        'bandwidth': None,
-        'extra': {
-            'cpu': 4
-        }
-    },
-    'c1.medium': {
-        'id': 'c1.medium',
-        'name': 'High-CPU Medium Instance',
-        'ram': GiB(1.7),
-        'disk': 350,  # GB
-        'bandwidth': None,
-        'extra': {
-            'cpu': 2
-        }
-    },
-    'c1.xlarge': {
-        'id': 'c1.xlarge',
-        'name': 'High-CPU Extra Large Instance',
-        'ram': GiB(7),
-        'disk': 4 * 420,  # GB
-        'bandwidth': None,
-        'extra': {
-            'cpu': 8
-        }
-    },
-    'm2.xlarge': {
-        'id': 'm2.xlarge',
-        'name': 'High-Memory Extra Large Instance',
-        'ram': GiB(17.1),
-        'disk': 420,  # GB
-        'bandwidth': None,
-        'extra': {
-            'cpu': 2
-        }
-    },
-    'm2.2xlarge': {
-        'id': 'm2.2xlarge',
-        'name': 'High-Memory Double Extra Large Instance',
-        'ram': GiB(34.2),
-        'disk': 850,  # GB
-        'bandwidth': None,
-        'extra': {
-            'cpu': 4
-        }
-    },
-    'm2.4xlarge': {
-        'id': 'm2.4xlarge',
-        'name': 'High-Memory Quadruple Extra Large Instance',
-        'ram': GiB(68.4),
-        'disk': 2 * 840,  # GB
-        'bandwidth': None,
-        'extra': {
-            'cpu': 8
-        }
-    },
-    'm3.medium': {
-        'id': 'm3.medium',
-        'name': 'Medium Instance',
-        'ram': GiB(3.75),
-        'disk': 4,  # GB
-        'bandwidth': None,
-        'extra': {
-            'cpu': 1
-        }
-    },
-    'm3.large': {
-        'id': 'm3.large',
-        'name': 'Large Instance',
-        'ram': GiB(7.5),
-        'disk': 32,  # GB
-        'bandwidth': None,
-        'extra': {
-            'cpu': 2
-        }
-    },
-    'm3.xlarge': {
-        'id': 'm3.xlarge',
-        'name': 'Extra Large Instance',
-        'ram': GiB(15),
-        'disk': 2 * 40,  # GB
-        'bandwidth': None,
-        'extra': {
-            'cpu': 4
-        }
-    },
-    'm3.2xlarge': {
-        'id': 'm3.2xlarge',
-        'name': 'Double Extra Large Instance',
-        'ram': GiB(30),
-        'disk': 2 * 80,  # GB
-        'bandwidth': None,
-        'extra': {
-            'cpu': 8
-        }
-    },
-    'm4.large': {
-        'id': 'm4.large',
-        'name': 'Large Instance',
-        'ram': GiB(8),
-        'disk': 0,  # EBS only
-        'bandwidth': None,
-        'extra': {
-            'cpu': 2
-        }
-    },
-    'm4.xlarge': {
-        'id': 'm4.xlarge',
-        'name': 'Extra Large Instance',
-        'ram': GiB(16),
-        'disk': 0,  # EBS only
-        'bandwidth': None,
-        'extra': {
-            'cpu': 4
-        }
-    },
-    'm4.2xlarge': {
-        'id': 'm4.2xlarge',
-        'name': 'Double Extra Large Instance',
-        'ram': GiB(32),
-        'disk': 0,  # EBS only
-        'bandwidth': None,
-        'extra': {
-            'cpu': 8
-        }
-    },
-    'm4.4xlarge': {
-        'id': 'm4.4xlarge',
-        'name': 'Quadruple Extra Large Instance',
-        'ram': GiB(64),
-        'disk': 0,  # EBS only
-        'bandwidth': None,
-        'extra': {
-            'cpu': 16
-        }
-    },
-    'm4.10xlarge': {
-        'id': 'm4.10xlarge',
-        'name': '10 Extra Large Instance',
-        'ram': GiB(160),
-        'disk': 0,  # EBS only
-        'bandwidth': None,
-        'extra': {
-            'cpu': 40
-        }
-    },
-    'cg1.4xlarge': {
-        'id': 'cg1.4xlarge',
-        'name': 'Cluster GPU Quadruple Extra Large Instance',
-        'ram': GiB(22.5),
-        'disk': 2 * 840,  # GB
-        'bandwidth': None,
-        'extra': {
-            'cpu': 16
-        }
-    },
-    'g2.2xlarge': {
-        'id': 'g2.2xlarge',
-        'name': 'Cluster GPU G2 Double Extra Large Instance',
-        'ram': GiB(15),
-        'disk': 60,  # GB
-        'bandwidth': None,
-        'extra': {
-            'cpu': 8
-        }
-    },
-    'g2.8xlarge': {
-        'id': 'g2.8xlarge',
-        'name': 'Cluster GPU G2 Eight Extra Large Instance',
-        'ram': GiB(60),
-        'disk': 2 * 120,  # GB
-        'bandwidth': None,
-        'extra': {
-            'cpu': 32
-        }
-    },
-    'cc1.4xlarge': {
-        'id': 'cc1.4xlarge',
-        'name': 'Cluster Compute Quadruple Extra Large Instance',
-        'ram': 23552,
-        'disk': 1690,
-        'bandwidth': None
-    },
-    'cc2.8xlarge': {
-        'id': 'cc2.8xlarge',
-        'name': 'Cluster Compute Eight Extra Large Instance',
-        'ram': GiB(60.5),
-        'disk': 4 * 840,  # GB
-        'bandwidth': None,
-        'extra': {
-            'cpu': 32
-        }
-    },
-    # c3 instances have 2 SSDs of the specified disk size
-    'c3.large': {
-        'id': 'c3.large',
-        'name': 'Compute Optimized Large Instance',
-        'ram': GiB(3.75),
-        'disk': 2 * 16,  # GB
-        'bandwidth': None,
-        'extra': {
-            'cpu': 2
-        }
-    },
-    'c3.xlarge': {
-        'id': 'c3.xlarge',
-        'name': 'Compute Optimized Extra Large Instance',
-        'ram': GiB(7.5),
-        'disk': 2 * 40,  # GB
-        'bandwidth': None,
-        'extra': {
-            'cpu': 4
-        }
-    },
-    'c3.2xlarge': {
-        'id': 'c3.2xlarge',
-        'name': 'Compute Optimized Double Extra Large Instance',
-        'ram': GiB(15),
-        'disk': 2 * 80,  # GB
-        'bandwidth': None,
-        'extra': {
-            'cpu': 8
-        }
-    },
-    'c3.4xlarge': {
-        'id': 'c3.4xlarge',
-        'name': 'Compute Optimized Quadruple Extra Large Instance',
-        'ram': GiB(30),
-        'disk': 2 * 160,  # GB
-        'bandwidth': None,
-        'extra': {
-            'cpu': 16
-        }
-    },
-    'c3.8xlarge': {
-        'id': 'c3.8xlarge',
-        'name': 'Compute Optimized Eight Extra Large Instance',
-        'ram': GiB(60),
-        'disk': 2 * 320,  # GB
-        'bandwidth': None,
-        'extra': {
-            'cpu': 32
-        }
-    },
-    'c4.large': {
-        'id': 'c4.large',
-        'name': 'Compute Optimized Large Instance',
-        'ram': GiB(3.75),
-        'disk': 0,  # EBS only
-        'bandwidth': None,
-        'extra': {
-            'cpu': 2
-        }
-    },
-    'c4.xlarge': {
-        'id': 'c4.xlarge',
-        'name': 'Compute Optimized Extra Large Instance',
-        'ram': GiB(7.5),
-        'disk': 0,  # EBS only
-        'bandwidth': None,
-        'extra': {
-            'cpu': 4
-        }
-    },
-    'c4.2xlarge': {
-        'id': 'c4.2xlarge',
-        'name': 'Compute Optimized Double Large Instance',
-        'ram': GiB(15),
-        'disk': 0,  # EBS only
-        'bandwidth': None,
-        'extra': {
-            'cpu': 8
-        }
-    },
-    'c4.4xlarge': {
-        'id': 'c4.4xlarge',
-        'name': 'Compute Optimized Quadruple Extra Large Instance',
-        'ram': GiB(30),
-        'disk': 0,  # EBS only
-        'bandwidth': None,
-        'extra': {
-            'cpu': 16
-        }
-    },
-    'c4.8xlarge': {
-        'id': 'c4.8xlarge',
-        'name': 'Compute Optimized Eight Extra Large Instance',
-        'ram': GiB(60),
-        'disk': 0,  # EBS only
-        'bandwidth': None,
-        'extra': {
-            'cpu': 32
-        }
-    },
-    'cr1.8xlarge': {
-        'id': 'cr1.8xlarge',
-        'name': 'High Memory Cluster Eight Extra Large',
-        'ram': GiB(244),
-        'disk': 2 * 120,  # GB
-        'bandwidth': None,
-        'extra': {
-            'cpu': 32
-        }
-    },
-    'hs1.4xlarge': {
-        'id': 'hs1.4xlarge',
-        'name': 'High Storage Quadruple Extra Large Instance',
-        'ram': GiB(64),
-        'disk': 2 * 1024,  # GB
-        'bandwidth': None,
-        'extra': {
-            'cpu': 16
-        }
-    },
-    'hs1.8xlarge': {
-        'id': 'hs1.8xlarge',
-        'name': 'High Storage Eight Extra Large Instance',
-        'ram': GiB(117),
-        'disk': 24 * 2000,
-        'bandwidth': None,
-        'extra': {
-            'cpu': 17
-        }
-    },
-    # i2 instances have up to eight SSD drives
-    'i2.xlarge': {
-        'id': 'i2.xlarge',
-        'name': 'High I/O Storage Optimized Extra Large Instance',
-        'ram': GiB(30.5),
-        'disk': 800,  # GB
-        'bandwidth': None,
-        'extra': {
-            'cpu': 4
-        }
-    },
-    'i2.2xlarge': {
-        'id': 'i2.2xlarge',
-        'name': 'High I/O Storage Optimized Double Extra Large Instance',
-        'ram': GiB(61),
-        'disk': 2 * 800,  # GB
-        'bandwidth': None,
-        'extra': {
-            'cpu': 8
-        }
-    },
-    'i2.4xlarge': {
-        'id': 'i2.4xlarge',
-        'name': 'High I/O Storage Optimized Quadruple Large Instance',
-        'ram': GiB(122),
-        'disk': 4 * 800,  # GB
-        'bandwidth': None,
-        'extra': {
-            'cpu': 16
-        }
-    },
-    'i2.8xlarge': {
-        'id': 'i2.8xlarge',
-        'name': 'High I/O Storage Optimized Eight Extra Large Instance',
-        'ram': GiB(244),
-        'disk': 8 * 800,  # GB
-        'bandwidth': None,
-        'extra': {
-            'cpu': 32
-        }
-    },
-    'd2.xlarge': {
-        'id': 'd2.xlarge',
-        'name': 'Dense Storage Optimized Extra Large Instance',
-        'ram': GiB(30.5),
-        'disk': 3 * 2000,  # GB
-        'bandwidth': None,
-        'extra': {
-            'cpu': 4
-        }
-    },
-    'd2.2xlarge': {
-        'id': 'd2.2xlarge',
-        'name': 'Dense Storage Optimized Double Extra Large Instance',
-        'ram': GiB(61),
-        'disk': 6 * 2000,  # GB
-        'bandwidth': None,
-        'extra': {
-            'cpu': 8
-        }
-    },
-    'd2.4xlarge': {
-        'id': 'd2.4xlarge',
-        'name': 'Dense Storage Optimized Quadruple Extra Large Instance',
-        'ram': GiB(122),
-        'disk': 12 * 2000,  # GB
-        'bandwidth': None,
-        'extra': {
-            'cpu': 16
-        }
-    },
-    'd2.8xlarge': {
-        'id': 'd2.8xlarge',
-        'name': 'Dense Storage Optimized Eight Extra Large Instance',
-        'ram': GiB(244),
-        'disk': 24 * 2000,  # GB
-        'bandwidth': None,
-        'extra': {
-            'cpu': 36
-        }
-    },
-    # 1x SSD
-    'r3.large': {
-        'id': 'r3.large',
-        'name': 'Memory Optimized Large instance',
-        'ram': GiB(15.25),
-        'disk': 32,  # GB
-        'bandwidth': None,
-        'extra': {
-            'cpu': 2
-        }
-    },
-    'r3.xlarge': {
-        'id': 'r3.xlarge',
-        'name': 'Memory Optimized Extra Large instance',
-        'ram': GiB(30.5),
-        'disk': 80,  # GB
-        'bandwidth': None,
-        'extra': {
-            'cpu': 4
-        }
-    },
-    'r3.2xlarge': {
-        'id': 'r3.2xlarge',
-        'name': 'Memory Optimized Double Extra Large instance',
-        'ram': GiB(61),
-        'disk': 160,  # GB
-        'bandwidth': None,
-        'extra': {
-            'cpu': 8
-        }
-    },
-    'r3.4xlarge': {
-        'id': 'r3.4xlarge',
-        'name': 'Memory Optimized Quadruple Extra Large instance',
-        'ram': GiB(122),
-        'disk': 320,  # GB
-        'bandwidth': None,
-        'extra': {
-            'cpu': 16
-        }
-    },
-    'r3.8xlarge': {
-        'id': 'r3.8xlarge',
-        'name': 'Memory Optimized Eight Extra Large instance',
-        'ram': GiB(244),
-        'disk': 2 * 320,  # GB
-        'bandwidth': None,
-        'extra': {
-            'cpu': 32
-        }
-    },
-    # Burstable Performance General Purpose
-    't2.nano': {
-        'id': 't2.nano',
-        'name': 'Burstable Performance Nano Instance',
-        'ram': 512,
-        'disk': 0,  # EBS Only
-        'bandwidth': None,
-        'extra': {
-            'cpu': 1
-        }
-    },
-    't2.micro': {
-        'id': 't2.micro',
-        'name': 'Burstable Performance Micro Instance',
-        'ram': GiB(1),
-        'disk': 0,  # EBS Only
-        'bandwidth': None,
-        'extra': {
-            'cpu': 1
-        }
-    },
-    't2.small': {
-        'id': 't2.small',
-        'name': 'Burstable Performance Small Instance',
-        'ram': GiB(2),
-        'disk': 0,  # EBS Only
-        'bandwidth': None,
-        'extra': {
-            'cpu': 11
-        }
-    },
-    't2.medium': {
-        'id': 't2.medium',
-        'name': 'Burstable Performance Medium Instance',
-        'ram': GiB(4),
-        'disk': 0,  # EBS Only
-        'bandwidth': None,
-        'extra': {
-            'cpu': 2
-        }
-    },
-    't2.large': {
-        'id': 't2.large',
-        'name': 'Burstable Performance Medium Instance',
-        'ram': GiB(8),
-        'disk': 0,  # EBS Only
-        'bandwidth': None,
-        'extra': {
-            'cpu': 2
-        }
-    }
-}
-
-#  From <https://aws.amazon.com/marketplace/help/200777880>
-REGION_DETAILS = {
-    # US East (Northern Virginia) Region
-    'us-east-1': {
-        'endpoint': 'ec2.us-east-1.amazonaws.com',
-        'api_name': 'ec2_us_east',
-        'country': 'USA',
-        'signature_version': '2',
-        'instance_types': [
-            't1.micro',
-            'm1.small',
-            'm1.medium',
-            'm1.large',
-            'm1.xlarge',
-            'm2.xlarge',
-            'm2.2xlarge',
-            'm2.4xlarge',
-            'm3.medium',
-            'm3.large',
-            'm3.xlarge',
-            'm3.2xlarge',
-            'm4.large',
-            'm4.xlarge',
-            'm4.2xlarge',
-            'm4.4xlarge',
-            'm4.10xlarge',
-            'c1.medium',
-            'c1.xlarge',
-            'cc2.8xlarge',
-            'c3.large',
-            'c3.xlarge',
-            'c3.2xlarge',
-            'c3.4xlarge',
-            'c3.8xlarge',
-            'c4.large',
-            'c4.xlarge',
-            'c4.2xlarge',
-            'c4.4xlarge',
-            'c4.8xlarge',
-            'cg1.4xlarge',
-            'g2.2xlarge',
-            'g2.8xlarge',
-            'cr1.8xlarge',
-            'hs1.8xlarge',
-            'i2.xlarge',
-            'i2.2xlarge',
-            'i2.4xlarge',
-            'i2.8xlarge',
-            'd2.xlarge',
-            'd2.2xlarge',
-            'd2.4xlarge',
-            'd2.8xlarge',
-            'r3.large',
-            'r3.xlarge',
-            'r3.2xlarge',
-            'r3.4xlarge',
-            'r3.8xlarge',
-            't2.nano',
-            't2.micro',
-            't2.small',
-            't2.medium',
-            't2.large'
-        ]
-    },
-    # US West (Northern California) Region
-    'us-west-1': {
-        'endpoint': 'ec2.us-west-1.amazonaws.com',
-        'api_name': 'ec2_us_west',
-        'country': 'USA',
-        'signature_version': '2',
-        'instance_types': [
-            't1.micro',
-            'm1.small',
-            'm1.medium',
-            'm1.large',
-            'm1.xlarge',
-            'm2.xlarge',
-            'm2.2xlarge',
-            'm2.4xlarge',
-            'm3.medium',
-            'm3.large',
-            'm3.xlarge',
-            'm3.2xlarge',
-            'm4.large',
-            'm4.xlarge',
-            'm4.2xlarge',
-            'm4.4xlarge',
-            'm4.10xlarge',
-            'c1.medium',
-            'c1.xlarge',
-            'g2.2xlarge',
-            'g2.8xlarge',
-            'c3.large',
-            'c3.xlarge',
-            'c3.2xlarge',
-            'c3.4xlarge',
-            'c3.8xlarge',
-            'c4.large',
-            'c4.xlarge',
-            'c4.2xlarge',
-            'c4.4xlarge',
-            'c4.8xlarge',
-            'i2.xlarge',
-            'i2.2xlarge',
-            'i2.4xlarge',
-            'i2.8xlarge',
-            'r3.large',
-            'r3.xlarge',
-            'r3.2xlarge',
-            'r3.4xlarge',
-            'r3.8xlarge',
-            't2.nano',
-            't2.micro',
-            't2.small',
-            't2.medium',
-            't2.large'
-        ]
-    },
-    # US West (Oregon) Region
-    'us-west-2': {
-        'endpoint': 'ec2.us-west-2.amazonaws.com',
-        'api_name': 'ec2_us_west_oregon',
-        'country': 'US',
-        'signature_version': '2',
-        'instance_types': [
-            't1.micro',
-            'm1.small',
-            'm1.medium',
-            'm1.large',
-            'm1.xlarge',
-            'm2.xlarge',
-            'm2.2xlarge',
-            'm2.4xlarge',
-            'm3.medium',
-            'm3.large',
-            'm3.xlarge',
-            'm3.2xlarge',
-            'm4.large',
-            'm4.xlarge',
-            'm4.2xlarge',
-            'm4.4xlarge',
-            'm4.10xlarge',
-            'c1.medium',
-            'c1.xlarge',
-            'g2.2xlarge',
-            'g2.8xlarge',
-            'c3.large',
-            'c3.xlarge',
-            'c3.2xlarge',
-            'c3.4xlarge',
-            'c3.8xlarge',
-            'c4.large',
-            'c4.xlarge',
-            'c4.2xlarge',
-            'c4.4xlarge',
-            'c4.8xlarge',
-            'hs1.8xlarge',
-            'cc2.8xlarge',
-            'i2.xlarge',
-            'i2.2xlarge',
-            'i2.4xlarge',
-            'i2.8xlarge',
-            'd2.xlarge',
-            'd2.2xlarge',
-            'd2.4xlarge',
-            'd2.8xlarge',
-            'r3.large',
-            'r3.xlarge',
-            'r3.2xlarge',
-            'r3.4xlarge',
-            'r3.8xlarge',
-            't2.nano',
-            't2.micro',
-            't2.small',
-            't2.medium',
-            't2.large'
-        ]
-    },
-    # EU (Ireland) Region
-    'eu-west-1': {
-        'endpoint': 'ec2.eu-west-1.amazonaws.com',
-        'api_name': 'ec2_eu_west',
-        'country': 'Ireland',
-        'signature_version': '2',
-        'instance_types': [
-            't1.micro',
-            'm1.small',
-            'm1.medium',
-            'm1.large',
-            'm1.xlarge',
-            'm2.xlarge',
-            'm2.2xlarge',
-            'm2.4xlarge',
-            'm3.medium',
-            'm3.large',
-            'm3.xlarge',
-            'm3.2xlarge',
-            'm4.large',
-            'm4.xlarge',
-            'm4.2xlarge',
-            'm4.4xlarge',
-            'm4.10xlarge',
-            'c1.medium',
-            'c1.xlarge',
-            'g2.2xlarge',
-            'g2.8xlarge',
-            'c3.large',
-            'c3.xlarge',
-            'c3.2xlarge',
-            'c3.4xlarge',
-            'c3.8xlarge',
-            'c4.large',
-            'c4.xlarge',
-            'c4.2xlarge',
-            'c4.4xlarge',
-            'c4.8xlarge',
-            'hs1.8xlarge',
-            'cc2.8xlarge',
-            'i2.xlarge',
-            'i2.2xlarge',
-            'i2.4xlarge',
-            'i2.8xlarge',
-            'd2.xlarge',
-            'd2.2xlarge',
-            'd2.4xlarge',
-            'd2.8xlarge',
-            'r3.large',
-            'r3.xlarge',
-            'r3.2xlarge',
-            'r3.4xlarge',
-            'r3.8xlarge',
-            't2.nano',
-            't2.micro',
-            't2.small',
-            't2.medium',
-            't2.large'
-        ]
-    },
-    # EU (Frankfurt) Region
-    'eu-central-1': {
-        'endpoint': 'ec2.eu-central-1.amazonaws.com',
-        'api_name': 'ec2_eu_central',
-        'country': 'Frankfurt',
-        'signature_version': '4',
-        'instance_types': [
-            'm3.medium',
-            'm3.large',
-            'm3.xlarge',
-            'm3.2xlarge',
-            'c3.large',
-            'c3.xlarge',
-            'c3.2xlarge',
-            'c3.4xlarge',
-            'c4.large',
-            'c4.xlarge',
-            'c4.2xlarge',
-            'c4.4xlarge',
-            'c4.8xlarge',
-            'm4.large',
-            'm4.xlarge',
-            'm4.2xlarge',
-            'm4.4xlarge',
-            'm4.10xlarge',
-            'c3.8xlarge',
-            'i2.xlarge',
-            'i2.2xlarge',
-            'i2.4xlarge',
-            'i2.8xlarge',
-            'd2.xlarge',
-            'd2.2xlarge',
-            'd2.4xlarge',
-            'd2.8xlarge',
-            'r3.large',
-            'r3.xlarge',
-            'r3.2xlarge',
-            'r3.4xlarge',
-            'r3.8xlarge',
-            't2.micro',
-            't2.small',
-            't2.medium',
-            't2.large'
-        ]
-    },
-    # Asia Pacific (Singapore) Region
-    'ap-southeast-1': {
-        'endpoint': 'ec2.ap-southeast-1.amazonaws.com',
-        'api_name': 'ec2_ap_southeast',
-        'country': 'Singapore',
-        'signature_version': '2',
-        'instance_types': [
-            't1.micro',
-            'm1.small',
-            'm1.medium',
-            'm1.large',
-            'm1.xlarge',
-            'm2.xlarge',
-            'm2.2xlarge',
-            'm2.4xlarge',
-            'm3.medium',
-            'm3.large',
-            'm3.xlarge',
-            'm3.2xlarge',
-            'm4.large',
-            'm4.xlarge',
-            'm4.2xlarge',
-            'm4.4xlarge',
-            'm4.10xlarge',
-            'c1.medium',
-            'c1.xlarge',
-            'c3.large',
-            'c3.xlarge',
-            'c3.2xlarge',
-            'c3.4xlarge',
-            'c3.8xlarge',
-            'c4.large',
-            'c4.xlarge',
-            'c4.2xlarge',
-            'c4.4xlarge',
-            'c4.8xlarge',
-            'hs1.8xlarge',
-            'i2.xlarge',
-            'i2.2xlarge',
-            'i2.4xlarge',
-            'i2.8xlarge',
-            'd2.xlarge',
-            'd2.2xlarge',
-            'd2.4xlarge',
-            'd2.8xlarge',
-            't2.nano',
-            't2.micro',
-            't2.small',
-            't2.medium',
-            't2.large'
-        ]
-    },
-    # Asia Pacific (Tokyo) Region
-    'ap-northeast-1': {
-        'endpoint': 'ec2.ap-northeast-1.amazonaws.com',
-        'api_name': 'ec2_ap_northeast',
-        'country': 'Japan',
-        'signature_version': '2',
-        'instance_types': [
-            't1.micro',
-            'm1.small',
-            'm1.medium',
-            'm1.large',
-            'm1.xlarge',
-            'm2.xlarge',
-            'm2.2xlarge',
-            'm2.4xlarge',
-            'm3.medium',
-            'm3.large',
-            'm3.xlarge',
-            'm3.2xlarge',
-            'c1.medium',
-            'g2.2xlarge',
-            'g2.8xlarge',
-            'c1.xlarge',
-            'c3.large',
-            'c3.xlarge',
-            'c3.2xlarge',
-            'c3.4xlarge',
-            'c3.8xlarge',
-            'c4.large',
-            'c4.xlarge',
-            'c4.2xlarge',
-            'c4.4xlarge',
-            'c4.8xlarge',
-            'm4.large',
-            'm4.xlarge',
-            'm4.2xlarge',
-            'm4.4xlarge',
-            'm4.10xlarge',
-            'hs1.8xlarge',
-            'i2.xlarge',
-            'i2.2xlarge',
-            'i2.4xlarge',
-            'i2.8xlarge',
-            'd2.xlarge',
-            'd2.2xlarge',
-            'd2.4xlarge',
-            'd2.8xlarge',
-            'r3.large',
-            'r3.xlarge',
-            'r3.2xlarge',
-            'r3.4xlarge',
-            'r3.8xlarge',
-            't2.nano',
-            't2.micro',
-            't2.small',
-            't2.medium',
-            't2.large'
-        ]
-    },
-    # Asia Pacific (Seoul) Region
-    'ap-northeast-2': {
-        'endpoint': 'ec2.ap-northeast-2.amazonaws.com',
-        'api_name': 'ec2_ap_northeast',
-        'country': 'South Korea',
-        'signature_version': '4',
-        'instance_types': [
-            'c4.large',
-            'c4.xlarge',
-            'c4.2xlarge',
-            'c4.4xlarge',
-            'c4.8xlarge',
-            'm4.large',
-            'm4.xlarge',
-            'm4.2xlarge',
-            'm4.4xlarge',
-            'm4.10xlarge',
-            'i2.xlarge',
-            'i2.2xlarge',
-            'i2.4xlarge',
-            'i2.8xlarge',
-            'd2.xlarge',
-            'd2.2xlarge',
-            'd2.4xlarge',
-            'd2.8xlarge',
-            'r3.large',
-            'r3.xlarge',
-            'r3.2xlarge',
-            'r3.4xlarge',
-            'r3.8xlarge',
-            't2.nano',
-            't2.micro',
-            't2.small',
-            't2.medium',
-            't2.large'
-        ]
-    },
-    # South America (Sao Paulo) Region
-    'sa-east-1': {
-        'endpoint': 'ec2.sa-east-1.amazonaws.com',
-        'api_name': 'ec2_sa_east',
-        'country': 'Brazil',
-        'signature_version': '2',
-        'instance_types': [
-            't1.micro',
-            'm1.small',
-            'm1.medium',
-            'm1.large',
-            'm1.xlarge',
-            'm2.xlarge',
-            'm2.2xlarge',
-            'm2.4xlarge',
-            'm3.medium',
-            'm3.large',
-            'm3.xlarge',
-            'm3.2xlarge',
-            'c1.medium',
-            'c1.xlarge',
-            't2.nano',
-            't2.micro',
-            't2.small',
-            't2.medium',
-            't2.large'
-        ]
-    },
-    # Asia Pacific (Sydney) Region
-    'ap-southeast-2': {
-        'endpoint': 'ec2.ap-southeast-2.amazonaws.com',
-        'api_name': 'ec2_ap_southeast_2',
-        'country': 'Australia',
-        'signature_version': '2',
-        'instance_types': [
-            't1.micro',
-            'm1.small',
-            'm1.medium',
-            'm1.large',
-            'm1.xlarge',
-            'm2.xlarge',
-            'm2.2xlarge',
-            'm2.4xlarge',
-            'm3.medium',
-            'm3.large',
-            'm3.xlarge',
-            'm3.2xlarge',
-            'm4.large',
-            'm4.xlarge',
-            'm4.2xlarge',
-            'm4.4xlarge',
-            'm4.10xlarge',
-            'c1.medium',
-            'c1.xlarge',
-            'c3.large',
-            'c3.xlarge',
-            'c3.2xlarge',
-            'c3.4xlarge',
-            'c3.8xlarge',
-            'c4.large',
-            'c4.xlarge',
-            'c4.2xlarge',
-            'c4.4xlarge',
-            'c4.8xlarge',
-            'hs1.8xlarge',
-            'i2.xlarge',
-            'i2.2xlarge',
-            'i2.4xlarge',
-            'i2.8xlarge',
-            'd2.xlarge',
-            'd2.2xlarge',
-            'd2.4xlarge',
-            'd2.8xlarge',
-            'r3.large',
-            'r3.xlarge',
-            'r3.2xlarge',
-            'r3.4xlarge',
-            'r3.8xlarge',
-            't2.micro',
-            't2.small',
-            't2.medium',
-            't2.large'
-        ]
-    },
-    'us-gov-west-1': {
-        'endpoint': 'ec2.us-gov-west-1.amazonaws.com',
-        'api_name': 'ec2_us_govwest',
-        'country': 'US',
-        'signature_version': '2',
-        'instance_types': [
-            't1.micro',
-            'm1.small',
-            'm1.medium',
-            'm1.large',
-            'm1.xlarge',
-            'm2.xlarge',
-            'm2.2xlarge',
-            'm2.4xlarge',
-            'm3.medium',
-            'm3.large',
-            'm3.xlarge',
-            'm3.2xlarge',
-            'c1.medium',
-            'c1.xlarge',
-            'g2.2xlarge',
-            'g2.8xlarge',
-            'c3.large',
-            'c3.xlarge',
-            'c3.2xlarge',
-            'c3.4xlarge',
-            'c3.8xlarge',
-            'c4.large',
-            'c4.xlarge',
-            'c4.2xlarge',
-            'c4.4xlarge',
-            'c4.8xlarge',
-            'hs1.4xlarge',
-            'hs1.8xlarge',
-            'i2.xlarge',
-            'i2.2xlarge',
-            'i2.4xlarge',
-            'i2.8xlarge',
-            'r3.large',
-            'r3.xlarge',
-            'r3.2xlarge',
-            'r3.4xlarge',
-            'r3.8xlarge',
-            't2.nano',
-            't2.micro',
-            't2.small',
-            't2.medium',
-            't2.large'
-        ]
-    },
-    'nimbus': {
-        # Nimbus clouds have 3 EC2-style instance types but their particular
-        # RAM allocations are configured by the admin
-        'country': 'custom',
-        'signature_version': '2',
-        'instance_types': [
-            'm1.small',
-            'm1.large',
-            'm1.xlarge'
-        ]
-    }
-}
-
-
-"""
-Sizes must be hardcoded because Outscale doesn't provide an API to fetch them.
-Outscale cloud instances share some names with EC2 but have different
-specifications so declare them in another constant.
-"""
-OUTSCALE_INSTANCE_TYPES = {
-    't1.micro': {
-        'id': 't1.micro',
-        'name': 'Micro Instance',
-        'ram': 615,
-        'disk': 0,
-        'bandwidth': None
-    },
-    'm1.small': {
-        'id': 'm1.small',
-        'name': 'Standard Small Instance',
-        'ram': 1740,
-        'disk': 150,
-        'bandwidth': None
-    },
-    'm1.medium': {
-        'id': 'm1.medium',
-        'name': 'Standard Medium Instance',
-        'ram': 3840,
-        'disk': 420,
-        'bandwidth': None
-    },
-    'm1.large': {
-        'id': 'm1.large',
-        'name': 'Standard Large Instance',
-        'ram': 7680,
-        'disk': 840,
-        'bandwidth': None
-    },
-    'm1.xlarge': {
-        'id': 'm1.xlarge',
-        'name': 'Standard Extra Large Instance',
-        'ram': 15360,
-        'disk': 1680,
-        'bandwidth': None
-    },
-    'c1.medium': {
-        'id': 'c1.medium',
-        'name': 'Compute Optimized Medium Instance',
-        'ram': 1740,
-        'disk': 340,
-        'bandwidth': None
-    },
-    'c1.xlarge': {
-        'id': 'c1.xlarge',
-        'name': 'Compute Optimized Extra Large Instance',
-        'ram': 7168,
-        'disk': 1680,
-        'bandwidth': None
-    },
-    'c3.large': {
-        'id': 'c3.large',
-        'name': 'Compute Optimized Large Instance',
-        'ram': 3840,
-        'disk': 32,
-        'bandwidth': None
-    },
-    'c3.xlarge': {
-        'id': 'c3.xlarge',
-        'name': 'Compute Optimized Extra Large Instance',
-        'ram': 7168,
-        'disk': 80,
-        'bandwidth': None
-    },
-    'c3.2xlarge': {
-        'id': 'c3.2xlarge',
-        'name': 'Compute Optimized Double Extra Large Instance',
-        'ram': 15359,
-        'disk': 160,
-        'bandwidth': None
-    },
-    'c3.4xlarge': {
-        'id': 'c3.4xlarge',
-        'name': 'Compute Optimized Quadruple Extra Large Instance',
-        'ram': 30720,
-        'disk': 320,
-        'bandwidth': None
-    },
-    'c3.8xlarge': {
-        'id': 'c3.8xlarge',
-        'name': 'Compute Optimized Eight Extra Large Instance',
-        'ram': 61440,
-        'disk': 640,
-        'bandwidth': None
-    },
-    'm2.xlarge': {
-        'id': 'm2.xlarge',
-        'name': 'High Memory Extra Large Instance',
-        'ram': 17510,
-        'disk': 420,
-        'bandwidth': None
-    },
-    'm2.2xlarge': {
-        'id': 'm2.2xlarge',
-        'name': 'High Memory Double Extra Large Instance',
-        'ram': 35020,
-        'disk': 840,
-        'bandwidth': None
-    },
-    'm2.4xlarge': {
-        'id': 'm2.4xlarge',
-        'name': 'High Memory Quadruple Extra Large Instance',
-        'ram': 70042,
-        'disk': 1680,
-        'bandwidth': None
-    },
-    'nv1.small': {
-        'id': 'nv1.small',
-        'name': 'GPU Small Instance',
-        'ram': 1739,
-        'disk': 150,
-        'bandwidth': None
-    },
-    'nv1.medium': {
-        'id': 'nv1.medium',
-        'name': 'GPU Medium Instance',
-        'ram': 3839,
-        'disk': 420,
-        'bandwidth': None
-    },
-    'nv1.large': {
-        'id': 'nv1.large',
-        'name': 'GPU Large Instance',
-        'ram': 7679,
-        'disk': 840,
-        'bandwidth': None
-    },
-    'nv1.xlarge': {
-        'id': 'nv1.xlarge',
-        'name': 'GPU Extra Large Instance',
-        'ram': 15358,
-        'disk': 1680,
-        'bandwidth': None
-    },
-    'g2.2xlarge': {
-        'id': 'g2.2xlarge',
-        'name': 'GPU Double Extra Large Instance',
-        'ram': 15360,
-        'disk': 60,
-        'bandwidth': None
-    },
-    'cc1.4xlarge': {
-        'id': 'cc1.4xlarge',
-        'name': 'Cluster Compute Quadruple Extra Large Instance',
-        'ram': 24576,
-        'disk': 1680,
-        'bandwidth': None
-    },
-    'cc2.8xlarge': {
-        'id': 'cc2.8xlarge',
-        'name': 'Cluster Compute Eight Extra Large Instance',
-        'ram': 65536,
-        'disk': 3360,
-        'bandwidth': None
-    },
-    'hi1.xlarge': {
-        'id': 'hi1.xlarge',
-        'name': 'High Storage Extra Large Instance',
-        'ram': 15361,
-        'disk': 1680,
-        'bandwidth': None
-    },
-    'm3.xlarge': {
-        'id': 'm3.xlarge',
-        'name': 'High Storage Optimized Extra Large Instance',
-        'ram': 15357,
-        'disk': 0,
-        'bandwidth': None
-    },
-    'm3.2xlarge': {
-        'id': 'm3.2xlarge',
-        'name': 'High Storage Optimized Double Extra Large Instance',
-        'ram': 30720,
-        'disk': 0,
-        'bandwidth': None
-    },
-    'm3s.xlarge': {
-        'id': 'm3s.xlarge',
-        'name': 'High Storage Optimized Extra Large Instance',
-        'ram': 15359,
-        'disk': 0,
-        'bandwidth': None
-    },
-    'm3s.2xlarge': {
-        'id': 'm3s.2xlarge',
-        'name': 'High Storage Optimized Double Extra Large Instance',
-        'ram': 30719,
-        'disk': 0,
-        'bandwidth': None
-    },
-    'cr1.8xlarge': {
-        'id': 'cr1.8xlarge',
-        'name': 'Memory Optimized Eight Extra Large Instance',
-        'ram': 249855,
-        'disk': 240,
-        'bandwidth': None
-    },
-    'os1.2xlarge': {
-        'id': 'os1.2xlarge',
-        'name': 'Memory Optimized, High Storage, Passthrough NIC Double Extra '
-                'Large Instance',
-        'ram': 65536,
-        'disk': 60,
-        'bandwidth': None
-    },
-    'os1.4xlarge': {
-        'id': 'os1.4xlarge',
-        'name': 'Memory Optimized, High Storage, Passthrough NIC Quadruple Ext'
-                'ra Large Instance',
-        'ram': 131072,
-        'disk': 120,
-        'bandwidth': None
-    },
-    'os1.8xlarge': {
-        'id': 'os1.8xlarge',
-        'name': 'Memory Optimized, High Storage, Passthrough NIC Eight Extra L'
-                'arge Instance',
-        'ram': 249856,
-        'disk': 500,
-        'bandwidth': None
-    },
-    'oc1.4xlarge': {
-        'id': 'oc1.4xlarge',
-        'name': 'Outscale Quadruple Extra Large Instance',
-        'ram': 24575,
-        'disk': 1680,
-        'bandwidth': None
-    },
-    'oc2.8xlarge': {
-        'id': 'oc2.8xlarge',
-        'name': 'Outscale Eight Extra Large Instance',
-        'ram': 65535,
-        'disk': 3360,
-        'bandwidth': None
-    }
-}
-
-
-"""
-The function manipulating Outscale cloud regions will be overridden because
-Outscale instances types are in a separate dict so also declare Outscale cloud
-regions in some other constants.
-"""
-OUTSCALE_SAS_REGION_DETAILS = {
-    'eu-west-3': {
-        'endpoint': 'api-ppd.outscale.com',
-        'api_name': 'osc_sas_eu_west_3',
-        'country': 'FRANCE',
-        'instance_types': [
-            't1.micro',
-            'm1.small',
-            'm1.medium',
-            'm1.large',
-            'm1.xlarge',
-            'c1.medium',
-            'c1.xlarge',
-            'm2.xlarge',
-            'm2.2xlarge',
-            'm2.4xlarge',
-            'nv1.small',
-            'nv1.medium',
-            'nv1.large',
-            'nv1.xlarge',
-            'cc1.4xlarge',
-            'cc2.8xlarge',
-            'm3.xlarge',
-            'm3.2xlarge',
-            'cr1.8xlarge',
-            'os1.8xlarge'
-        ]
-    },
-    'eu-west-1': {
-        'endpoint': 'api.eu-west-1.outscale.com',
-        'api_name': 'osc_sas_eu_west_1',
-        'country': 'FRANCE',
-        'instance_types': [
-            't1.micro',
-            'm1.small',
-            'm1.medium',
-            'm1.large',
-            'm1.xlarge',
-            'c1.medium',
-            'c1.xlarge',
-            'm2.xlarge',
-            'm2.2xlarge',
-            'm2.4xlarge',
-            'nv1.small',
-            'nv1.medium',
-            'nv1.large',
-            'nv1.xlarge',
-            'cc1.4xlarge',
-            'cc2.8xlarge',
-            'm3.xlarge',
-            'm3.2xlarge',
-            'cr1.8xlarge',
-            'os1.8xlarge'
-        ]
-    },
-    'eu-west-2': {
-        'endpoint': 'fcu.eu-west-2.outscale.com',
-        'api_name': 'osc_sas_eu_west_2',
-        'country': 'FRANCE',
-        'instance_types': [
-            't1.micro',
-            'm1.small',
-            'm1.medium',
-            'm1.large',
-            'm1.xlarge',
-            'c1.medium',
-            'c1.xlarge',
-            'm2.xlarge',
-            'm2.2xlarge',
-            'm2.4xlarge',
-            'nv1.small',
-            'nv1.medium',
-            'nv1.large',
-            'nv1.xlarge',
-            'cc1.4xlarge',
-            'cc2.8xlarge',
-            'm3.xlarge',
-            'm3.2xlarge',
-            'cr1.8xlarge',
-            'os1.8xlarge'
-        ]
-    },
-    'us-east-1': {
-        'endpoint': 'api.us-east-1.outscale.com',
-        'api_name': 'osc_sas_us_east_1',
-        'country': 'USA',
-        'instance_types': [
-            't1.micro',
-            'm1.small',
-            'm1.medium',
-            'm1.large',
-            'm1.xlarge',
-            'c1.medium',
-            'c1.xlarge',
-            'm2.xlarge',
-            'm2.2xlarge',
-            'm2.4xlarge',
-            'nv1.small',
-            'nv1.medium',
-            'nv1.large',
-            'nv1.xlarge',
-            'cc1.4xlarge',
-            'cc2.8xlarge',
-            'm3.xlarge',
-            'm3.2xlarge',
-            'cr1.8xlarge',
-            'os1.8xlarge'
-        ]
-    },
-    'us-east-2': {
-        'endpoint': 'fcu.us-east-2.outscale.com',
-        'api_name': 'osc_sas_us_east_2',
-        'country': 'USA',
-        'instance_types': [
-            't1.micro',
-            'm1.small',
-            'm1.medium',
-            'm1.large',
-            'm1.xlarge',
-            'c1.medium',
-            'c1.xlarge',
-            'm2.xlarge',
-            'm2.2xlarge',
-            'm2.4xlarge',
-            'nv1.small',
-            'nv1.medium',
-            'nv1.large',
-            'nv1.xlarge',
-            'cc1.4xlarge',
-            'cc2.8xlarge',
-            'm3.xlarge',
-            'm3.2xlarge',
-            'cr1.8xlarge',
-            'os1.8xlarge'
-        ]
-    },
-    'us-east-2': {
-        'endpoint': 'fcu.us-east-2.outscale.com',
-        'api_name': 'osc_sas_us_east_2',
-        'country': 'USA',
-        'instance_types': [
-            't1.micro',
-            'm1.small',
-            'm1.medium',
-            'm1.large',
-            'm1.xlarge',
-            'c1.medium',
-            'c1.xlarge',
-            'm2.xlarge',
-            'm2.2xlarge',
-            'm2.4xlarge',
-            'nv1.small',
-            'nv1.medium',
-            'nv1.large',
-            'nv1.xlarge',
-            'cc1.4xlarge',
-            'cc2.8xlarge',
-            'm3.xlarge',
-            'm3.2xlarge',
-            'cr1.8xlarge',
-            'os1.8xlarge'
-        ]
-    },
-    'us-east-2': {
-        'endpoint': 'fcu.us-east-2.outscale.com',
-        'api_name': 'osc_sas_us_east_2',
-        'country': 'USA',
-        'instance_types': [
-            't1.micro',
-            'm1.small',
-            'm1.medium',
-            'm1.large',
-            'm1.xlarge',
-            'c1.medium',
-            'c1.xlarge',
-            'm2.xlarge',
-            'm2.2xlarge',
-            'm2.4xlarge',
-            'nv1.small',
-            'nv1.medium',
-            'nv1.large',
-            'nv1.xlarge',
-            'cc1.4xlarge',
-            'cc2.8xlarge',
-            'm3.xlarge',
-            'm3.2xlarge',
-            'cr1.8xlarge',
-            'os1.8xlarge'
-        ]
-    },
-    'us-east-2': {
-        'endpoint': 'fcu.us-east-2.outscale.com',
-        'api_name': 'osc_sas_us_east_2',
-        'country': 'USA',
-        'instance_types': [
-            't1.micro',
-            'm1.small',
-            'm1.medium',
-            'm1.large',
-            'm1.xlarge',
-            'c1.medium',
-            'c1.xlarge',
-            'm2.xlarge',
-            'm2.2xlarge',
-            'm2.4xlarge',
-            'nv1.small',
-            'nv1.medium',
-            'nv1.large',
-            'nv1.xlarge',
-            'cc1.4xlarge',
-            'cc2.8xlarge',
-            'm3.xlarge',
-            'm3.2xlarge',
-            'cr1.8xlarge',
-            'os1.8xlarge'
-        ]
-    }
-}
-
-
-OUTSCALE_INC_REGION_DETAILS = {
-    'eu-west-1': {
-        'endpoint': 'api.eu-west-1.outscale.com',
-        'api_name': 'osc_inc_eu_west_1',
-        'country': 'FRANCE',
-        'instance_types': [
-            't1.micro',
-            'm1.small',
-            'm1.medium',
-            'm1.large',
-            'm1.xlarge',
-            'c1.medium',
-            'c1.xlarge',
-            'm2.xlarge',
-            'm2.2xlarge',
-            'm2.4xlarge',
-            'nv1.small',
-            'nv1.medium',
-            'nv1.large',
-            'nv1.xlarge',
-            'cc1.4xlarge',
-            'cc2.8xlarge',
-            'm3.xlarge',
-            'm3.2xlarge',
-            'cr1.8xlarge',
-            'os1.8xlarge'
-        ]
-    },
-    'eu-west-2': {
-        'endpoint': 'fcu.eu-west-2.outscale.com',
-        'api_name': 'osc_inc_eu_west_2',
-        'country': 'FRANCE',
-        'instance_types': [
-            't1.micro',
-            'm1.small',
-            'm1.medium',
-            'm1.large',
-            'm1.xlarge',
-            'c1.medium',
-            'c1.xlarge',
-            'm2.xlarge',
-            'm2.2xlarge',
-            'm2.4xlarge',
-            'nv1.small',
-            'nv1.medium',
-            'nv1.large',
-            'nv1.xlarge',
-            'cc1.4xlarge',
-            'cc2.8xlarge',
-            'm3.xlarge',
-            'm3.2xlarge',
-            'cr1.8xlarge',
-            'os1.8xlarge'
-        ]
-    },
-    'eu-west-3': {
-        'endpoint': 'api-ppd.outscale.com',
-        'api_name': 'osc_inc_eu_west_3',
-        'country': 'FRANCE',
-        'instance_types': [
-            't1.micro',
-            'm1.small',
-            'm1.medium',
-            'm1.large',
-            'm1.xlarge',
-            'c1.medium',
-            'c1.xlarge',
-            'm2.xlarge',
-            'm2.2xlarge',
-            'm2.4xlarge',
-            'nv1.small',
-            'nv1.medium',
-            'nv1.large',
-            'nv1.xlarge',
-            'cc1.4xlarge',
-            'cc2.8xlarge',
-            'm3.xlarge',
-            'm3.2xlarge',
-            'cr1.8xlarge',
-            'os1.8xlarge'
-        ]
-    },
-    'us-east-1': {
-        'endpoint': 'api.us-east-1.outscale.com',
-        'api_name': 'osc_inc_us_east_1',
-        'country': 'USA',
-        'instance_types': [
-            't1.micro',
-            'm1.small',
-            'm1.medium',
-            'm1.large',
-            'm1.xlarge',
-            'c1.medium',
-            'c1.xlarge',
-            'm2.xlarge',
-            'm2.2xlarge',
-            'm2.4xlarge',
-            'nv1.small',
-            'nv1.medium',
-            'nv1.large',
-            'nv1.xlarge',
-            'cc1.4xlarge',
-            'cc2.8xlarge',
-            'm3.xlarge',
-            'm3.2xlarge',
-            'cr1.8xlarge',
-            'os1.8xlarge'
-        ]
-    },
-    'us-east-2': {
-        'endpoint': 'fcu.us-east-2.outscale.com',
-        'api_name': 'osc_inc_us_east_2',
-        'country': 'USA',
-        'instance_types': [
-            't1.micro',
-            'm1.small',
-            'm1.medium',
-            'm1.large',
-            'm1.xlarge',
-            'c1.medium',
-            'c1.xlarge',
-            'm2.xlarge',
-            'm2.2xlarge',
-            'm2.4xlarge',
-            'nv1.small',
-            'nv1.medium',
-            'nv1.large',
-            'nv1.xlarge',
-            'cc1.4xlarge',
-            'cc2.8xlarge',
-            'm3.xlarge',
-            'm3.2xlarge',
-            'cr1.8xlarge',
-            'os1.8xlarge'
-        ]
-    }
-}
-
-
-"""
-Define the extra dictionary for specific resources
-"""
-RESOURCE_EXTRA_ATTRIBUTES_MAP = {
-    'ebs_volume': {
-        'snapshot_id': {
-            'xpath': 'ebs/snapshotId',
-            'transform_func': str
-        },
-        'volume_id': {
-            'xpath': 'ebs/volumeId',
-            'transform_func': str
-        },
-        'volume_size': {
-            'xpath': 'ebs/volumeSize',
-            'transform_func': int
-        },
-        'delete': {
-            'xpath': 'ebs/deleteOnTermination',
-            'transform_func': str
-        },
-        'volume_type': {
-            'xpath': 'ebs/volumeType',
-            'transform_func': str
-        },
-        'iops': {
-            'xpath': 'ebs/iops',
-            'transform_func': int
-        }
-    },
-    'elastic_ip': {
-        'allocation_id': {
-            'xpath': 'allocationId',
-            'transform_func': str,
-        },
-        'association_id': {
-            'xpath': 'associationId',
-            'transform_func': str,
-        },
-        'interface_id': {
-            'xpath': 'networkInterfaceId',
-            'transform_func': str,
-        },
-        'owner_id': {
-            'xpath': 'networkInterfaceOwnerId',
-            'transform_func': str,
-        },
-        'private_ip': {
-            'xpath': 'privateIp',
-            'transform_func': str,
-        }
-    },
-    'image': {
-        'state': {
-            'xpath': 'imageState',
-            'transform_func': str
-        },
-        'owner_id': {
-            'xpath': 'imageOwnerId',
-            'transform_func': str
-        },
-        'owner_alias': {
-            'xpath': 'imageOwnerAlias',
-            'transform_func': str
-        },
-        'is_public': {
-            'xpath': 'isPublic',
-            'transform_func': str
-        },
-        'architecture': {
-            'xpath': 'architecture',
-            'transform_func': str
-        },
-        'image_type': {
-            'xpath': 'imageType',
-            'transform_func': str
-        },
-        'image_location': {
-            'xpath': 'imageLocation',
-            'transform_func': str
-        },
-        'platform': {
-            'xpath': 'platform',
-            'transform_func': str
-        },
-        'description': {
-            'xpath': 'description',
-            'transform_func': str
-        },
-        'root_device_type': {
-            'xpath': 'rootDeviceType',
-            'transform_func': str
-        },
-        'virtualization_type': {
-            'xpath': 'virtualizationType',
-            'transform_func': str
-        },
-        'hypervisor': {
-            'xpath': 'hypervisor',
-            'transform_func': str
-        },
-        'kernel_id': {
-            'xpath': 'kernelId',
-            'transform_func': str
-        },
-        'ramdisk_id': {
-            'xpath': 'ramdiskId',
-            'transform_func': str
-        }
-    },
-    'network': {
-        'state': {
-            'xpath': 'state',
-            'transform_func': str
-        },
-        'dhcp_options_id': {
-            'xpath': 'dhcpOptionsId',
-            'transform_func': str
-        },
-        'instance_tenancy': {
-            'xpath': 'instanceTenancy',
-            'transform_func': str
-        },
-        'is_default': {
-            'xpath': 'isDefault',
-            'transform_func': str
-        }
-    },
-    'network_interface': {
-        'subnet_id': {
-            'xpath': 'subnetId',
-            'transform_func': str
-        },
-        'vpc_id': {
-            'xpath': 'vpcId',
-            'transform_func': str
-        },
-        'zone': {
-            'xpath': 'availabilityZone',
-            'transform_func': str
-        },
-        'description': {
-            'xpath': 'description',
-            'transform_func': str
-        },
-        'owner_id': {
-            'xpath': 'ownerId',
-            'transform_func': str
-        },
-        'mac_address': {
-            'xpath': 'macAddress',
-            'transform_func': str
-        },
-        'private_dns_name': {
-            'xpath': 'privateIpAddressesSet/privateDnsName',
-            'transform_func': str
-        },
-        'source_dest_check': {
-            'xpath': 'sourceDestCheck',
-            'transform_func': str
-        }
-    },
-    'network_interface_attachment': {
-        'attachment_id': {
-            'xpath': 'attachment/attachmentId',
-            'transform_func': str
-        },
-        'instance_id': {
-            'xpath': 'attachment/instanceId',
-            'transform_func': str
-        },
-        'owner_id': {
-            'xpath': 'attachment/instanceOwnerId',
-            'transform_func': str
-        },
-        'device_index': {
-            'xpath': 'attachment/deviceIndex',
-            'transform_func': int
-        },
-        'status': {
-            'xpath': 'attachment/status',
-            'transform_func': str
-        },
-        'attach_time': {
-            'xpath': 'attachment/attachTime',
-            'transform_func': parse_date
-        },
-        'delete': {
-            'xpath': 'attachment/deleteOnTermination',
-            'transform_func': str
-        }
-    },
-    'node': {
-        'availability': {
-            'xpath': 'placement/availabilityZone',
-            'transform_func': str
-        },
-        'architecture': {
-            'xpath': 'architecture',
-            'transform_func': str
-        },
-        'client_token': {
-            'xpath': 'clientToken',
-            'transform_func': str
-        },
-        'dns_name': {
-            'xpath': 'dnsName',
-            'transform_func': str
-        },
-        'hypervisor': {
-            'xpath': 'hypervisor',
-            'transform_func': str
-        },
-        'iam_profile': {
-            'xpath': 'iamInstanceProfile/id',
-            'transform_func': str
-        },
-        'image_id': {
-            'xpath': 'imageId',
-            'transform_func': str
-        },
-        'instance_id': {
-            'xpath': 'instanceId',
-            'transform_func': str
-        },
-        'instance_lifecycle': {
-            'xpath': 'instanceLifecycle',
-            'transform_func': str
-        },
-        'instance_tenancy': {
-            'xpath': 'placement/tenancy',
-            'transform_func': str
-        },
-        'instance_type': {
-            'xpath': 'instanceType',
-            'transform_func': str
-        },
-        'key_name': {
-            'xpath': 'keyName',
-            'transform_func': str
-        },
-        'launch_index': {
-            'xpath': 'amiLaunchIndex',
-            'transform_func': int
-        },
-        'launch_time': {
-            'xpath': 'launchTime',
-            'transform_func': str
-        },
-        'kernel_id': {
-            'xpath': 'kernelId',
-            'transform_func': str
-        },
-        'monitoring': {
-            'xpath': 'monitoring/state',
-            'transform_func': str
-        },
-        'platform': {
-            'xpath': 'platform',
-            'transform_func': str
-        },
-        'private_dns': {
-            'xpath': 'privateDnsName',
-            'transform_func': str
-        },
-        'ramdisk_id': {
-            'xpath': 'ramdiskId',
-            'transform_func': str
-        },
-        'root_device_type': {
-            'xpath': 'rootDeviceType',
-            'transform_func': str
-        },
-        'root_device_name': {
-            'xpath': 'rootDeviceName',
-            'transform_func': str
-        },
-        'reason': {
-            'xpath': 'reason',
-            'transform_func': str
-        },
-        'source_dest_check': {
-            'xpath': 'sourceDestCheck',
-            'transform_func': str
-        },
-        'status': {
-            'xpath': 'instanceState/name',
-            'transform_func': str
-        },
-        'subnet_id': {
-            'xpath': 'subnetId',
-            'transform_func': str
-        },
-        'virtualization_type': {
-            'xpath': 'virtualizationType',
-            'transform_func': str
-        },
-        'ebs_optimized': {
-            'xpath': 'ebsOptimized',
-            'transform_func': str
-        },
-        'vpc_id': {
-            'xpath': 'vpcId',
-            'transform_func': str
-        }
-    },
-    'reserved_node': {
-        'instance_type': {
-            'xpath': 'instanceType',
-            'transform_func': str
-        },
-        'availability': {
-            'xpath': 'availabilityZone',
-            'transform_func': str
-        },
-        'start': {
-            'xpath': 'start',
-            'transform_func': str
-        },
-        'duration': {
-            'xpath': 'duration',
-            'transform_func': int
-        },
-        'usage_price': {
-            'xpath': 'usagePrice',
-            'transform_func': float
-        },
-        'fixed_price': {
-            'xpath': 'fixedPrice',
-            'transform_func': float
-        },
-        'instance_count': {
-            'xpath': 'instanceCount',
-            'transform_func': int
-        },
-        'description': {
-            'xpath': 'productDescription',
-            'transform_func': str
-        },
-        'instance_tenancy': {
-            'xpath': 'instanceTenancy',
-            'transform_func': str
-        },
-        'currency_code': {
-            'xpath': 'currencyCode',
-            'transform_func': str
-        },
-        'offering_type': {
-            'xpath': 'offeringType',
-            'transform_func': str
-        }
-    },
-    'security_group': {
-        'vpc_id': {
-            'xpath': 'vpcId',
-            'transform_func': str
-        },
-        'description': {
-            'xpath': 'groupDescription',
-            'transform_func': str
-        },
-        'owner_id': {
-            'xpath': 'ownerId',
-            'transform_func': str
-        }
-    },
-    'snapshot': {
-        'volume_id': {
-            'xpath': 'volumeId',
-            'transform_func': str
-        },
-        'state': {
-            'xpath': 'status',
-            'transform_func': str
-        },
-        'description': {
-            'xpath': 'description',
-            'transform_func': str
-        },
-        'progress': {
-            'xpath': 'progress',
-            'transform_func': str
-        },
-        'start_time': {
-            'xpath': 'startTime',
-            'transform_func': parse_date
-        }
-    },
-    'subnet': {
-        'cidr_block': {
-            'xpath': 'cidrBlock',
-            'transform_func': str
-        },
-        'available_ips': {
-            'xpath': 'availableIpAddressCount',
-            'transform_func': int
-        },
-        'zone': {
-            'xpath': 'availabilityZone',
-            'transform_func': str
-        },
-        'vpc_id': {
-            'xpath': 'vpcId',
-            'transform_func': str
-        }
-    },
-    'volume': {
-        'device': {
-            'xpath': 'attachmentSet/item/device',
-            'transform_func': str
-        },
-        'snapshot_id': {
-            'xpath': 'snapshotId',
-            'transform_func': lambda v: str(v) or None
-        },
-        'iops': {
-            'xpath': 'iops',
-            'transform_func': int
-        },
-        'zone': {
-            'xpath': 'availabilityZone',
-            'transform_func': str
-        },
-        'create_time': {
-            'xpath': 'createTime',
-            'transform_func': parse_date
-        },
-        'state': {
-            'xpath': 'status',
-            'transform_func': str
-        },
-        'attach_time': {
-            'xpath': 'attachmentSet/item/attachTime',
-            'transform_func': parse_date
-        },
-        'attachment_status': {
-            'xpath': 'attachmentSet/item/status',
-            'transform_func': str
-        },
-        'instance_id': {
-            'xpath': 'attachmentSet/item/instanceId',
-            'transform_func': str
-        },
-        'delete': {
-            'xpath': 'attachmentSet/item/deleteOnTermination',
-            'transform_func': str
-        },
-        'type': {
-            'xpath': 'volumeType',
-            'transform_func': str
-        }
-    },
-    'route_table': {
-        'vpc_id': {
-            'xpath': 'vpcId',
-            'transform_func': str
-        }
-    }
-}
-
-VALID_EC2_REGIONS = REGION_DETAILS.keys()
-VALID_EC2_REGIONS = [r for r in VALID_EC2_REGIONS if r != 'nimbus']
-
-
-class EC2NodeLocation(NodeLocation):
-    def __init__(self, id, name, country, driver, availability_zone):
-        super(EC2NodeLocation, self).__init__(id, name, country, driver)
-        self.availability_zone = availability_zone
-
-    def __repr__(self):
-        return (('<EC2NodeLocation: id=%s, name=%s, country=%s, '
-                 'availability_zone=%s driver=%s>')
-                % (self.id, self.name, self.country,
-                   self.availability_zone, self.driver.name))
-
-
-class EC2Response(AWSBaseResponse):
-    """
-    EC2 specific response parsing and error handling.
-    """
-
-    def parse_error(self):
-        err_list = []
-        # Okay, so for Eucalyptus, you can get a 403, with no body,
-        # if you are using the wrong user/password.
-        msg = "Failure: 403 Forbidden"
-        if self.status == 403 and self.body[:len(msg)] == msg:
-            raise InvalidCredsError(msg)
-
-        try:
-            body = ET.XML(self.body)
-        except:
-            raise MalformedResponseError("Failed to parse XML",
-                                         body=self.body, driver=EC2NodeDriver)
-
-        for err in body.findall('Errors/Error'):
-            code, message = err.getchildren()
-            err_list.append('%s: %s' % (code.text, message.text))
-            if code.text == 'InvalidClientTokenId':
-                raise InvalidCredsError(err_list[-1])
-            if code.text == 'SignatureDoesNotMatch':
-                raise InvalidCredsError(err_list[-1])
-            if code.text == 'AuthFailure':
-                raise InvalidCredsError(err_list[-1])
-            if code.text == 'OptInRequired':
-                raise InvalidCredsError(err_list[-1])
-            if code.text == 'IdempotentParameterMismatch':
-                raise IdempotentParamError(err_list[-1])
-            if code.text == 'InvalidKeyPair.NotFound':
-                # TODO: Use connection context instead
-                match = re.match(r'.*\'(.+?)\'.*', message.text)
-
-                if match:
-                    name = match.groups()[0]
-                else:
-                    name = None
-
-                raise KeyPairDoesNotExistError(name=name,
-                                               driver=self.connection.driver)
-        return '\n'.join(err_list)
-
-
-class EC2Connection(SignedAWSConnection):
-    """
-    Represents a single connection to the EC2 Endpoint.
-    """
-
-    version = API_VERSION
-    host = REGION_DETAILS['us-east-1']['endpoint']
-    responseCls = EC2Response
-    service_name = 'ec2'
-
-
-class ExEC2AvailabilityZone(object):
-    """
-    Extension class which stores information about an EC2 availability zone.
-
-    Note: This class is EC2 specific.
-    """
-
-    def __init__(self, name, zone_state, region_name):
-        self.name = name
-        self.zone_state = zone_state
-        self.region_name = region_name
-
-    def __repr__(self):
-        return (('<ExEC2AvailabilityZone: name=%s, zone_state=%s, '
-                 'region_name=%s>')
-                % (self.name, self.zone_state, self.region_name))
-
-
-class EC2ReservedNode(Node):
-    """
-    Class which stores information about EC2 reserved instances/nodes
-    Inherits from Node and passes in None for name and private/public IPs
-
-    Note: This class is EC2 specific.
-    """
-
-    def __init__(self, id, state, driver, size=None, image=None, extra=None):
-        super(EC2ReservedNode, self).__init__(id=id, name=None, state=state,
-                                              public_ips=None,
-                                              private_ips=None,
-                                              driver=driver, extra=extra)
-
-    def __repr__(self):
-        return (('<EC2ReservedNode: id=%s>') % (self.id))
-
-
-class EC2SecurityGroup(object):
-    """
-    Represents information about a Security group
-
-    Note: This class is EC2 specific.
-    """
-
-    def __init__(self, id, name, ingress_rules, egress_rules, extra=None):
-        self.id = id
-        self.name = name
-        self.ingress_rules = ingress_rules
-        self.egress_rules = egress_rules
-        self.extra = extra or {}
-
-    def __repr__(self):
-        return (('<EC2SecurityGroup: id=%s, name=%s')
-                % (self.id, self.name))
-
-
-class EC2PlacementGroup(object):
-    """
-    Represents information about a Placement Grous
-
-    Note: This class is EC2 specific.
-    """
-    def __init__(self, name, state, strategy='cluster', extra=None):
-        self.name = name
-        self.strategy = strategy
-        self.extra = extra or {}
-
-    def __repr__(self):
-        return '<EC2PlacementGroup: name=%s, state=%s>' % (self.name,
-                                                           self.strategy)
-
-
-class EC2Network(object):
-    """
-    Represents information about a VPC (Virtual Private Cloud) network
-
-    Note: This class is EC2 specific.
-    """
-
-    def __init__(self, id, name, cidr_block, extra=None):
-        self.id = id
-        self.name = name
-        self.cidr_block = cidr_block
-        self.extra = extra or {}
-
-    def __repr__(self):
-        return (('<EC2Network: id=%s, name=%s')
-                % (self.id, self.name))
-
-
-class EC2NetworkSubnet(object):
-    """
-    Represents information about a VPC (Virtual Private Cloud) subnet
-
-    Note: This class is EC2 specific.
-    """
-
-    def __init__(self, id, name, state, extra=None):
-        self.id = id
-        self.name = name
-        self.state = state
-        self.extra = extra or {}
-
-    def __repr__(self):
-        return (('<EC2NetworkSubnet: id=%s, name=%s') % (self.id, self.name))
-
-
-class EC2NetworkInterface(object):
-    """
-    Represents information about a VPC network interface
-
-    Note: This class is EC2 specific. The state parameter denotes the current
-    status of the interface. Valid values for state are attaching, attached,
-    detaching and detached.
-    """
-
-    def __init__(self, id, name, state, extra=None):
-        self.id = id
-        self.name = name
-        self.state = state
-        self.extra = extra or {}
-
-    def __repr__(self):
-        return (('<EC2NetworkInterface: id=%s, name=%s')
-                % (self.id, self.name))
-
-
-class ElasticIP(object):
-    """
-    Represents information about an elastic IP address
-
-    :param      ip: The elastic IP address
-    :type       ip: ``str``
-
-    :param      domain: The domain that the IP resides in (EC2-Classic/VPC).
-                        EC2 classic is represented with standard and VPC
-                        is represented with vpc.
-    :type       domain: ``str``
-
-    :param      instance_id: The identifier of the instance which currently
-                             has the IP associated.
-    :type       instance_id: ``str``
-
-    Note: This class is used to support both EC2 and VPC IPs.
-          For VPC specific attributes are stored in the extra
-          dict to make promotion to the base API easier.
-    """
-
-    def __init__(self, ip, domain, instance_id, extra=None):
-        self.ip = ip
-        self.domain = domain
-        self.instance_id = instance_id
-        self.extra = extra or {}
-
-    def __repr__(self):
-        return (('<ElasticIP: ip=%s, domain=%s, instance_id=%s>')
-                % (self.ip, self.domain, self.instance_id))
-
-
-class VPCInternetGateway(object):
-    """
-    Class which stores information about VPC Internet Gateways.
-
-    Note: This class is VPC specific.
-    """
-
-    def __init__(self, id, name, vpc_id, state, driver, extra=None):
-        self.id = id
-        self.name = name
-        self.vpc_id = vpc_id
-        self.state = state
-        self.extra = extra or {}
-
-    def __repr__(self):
-        return (('<VPCInternetGateway: id=%s>') % (self.id))
-
-
-class EC2RouteTable(object):
-    """
-    Class which stores information about VPC Route Tables.
-
-    Note: This class is VPC specific.
-    """
-
-    def __init__(self, id, name, routes, subnet_associations,
-                 propagating_gateway_ids, extra=None):
-        """
-        :param      id: The ID of the route table.
-        :type       id: ``str``
-
-        :param      name: The name of the route table.
-        :type       name: ``str``
-
-        :param      routes: A list of routes in the route table.
-        :type       routes: ``list`` of :class:`EC2Route`
-
-        :param      subnet_associations: A list of associations between the
-                                         route table and one or more subnets.
-        :type       subnet_associations: ``list`` of
-                                         :class:`EC2SubnetAssociation`
-
-        :param      propagating_gateway_ids: The list of IDs of any virtual
-                                             private gateways propagating the
-                                             routes.
-        :type       propagating_gateway_ids: ``list``
-        """
-
-        self.id = id
-        self.name = name
-        self.routes = routes
-        self.subnet_associations = subnet_associations
-        self.propagating_gateway_ids = propagating_gateway_ids
-        self.extra = extra or {}
-
-    def __repr__(self):
-        return (('<EC2RouteTable: id=%s>') % (self.id))
-
-
-class EC2Route(object):
-    """
-    Class which stores information about a Route.
-
-    Note: This class is VPC specific.
-    """
-
-    def __init__(self, cidr, gateway_id, instance_id, owner_id,
-                 interface_id, state, origin, vpc_peering_connection_id):
-        """
-        :param      cidr: The CIDR block used for the destination match.
-        :type       cidr: ``str``
-
-        :param      gateway_id: The ID of a gateway attached to the VPC.
-        :type       gateway_id: ``str``
-
-        :param      instance_id: The ID of a NAT instance in the VPC.
-        :type       instance_id: ``str``
-
-        :param      owner_id: The AWS account ID of the owner of the instance.
-        :type       owner_id: ``str``
-
-        :param      interface_id: The ID of the network interface.
-        :type       interface_id: ``str``
-
-        :param      state: The state of the route (active | blackhole).
-        :type       state: ``str``
-
-        :param      origin: Describes how the route was created.
-        :type       origin: ``str``
-
-        :param      vpc_peering_connection_id: The ID of the VPC
-                                               peering connection.
-        :type       vpc_peering_connection_id: ``str``
-        """
-
-        self.cidr = cidr
-        self.gateway_id = gateway_id
-        self.instance_id = instance_id
-        self.owner_id = owner_id
-        self.interface_id = interface_id
-        self.state = state
-        self.origin = origin
-        self.vpc_peering_connection_id = vpc_peering_connection_id
-
-    def __repr__(self):
-        return (('<EC2Route: cidr=%s>') % (self.cidr))
-
-
-class EC2SubnetAssociation(object):
-    """
-    Class which stores information about Route Table associated with
-    a given Subnet in a VPC
-
-    Note: This class is VPC specific.
-    """
-
-    def __init__(self, id, route_table_id, subnet_id, main=False):
-        """
-        :param      id: The ID of the subnet association in the VPC.
-        :type       id: ``str``
-
-        :param      route_table_id: The ID of a route table in the VPC.
-        :type       route_table_id: ``str``
-
-        :param      subnet_id: The ID of a subnet in the VPC.
-        :type       subnet_id: ``str``
-
-        :param      main: If true, means this is a main VPC route table.
-        :type       main: ``bool``
-        """
-
-        self.id = id
-        self.route_table_id = route_table_id
-        self.subnet_id = subnet_id
-        self.main = main
-
-    def __repr__(self):
-        return (('<EC2SubnetAssociation: id=%s>') % (self.id))
-
-
-class BaseEC2NodeDriver(NodeDriver):
-    """
-    Base Amazon EC2 node driver.
-
-    Used for main EC2 and other derivate driver classes to inherit from it.
-    """
-
-    connectionCls = EC2Connection
-    features = {'create_node': ['ssh_key']}
-    path = '/'
-    signature_version = DEFAULT_SIGNATURE_VERSION
-
-    NODE_STATE_MAP = {
-        'pending': NodeState.PENDING,
-        'running': NodeState.RUNNING,
-        'shutting-down': NodeState.UNKNOWN,
-        'terminated': NodeState.TERMINATED
-    }
-
-    # http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_Volume.html
-    VOLUME_STATE_MAP = {
-        'available': StorageVolumeState.AVAILABLE,
-        'in-use': StorageVolumeState.INUSE,
-        'error': StorageVolumeState.ERROR,
-        'creating': StorageVolumeState.CREATING,
-        'deleting': StorageVolumeState.DELETING,
-        'deleted': StorageVolumeState.DELETED,
-        'error_deleting': StorageVolumeState.ERROR
-    }
-
-    SNAPSHOT_STATE_MAP = {
-        'pending': VolumeSnapshotState.CREATING,
-        'completed': VolumeSnapshotState.AVAILABLE,
-        'error': VolumeSnapshotState.ERROR,
-    }
-
-    def list_nodes(self, ex_node_ids=None, ex_filters=None):
-        """
-        List all nodes
-
-        Ex_node_ids parameter is used to filter the list of
-        nodes that should be returned. Only the nodes
-        with the corresponding node ids will be returned.
-
-        :param      ex_node_ids: List of ``node.id``
-        :type       ex_node_ids: ``list`` of ``str``
-
-        :param      ex_filters: The filters so that the response includes
-                             information for only certain nodes.
-        :type       ex_filters: ``dict``
-
-        :rtype: ``list`` of :class:`Node`
-        """
-
-        params = {'Action': 'DescribeInstances'}
-
-        if ex_node_ids:
-            params.update(self._pathlist('InstanceId', ex_node_ids))
-
-        if ex_filters:
-            params.update(self._build_filters(ex_filters))
-
-        elem = self.connection.request(self.path, params=params).object
-
-        nodes = []
-        for rs in findall(element=elem, xpath='reservationSet/item',
-                          namespace=NAMESPACE):
-            nodes += self._to_nodes(rs, 'instancesSet/item')
-
-        nodes_elastic_ips_mappings = self.ex_describe_addresses(nodes)
-
-        for node in nodes:
-            ips = nodes_elastic_ips_mappings[node.id]
-            node.public_ips.extend(ips)
-
-        return nodes
-
-    def list_sizes(self, location=None):
-        available_types = REGION_DETAILS[self.region_name]['instance_types']
-        sizes = []
-
-        for instance_type in available_types:
-            attributes = INSTANCE_TYPES[instance_type]
-            attributes = copy.deepcopy(attributes)
-            price = self._get_size_price(size_id=instance_type)
-            attributes.update({'price': price})
-            sizes.append(NodeSize(driver=self, **attributes))
-        return sizes
-
-    def list_images(self, location=None, ex_image_ids=None, ex_owner=None,
-                    ex_executableby=None, ex_filters=None):
-        """
-        List all images
-        @inherits: :class:`NodeDriver.list_images`
-
-        Ex_image_ids parameter is used to filter the list of
-        images that should be returned. Only the images
-        with the corresponding image ids will be returned.
-
-        Ex_owner parameter is used to filter the list of
-        images that should be returned. Only the images
-        with the corresponding owner will be returned.
-        Valid values: amazon|aws-marketplace|self|all|aws id
-
-        Ex_executableby parameter describes images for which
-        the specified user has explicit launch permissions.
-        The user can be an AWS account ID, self to return
-        images for which the sender of the request has
-        explicit launch permissions, or all to return
-        images with public launch permissions.
-        Valid values: all|self|aws id
-
-        Ex_filters parameter is used to filter the list of
-        images that should be returned. Only images matching
-        the filter will be returned.
-
-        :param      ex_image_ids: List of ``NodeImage.id``
-        :type       ex_image_ids: ``list`` of ``str``
-
-        :param      ex_owner: Owner name
-        :type       ex_owner: ``str``
-
-        :param      ex_executableby: Executable by
-        :type       ex_executableby: ``str``
-
-        :param      ex_filters: Filter by
-        :type       ex_filters: ``dict``
-
-        :rtype: ``list`` of :class:`NodeImage`
-        """
-        params = {'Action': 'DescribeImages'}
-
-        if ex_owner:
-            params.update({'Owner.1': ex_owner})
-
-        if ex_executableby:
-            params.update({'ExecutableBy.1': ex_executableby})
-
-        if ex_image_ids:
-            for index, image_id in enumerate(ex_image_ids):
-                index += 1
-                params.update({'ImageId.%s' % (index): image_id})
-
-        if ex_filters:
-            params.update(self._build_filters(ex_filters))
-
-        images = self._to_images(
-            self.connection.request(self.path, params=params).object
-        )
-        return images
-
-    def get_image(self, image_id):
-        """
-        Get an image based on an image_id
-
-        :param image_id: Image identifier
-        :type image_id: ``str``
-
-        :return: A NodeImage object
-        :rtype: :class:`NodeImage`
-
-        """
-        images = self.list_images(ex_image_ids=[image_id])
-        image = images[0]
-
-        return image
-
-    def list_locations(self):
-        locations = []
-        for index, availability_zone in \
-                enumerate(self.ex_list_availability_zones()):
-                    locations.append(EC2NodeLocation(
-                        index, availability_zone.name, self.country, self,
-                        availability_zone)
-                    )
-        return locations
-
-    def list_volumes(self, node=None):
-        params = {
-            'Action': 'DescribeVolumes',
-        }
-        if node:
-            filters = {'attachment.instance-id': node.id}
-            params.update(self._build_filters(filters))
-
-        response = self.connection.request(self.path, params=params).object
-        volumes = [self._to_volume(el) for el in response.findall(
-            fixxpath(xpath='volumeSet/item', namespace=NAMESPACE))
-        ]
-        return volumes
-
-    def create_node(self, **kwargs):
-        """
-        Create a new EC2 node.
-
-        Reference: http://bit.ly/8ZyPSy [docs.amazonwebservices.com]
-
-        @inherits: :class:`NodeDriver.create_node`
-
-        :keyword    ex_keyname: The name of the key pair
-        :type       ex_keyname: ``str``
-
-        :keyword    ex_userdata: User data
-        :type       ex_userdata: ``str``
-
-        :keyword    ex_security_groups: A list of names of security groups to
-                                        assign to the node.
-        :type       ex_security_groups:   ``list``
-
-        :keyword    ex_security_group_ids: A list of ids of security groups to
-                                        assign to the node.[for VPC nodes only]
-        :type       ex_security_group_ids:   ``list``
-
-        :keyword    ex_metadata: Key/Value metadata to associate with a node
-        :type       ex_metadata: ``dict``
-
-        :keyword    ex_mincount: Minimum number of instances to launch
-        :type       ex_mincount: ``int``
-
-        :keyword    ex_maxcount: Maximum number of instances to launch
-        :type       ex_maxcount: ``int``
-
-        :keyword    ex_clienttoken: Unique identifier to ensure idempotency
-        :type       ex_clienttoken: ``str``
-
-        :keyword    ex_blockdevicemappings: ``list`` of ``dict`` block device
-                    mappings.
-        :type       ex_blockdevicemappings: ``list`` of ``dict``
-
-        :keyword    ex_iamprofile: Name or ARN of IAM profile
-        :type       ex_iamprofile: ``str``
-
-        :keyword    ex_ebs_optimized: EBS-Optimized if True
-        :type       ex_ebs_optimized: ``bool``
-
-        :keyword    ex_subnet: The subnet to launch the instance into.
-        :type       ex_subnet: :class:`.EC2Subnet`
-
-        :keyword    ex_placement_group: The name of the placement group to
-                                        launch the instance into.
-        :type       ex_placement_group: ``str``
-
-        :keyword    ex_assign_public_ip: If True, the instance will
-                                         be assigned a public ip address.
-                                         Note : It takes takes a short
-                                         while for the instance to be
-                                         assigned the public ip so the
-                                         node returned will NOT have
-                                         the public ip assigned yet.
-        :type       ex_assign_public_ip: ``bool``
-
-        :keyword    ex_terminate_on_shutdown: Indicates if the instance
-                                              should be terminated instead
-                                              of just shut down when using
-                                              the operating systems command
-                                              for system shutdown.
-        :type       ex_terminate_on_shutdown: ``bool``
-        """
-        image = kwargs["image"]
-        size = kwargs["size"]
-        params = {
-            'Action': 'RunInstances',
-            'ImageId': image.id,
-            'MinCount': str(kwargs.get('ex_mincount', '1')),
-            'MaxCount': str(kwargs.get('ex_maxcount', '1')),
-            'InstanceType': size.id
-        }
-
-        if kwargs.get("ex_terminate_on_shutdown", False):
-            params["InstanceInitiatedShutdownBehavior"] = "terminate"
-
-        if 'ex_security_groups' in kwargs and 'ex_securitygroup' in kwargs:
-            raise ValueError('You can only supply ex_security_groups or'
-                             ' ex_securitygroup')
-
-        # ex_securitygroup is here for backward compatibility
-        ex_security_groups = kwargs.get('ex_security_groups', None)
-        ex_securitygroup = kwargs.get('ex_securitygroup', None)
-        security_groups = ex_security_groups or ex_securitygroup
-
-        if security_groups:
-            if not isinstance(security_groups, (tuple, list)):
-                security_groups = [security_groups]
-
-            for sig in range(len(security_groups)):
-                params['SecurityGroup.%d' % (sig + 1,)] =\
-                    security_groups[sig]
-
-        if 'ex_security_group_ids' in kwargs and 'ex_subnet' not in kwargs:
-            raise ValueError('You can only supply ex_security_group_ids'
-                             ' combinated with ex_subnet')
-
-        security_group_ids = kwargs.get('ex_security_group_ids', None)
-        security_group_id_params = {}
-
-        if security_group_ids:
-            if not isinstance(security_group_ids, (tuple, list)):
-                security_group_ids = [security_group_ids]
-
-            for sig in range(len(security_group_ids)):
-                security_group_id_params['SecurityGroupId.%d' % (sig + 1,)] =\
-                    security_group_ids[sig]
-
-        if 'location' in kwargs:
-            availability_zone = getattr(kwargs['location'],
-                                        'availability_zone', None)
-            if availability_zone:
-                if availability_zone.region_name != self.region_name:
-                    raise AttributeError('Invalid availability zone: %s'
-                                         % (availability_zone.name))
-                params['Placement.AvailabilityZone'] = availability_zone.name
-
-        if 'auth' in kwargs and 'ex_keyname' in kwargs:
-            raise AttributeError('Cannot specify auth and ex_keyname together')
-
-        if 'auth' in kwargs:
-            auth = self._get_and_check_auth(kwargs['auth'])
-            key = self.ex_find_or_import_keypair_by_key_material(auth.pubkey)
-            params['KeyName'] = key['keyName']
-
-        if 'ex_keyname' in kwargs:
-            params['KeyName'] = kwargs['ex_keyname']
-
-        if 'ex_userdata' in kwargs:
-            params['UserData'] = base64.b64encode(b(kwargs['ex_userdata']))\
-                .decode('utf-8')
-
-        if 'ex_clienttoken' in kwargs:
-            params['ClientToken'] = kwargs['ex_clienttoken']
-
-        if 'ex_blockdevicemappings' in kwargs:
-            params.update(self._get_block_device_mapping_params(
-                          kwargs['ex_blockdevicemappings']))
-
-        if 'ex_iamprofile' in kwargs:
-            if not isinstance(kwargs['ex_iamprofile'], basestring):
-                raise AttributeError('ex_iamprofile not string')
-
-            if kwargs['ex_iamprofile'].startswith('arn:aws:iam:'):
-                params['IamInstanceProfile.Arn'] = kwargs['ex_iamprofile']
-            else:
-                params['IamInstanceProfile.Name'] = kwargs['ex_iamprofile']
-
-        if 'ex_ebs_optimized' in kwargs:
-            params['EbsOptimized'] = kwargs['ex_ebs_optimized']
-
-        subnet_id = None
-        if 'ex_subnet' in kwargs:
-            subnet_id = kwargs['ex_subnet'].id
-
-        if 'ex_placement_group' in kwargs and kwargs['ex_placement_group']:
-            params['Placement.GroupName'] = kwargs['ex_placement_group']
-
-        assign_public_ip = kwargs.get('ex_assign_public_ip', False)
-        # In the event that a public ip is requested a NetworkInterface
-        # needs to be specified.  Some properties that would
-        # normally be at the root (security group ids and subnet id)
-        # need to be moved to the level of the NetworkInterface because
-        # the NetworkInterface is no longer created implicitly
-        if assign_public_ip:
-            root_key = 'NetworkInterface.1.'
-            params[root_key + 'AssociatePublicIpAddress'] = "true"
-            # This means that when the instance is terminated, the
-            # NetworkInterface we created for the instance will be
-            # deleted automatically
-            params[root_key + 'DeleteOnTermination'] = "true"
-            # Required to be 0 if we are associating a public ip
-            params[root_key + 'DeviceIndex'] = "0"
-
-            if subnet_id:
-                params[root_key + 'SubnetId'] = subnet_id
-
-            for key, security_group_id in security_group_id_params.items():
-                key = root_key + key
-                params[key] = security_group_id
-        else:
-            params.update(security_group_id_params)
-            if subnet_id:
-                params['SubnetId'] = subnet_id
-
-        object = self.connection.request(self.path, params=params).object
-        nodes = self._to_nodes(object, 'instancesSet/item')
-
-        for node in nodes:
-            tags = {'Name': kwargs['name']}
-            if 'ex_metadata' in kwargs:
-                tags.update(kwargs['ex_metadata'])
-
-            try:
-                self.ex_create_tags(resource=node, tags=tags)
-            except Exception:
-                continue
-
-            node.name = kwargs['name']
-            node.extra.update({'tags': tags})
-
-        if len(nodes) == 1:
-            return nodes[0]
-        else:
-            return nodes
-
-    def reboot_node(self, node):
-        params = {'Action': 'RebootInstances'}
-        params.update(self._pathlist('InstanceId', [node.id]))
-        res = self.connection.request(self.path, params=params).object
-        return self._get_boolea

<TRUNCATED>

[19/56] [abbrv] libcloud git commit: Removed sdist

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/runabove.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/runabove.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/runabove.py
deleted file mode 100644
index 72a45c6..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/runabove.py
+++ /dev/null
@@ -1,453 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-RunAbove driver
-"""
-from libcloud.common.runabove import API_ROOT, RunAboveConnection
-from libcloud.compute.base import NodeDriver, NodeSize, Node, NodeLocation
-from libcloud.compute.base import NodeImage, StorageVolume
-from libcloud.compute.types import Provider, StorageVolumeState
-from libcloud.compute.drivers.openstack import OpenStackNodeDriver
-from libcloud.compute.drivers.openstack import OpenStackKeyPair
-
-
-class RunAboveNodeDriver(NodeDriver):
-    """
-    Libcloud driver for the RunAbove API
-
-    For more information on the RunAbove API, read the official reference:
-
-        https://api.runabove.com/console/
-    """
-    type = Provider.RUNABOVE
-    name = "RunAbove"
-    website = 'https://www.runabove.com/'
-    connectionCls = RunAboveConnection
-    features = {'create_node': ['ssh_key']}
-    api_name = 'runabove'
-
-    NODE_STATE_MAP = OpenStackNodeDriver.NODE_STATE_MAP
-    VOLUME_STATE_MAP = OpenStackNodeDriver.VOLUME_STATE_MAP
-
-    def __init__(self, key, secret, ex_consumer_key=None):
-        """
-        Instantiate the driver with the given API credentials.
-
-        :param key: Your application key (required)
-        :type key: ``str``
-
-        :param secret: Your application secret (required)
-        :type secret: ``str``
-
-        :param ex_consumer_key: Your consumer key (required)
-        :type ex_consumer_key: ``str``
-
-        :rtype: ``None``
-        """
-        self.datacenter = None
-        self.consumer_key = ex_consumer_key
-        NodeDriver.__init__(self, key, secret, ex_consumer_key=ex_consumer_key)
-
-    def list_nodes(self, location=None):
-        """
-        List all nodes.
-
-        :keyword location: Location (region) used as filter
-        :type    location: :class:`NodeLocation`
-
-        :return: List of node objects
-        :rtype: ``list`` of :class:`Node`
-        """
-        action = API_ROOT + '/instance'
-        data = {}
-        if location:
-            data['region'] = location.id
-        response = self.connection.request(action, data=data)
-        return self._to_nodes(response.object)
-
-    def ex_get_node(self, node_id):
-        """
-        Get a individual node.
-
-        :keyword node_id: Node's ID
-        :type    node_id: ``str``
-
-        :return: Created node
-        :rtype  : :class:`Node`
-        """
-        action = API_ROOT + '/instance/' + node_id
-        response = self.connection.request(action, method='GET')
-        return self._to_node(response.object)
-
-    def create_node(self, name, image, size, location, ex_keyname=None):
-        """
-        Create a new node
-
-        :keyword name: Name of created node
-        :type    name: ``str``
-
-        :keyword image: Image used for node
-        :type    image: :class:`NodeImage`
-
-        :keyword size: Size (flavor) used for node
-        :type    size: :class:`NodeSize`
-
-        :keyword location: Location (region) where to create node
-        :type    location: :class:`NodeLocation`
-
-        :keyword ex_keyname: Name of SSH key used
-        :type    ex_keyname: ``str``
-
-        :return: Created node
-        :rtype : :class:`Node`
-        """
-        action = API_ROOT + '/instance'
-        data = {
-            'name': name,
-            'imageId': image.id,
-            'flavorId': size.id,
-            'region': location.id,
-        }
-        if ex_keyname:
-            data['sshKeyName'] = ex_keyname
-        response = self.connection.request(action, data=data, method='POST')
-        return self._to_node(response.object)
-
-    def destroy_node(self, node):
-        action = API_ROOT + '/instance/' + node.id
-        self.connection.request(action, method='DELETE')
-        return True
-
-    def list_sizes(self, location=None):
-        action = API_ROOT + '/flavor'
-        data = {}
-        if location:
-            data['region'] = location.id
-        response = self.connection.request(action, data=data)
-        return self._to_sizes(response.object)
-
-    def ex_get_size(self, size_id):
-        """
-        Get an individual size (flavor).
-
-        :keyword size_id: Size's ID
-        :type    size_id: ``str``
-
-        :return: Size
-        :rtype: :class:`NodeSize`
-        """
-        action = API_ROOT + '/flavor/' + size_id
-        response = self.connection.request(action)
-        return self._to_size(response.object)
-
-    def list_images(self, location=None, ex_size=None):
-        """
-        List available images
-
-        :keyword location: Location (region) used as filter
-        :type    location: :class:`NodeLocation`
-
-        :keyword ex_size: Exclude images which are uncompatible with given size
-        :type    ex_size: :class:`NodeImage`
-
-        :return: List of images
-        :rtype  : ``list`` of :class:`NodeImage`
-        """
-        action = API_ROOT + '/image'
-        data = {}
-        if location:
-            data['region'] = location.id
-        if ex_size:
-            data['flavorId'] = ex_size.id
-        response = self.connection.request(action, data=data)
-        return self._to_images(response.object)
-
-    def get_image(self, image_id):
-        action = API_ROOT + '/image/' + image_id
-        response = self.connection.request(action)
-        return self._to_image(response.object)
-
-    def list_locations(self):
-        action = API_ROOT + '/region'
-        data = self.connection.request(action)
-        return self._to_locations(data.object)
-
-    def list_key_pairs(self, location=None):
-        """
-        List available SSH public keys.
-
-        :keyword location: Location (region) used as filter
-        :type    location: :class:`NodeLocation`
-
-        :return: Public keys
-        :rtype: ``list``of :class:`KeyPair`
-        """
-        action = API_ROOT + '/ssh'
-        data = {}
-        if location:
-            data['region'] = location.id
-        response = self.connection.request(action, data=data)
-        return self._to_key_pairs(response.object)
-
-    def get_key_pair(self, name, location):
-        """
-        Get an individual SSH public key by its name and location.
-
-        :keyword name: SSH key name
-        :type name: str
-
-        :keyword location: Key's region
-        :type location: :class:`NodeLocation`
-
-        :return: Public key
-        :rtype: :class:`KeyPair`
-        """
-        action = API_ROOT + '/ssh/' + name
-        data = {'region': location.id}
-        response = self.connection.request(action, data=data)
-        return self._to_key_pair(response.object)
-
-    def import_key_pair_from_string(self, name, key_material, location):
-        """
-        Import a new public key from string.
-
-        :param name: Key pair name.
-        :type name: ``str``
-
-        :param key_material: Public key material.
-        :type key_material: ``str``
-
-        :return: Imported key pair object.
-        :rtype: :class:`KeyPair`
-        """
-        action = API_ROOT + '/ssh'
-        data = {'name': name, 'publicKey': key_material, 'region': location.id}
-        response = self.connection.request(action, data=data, method='POST')
-        return self._to_key_pair(response.object)
-
-    def delete_key_pair(self, name, location):
-        """
-        Delete an existing key pair.
-
-        :param name: Key pair name.
-        :type name: ``str``
-
-        :keyword location: Key's region
-        :type location: :class:`NodeLocation`
-
-        :return:   True of False based on success of Keypair deletion
-        :rtype:    ``bool``
-        """
-        action = API_ROOT + '/ssh/' + name
-        data = {'name': name, 'region': location.id}
-        self.connection.request(action, data=data, method='DELETE')
-        return True
-
-    def create_volume(self, size, location, name=None,
-                      ex_volume_type='classic', ex_description=None):
-        """
-        Create a volume.
-
-        :param size: Size of volume to create (in GB).
-        :type size: ``int``
-
-        :param name: Name of volume to create
-        :type name: ``str``
-
-        :keyword location: Location to create the volume in
-        :type location: :class:`NodeLocation` or ``None``
-
-        :keyword ex_volume_type: ``'classic'`` or ``'high-speed'``
-        :type ex_volume_type: ``str``
-
-        :keyword ex_description: Optionnal description of volume
-        :type ex_description: str
-
-        :return:  Storage Volume object
-        :rtype:   :class:`StorageVolume`
-        """
-        action = API_ROOT + '/volume'
-        data = {
-            'region': location.id,
-            'size': str(size),
-            'type': ex_volume_type,
-        }
-        if name:
-            data['name'] = name
-        if ex_description:
-            data['description'] = ex_description
-        response = self.connection.request(action, data=data, method='POST')
-        return self._to_volume(response.object)
-
-    def destroy_volume(self, volume):
-        action = API_ROOT + '/volume/' + volume.id
-        self.connection.request(action, method='DELETE')
-        return True
-
-    def list_volumes(self, location=None):
-        """
-        Return a list of volumes.
-
-        :keyword location: Location use for filter
-        :type location: :class:`NodeLocation` or ``None``
-
-        :return: A list of volume objects.
-        :rtype: ``list`` of :class:`StorageVolume`
-        """
-        action = API_ROOT + '/volume'
-        data = {}
-        if location:
-            data['region'] = location.id
-        response = self.connection.request(action, data=data)
-        return self._to_volumes(response.object)
-
-    def ex_get_volume(self, volume_id):
-        """
-        Return a Volume object based on a volume ID.
-
-        :param  volume_id: The ID of the volume
-        :type   volume_id: ``int``
-
-        :return:  A StorageVolume object for the volume
-        :rtype:   :class:`StorageVolume`
-        """
-        action = API_ROOT + '/volume/' + volume_id
-        response = self.connection.request(action)
-        return self._to_volume(response.object)
-
-    def attach_volume(self, node, volume, device=None):
-        """
-        Attach a volume to a node.
-
-        :param node: Node where to attach volume
-        :type node: :class:`Node`
-
-        :param volume: The ID of the volume
-        :type volume: :class:`StorageVolume`
-
-        :param device: Unsed parameter
-
-        :return: True or False representing operation successful
-        :rtype:   ``bool``
-        """
-        action = '%s/volume/%s/attach' % (API_ROOT, volume.id)
-        data = {'instanceId': node.id}
-        self.connection.request(action, data=data, method='POST')
-        return True
-
-    def detach_volume(self, volume, ex_node=None):
-        """
-        Detach a volume to a node.
-
-        :param volume: The ID of the volume
-        :type volume: :class:`StorageVolume`
-
-        :param ex_node: Node to detach from (optionnal if volume is attached
-                        to only one node)
-        :type ex_node: :class:`Node`
-
-        :return: True or False representing operation successful
-        :rtype:   ``bool``
-
-        :raises: Exception: If ``ex_node`` is not provided and more than one
-                            node is attached to the volume
-        """
-        action = '%s/volume/%s/detach' % (API_ROOT, volume.id)
-        if ex_node is None:
-            if len(volume.extra['attachedTo']) != 1:
-                err_msg = "Volume '%s' has more or less than one attached \
-                    nodes, you must specify one."
-                raise Exception(err_msg)
-            ex_node = self.ex_get_node(volume.extra['attachedTo'][0])
-        data = {'instanceId': ex_node.id}
-        self.connection.request(action, data=data, method='POST')
-        return True
-
-    def _to_volume(self, obj):
-        extra = obj.copy()
-        extra.pop('id')
-        extra.pop('name')
-        extra.pop('size')
-        state = self.VOLUME_STATE_MAP.get(obj.pop('status', None),
-                                          StorageVolumeState.UNKNOWN)
-        return StorageVolume(id=obj['id'], name=obj['name'], size=obj['size'],
-                             state=state, extra=extra, driver=self)
-
-    def _to_volumes(self, objs):
-        return [self._to_volume(obj) for obj in objs]
-
-    def _to_location(self, obj):
-        location = self.connection.LOCATIONS[obj]
-        return NodeLocation(driver=self, **location)
-
-    def _to_locations(self, objs):
-        return [self._to_location(obj) for obj in objs]
-
-    def _to_node(self, obj):
-        extra = obj.copy()
-        if 'flavorId' in extra:
-            public_ips = [obj.pop('ip')]
-        else:
-            ip = extra.pop('ipv4')
-            public_ips = [ip] if ip else []
-        del extra['instanceId']
-        del extra['name']
-        return Node(id=obj['instanceId'], name=obj['name'],
-                    state=self.NODE_STATE_MAP[obj['status']],
-                    public_ips=public_ips, private_ips=[], driver=self,
-                    extra=extra)
-
-    def _to_nodes(self, objs):
-        return [self._to_node(obj) for obj in objs]
-
-    def _to_size(self, obj):
-        extra = {'vcpus': obj['vcpus'], 'type': obj['type'],
-                 'region': obj['region']}
-        return NodeSize(id=obj['id'], name=obj['name'], ram=obj['ram'],
-                        disk=obj['disk'], bandwidth=None, price=None,
-                        driver=self, extra=extra)
-
-    def _to_sizes(self, objs):
-        return [self._to_size(obj) for obj in objs]
-
-    def _to_image(self, obj):
-        extra = {'region': obj['region'], 'visibility': obj['visibility'],
-                 'deprecated': obj['deprecated']}
-        return NodeImage(id=obj['id'], name=obj['name'], driver=self,
-                         extra=extra)
-
-    def _to_images(self, objs):
-        return [self._to_image(obj) for obj in objs]
-
-    def _to_key_pair(self, obj):
-        extra = {'region': obj['region']}
-        return OpenStackKeyPair(name=obj['name'], public_key=obj['publicKey'],
-                                driver=self, fingerprint=obj['fingerPrint'],
-                                extra=extra)
-
-    def _to_key_pairs(self, objs):
-        return [self._to_key_pair(obj) for obj in objs]
-
-    def _ex_connection_class_kwargs(self):
-        return {'ex_consumer_key': self.consumer_key}
-
-    def _add_required_headers(self, headers, method, action, data, timestamp):
-        timestamp = self.connection.get_timestamp()
-        signature = self.connection.make_signature(method, action, data,
-                                                   str(timestamp))
-        headers.update({
-            'X-Ra-Timestamp': timestamp,
-            'X-Ra-Signature': signature
-        })

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/serverlove.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/serverlove.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/serverlove.py
deleted file mode 100644
index 2ba92a9..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/serverlove.py
+++ /dev/null
@@ -1,83 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-ServerLove Driver
-"""
-
-from libcloud.compute.types import Provider
-from libcloud.compute.drivers.elasticstack import ElasticStackBaseNodeDriver
-from libcloud.compute.drivers.elasticstack import ElasticStackBaseConnection
-
-
-# API end-points
-API_ENDPOINTS = {
-    'uk-1': {
-        'name': 'United Kingdom, Manchester',
-        'country': 'United Kingdom',
-        'host': 'api.z1-man.serverlove.com'
-    }
-}
-
-# Default API end-point for the base connection class.
-DEFAULT_ENDPOINT = 'uk-1'
-
-# Retrieved from http://www.serverlove.com/cloud-server-faqs/api-questions/
-STANDARD_DRIVES = {
-    '679f5f44-0be7-4745-a658-cccd4334c1aa': {
-        'uuid': '679f5f44-0be7-4745-a658-cccd4334c1aa',
-        'description': 'CentOS 5.5',
-        'size_gunzipped': '1GB',
-        'supports_deployment': True,
-    },
-    '5f2e0e29-2937-42b9-b362-d2d07eddbdeb': {
-        'uuid': '5f2e0e29-2937-42b9-b362-d2d07eddbdeb',
-        'description': 'Ubuntu Linux 10.04',
-        'size_gunzipped': '1GB',
-        'supports_deployment': True,
-    },
-    '5795b68f-ed26-4639-b41d-c93235062b6b': {
-        'uuid': '5795b68f-ed26-4639-b41d-c93235062b6b',
-        'description': 'Debian Linux 5',
-        'size_gunzipped': '1GB',
-        'supports_deployment': True,
-    },
-    '41993a02-0b22-4e49-bb47-0aa8975217e4': {
-        'uuid': '41993a02-0b22-4e49-bb47-0aa8975217e4',
-        'description': 'Windows Server 2008 R2 Standard',
-        'size_gunzipped': '15GB',
-        'supports_deployment': False,
-    },
-    '85623ca1-9c2a-4398-a771-9a43c347e86b': {
-        'uuid': '85623ca1-9c2a-4398-a771-9a43c347e86b',
-        'description': 'Windows Web Server 2008 R2',
-        'size_gunzipped': '15GB',
-        'supports_deployment': False,
-    }
-}
-
-
-class ServerLoveConnection(ElasticStackBaseConnection):
-    host = API_ENDPOINTS[DEFAULT_ENDPOINT]['host']
-
-
-class ServerLoveNodeDriver(ElasticStackBaseNodeDriver):
-    type = Provider.SERVERLOVE
-    api_name = 'serverlove'
-    website = 'http://www.serverlove.com/'
-    name = 'ServerLove'
-    connectionCls = ServerLoveConnection
-    features = {'create_node': ['generates_password']}
-    _standard_drives = STANDARD_DRIVES

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/skalicloud.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/skalicloud.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/skalicloud.py
deleted file mode 100644
index c0b0d79..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/skalicloud.py
+++ /dev/null
@@ -1,83 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-skalicloud Driver
-"""
-
-from libcloud.compute.types import Provider
-from libcloud.compute.drivers.elasticstack import ElasticStackBaseNodeDriver
-from libcloud.compute.drivers.elasticstack import ElasticStackBaseConnection
-
-
-# API end-points
-API_ENDPOINTS = {
-    'my-1': {
-        'name': 'Malaysia, Kuala Lumpur',
-        'country': 'Malaysia',
-        'host': 'api.sdg-my.skalicloud.com'
-    }
-}
-
-# Default API end-point for the base connection class.
-DEFAULT_ENDPOINT = 'my-1'
-
-# Retrieved from http://www.skalicloud.com/cloud-api/
-STANDARD_DRIVES = {
-    '90aa51f2-15c0-4cff-81ee-e93aa20b9468': {
-        'uuid': '90aa51f2-15c0-4cff-81ee-e93aa20b9468',
-        'description': 'CentOS 5.5 -64bit',
-        'size_gunzipped': '1GB',
-        'supports_deployment': True,
-    },
-    'c144d7a7-e24b-48ab-954b-6b6ec514ed6f': {
-        'uuid': 'c144d7a7-e24b-48ab-954b-6b6ec514ed6f',
-        'description': 'Debian 5 -64bit',
-        'size_gunzipped': '1GB',
-        'supports_deployment': True,
-    },
-    '3051699a-a536-4220-aeb5-67f2ec101a09': {
-        'uuid': '3051699a-a536-4220-aeb5-67f2ec101a09',
-        'description': 'Ubuntu Server 10.10 -64bit',
-        'size_gunzipped': '1GB',
-        'supports_deployment': True,
-    },
-    '11c4c922-5ff8-4094-b06c-eb8ffaec1ea9': {
-        'uuid': '11c4c922-5ff8-4094-b06c-eb8ffaec1ea9',
-        'description': 'Windows 2008R2 Web Edition',
-        'size_gunzipped': '13GB',
-        'supports_deployment': False,
-    },
-    '93bf390e-4f46-4252-a8bc-9d6d80e3f955': {
-        'uuid': '93bf390e-4f46-4252-a8bc-9d6d80e3f955',
-        'description': 'Windows Server 2008R2 Standard',
-        'size_gunzipped': '13GB',
-        'supports_deployment': False,
-    }
-}
-
-
-class SkaliCloudConnection(ElasticStackBaseConnection):
-    host = API_ENDPOINTS[DEFAULT_ENDPOINT]['host']
-
-
-class SkaliCloudNodeDriver(ElasticStackBaseNodeDriver):
-    type = Provider.SKALICLOUD
-    api_name = 'skalicloud'
-    name = 'skalicloud'
-    website = 'http://www.skalicloud.com/'
-    connectionCls = SkaliCloudConnection
-    features = {"create_node": ["generates_password"]}
-    _standard_drives = STANDARD_DRIVES

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/softlayer.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/softlayer.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/softlayer.py
deleted file mode 100644
index 5243d0b..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/softlayer.py
+++ /dev/null
@@ -1,505 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-Softlayer driver
-"""
-
-import time
-try:
-    from Crypto.PublicKey import RSA
-    crypto = True
-except ImportError:
-    crypto = False
-
-from libcloud.common.softlayer import SoftLayerConnection, SoftLayerException
-from libcloud.compute.types import Provider, NodeState
-from libcloud.compute.base import NodeDriver, Node, NodeLocation, NodeSize, \
-    NodeImage, KeyPair
-from libcloud.compute.types import KeyPairDoesNotExistError
-
-DEFAULT_DOMAIN = 'example.com'
-DEFAULT_CPU_SIZE = 1
-DEFAULT_RAM_SIZE = 2048
-DEFAULT_DISK_SIZE = 100
-
-DATACENTERS = {
-    'hou02': {'country': 'US'},
-    'sea01': {'country': 'US', 'name': 'Seattle - West Coast U.S.'},
-    'wdc01': {'country': 'US', 'name': 'Washington, DC - East Coast U.S.'},
-    'dal01': {'country': 'US'},
-    'dal02': {'country': 'US'},
-    'dal04': {'country': 'US'},
-    'dal05': {'country': 'US', 'name': 'Dallas - Central U.S.'},
-    'dal06': {'country': 'US'},
-    'dal07': {'country': 'US'},
-    'sjc01': {'country': 'US', 'name': 'San Jose - West Coast U.S.'},
-    'sng01': {'country': 'SG', 'name': 'Singapore - Southeast Asia'},
-    'ams01': {'country': 'NL', 'name': 'Amsterdam - Western Europe'},
-    'tok02': {'country': 'JP', 'name': 'Tokyo - Japan'},
-}
-
-NODE_STATE_MAP = {
-    'RUNNING': NodeState.RUNNING,
-    'HALTED': NodeState.UNKNOWN,
-    'PAUSED': NodeState.UNKNOWN,
-    'INITIATING': NodeState.PENDING
-}
-
-SL_BASE_TEMPLATES = [
-    {
-        'name': '1 CPU, 1GB ram, 25GB',
-        'ram': 1024,
-        'disk': 25,
-        'cpus': 1,
-    }, {
-        'name': '1 CPU, 1GB ram, 100GB',
-        'ram': 1024,
-        'disk': 100,
-        'cpus': 1,
-    }, {
-        'name': '1 CPU, 2GB ram, 100GB',
-        'ram': 2 * 1024,
-        'disk': 100,
-        'cpus': 1,
-    }, {
-        'name': '1 CPU, 4GB ram, 100GB',
-        'ram': 4 * 1024,
-        'disk': 100,
-        'cpus': 1,
-    }, {
-        'name': '2 CPU, 2GB ram, 100GB',
-        'ram': 2 * 1024,
-        'disk': 100,
-        'cpus': 2,
-    }, {
-        'name': '2 CPU, 4GB ram, 100GB',
-        'ram': 4 * 1024,
-        'disk': 100,
-        'cpus': 2,
-    }, {
-        'name': '2 CPU, 8GB ram, 100GB',
-        'ram': 8 * 1024,
-        'disk': 100,
-        'cpus': 2,
-    }, {
-        'name': '4 CPU, 4GB ram, 100GB',
-        'ram': 4 * 1024,
-        'disk': 100,
-        'cpus': 4,
-    }, {
-        'name': '4 CPU, 8GB ram, 100GB',
-        'ram': 8 * 1024,
-        'disk': 100,
-        'cpus': 4,
-    }, {
-        'name': '6 CPU, 4GB ram, 100GB',
-        'ram': 4 * 1024,
-        'disk': 100,
-        'cpus': 6,
-    }, {
-        'name': '6 CPU, 8GB ram, 100GB',
-        'ram': 8 * 1024,
-        'disk': 100,
-        'cpus': 6,
-    }, {
-        'name': '8 CPU, 8GB ram, 100GB',
-        'ram': 8 * 1024,
-        'disk': 100,
-        'cpus': 8,
-    }, {
-        'name': '8 CPU, 16GB ram, 100GB',
-        'ram': 16 * 1024,
-        'disk': 100,
-        'cpus': 8,
-    }]
-
-SL_TEMPLATES = {}
-for i, template in enumerate(SL_BASE_TEMPLATES):
-    # Add local disk templates
-    local = template.copy()
-    local['local_disk'] = True
-    SL_TEMPLATES[i] = local
-
-
-class SoftLayerNodeDriver(NodeDriver):
-    """
-    SoftLayer node driver
-
-    Extra node attributes:
-        - password: root password
-        - hourlyRecurringFee: hourly price (if applicable)
-        - recurringFee      : flat rate    (if applicable)
-        - recurringMonths   : The number of months in which the recurringFee
-         will be incurred.
-    """
-    connectionCls = SoftLayerConnection
-    name = 'SoftLayer'
-    website = 'http://www.softlayer.com/'
-    type = Provider.SOFTLAYER
-
-    features = {'create_node': ['generates_password', 'ssh_key']}
-    api_name = 'softlayer'
-
-    def _to_node(self, host):
-        try:
-            password = \
-                host['operatingSystem']['passwords'][0]['password']
-        except (IndexError, KeyError):
-            password = None
-
-        hourlyRecurringFee = host.get('billingItem', {}).get(
-            'hourlyRecurringFee', 0)
-        recurringFee = host.get('billingItem', {}).get('recurringFee', 0)
-        recurringMonths = host.get('billingItem', {}).get('recurringMonths', 0)
-        createDate = host.get('createDate', None)
-
-        # When machine is launching it gets state halted
-        # we change this to pending
-        state = NODE_STATE_MAP.get(host['powerState']['keyName'],
-                                   NodeState.UNKNOWN)
-
-        if not password and state == NodeState.UNKNOWN:
-            state = NODE_STATE_MAP['INITIATING']
-
-        public_ips = []
-        private_ips = []
-
-        if 'primaryIpAddress' in host:
-            public_ips.append(host['primaryIpAddress'])
-
-        if 'primaryBackendIpAddress' in host:
-            private_ips.append(host['primaryBackendIpAddress'])
-
-        image = host.get('operatingSystem', {}).get('softwareLicense', {}) \
-                    .get('softwareDescription', {}) \
-                    .get('longDescription', None)
-
-        return Node(
-            id=host['id'],
-            name=host['fullyQualifiedDomainName'],
-            state=state,
-            public_ips=public_ips,
-            private_ips=private_ips,
-            driver=self,
-            extra={
-                'hostname': host['hostname'],
-                'fullyQualifiedDomainName': host['fullyQualifiedDomainName'],
-                'password': password,
-                'maxCpu': host.get('maxCpu', None),
-                'datacenter': host.get('datacenter', {}).get('longName', None),
-                'maxMemory': host.get('maxMemory', None),
-                'image': image,
-                'hourlyRecurringFee': hourlyRecurringFee,
-                'recurringFee': recurringFee,
-                'recurringMonths': recurringMonths,
-                'created': createDate,
-            }
-        )
-
-    def destroy_node(self, node):
-        self.connection.request(
-            'SoftLayer_Virtual_Guest', 'deleteObject', id=node.id
-        )
-        return True
-
-    def reboot_node(self, node):
-        self.connection.request(
-            'SoftLayer_Virtual_Guest', 'rebootSoft', id=node.id
-        )
-        return True
-
-    def ex_stop_node(self, node):
-        self.connection.request(
-            'SoftLayer_Virtual_Guest', 'powerOff', id=node.id
-        )
-        return True
-
-    def ex_start_node(self, node):
-        self.connection.request(
-            'SoftLayer_Virtual_Guest', 'powerOn', id=node.id
-        )
-        return True
-
-    def _get_order_information(self, node_id, timeout=1200, check_interval=5):
-        mask = {
-            'billingItem': '',
-            'powerState': '',
-            'operatingSystem': {'passwords': ''},
-            'provisionDate': '',
-        }
-
-        for i in range(0, timeout, check_interval):
-            res = self.connection.request(
-                'SoftLayer_Virtual_Guest',
-                'getObject',
-                id=node_id,
-                object_mask=mask
-            ).object
-
-            if res.get('provisionDate', None):
-                return res
-
-            time.sleep(check_interval)
-
-        raise SoftLayerException('Timeout on getting node details')
-
-    def create_node(self, **kwargs):
-        """Create a new SoftLayer node
-
-        @inherits: :class:`NodeDriver.create_node`
-
-        :keyword    ex_domain: e.g. libcloud.org
-        :type       ex_domain: ``str``
-        :keyword    ex_cpus: e.g. 2
-        :type       ex_cpus: ``int``
-        :keyword    ex_disk: e.g. 100
-        :type       ex_disk: ``int``
-        :keyword    ex_ram: e.g. 2048
-        :type       ex_ram: ``int``
-        :keyword    ex_bandwidth: e.g. 100
-        :type       ex_bandwidth: ``int``
-        :keyword    ex_local_disk: e.g. True
-        :type       ex_local_disk: ``bool``
-        :keyword    ex_datacenter: e.g. Dal05
-        :type       ex_datacenter: ``str``
-        :keyword    ex_os: e.g. UBUNTU_LATEST
-        :type       ex_os: ``str``
-        :keyword    ex_keyname: The name of the key pair
-        :type       ex_keyname: ``str``
-        """
-        name = kwargs['name']
-        os = 'DEBIAN_LATEST'
-        if 'ex_os' in kwargs:
-            os = kwargs['ex_os']
-        elif 'image' in kwargs:
-            os = kwargs['image'].id
-
-        size = kwargs.get('size', NodeSize(id=123, name='Custom', ram=None,
-                                           disk=None, bandwidth=None,
-                                           price=None,
-                                           driver=self.connection.driver))
-        ex_size_data = SL_TEMPLATES.get(int(size.id)) or {}
-        # plan keys are ints
-        cpu_count = kwargs.get('ex_cpus') or ex_size_data.get('cpus') or \
-            DEFAULT_CPU_SIZE
-        ram = kwargs.get('ex_ram') or ex_size_data.get('ram') or \
-            DEFAULT_RAM_SIZE
-        bandwidth = kwargs.get('ex_bandwidth') or size.bandwidth or 10
-        hourly = 'true' if kwargs.get('ex_hourly', True) else 'false'
-
-        local_disk = 'true'
-        if ex_size_data.get('local_disk') is False:
-            local_disk = 'false'
-
-        if kwargs.get('ex_local_disk') is False:
-            local_disk = 'false'
-
-        disk_size = DEFAULT_DISK_SIZE
-        if size.disk:
-            disk_size = size.disk
-        if kwargs.get('ex_disk'):
-            disk_size = kwargs.get('ex_disk')
-
-        datacenter = ''
-        if 'ex_datacenter' in kwargs:
-            datacenter = kwargs['ex_datacenter']
-        elif 'location' in kwargs:
-            datacenter = kwargs['location'].id
-
-        domain = kwargs.get('ex_domain')
-        if domain is None:
-            if name.find('.') != -1:
-                domain = name[name.find('.') + 1:]
-        if domain is None:
-            # TODO: domain is a required argument for the Sofylayer API, but it
-            # it shouldn't be.
-            domain = DEFAULT_DOMAIN
-
-        newCCI = {
-            'hostname': name,
-            'domain': domain,
-            'startCpus': cpu_count,
-            'maxMemory': ram,
-            'networkComponents': [{'maxSpeed': bandwidth}],
-            'hourlyBillingFlag': hourly,
-            'operatingSystemReferenceCode': os,
-            'localDiskFlag': local_disk,
-            'blockDevices': [
-                {
-                    'device': '0',
-                    'diskImage': {
-                        'capacity': disk_size,
-                    }
-                }
-            ]
-
-        }
-
-        if datacenter:
-            newCCI['datacenter'] = {'name': datacenter}
-
-        if 'ex_keyname' in kwargs:
-            newCCI['sshKeys'] = [
-                {
-                    'id': self._key_name_to_id(kwargs['ex_keyname'])
-                }
-            ]
-
-        res = self.connection.request(
-            'SoftLayer_Virtual_Guest', 'createObject', newCCI
-        ).object
-
-        node_id = res['id']
-        raw_node = self._get_order_information(node_id)
-
-        return self._to_node(raw_node)
-
-    def list_key_pairs(self):
-        result = self.connection.request(
-            'SoftLayer_Account', 'getSshKeys'
-        ).object
-        elems = [x for x in result]
-        key_pairs = self._to_key_pairs(elems=elems)
-        return key_pairs
-
-    def get_key_pair(self, name):
-        key_id = self._key_name_to_id(name=name)
-        result = self.connection.request(
-            'SoftLayer_Security_Ssh_Key', 'getObject', id=key_id
-        ).object
-        return self._to_key_pair(result)
-
-    # TODO: Check this with the libcloud guys,
-    # can we create new dependencies?
-    def create_key_pair(self, name, ex_size=4096):
-        if crypto is False:
-            raise NotImplementedError('create_key_pair needs'
-                                      'the pycrypto library')
-        key = RSA.generate(ex_size)
-        new_key = {
-            'key': key.publickey().exportKey('OpenSSH'),
-            'label': name,
-            'notes': '',
-        }
-        result = self.connection.request(
-            'SoftLayer_Security_Ssh_Key', 'createObject', new_key
-        ).object
-        result['private'] = key.exportKey('PEM')
-        return self._to_key_pair(result)
-
-    def import_key_pair_from_string(self, name, key_material):
-        new_key = {
-            'key': key_material,
-            'label': name,
-            'notes': '',
-        }
-        result = self.connection.request(
-            'SoftLayer_Security_Ssh_Key', 'createObject', new_key
-        ).object
-
-        key_pair = self._to_key_pair(result)
-        return key_pair
-
-    def delete_key_pair(self, key_pair):
-        key = self._key_name_to_id(key_pair)
-        result = self.connection.request(
-            'SoftLayer_Security_Ssh_Key', 'deleteObject', id=key
-        ).object
-        return result
-
-    def _to_image(self, img):
-        return NodeImage(
-            id=img['template']['operatingSystemReferenceCode'],
-            name=img['itemPrice']['item']['description'],
-            driver=self.connection.driver
-        )
-
-    def list_images(self, location=None):
-        result = self.connection.request(
-            'SoftLayer_Virtual_Guest', 'getCreateObjectOptions'
-        ).object
-        return [self._to_image(i) for i in result['operatingSystems']]
-
-    def _to_size(self, id, size):
-        return NodeSize(
-            id=id,
-            name=size['name'],
-            ram=size['ram'],
-            disk=size['disk'],
-            bandwidth=size.get('bandwidth'),
-            price=self._get_size_price(str(id)),
-            driver=self.connection.driver,
-        )
-
-    def list_sizes(self, location=None):
-        return [self._to_size(id, s) for id, s in SL_TEMPLATES.items()]
-
-    def _to_loc(self, loc):
-        country = 'UNKNOWN'
-        loc_id = loc['template']['datacenter']['name']
-        name = loc_id
-
-        if loc_id in DATACENTERS:
-            country = DATACENTERS[loc_id]['country']
-            name = DATACENTERS[loc_id].get('name', loc_id)
-        return NodeLocation(id=loc_id, name=name,
-                            country=country, driver=self)
-
-    def list_locations(self):
-        res = self.connection.request(
-            'SoftLayer_Virtual_Guest', 'getCreateObjectOptions'
-        ).object
-        return [self._to_loc(l) for l in res['datacenters']]
-
-    def list_nodes(self):
-        mask = {
-            'virtualGuests': {
-                'powerState': '',
-                'hostname': '',
-                'maxMemory': '',
-                'datacenter': '',
-                'operatingSystem': {'passwords': ''},
-                'billingItem': '',
-            },
-        }
-        res = self.connection.request(
-            'SoftLayer_Account',
-            'getVirtualGuests',
-            object_mask=mask
-        ).object
-        return [self._to_node(h) for h in res]
-
-    def _to_key_pairs(self, elems):
-        key_pairs = [self._to_key_pair(elem=elem) for elem in elems]
-        return key_pairs
-
-    def _to_key_pair(self, elem):
-        key_pair = KeyPair(name=elem['label'],
-                           public_key=elem['key'],
-                           fingerprint=elem['fingerprint'],
-                           private_key=elem.get('private', None),
-                           driver=self,
-                           extra={'id': elem['id']})
-        return key_pair
-
-    def _key_name_to_id(self, name):
-        result = self.connection.request(
-            'SoftLayer_Account', 'getSshKeys'
-        ).object
-        key_id = [x for x in result if x['label'] == name]
-        if len(key_id) == 0:
-            raise KeyPairDoesNotExistError(name, self)
-        else:
-            return int(key_id[0]['id'])

http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/vcl.py
----------------------------------------------------------------------
diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/vcl.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/vcl.py
deleted file mode 100644
index a5ec464..0000000
--- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/vcl.py
+++ /dev/null
@@ -1,302 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-"""
-VCL driver
-"""
-
-import time
-
-from libcloud.common.base import ConnectionUserAndKey
-from libcloud.common.xmlrpc import XMLRPCResponse, XMLRPCConnection
-from libcloud.common.types import InvalidCredsError, LibcloudError
-from libcloud.compute.types import Provider, NodeState
-from libcloud.compute.base import NodeDriver, Node
-from libcloud.compute.base import NodeSize, NodeImage
-
-
-class VCLResponse(XMLRPCResponse):
-    exceptions = {
-        'VCL_Account': InvalidCredsError,
-    }
-
-
-class VCLConnection(XMLRPCConnection, ConnectionUserAndKey):
-    endpoint = '/index.php?mode=xmlrpccall'
-
-    def add_default_headers(self, headers):
-        headers['X-APIVERSION'] = '2'
-        headers['X-User'] = self.user_id
-        headers['X-Pass'] = self.key
-        return headers
-
-
-class VCLNodeDriver(NodeDriver):
-    """
-    VCL node driver
-
-    :keyword   host: The VCL host to which you make requests(required)
-    :type      host: ``str``
-    """
-
-    NODE_STATE_MAP = {
-        'ready': NodeState.RUNNING,
-        'failed': NodeState.TERMINATED,
-        'timedout': NodeState.TERMINATED,
-        'loading': NodeState.PENDING,
-        'time': NodeState.PENDING,
-        'future': NodeState.PENDING,
-        'error': NodeState.UNKNOWN,
-        'notready': NodeState.PENDING,
-        'notavailable': NodeState.TERMINATED,
-        'success': NodeState.PENDING
-    }
-
-    connectionCls = VCLConnection
-    name = 'VCL'
-    website = 'http://incubator.apache.org/vcl/'
-    type = Provider.VCL
-
-    def __init__(self, key, secret, secure=True, host=None, port=None, *args,
-                 **kwargs):
-        """
-        :param    key:    API key or username to used (required)
-        :type     key:    ``str``
-
-        :param    secret: Secret password to be used (required)
-        :type     secret: ``str``
-
-        :param    secure: Weither to use HTTPS or HTTP.
-        :type     secure: ``bool``
-
-        :param    host: Override hostname used for connections. (required)
-        :type     host: ``str``
-
-        :param    port: Override port used for connections.
-        :type     port: ``int``
-
-        :rtype: ``None``
-        """
-        if not host:
-            raise Exception('When instantiating VCL driver directly ' +
-                            'you also need to provide host')
-
-        super(VCLNodeDriver, self).__init__(key, secret, secure=True,
-                                            host=None, port=None, *args,
-                                            **kwargs)
-
-    def _vcl_request(self, method, *args):
-        res = self.connection.request(
-            method,
-            *args
-        ).object
-        if(res['status'] == 'error'):
-            raise LibcloudError(res['errormsg'], driver=self)
-        return res
-
-    def create_node(self, **kwargs):
-        """Create a new VCL reservation
-        size and name ignored, image is the id from list_image
-
-        @inherits: :class:`NodeDriver.create_node`
-
-        :keyword    image: image is the id from list_image
-        :type       image: ``str``
-
-        :keyword    start: start time as unix timestamp
-        :type       start: ``str``
-
-        :keyword    length: length of time in minutes
-        :type       length: ``str``
-        """
-
-        image = kwargs["image"]
-        start = kwargs.get('start', int(time.time()))
-        length = kwargs.get('length', '60')
-
-        res = self._vcl_request(
-            "XMLRPCaddRequest",
-            image.id,
-            start,
-            length
-        )
-
-        return Node(
-            id=res['requestid'],
-            name=image.name,
-            state=self.NODE_STATE_MAP[res['status']],
-            public_ips=[],
-            private_ips=[],
-            driver=self,
-            image=image.name
-        )
-
-    def destroy_node(self, node):
-        """
-        End VCL reservation for the node passed in.
-        Throws error if request fails.
-
-        :param  node: The node to be destroyed
-        :type   node: :class:`Node`
-
-        :rtype: ``bool``
-        """
-        try:
-            self._vcl_request(
-                'XMLRPCendRequest',
-                node.id
-            )
-        except LibcloudError:
-            return False
-        return True
-
-    def _to_image(self, img):
-        return NodeImage(
-            id=img['id'],
-            name=img['name'],
-            driver=self.connection.driver
-        )
-
-    def list_images(self, location=None):
-        """
-        List images available to the user provided credentials
-
-        @inherits: :class:`NodeDriver.list_images`
-        """
-        res = self.connection.request(
-            "XMLRPCgetImages"
-        ).object
-        return [self._to_image(i) for i in res]
-
-    def list_sizes(self, location=None):
-        """
-        VCL does not choosing sizes for node creation.
-        Size of images are statically set by administrators.
-
-        @inherits: :class:`NodeDriver.list_sizes`
-        """
-        return [NodeSize(
-            't1.micro',
-            'none',
-            '512',
-            0, 0, 0, self)
-        ]
-
-    def _to_connect_data(self, request_id, ipaddr):
-        res = self._vcl_request(
-            "XMLRPCgetRequestConnectData",
-            request_id,
-            ipaddr
-        )
-        return res
-
-    def _to_status(self, requestid, imagename, ipaddr):
-        res = self._vcl_request(
-            "XMLRPCgetRequestStatus",
-            requestid
-        )
-
-        public_ips = []
-        extra = []
-        if(res['status'] == 'ready'):
-            cdata = self._to_connect_data(requestid, ipaddr)
-            public_ips = [cdata['serverIP']]
-            extra = {
-                'user': cdata['user'],
-                'pass': cdata['password']
-            }
-        return Node(
-            id=requestid,
-            name=imagename,
-            state=self.NODE_STATE_MAP[res['status']],
-            public_ips=public_ips,
-            private_ips=[],
-            driver=self,
-            image=imagename,
-            extra=extra
-        )
-
-    def _to_nodes(self, res, ipaddr):
-        return [self._to_status(
-            h['requestid'],
-            h['imagename'],
-            ipaddr
-        ) for h in res]
-
-    def list_nodes(self, ipaddr):
-        """
-        List nodes
-
-        :param  ipaddr: IP address which should be used
-        :type   ipaddr: ``str``
-
-        :rtype: ``list`` of :class:`Node`
-        """
-        res = self._vcl_request(
-            "XMLRPCgetRequestIds"
-        )
-        return self._to_nodes(res['requests'], ipaddr)
-
-    def ex_update_node_access(self, node, ipaddr):
-        """
-        Update the remote ip accessing the node.
-
-        :param node: the reservation node to update
-        :type  node: :class:`Node`
-
-        :param ipaddr: the ipaddr used to access the node
-        :type  ipaddr: ``str``
-
-        :return: node with updated information
-        :rtype: :class:`Node`
-        """
-        return self._to_status(node.id, node.image, ipaddr)
-
-    def ex_extend_request_time(self, node, minutes):
-        """
-        Time in minutes to extend the requested node's reservation time
-
-        :param node: the reservation node to update
-        :type  node: :class:`Node`
-
-        :param minutes: the number of mintes to update
-        :type  minutes: ``str``
-
-        :return: true on success, throws error on failure
-        :rtype: ``bool``
-        """
-        return self._vcl_request(
-            "XMLRPCextendRequest",
-            node.id,
-            minutes
-        )
-
-    def ex_get_request_end_time(self, node):
-        """
-        Get the ending time of the node reservation.
-
-        :param node: the reservation node to update
-        :type  node: :class:`Node`
-
-        :return: unix timestamp
-        :rtype: ``int``
-        """
-        res = self._vcl_request(
-            "XMLRPCgetRequestIds"
-        )
-        time = 0
-        for i in res['requests']:
-                if i['requestid'] == node.id:
-                        time = i['end']
-        return time