[Python-modules-commits] [python-cs] 01/03: Import python-cs_1.0.0.orig.tar.gz

Vincent Bernat bernat at moszumanska.debian.org
Sun Dec 25 09:23:48 UTC 2016


This is an automated email from the git hooks/post-receive script.

bernat pushed a commit to branch master
in repository python-cs.

commit 482639360fe70e5b152ac625ec73824bf757bf5b
Author: Vincent Bernat <bernat at debian.org>
Date:   Sun Dec 25 10:19:24 2016 +0100

    Import python-cs_1.0.0.orig.tar.gz
---
 README.rst |  6 ++++++
 cs.py      | 25 +++++++++++++++++-------
 setup.py   |  2 +-
 tests.py   | 64 ++++++++++++++++++++++++++++++++++++++------------------------
 4 files changed, 64 insertions(+), 33 deletions(-)

diff --git a/README.rst b/README.rst
index 726a63f..9974473 100644
--- a/README.rst
+++ b/README.rst
@@ -41,6 +41,10 @@ From the command-line, this requires some configuration::
     endpoint = https://api.exoscale.ch/compute
     key = cloudstack api key
     secret = cloudstack api secret
+    # Optional ca authority certificate
+    verify = /path/to/certs/exoscale_ca.crt
+    # Optional client PEM certificate
+    cert = /path/to/client_exoscale.pem
 
 Then::
 
@@ -73,6 +77,8 @@ Configuration is read from several locations, in the following order:
 * The ``CLOUDSTACK_ENDPOINT``, ``CLOUDSTACK_KEY``, ``CLOUDSTACK_SECRET`` and
   ``CLOUDSTACK_METHOD`` environment variables,
 * A ``CLOUDSTACK_CONFIG`` environment variable pointing to an ``.ini`` file,
+* A ``CLOUDSTACK_VERIFY`` (optional) environment variable pointing to a CA authority cert file,
+* A ``CLOUDSTACK_CERT`` (optional) environment variable pointing to a client PEM cert file,
 * A ``cloudstack.ini`` file in the current working directory,
 * A ``.cloudstack.ini`` file in the home directory.
 
diff --git a/cs.py b/cs.py
index 862c864..c6d1bfb 100644
--- a/cs.py
+++ b/cs.py
@@ -6,7 +6,6 @@ import hashlib
 import hmac
 import json
 import os
-import requests
 import sys
 import time
 
@@ -29,6 +28,8 @@ try:
 except ImportError:
     pygments = None
 
+import requests
+
 
 PY2 = sys.version_info < (3, 0)
 
@@ -90,12 +91,15 @@ class Unauthorized(CloudStackException):
 
 
 class CloudStack(object):
-    def __init__(self, endpoint, key, secret, timeout=10, method='get'):
+    def __init__(self, endpoint, key, secret, timeout=10, method='get',
+                 verify=True, cert=None):
         self.endpoint = endpoint
         self.key = key
         self.secret = secret
         self.timeout = int(timeout)
         self.method = method.lower()
+        self.verify = verify
+        self.cert = cert
 
     def __repr__(self):
         return '<CloudStack: {0}>'.format(self.endpoint)
@@ -131,6 +135,8 @@ class CloudStack(object):
 
             response = getattr(requests, self.method)(self.endpoint,
                                                       timeout=self.timeout,
+                                                      verify=self.verify,
+                                                      cert=self.cert,
                                                       **{kwarg: kwargs})
 
             try:
@@ -167,9 +173,9 @@ class CloudStack(object):
         signature method (hmac/sha1).
         """
         params = "&".join(sorted([
-            "=".join((key, cs_encode(value))).lower()
+            "=".join((key, cs_encode(value)))
             for key, value in data.items()
-        ]))
+        ])).lower()
         digest = hmac.new(
             self.secret.encode('utf-8'),
             msg=params.encode('utf-8'),
@@ -191,6 +197,8 @@ def read_config(ini_group=None):
         else:
             env_conf[key] = os.environ['CLOUDSTACK_{0}'.format(key.upper())]
     else:
+        env_conf['verify'] = os.environ.get('CLOUDSTACK_VERIFY', True)
+        env_conf['cert'] = os.environ.get('CLOUDSTACK_CERT', None)
         return env_conf
 
     # Config file: $PWD/cloudstack.ini or $HOME/.cloudstack.ini
@@ -257,10 +265,12 @@ def main():
     try:
         response = getattr(cs, command)(**kwargs)
     except CloudStackException as e:
-        response = e.args[2]
+        response = e.args[1]
         if not options.quiet:
-            sys.stderr.write("Cloudstack error:\n")
-        ok = False
+            sys.stderr.write("Cloudstack error: HTTP response "
+                             "{0}\n".format(response.status_code))
+            sys.stderr.write(response.text)
+            sys.exit(1)
 
     if 'Async' not in command and 'jobid' in response and not options.async:
         if not options.quiet:
@@ -284,6 +294,7 @@ def main():
     if pygments and sys.stdout.isatty():
         data = pygments.highlight(data, JsonLexer(), TerminalFormatter())
     sys.stdout.write(data)
+    sys.stdout.write('\n')
     sys.exit(int(not ok))
 
 
diff --git a/setup.py b/setup.py
index 2099f98..8ce1f19 100644
--- a/setup.py
+++ b/setup.py
@@ -6,7 +6,7 @@ with open('README.rst', 'r') as f:
 
 setup(
     name='cs',
-    version='0.8.3',
+    version='1.0.0',
     url='https://github.com/exoscale/cs',
     license='BSD',
     author=u'Bruno Renié',
diff --git a/tests.py b/tests.py
index 3048db4..aac854e 100644
--- a/tests.py
+++ b/tests.py
@@ -11,7 +11,7 @@ try:
 except ImportError:
     from mock import patch, call
 
-from cs import read_config, CloudStack, CloudStackException
+from cs import CloudStack, CloudStackException, read_config
 
 
 @contextmanager
@@ -67,13 +67,17 @@ class ConfigTest(TestCase):
                 'endpoint': 'https://api.example.com/from-env',
                 'method': 'get',
                 'timeout': '10',
+                'verify': True,
+                'cert': None,
             })
 
         with env(CLOUDSTACK_KEY='test key from env',
                  CLOUDSTACK_SECRET='test secret from env',
                  CLOUDSTACK_ENDPOINT='https://api.example.com/from-env',
                  CLOUDSTACK_METHOD='post',
-                 CLOUDSTACK_TIMEOUT='99'):
+                 CLOUDSTACK_TIMEOUT='99',
+                 CLOUDSTACK_VERIFY='/path/to/ca.pem',
+                 CLOUDSTACK_CERT='/path/to/cert.pem'):
             conf = read_config()
             self.assertEqual(conf, {
                 'key': 'test key from env',
@@ -81,6 +85,8 @@ class ConfigTest(TestCase):
                 'endpoint': 'https://api.example.com/from-env',
                 'method': 'post',
                 'timeout': '99',
+                'verify': '/path/to/ca.pem',
+                'cert': '/path/to/cert.pem',
             })
 
     def test_current_dir_config(self):
@@ -113,12 +119,15 @@ class RequestTest(TestCase):
         }
         machines = cs.listVirtualMachines(listall='true')
         self.assertEqual(machines, {})
-        get.assert_called_once_with('localhost', timeout=20, params={
-            'apiKey': 'foo',
-            'response': 'json',
-            'command': 'listVirtualMachines',
-            'listall': 'true',
-            'signature': 'B0d6hBsZTcFVCiioSxzwKA9Pke8='})
+        get.assert_called_once_with(
+            'localhost', timeout=20, verify=True, cert=None, params={
+                'apiKey': 'foo',
+                'response': 'json',
+                'command': 'listVirtualMachines',
+                'listall': 'true',
+                'signature': 'B0d6hBsZTcFVCiioSxzwKA9Pke8=',
+            },
+        )
 
     @patch('requests.get')
     def test_encoding(self, get):
@@ -128,13 +137,16 @@ class RequestTest(TestCase):
             'listvirtualmachinesresponse': {},
         }
         cs.listVirtualMachines(listall=1, unicode_param=u'éèààû')
-        get.assert_called_once_with('localhost', timeout=10, params={
-            'apiKey': 'foo',
-            'response': 'json',
-            'command': 'listVirtualMachines',
-            'listall': '1',
-            'unicode_param': u'éèààû',
-            'signature': 'gABU/KFJKD3FLAgKDuxQoryu4sA='})
+        get.assert_called_once_with(
+            'localhost', timeout=10, verify=True, cert=None, params={
+                'apiKey': 'foo',
+                'response': 'json',
+                'command': 'listVirtualMachines',
+                'listall': '1',
+                'unicode_param': u'éèààû',
+                'signature': 'gABU/KFJKD3FLAgKDuxQoryu4sA=',
+            },
+        )
 
     @patch("requests.get")
     def test_transformt(self, get):
@@ -145,15 +157,17 @@ class RequestTest(TestCase):
         }
         cs.listVirtualMachines(foo=["foo", "bar"],
                                bar=[{'baz': 'blah', 'foo': 'meh'}])
-        get.assert_called_once_with('localhost', timeout=10, params={
-            'command': 'listVirtualMachines',
-            'response': 'json',
-            'bar[0].foo': 'meh',
-            'bar[0].baz': 'blah',
-            'foo': 'foo,bar',
-            'apiKey': 'foo',
-            'signature': 'UGUVEfCOfGfOlqoTj1D2m5adr2g=',
-        })
+        get.assert_called_once_with(
+            'localhost', timeout=10, cert=None, verify=True, params={
+                'command': 'listVirtualMachines',
+                'response': 'json',
+                'bar[0].foo': 'meh',
+                'bar[0].baz': 'blah',
+                'foo': 'foo,bar',
+                'apiKey': 'foo',
+                'signature': 'UGUVEfCOfGfOlqoTj1D2m5adr2g=',
+            },
+        )
 
     @patch("requests.post")
     @patch("requests.get")
@@ -167,7 +181,7 @@ class RequestTest(TestCase):
         cs.listVirtualMachines(blah='brah')
         self.assertEqual(get.call_args_list, [])
         self.assertEqual(post.call_args_list, [
-            call('localhost', timeout=10, data={
+            call('localhost', timeout=10, verify=True, cert=None, data={
                 'command': 'listVirtualMachines',
                 'blah': 'brah',
                 'apiKey': 'foo',

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-cs.git



More information about the Python-modules-commits mailing list