You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by to...@apache.org on 2014/08/19 18:24:02 UTC
[1/2] git commit: Update OpenStack driver to map more node states to
states recognized by Libcloud.
Repository: libcloud
Updated Branches:
refs/heads/trunk c849b95af -> f3f600028
Update OpenStack driver to map more node states to states recognized by
Libcloud.
Patch by Chris DeRamus.
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/52070382
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/52070382
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/52070382
Branch: refs/heads/trunk
Commit: 520703820c3fe7204ffefe75d2eca4c37998c1d2
Parents: c849b95
Author: Tomaz Muraus <to...@apache.org>
Authored: Tue Aug 19 13:43:47 2014 +0200
Committer: Tomaz Muraus <to...@apache.org>
Committed: Tue Aug 19 13:43:47 2014 +0200
----------------------------------------------------------------------
CHANGES.rst | 4 ++++
libcloud/compute/drivers/openstack.py | 4 +++-
2 files changed, 7 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/52070382/CHANGES.rst
----------------------------------------------------------------------
diff --git a/CHANGES.rst b/CHANGES.rst
index a7943bb..4a547aa 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -66,6 +66,10 @@ Compute
(GITHUB-347)
[Eddy Reyes]
+- Update OpenStack driver to map more node states to states recognized by
+ Libcloud.
+ [Chris DeRamus]
+
Storage
~~~~~~~
http://git-wip-us.apache.org/repos/asf/libcloud/blob/52070382/libcloud/compute/drivers/openstack.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/openstack.py b/libcloud/compute/drivers/openstack.py
index 93834dc..af306e0 100644
--- a/libcloud/compute/drivers/openstack.py
+++ b/libcloud/compute/drivers/openstack.py
@@ -86,7 +86,8 @@ class OpenStackNodeDriver(NodeDriver, OpenStackDriverMixin):
'BUILD': NodeState.PENDING,
'REBUILD': NodeState.PENDING,
'ACTIVE': NodeState.RUNNING,
- 'SUSPENDED': NodeState.TERMINATED,
+ 'SUSPENDED': NodeState.STOPPED,
+ 'SHUTOFF': NodeState.STOPPED,
'DELETED': NodeState.TERMINATED,
'QUEUE_RESIZE': NodeState.PENDING,
'PREP_RESIZE': NodeState.PENDING,
@@ -98,6 +99,7 @@ class OpenStackNodeDriver(NodeDriver, OpenStackDriverMixin):
'SHARE_IP': NodeState.PENDING,
'SHARE_IP_NO_CONFIG': NodeState.PENDING,
'DELETE_IP': NodeState.PENDING,
+ 'ERROR': NodeState.ERROR,
'UNKNOWN': NodeState.UNKNOWN
}
[2/2] git commit: Add support for HTTP proxy to
LibcloudHTTPConnection and LibcloudHTTPSConnection class.
Posted by to...@apache.org.
Add support for HTTP proxy to LibcloudHTTPConnection and
LibcloudHTTPSConnection class.
User can specify which HTTP proxy to use using one of the following
approaches:
* by setting "proxy_url" environment variable (global / process wide)
* by passing "proxy_url" argument to the Connection class constructor (per
connection instance)
* by calling "set_http_proxy" method on the Connection class (per connection
instance)
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/f3f60002
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/f3f60002
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/f3f60002
Branch: refs/heads/trunk
Commit: f3f600028384bc19c0f7ff051306a401d57afd35
Parents: 5207038
Author: Tomaz Muraus <to...@apache.org>
Authored: Tue Aug 19 16:29:54 2014 +0200
Committer: Tomaz Muraus <to...@apache.org>
Committed: Tue Aug 19 18:22:18 2014 +0200
----------------------------------------------------------------------
.../examples/http_proxy/constructor_argument.py | 6 +
.../http_proxy/set_http_proxy_method.py | 12 ++
docs/other/using-http-proxy.rst | 52 ++++++++
libcloud/common/base.py | 15 ++-
libcloud/httplib_ssl.py | 129 ++++++++++++++++++-
libcloud/test/test_connection.py | 53 ++++++++
6 files changed, 262 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f3f60002/docs/examples/http_proxy/constructor_argument.py
----------------------------------------------------------------------
diff --git a/docs/examples/http_proxy/constructor_argument.py b/docs/examples/http_proxy/constructor_argument.py
new file mode 100644
index 0000000..ae54945
--- /dev/null
+++ b/docs/examples/http_proxy/constructor_argument.py
@@ -0,0 +1,6 @@
+from libcloud.compute.drivers.dreamhost import DreamhostConnection
+
+PROXY_URL = 'http://<proxy hostname>:<proxy port>'
+
+conn = DreamhostConnection(host='dreamhost.com', port=443,
+ timeout=None, proxy_url=PROXY_URL)
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f3f60002/docs/examples/http_proxy/set_http_proxy_method.py
----------------------------------------------------------------------
diff --git a/docs/examples/http_proxy/set_http_proxy_method.py b/docs/examples/http_proxy/set_http_proxy_method.py
new file mode 100644
index 0000000..d8c5e83
--- /dev/null
+++ b/docs/examples/http_proxy/set_http_proxy_method.py
@@ -0,0 +1,12 @@
+from pprint import pprint
+
+from libcloud.compute.types import Provider
+from libcloud.compute.providers import get_driver
+
+PROXY_URL = 'http://<proxy hostname>:<proxy port>'
+
+cls = get_driver(Provider.RACKSPACE)
+driver = cls('username', 'api key', region='ord')
+driver.set_http_proxy(proxy_url=PROXY_URL)
+
+pprint(driver.list_nodes())
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f3f60002/docs/other/using-http-proxy.rst
----------------------------------------------------------------------
diff --git a/docs/other/using-http-proxy.rst b/docs/other/using-http-proxy.rst
new file mode 100644
index 0000000..8c12dc5
--- /dev/null
+++ b/docs/other/using-http-proxy.rst
@@ -0,0 +1,52 @@
+Using an HTTP proxy
+===================
+
+.. note::
+
+ Support for HTTP proxies is only available in Libcloud trunk and higher.
+
+Libcloud supports using an HTTP proxy for outgoing HTTP and HTTPS requests. At
+the moment, using a proxy is only supported if you are using Python 2.7 or
+above (it has been tested with 2.7, PyPy, 3.1, 3.3, 3.3, 3.4).
+
+You can specify which HTTP proxy to use using one of the approaches described
+bellow:
+
+* By setting ``http_proxy`` environment variable (this setting is system /
+ process wide)
+* By passing ``http_proxy`` argument to the
+ :class:`libcloud.common.base.LibcloudHTTPConnection` class constructor (this
+ setting is local to the connection instance)
+* By calling :meth:`libcloud.common.base.LibcloudHTTPConnection.set_http_proxy`
+ method (this setting is local to the connection instance)
+
+Known limitations
+-----------------
+
+* HTTP proxies which require authentication are not supported
+* Python 2.6 is not supported
+
+Examples
+--------
+
+This section includes some code examples which show how to use an HTTP proxy
+with Libcloud.
+
+1. Using http_proxy environment variable
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. sourcecode:: python
+
+ http_proxy=http://<proxy hostname>:<proxy port> python my_script.py
+
+2. Passing http_proxy argument to the connection class
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. literalinclude:: /examples/http_proxy/constructor_argument.py
+ :language: python
+
+3. Calling set_http_proxy method
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. literalinclude:: /examples/http_proxy/set_http_proxy_method.py
+ :language: python
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f3f60002/libcloud/common/base.py
----------------------------------------------------------------------
diff --git a/libcloud/common/base.py b/libcloud/common/base.py
index 488f084..daf04d2 100644
--- a/libcloud/common/base.py
+++ b/libcloud/common/base.py
@@ -46,10 +46,9 @@ from libcloud.utils.misc import lowercase_keys
from libcloud.utils.compression import decompress_data
from libcloud.common.types import LibcloudError, MalformedResponseError
+from libcloud.httplib_ssl import LibcloudHTTPConnection
from libcloud.httplib_ssl import LibcloudHTTPSConnection
-LibcloudHTTPConnection = httplib.HTTPConnection
-
class HTTPResponse(httplib.HTTPResponse):
# On python 2.6 some calls can hang because HEAD isn't quite properly
@@ -267,7 +266,9 @@ class LoggingConnection():
:cvar log: file-like object that logs entries are written to.
"""
+
log = None
+ http_proxy_used = False
def _log_response(self, r):
rv = "# -------- begin %d:%d response ----------\n" % (id(self), id(r))
@@ -341,7 +342,15 @@ class LoggingConnection():
return (rr, rv)
def _log_curl(self, method, url, body, headers):
- cmd = ["curl", "-i"]
+ cmd = ["curl"]
+
+ if self.http_proxy_used:
+ proxy_url = 'http://%s:%s' % (self.proxy_host,
+ self.proxy_port)
+ proxy_url = pquote(proxy_url)
+ cmd.extend(['--proxy', proxy_url])
+
+ cmd.extend(['-i'])
if method.lower() == 'head':
# HEAD method need special handling
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f3f60002/libcloud/httplib_ssl.py
----------------------------------------------------------------------
diff --git a/libcloud/httplib_ssl.py b/libcloud/httplib_ssl.py
index 29136ef..2024433 100644
--- a/libcloud/httplib_ssl.py
+++ b/libcloud/httplib_ssl.py
@@ -19,14 +19,126 @@ verification, depending on libcloud.security settings.
import os
import re
import socket
+import sys
import ssl
import warnings
import libcloud.security
from libcloud.utils.py3 import httplib
+from libcloud.utils.py3 import urlparse
+__all__ = [
+ 'LibcloudBaseConnection',
+ 'LibcloudHTTPConnection',
+ 'LibcloudHTTPSConnection'
+]
-class LibcloudHTTPSConnection(httplib.HTTPSConnection):
+HTTP_PROXY_ENV_VARIABLE_NAME = 'http_proxy'
+
+
+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
+ 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:3128)
+ :type proxy_url: ``str``
+ """
+ if sys.version_info[:2] == (2, 6):
+ raise Exception('HTTP proxy support requires Python 2.7 or higher')
+
+ scheme, host, port = self._parse_proxy_url(proxy_url=proxy_url)
+
+ self.proxy_scheme = scheme
+ self.proxy_host = host
+ self.proxy_port = port
+
+ 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
+
+ return (proxy_scheme, proxy_host, proxy_port)
+
+ def _setup_http_proxy(self):
+ """
+ Set up HTTP proxy.
+
+ :param proxy_url: Proxy URL (e.g. http://<host>:3128)
+ :type proxy_url: ``str``
+ """
+ self.set_tunnel(host=self.host, port=self.port)
+ self._set_hostport(host=self.proxy_host, port=self.proxy_port)
+
+ def _activate_http_proxy(self, sock):
+ self.sock = sock
+ self._tunnel()
+
+ 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
+ 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
@@ -41,7 +153,15 @@ class LibcloudHTTPSConnection(httplib.HTTPSConnection):
Constructor
"""
self._setup_verify()
- httplib.HTTPSConnection.__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(LibcloudHTTPSConnection, self).__init__(*args, **kwargs)
+
+ if proxy_url:
+ self.set_http_proxy(proxy_url=proxy_url)
def _setup_verify(self):
"""
@@ -97,6 +217,11 @@ class LibcloudHTTPSConnection(httplib.HTTPSConnection):
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)
+
self.sock = ssl.wrap_socket(sock,
self.key_file,
self.cert_file,
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f3f60002/libcloud/test/test_connection.py
----------------------------------------------------------------------
diff --git a/libcloud/test/test_connection.py b/libcloud/test/test_connection.py
index 5df7919..b5c2abb 100644
--- a/libcloud/test/test_connection.py
+++ b/libcloud/test/test_connection.py
@@ -14,6 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import os
import sys
import ssl
@@ -22,6 +23,58 @@ from mock import Mock, call
from libcloud.test import unittest
from libcloud.common.base import Connection
from libcloud.common.base import LoggingConnection
+from libcloud.httplib_ssl import LibcloudBaseConnection
+from libcloud.httplib_ssl import LibcloudHTTPConnection
+
+
+class BaseConnectionClassTestCase(unittest.TestCase):
+ def test_parse_proxy_url(self):
+ conn = LibcloudBaseConnection()
+
+ proxy_url = 'http://127.0.0.1:3128'
+ result = conn._parse_proxy_url(proxy_url=proxy_url)
+ self.assertEqual(result[0], 'http')
+ self.assertEqual(result[1], '127.0.0.1')
+ self.assertEqual(result[2], 3128)
+
+ proxy_url = 'https://127.0.0.1:3128'
+ expected_msg = 'Only http proxies are supported'
+ self.assertRaisesRegexp(ValueError, expected_msg,
+ conn._parse_proxy_url,
+ proxy_url=proxy_url)
+
+ proxy_url = 'http://127.0.0.1'
+ expected_msg = 'proxy_url must be in the following format'
+ self.assertRaisesRegexp(ValueError, expected_msg,
+ conn._parse_proxy_url,
+ proxy_url=proxy_url)
+
+ def test_constructor(self):
+ conn = LibcloudHTTPConnection(host='localhost', port=80)
+ self.assertEqual(conn.proxy_scheme, None)
+ self.assertEqual(conn.proxy_host, None)
+ self.assertEqual(conn.proxy_port, None)
+
+ proxy_url = 'http://127.0.0.3:3128'
+ conn.set_http_proxy(proxy_url=proxy_url)
+ self.assertEqual(conn.proxy_scheme, 'http')
+ self.assertEqual(conn.proxy_host, '127.0.0.3')
+ self.assertEqual(conn.proxy_port, 3128)
+
+ proxy_url = 'http://127.0.0.4:3128'
+ conn = LibcloudHTTPConnection(host='localhost', port=80,
+ proxy_url=proxy_url)
+ self.assertEqual(conn.proxy_scheme, 'http')
+ self.assertEqual(conn.proxy_host, '127.0.0.4')
+ self.assertEqual(conn.proxy_port, 3128)
+
+ os.environ['http_proxy'] = proxy_url
+ proxy_url = 'http://127.0.0.5:3128'
+ conn = LibcloudHTTPConnection(host='localhost', port=80,
+ proxy_url=proxy_url)
+ self.assertEqual(conn.proxy_scheme, 'http')
+ self.assertEqual(conn.proxy_host, '127.0.0.5')
+ self.assertEqual(conn.proxy_port, 3128)
class ConnectionClassTestCase(unittest.TestCase):