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:51:27 UTC

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

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))