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:57 UTC
[10/56] [abbrv] libcloud git commit: Removed sdist
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