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 2022/01/28 22:44:42 UTC

[libcloud] branch trunk updated (a385009 -> 4749799)

This is an automated email from the ASF dual-hosted git repository.

tomaz pushed a change to branch trunk
in repository https://gitbox.apache.org/repos/asf/libcloud.git.


    from a385009  Merge branch 'reixd-scw_object_storage_driver' into trunk
     add 123e115  add support for retrieving private key from JSON object/string/file
     add 1ac4601  add more thorough verification of PEM key
     add d065361  update docs with service account credentials directly as dict
     new 836e0d7  Merge branch 'LIBCLOUD-996_gcp_svc_acct_credentials_from_json' of https://github.com/bverschueren/libcloud into bverschueren-LIBCLOUD-996_gcp_svc_acct_credentials_from_json
     new b57ca4f  Reformat code with black.
     new b1b3e2d  Add changelog entry.
     new 1ecaad4  Fix formatting.
     new 973ce29  Fix black tox target, make sure we also run it on code in libcloud/ directory.
     new 6b8cee9  Reformat code with black.
     new 1e2a039  Add a test case for scenario where the PEM key is invalid.
     new 4749799  Add new test fixture files.

The 8 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 CHANGES.rst                                        |  8 +++
 docs/compute/drivers/gce.rst                       |  6 ++
 docs/dns/drivers/google.rst                        |  8 ++-
 .../compute/gce/gce_service_account_infile.py      | 15 +++++
 .../dns/google/dns_service_account_infile.py       | 13 ++++
 .../loadbalancer/gce/gce_service_account_infile.py | 15 +++++
 docs/loadbalancer/drivers/gce.rst                  |  7 +-
 libcloud/common/google.py                          | 73 ++++++++++++++++-----
 libcloud/test/common/fixtures/google/pkey.json     |  2 +-
 libcloud/test/common/fixtures/google/pkey.pem      | 31 ++++-----
 .../test/common/fixtures/google/pkey_invalid.json  |  7 ++
 .../test/common/fixtures/google/pkey_invalid.pem   | 16 +++++
 libcloud/test/common/test_google.py                | 76 ++++++++++++++++++++++
 tox.ini                                            |  1 +
 14 files changed, 241 insertions(+), 37 deletions(-)
 create mode 100644 docs/examples/compute/gce/gce_service_account_infile.py
 create mode 100644 docs/examples/dns/google/dns_service_account_infile.py
 create mode 100644 docs/examples/loadbalancer/gce/gce_service_account_infile.py
 create mode 100644 libcloud/test/common/fixtures/google/pkey_invalid.json
 create mode 100644 libcloud/test/common/fixtures/google/pkey_invalid.pem

[libcloud] 07/08: Add a test case for scenario where the PEM key is invalid.

Posted by to...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

tomaz pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/libcloud.git

commit 1e2a039a9459fe24ae701b924dfa40ccff98ff9c
Author: Tomaz Muraus <to...@tomaz.me>
AuthorDate: Fri Jan 28 23:41:42 2022 +0100

    Add a test case for scenario where the PEM key is invalid.
---
 libcloud/test/common/test_google.py | 82 +++++++++++++++++++++++++++----------
 1 file changed, 60 insertions(+), 22 deletions(-)

diff --git a/libcloud/test/common/test_google.py b/libcloud/test/common/test_google.py
index d10fbcb..b613067 100644
--- a/libcloud/test/common/test_google.py
+++ b/libcloud/test/common/test_google.py
@@ -52,6 +52,7 @@ except ImportError:
 SCRIPT_PATH = os.path.dirname(os.path.realpath(__file__))
 PEM_KEY = os.path.join(SCRIPT_PATH, "fixtures", "google", "pkey.pem")
 JSON_KEY = os.path.join(SCRIPT_PATH, "fixtures", "google", "pkey.json")
+JSON_KEY_INVALID = os.path.join(SCRIPT_PATH, "fixtures", "google", "pkey_invalid.json")
 with open(JSON_KEY, "r") as f:
     KEY_STR = json.loads(f.read())["private_key"]
 
@@ -81,28 +82,40 @@ GCS_S3_PARAMS_61 = (
     # 40 base64 chars
     "0102030405060708091011121314151617181920",
 )
-PEM_KEY_FILE = os.path.join(SCRIPT_PATH, 'fixtures', 'google', 'pkey.pem')
-JSON_KEY_FILE = os.path.join(SCRIPT_PATH, 'fixtures', 'google', 'pkey.json')
-with open(JSON_KEY_FILE, 'r') as f:
-    PEM_KEY_STR = json.loads(f.read())['private_key']
-with open(JSON_KEY_FILE, 'r') as f:
+PEM_KEY_FILE = os.path.join(SCRIPT_PATH, "fixtures", "google", "pkey.pem")
+PEM_KEY_FILE_INVALID = os.path.join(
+    SCRIPT_PATH, "fixtures", "google", "pkey_invalid.pem"
+)
+
+JSON_KEY_FILE = os.path.join(SCRIPT_PATH, "fixtures", "google", "pkey.json")
+
+with open(JSON_KEY_FILE, "r") as f:
+    PEM_KEY_STR = json.loads(f.read())["private_key"]
+
+with open(JSON_KEY_FILE, "r") as f:
     JSON_KEY_STR = f.read()
     JSON_KEY = json.loads(JSON_KEY_STR)
 
 
-GCE_USERID_EMAIL = 'email@developer.gserviceaccount.com'
-GCE_PARAMS = (GCE_USERID_EMAIL, 'key')
+GCE_USERID_EMAIL = "email@developer.gserviceaccount.com"
+GCE_PARAMS = (GCE_USERID_EMAIL, "key")
 GCE_PARAMS_PEM_KEY_FILE = (GCE_USERID_EMAIL, PEM_KEY_FILE)
+GCE_PARAMS_PEM_KEY_FILE_INVALID = (GCE_USERID_EMAIL, PEM_KEY_FILE_INVALID)
 GCE_PARAMS_PEM_KEY = (GCE_USERID_EMAIL, PEM_KEY_STR)
 GCE_PARAMS_JSON_KEY_FILE = (GCE_USERID_EMAIL, JSON_KEY_FILE)
 GCE_PARAMS_JSON_KEY = (GCE_USERID_EMAIL, JSON_KEY)
+GCE_PARAMS_JSON_KEY_INVALID = (GCE_USERID_EMAIL, JSON_KEY_INVALID)
 GCE_PARAMS_JSON_KEY_STR = (GCE_USERID_EMAIL, JSON_KEY_STR)
-GCE_PARAMS_IA = ('client_id', 'client_secret')
-GCE_PARAMS_GCE = ('foo', 'bar')
-GCS_S3_PARAMS_20 = ('GOOG0123456789ABCXYZ',  # GOOG + 16 alphanumeric chars
-                 '0102030405060708091011121314151617181920')  # 40 base64 chars
-GCS_S3_PARAMS_24 = ('GOOGDF5OVRRGU4APFNSTVCXI',  # GOOG + 20 alphanumeric chars
-                 '0102030405060708091011121314151617181920')  # 40 base64 chars
+GCE_PARAMS_IA = ("client_id", "client_secret")
+GCE_PARAMS_GCE = ("foo", "bar")
+GCS_S3_PARAMS_20 = (
+    "GOOG0123456789ABCXYZ",  # GOOG + 16 alphanumeric chars
+    "0102030405060708091011121314151617181920",
+)  # 40 base64 chars
+GCS_S3_PARAMS_24 = (
+    "GOOGDF5OVRRGU4APFNSTVCXI",  # GOOG + 20 alphanumeric chars
+    "0102030405060708091011121314151617181920",
+)  # 40 base64 chars
 
 STUB_UTCNOW = _utcnow()
 
@@ -357,12 +370,14 @@ class GoogleOAuth2CredentialTest(GoogleTestCase):
         if SHA256:
             kwargs["auth_type"] = GoogleAuthType.SA
             cred1 = GoogleOAuth2Credential(*GCE_PARAMS_PEM_KEY_FILE, **kwargs)
-            self.assertTrue(isinstance(cred1.oauth2_conn,
-                                       GoogleServiceAcctAuthConnection))
+            self.assertTrue(
+                isinstance(cred1.oauth2_conn, GoogleServiceAcctAuthConnection)
+            )
 
             cred1 = GoogleOAuth2Credential(*GCE_PARAMS_JSON_KEY_FILE, **kwargs)
-            self.assertTrue(isinstance(cred1.oauth2_conn,
-                                       GoogleServiceAcctAuthConnection))
+            self.assertTrue(
+                isinstance(cred1.oauth2_conn, GoogleServiceAcctAuthConnection)
+            )
 
             cred1 = GoogleOAuth2Credential(*GCE_PARAMS_PEM_KEY, **kwargs)
             self.assertTrue(
@@ -381,13 +396,36 @@ class GoogleOAuth2CredentialTest(GoogleTestCase):
 
             kwargs["auth_type"] = GoogleAuthType.SA
             cred1 = GoogleOAuth2Credential(*GCE_PARAMS_JSON_KEY_STR, **kwargs)
-            self.assertTrue(isinstance(cred1.oauth2_conn,
-                                       GoogleServiceAcctAuthConnection))
+            self.assertTrue(
+                isinstance(cred1.oauth2_conn, GoogleServiceAcctAuthConnection)
+            )
 
-            self.assertRaises(GoogleAuthError, GoogleOAuth2Credential,
-                              *GCE_PARAMS, **kwargs)
+            self.assertRaises(
+                GoogleAuthError, GoogleOAuth2Credential, *GCE_PARAMS, **kwargs
+            )
+
+            # Invalid pem key
+            kwargs["auth_type"] = GoogleAuthType.SA
+            expected_msg = "Unable to decode provided PEM key:"
+            self.assertRaisesRegex(
+                GoogleAuthError,
+                expected_msg,
+                GoogleOAuth2Credential,
+                *GCE_PARAMS_PEM_KEY_FILE_INVALID,
+                **kwargs,
+            )
+
+            kwargs["auth_type"] = GoogleAuthType.SA
+            expected_msg = "Unable to decode provided PEM key:"
+            self.assertRaisesRegex(
+                GoogleAuthError,
+                expected_msg,
+                GoogleOAuth2Credential,
+                *GCE_PARAMS_JSON_KEY_INVALID,
+                **kwargs,
+            )
 
-        kwargs['auth_type'] = GoogleAuthType.IA
+        kwargs["auth_type"] = GoogleAuthType.IA
         cred2 = GoogleOAuth2Credential(*GCE_PARAMS_IA, **kwargs)
         self.assertTrue(isinstance(cred2.oauth2_conn, GoogleInstalledAppAuthConnection))
 

[libcloud] 03/08: Add changelog entry.

Posted by to...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

tomaz pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/libcloud.git

commit b1b3e2df3f5787a3b6b459e709cbe31c173e3906
Author: Tomaz Muraus <to...@tomaz.me>
AuthorDate: Fri Jan 28 23:31:08 2022 +0100

    Add changelog entry.
---
 CHANGES.rst | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/CHANGES.rst b/CHANGES.rst
index 96ba1fa..923fd2e 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -33,6 +33,14 @@ Compute
   (GITHUB-1641)
   [Thomas JOUANNOT - @mazerty]
 
+- [GCE] Allow ``credentials`` argument which is provided to the driver
+  constructor to also be either a Python dictionary with the credentials object
+  or a JSON string with the serialized credentials object. That's in addition
+  to supporting passing in path to the credentials file or string PEM version of
+  the key.
+  (GITHUB-1214)
+  [@bverschueren]
+
 Storage
 ~~~~~~~
 

[libcloud] 08/08: Add new test fixture files.

Posted by to...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

tomaz pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/libcloud.git

commit 4749799257babfa86fe1080b3e6fd3aa5d89ab6a
Author: Tomaz Muraus <to...@tomaz.me>
AuthorDate: Fri Jan 28 23:44:05 2022 +0100

    Add new test fixture files.
---
 libcloud/test/common/fixtures/google/pkey_invalid.json |  7 +++++++
 libcloud/test/common/fixtures/google/pkey_invalid.pem  | 16 ++++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/libcloud/test/common/fixtures/google/pkey_invalid.json b/libcloud/test/common/fixtures/google/pkey_invalid.json
new file mode 100644
index 0000000..79f0529
--- /dev/null
+++ b/libcloud/test/common/fixtures/google/pkey_invalid.json
@@ -0,0 +1,7 @@
+{
+  "private_key_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
+  "private_key": "-----BEGIN PRIVATE KEY-----\nMxxIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALskegl+DrI3Msw5\nZ63xnj1rgoPR0KykwBi+jZgAwHv/B0TJyhy6NuEnaf+x442L7lepOqoWQzlUGXyu\naSQU9mT/vHTGZ2xM8QJJaccr4eGho0MU9HePyNCFWjWVrGKpwSEAd6CLlzC0Wiy4\nkC9IoAUoS/IPjeyLTQNCddatgcARAgMBAAECgYAA/LlKJgeJUStTcpHgGD6mXjHv\nnAwWJELQKDP5+tA8VAQGwBX1G5qzJDGrPGtHQ7DSqdwF4YFZtgTpZmGq1wsAjz3l\nv6L4XiVsHiIPtP1B4gMxX9ogxcDzVQ7hyezXPioMAcp7Isus9Csn8HhftcL56BRa\nbn6GvWqbIAy6zJcgEQJBAMlZnymKW5/jKth+wkCfqEXlPhGNPO1u [...]
+  "client_email": "foo@developer.gserviceaccount.com",
+  "client_id": "foo.apps.googleusercontent.com",
+  "type": "service_account"
+}
diff --git a/libcloud/test/common/fixtures/google/pkey_invalid.pem b/libcloud/test/common/fixtures/google/pkey_invalid.pem
new file mode 100644
index 0000000..44c3cba
--- /dev/null
+++ b/libcloud/test/common/fixtures/google/pkey_invalid.pem
@@ -0,0 +1,16 @@
+-----BEGIN PRIVATE KEY-----
+MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALskegl+DrI3Msw5
+Z63xnj1rgoPR0KykwBi+jZgAwHv/B0TJyhy6NuEnaf+x442L7lepOqoWQzlUGXyu
+aSQU9mT/vHTGZ2xM8QJJaccr4eGho0MU9HePyNCFWjWVrGKpwSEAd6CLlzC0Wiy4
+kC9IoAUoS/IPjeyLTQNCddatgcARAgMBAAECgYAA/LlKJgeJUStTcpHgGD6mXjHv
+nAwWJELQKDP5+tA8VAQGwBX1G5qzJDGrPGtHQ7DSqdwF4YFZtgTpZmGq1wsAjz3l
+v6L4XiVsHiIPtP1B4gMxX9ogxcDzVQ7hyezXPioMAcp7Isus9Csn8HhftcL56BRa
+bn6GvWqbIAy6zJcgEQJBAMlZnymKW5/jKth+wkCfqEXlPhGNPO1uq87QZUbYxwdj
+tSM09J9+HMfH+WXR9ARCOL46DJ0IJfyjcdmuDDlh9IkCQQDt76up1Tmc7lkb/89I
+RBu2MudGJPMEf96VCG11nmcXulyk1OLiTXfO62YpxZbgYrvlrNxEYlSG7WQMztBg
+A51JAkBU2RhyJ+S+drsaaigvlVgSxCyotszi/Q0XZMgY18bfPUwanvkqsLkuEv3s
+w1HB7an9t3aTQdjIIpQad/acw8OJAkEAjvmnCK21KgTbjQShtQYgNNLPwImxcjG4
+OYvP4o6l2k9FHlNCZsQwSymOwWkXKYyK5g+CaKFBs7ZwmXWpJxjk6QJBAInqbm1w
+3yVfGD9I2mMQi/6oDJQP3pdWU4mU4h4sdDyRgTQLpkD4yypgjOACt4mTzxifSVT9
+fT+a79SkT8Fxxx
+-----END PRIVATE KEY-----

[libcloud] 06/08: Reformat code with black.

Posted by to...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

tomaz pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/libcloud.git

commit 6b8cee9538dbd4d820726b91e695919fac39c1ca
Author: Tomaz Muraus <to...@tomaz.me>
AuthorDate: Fri Jan 28 23:41:32 2022 +0100

    Reformat code with black.
---
 libcloud/common/google.py | 24 ++++++++++--------------
 1 file changed, 10 insertions(+), 14 deletions(-)

diff --git a/libcloud/common/google.py b/libcloud/common/google.py
index 0d0f194..fa305b4 100644
--- a/libcloud/common/google.py
+++ b/libcloud/common/google.py
@@ -522,11 +522,12 @@ class GoogleServiceAcctAuthConnection(GoogleBaseAuthConnection):
             if os.path.exists(key_path) and os.path.isfile(key_path):
                 # Assume it's a file and read it
                 try:
-                    with open(key_path, 'r') as f:
+                    with open(key_path, "r") as f:
                         key_content = f.read()
                 except IOError:
-                    raise GoogleAuthError("Missing (or unreadable) key "
-                                          "file: '%s'" % key)
+                    raise GoogleAuthError(
+                        "Missing (or unreadable) key " "file: '%s'" % key
+                    )
             else:
                 # assume it's a PEM str or serialized JSON str
                 key_content = key
@@ -542,27 +543,22 @@ class GoogleServiceAcctAuthConnection(GoogleBaseAuthConnection):
             # it's been a PEM string all along
             pass
         finally:
-            if 'private_key' in key_content:
-                key = key_content['private_key']
+            if "private_key" in key_content:
+                key = key_content["private_key"]
             else:
                 key = key_content
 
         try:
             # check if the key is actually a PEM encoded private key
             serialization.load_pem_private_key(
-                b(key),
-                password=None,
-                backend=default_backend()
+                b(key), password=None, backend=default_backend()
             )
         except ValueError as e:
-            raise GoogleAuthError("Unable to decode provided PEM key: %s" %
-                                  e)
+            raise GoogleAuthError("Unable to decode provided PEM key: %s" % e)
         except TypeError as e:
-            raise GoogleAuthError("Unable to decode provided PEM key: %s" %
-                                  e)
+            raise GoogleAuthError("Unable to decode provided PEM key: %s" % e)
         except exceptions.UnsupportedAlgorithm as e:
-            raise GoogleAuthError("Unable to decode provided PEM key: %s" %
-                                  e)
+            raise GoogleAuthError("Unable to decode provided PEM key: %s" % e)
 
         super(GoogleServiceAcctAuthConnection, self).__init__(
             user_id, key, *args, **kwargs

[libcloud] 05/08: Fix black tox target, make sure we also run it on code in libcloud/ directory.

Posted by to...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

tomaz pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/libcloud.git

commit 973ce29d1f4f39df9f531d86438f9ab2b9f743e6
Author: Tomaz Muraus <to...@tomaz.me>
AuthorDate: Fri Jan 28 23:41:14 2022 +0100

    Fix black tox target, make sure we also run it on code in libcloud/
    directory.
---
 tox.ini | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tox.ini b/tox.ini
index e586f1c..59c3330 100644
--- a/tox.ini
+++ b/tox.ini
@@ -273,6 +273,7 @@ deps = -r{toxinidir}/requirements-tests.txt
 # won't expand to the list of files when the command runs
 commands =
            bash -c "black --config pyproject.toml *.py"
+           black --config pyproject.toml libcloud/
            black --config pyproject.toml docs/examples/
            black --config pyproject.toml demos/
            black --config pyproject.toml contrib/

[libcloud] 04/08: Fix formatting.

Posted by to...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

tomaz pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/libcloud.git

commit 1ecaad4122ced7c49d20410905ce1b67454d47d4
Author: Tomaz Muraus <to...@tomaz.me>
AuthorDate: Fri Jan 28 23:33:21 2022 +0100

    Fix formatting.
---
 docs/dns/drivers/google.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/docs/dns/drivers/google.rst b/docs/dns/drivers/google.rst
index 9d43b99..54fb3d7 100644
--- a/docs/dns/drivers/google.rst
+++ b/docs/dns/drivers/google.rst
@@ -22,6 +22,7 @@ shown below:
 
 1. Getting Driver with Service Account authentication
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
 With local key file:
 
 .. literalinclude:: /examples/dns/google/dns_service_account.py

[libcloud] 01/08: Merge branch 'LIBCLOUD-996_gcp_svc_acct_credentials_from_json' of https://github.com/bverschueren/libcloud into bverschueren-LIBCLOUD-996_gcp_svc_acct_credentials_from_json

Posted by to...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

tomaz pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/libcloud.git

commit 836e0d73d22107469275f536f2fa8f0ce960fc79
Merge: a385009 d065361
Author: Tomaz Muraus <to...@tomaz.me>
AuthorDate: Fri Jan 28 23:23:11 2022 +0100

    Merge branch 'LIBCLOUD-996_gcp_svc_acct_credentials_from_json' of https://github.com/bverschueren/libcloud into bverschueren-LIBCLOUD-996_gcp_svc_acct_credentials_from_json

 docs/compute/drivers/gce.rst                       |  6 ++
 docs/dns/drivers/google.rst                        |  7 +-
 .../compute/gce/gce_service_account_infile.py      | 14 ++++
 .../dns/google/dns_service_account_infile.py       | 14 ++++
 .../loadbalancer/gce/gce_service_account_infile.py | 14 ++++
 docs/loadbalancer/drivers/gce.rst                  |  7 +-
 libcloud/common/google.py                          | 77 +++++++++++++++++-----
 libcloud/test/common/fixtures/google/pkey.json     |  2 +-
 libcloud/test/common/fixtures/google/pkey.pem      | 31 ++++-----
 libcloud/test/common/test_google.py                | 40 ++++++++++-
 10 files changed, 174 insertions(+), 38 deletions(-)

diff --cc libcloud/common/google.py
index 637ec21,cc95af9..0d0f194
--- a/libcloud/common/google.py
+++ b/libcloud/common/google.py
@@@ -94,11 -93,12 +94,12 @@@ try
      from cryptography.hazmat.primitives import serialization
      from cryptography.hazmat.primitives.hashes import SHA256
      from cryptography.hazmat.primitives.asymmetric.padding import PKCS1v15
+     from cryptography import exceptions
  except ImportError:
      # The cryptography library is unavailable
 -    SHA256 = None
 +    SHA256 = None  # type: ignore
  
 -UTC_TIMESTAMP_FORMAT = '%Y-%m-%dT%H:%M:%SZ'
 +UTC_TIMESTAMP_FORMAT = "%Y-%m-%dT%H:%M:%SZ"
  
  LOG = logging.getLogger(__name__)
  
@@@ -491,41 -468,77 +492,81 @@@ class GoogleInstalledAppAuthConnection(
  
  class GoogleServiceAcctAuthConnection(GoogleBaseAuthConnection):
      """Authentication class for "Service Account" authentication."""
 +
      def __init__(self, user_id, key, *args, **kwargs):
          """
-         Check to see if cryptography is available, and convert key file path
-         into a key string if the key is in a file.
+         Check to see if cryptography is available, and convert PEM key file
+         into a key string, or extract the key from JSON object, string or
+         file.
  
          :param  user_id: Email address to be used for Service Account
                  authentication.
          :type   user_id: ``str``
  
-         :param  key: The RSA Key or path to file containing the key.
-         :type   key: ``str``
+         :param  key: The path to a PEM/JSON file containing the private RSA
+         key, or a str/dict containing the PEM/JSON.
+         :type   key: ``str`` or ``dict``
+ 
          """
          if SHA256 is None:
 -            raise GoogleAuthError('cryptography library required for '
 -                                  'Service Account Authentication.')
 +            raise GoogleAuthError(
 +                "cryptography library required for " "Service Account Authentication."
 +            )
-         # Check to see if 'key' is a file and read the file if it is.
-         if key.find("PRIVATE KEY---") == -1:
-             # key is a file
-             keypath = os.path.expanduser(key)
-             is_file_path = os.path.exists(keypath) and os.path.isfile(keypath)
-             if not is_file_path:
-                 raise ValueError("Missing (or not readable) key " "file: '%s'" % key)
-             with open(keypath, "r") as f:
-                 contents = f.read()
-             try:
-                 key = json.loads(contents)
-                 key = key["private_key"]
-             except ValueError:
-                 key = contents
+ 
 -        if type(key) is dict:
 -            # if it's a dict, assume it's containing the JSON
++        if isinstance(key, dict):
++            # if it's a dict, assume it's containing parsed JSON
+             key_content = key
+             key = None
+         else:
+             key_path = os.path.expanduser(key)
+             if os.path.exists(key_path) and os.path.isfile(key_path):
++                # Assume it's a file and read it
+                 try:
+                     with open(key_path, 'r') as f:
+                         key_content = f.read()
+                 except IOError:
+                     raise GoogleAuthError("Missing (or unreadable) key "
+                                           "file: '%s'" % key)
+             else:
+                 # assume it's a PEM str or serialized JSON str
+                 key_content = key
+                 key = None
+ 
+         try:
+             key_content = json.loads(key_content)
+             # check if serialized JSON given
+         except TypeError:
+             # already a dict
+             pass
+         except ValueError:
+             # it's been a PEM string all along
+             pass
+         finally:
+             if 'private_key' in key_content:
+                 key = key_content['private_key']
+             else:
+                 key = key_content
+ 
+         try:
+             # check if the key is actually a PEM encoded private key
+             serialization.load_pem_private_key(
+                 b(key),
+                 password=None,
+                 backend=default_backend()
+             )
+         except ValueError as e:
+             raise GoogleAuthError("Unable to decode provided PEM key: %s" %
+                                   e)
+         except TypeError as e:
+             raise GoogleAuthError("Unable to decode provided PEM key: %s" %
+                                   e)
+         except exceptions.UnsupportedAlgorithm as e:
+             raise GoogleAuthError("Unable to decode provided PEM key: %s" %
+                                   e)
  
          super(GoogleServiceAcctAuthConnection, self).__init__(
 -            user_id, key, *args, **kwargs)
 +            user_id, key, *args, **kwargs
 +        )
  
      def get_new_token(self):
          """
diff --cc libcloud/test/common/test_google.py
index a02cc08,1e372c4..d10fbcb
--- a/libcloud/test/common/test_google.py
+++ b/libcloud/test/common/test_google.py
@@@ -50,37 -48,28 +50,59 @@@ except ImportError
  
  
  SCRIPT_PATH = os.path.dirname(os.path.realpath(__file__))
 +PEM_KEY = os.path.join(SCRIPT_PATH, "fixtures", "google", "pkey.pem")
 +JSON_KEY = os.path.join(SCRIPT_PATH, "fixtures", "google", "pkey.json")
 +with open(JSON_KEY, "r") as f:
 +    KEY_STR = json.loads(f.read())["private_key"]
 +
 +
 +GCE_PARAMS = ("email@developer.gserviceaccount.com", "key")
 +GCE_PARAMS_PEM_KEY = ("email@developer.gserviceaccount.com", PEM_KEY)
 +GCE_PARAMS_JSON_KEY = ("email@developer.gserviceaccount.com", JSON_KEY)
 +GCE_PARAMS_KEY = ("email@developer.gserviceaccount.com", KEY_STR)
 +GCE_PARAMS_IA = ("client_id", "client_secret")
 +GCE_PARAMS_IA_2 = ("client_id@test.apps.googleusercontent.com", "client_secret")
 +GCE_PARAMS_GCE = ("foo", "bar")
 +# GOOG + 16 alphanumeric chars
 +GCS_S3_PARAMS_20 = (
 +    "GOOG0123456789ABCXYZ",
 +    # 40 base64 chars
 +    "0102030405060708091011121314151617181920",
 +)
 +# GOOG + 20 alphanumeric chars
 +GCS_S3_PARAMS_24 = (
 +    "GOOGDF5OVRRGU4APFNSTVCXI",
 +    # 40 base64 chars
 +    "0102030405060708091011121314151617181920",
 +)
 +# GOOG + 57 alphanumeric chars
 +GCS_S3_PARAMS_61 = (
 +    "GOOGDF5OVRRGU4APFNSTVCXIRRGU4AP56789ABCX56789ABCXRRGU4APFNSTV",
 +    # 40 base64 chars
 +    "0102030405060708091011121314151617181920",
 +)
+ PEM_KEY_FILE = os.path.join(SCRIPT_PATH, 'fixtures', 'google', 'pkey.pem')
+ JSON_KEY_FILE = os.path.join(SCRIPT_PATH, 'fixtures', 'google', 'pkey.json')
+ with open(JSON_KEY_FILE, 'r') as f:
+     PEM_KEY_STR = json.loads(f.read())['private_key']
+ with open(JSON_KEY_FILE, 'r') as f:
+     JSON_KEY_STR = f.read()
+     JSON_KEY = json.loads(JSON_KEY_STR)
+ 
+ 
+ GCE_USERID_EMAIL = 'email@developer.gserviceaccount.com'
+ GCE_PARAMS = (GCE_USERID_EMAIL, 'key')
+ GCE_PARAMS_PEM_KEY_FILE = (GCE_USERID_EMAIL, PEM_KEY_FILE)
+ GCE_PARAMS_PEM_KEY = (GCE_USERID_EMAIL, PEM_KEY_STR)
+ GCE_PARAMS_JSON_KEY_FILE = (GCE_USERID_EMAIL, JSON_KEY_FILE)
+ GCE_PARAMS_JSON_KEY = (GCE_USERID_EMAIL, JSON_KEY)
+ GCE_PARAMS_JSON_KEY_STR = (GCE_USERID_EMAIL, JSON_KEY_STR)
+ GCE_PARAMS_IA = ('client_id', 'client_secret')
+ GCE_PARAMS_GCE = ('foo', 'bar')
+ GCS_S3_PARAMS_20 = ('GOOG0123456789ABCXYZ',  # GOOG + 16 alphanumeric chars
+                  '0102030405060708091011121314151617181920')  # 40 base64 chars
+ GCS_S3_PARAMS_24 = ('GOOGDF5OVRRGU4APFNSTVCXI',  # GOOG + 20 alphanumeric chars
+                  '0102030405060708091011121314151617181920')  # 40 base64 chars
  
  STUB_UTCNOW = _utcnow()
  
@@@ -333,31 -296,39 +355,47 @@@ class GoogleOAuth2CredentialTest(Google
          kwargs = {}
  
          if SHA256:
 -            kwargs['auth_type'] = GoogleAuthType.SA
 +            kwargs["auth_type"] = GoogleAuthType.SA
+             cred1 = GoogleOAuth2Credential(*GCE_PARAMS_PEM_KEY_FILE, **kwargs)
+             self.assertTrue(isinstance(cred1.oauth2_conn,
+                                        GoogleServiceAcctAuthConnection))
+ 
+             cred1 = GoogleOAuth2Credential(*GCE_PARAMS_JSON_KEY_FILE, **kwargs)
+             self.assertTrue(isinstance(cred1.oauth2_conn,
+                                        GoogleServiceAcctAuthConnection))
+ 
              cred1 = GoogleOAuth2Credential(*GCE_PARAMS_PEM_KEY, **kwargs)
 -            self.assertTrue(isinstance(cred1.oauth2_conn,
 -                                       GoogleServiceAcctAuthConnection))
 +            self.assertTrue(
 +                isinstance(cred1.oauth2_conn, GoogleServiceAcctAuthConnection)
 +            )
  
              cred1 = GoogleOAuth2Credential(*GCE_PARAMS_JSON_KEY, **kwargs)
 -            self.assertTrue(isinstance(cred1.oauth2_conn,
 -                                       GoogleServiceAcctAuthConnection))
 +            self.assertTrue(
 +                isinstance(cred1.oauth2_conn, GoogleServiceAcctAuthConnection)
 +            )
  
 +            cred1 = GoogleOAuth2Credential(*GCE_PARAMS_KEY, **kwargs)
 +            self.assertTrue(
 +                isinstance(cred1.oauth2_conn, GoogleServiceAcctAuthConnection)
 +            )
 +
-         kwargs["auth_type"] = GoogleAuthType.IA
++            kwargs["auth_type"] = GoogleAuthType.SA
+             cred1 = GoogleOAuth2Credential(*GCE_PARAMS_JSON_KEY_STR, **kwargs)
+             self.assertTrue(isinstance(cred1.oauth2_conn,
+                                        GoogleServiceAcctAuthConnection))
+ 
+             self.assertRaises(GoogleAuthError, GoogleOAuth2Credential,
+                               *GCE_PARAMS, **kwargs)
+ 
+         kwargs['auth_type'] = GoogleAuthType.IA
          cred2 = GoogleOAuth2Credential(*GCE_PARAMS_IA, **kwargs)
 -        self.assertTrue(isinstance(cred2.oauth2_conn,
 -                                   GoogleInstalledAppAuthConnection))
 +        self.assertTrue(isinstance(cred2.oauth2_conn, GoogleInstalledAppAuthConnection))
  
 -        kwargs['auth_type'] = GoogleAuthType.GCE
 +        kwargs["auth_type"] = GoogleAuthType.GCE
          cred3 = GoogleOAuth2Credential(*GCE_PARAMS_GCE, **kwargs)
 -        self.assertTrue(isinstance(cred3.oauth2_conn,
 -                                   GoogleGCEServiceAcctAuthConnection))
 +        self.assertTrue(
 +            isinstance(cred3.oauth2_conn, GoogleGCEServiceAcctAuthConnection)
 +        )
  
  
  class GoogleBaseConnectionTest(GoogleTestCase):

[libcloud] 02/08: Reformat code with black.

Posted by to...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

tomaz pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/libcloud.git

commit b57ca4f0343b333d1a7d61901f4105c4d24df026
Author: Tomaz Muraus <to...@tomaz.me>
AuthorDate: Fri Jan 28 23:30:07 2022 +0100

    Reformat code with black.
---
 docs/examples/compute/gce/gce_service_account_infile.py   | 15 ++++++++-------
 docs/examples/dns/google/dns_service_account_infile.py    | 13 ++++++-------
 .../loadbalancer/gce/gce_service_account_infile.py        | 15 ++++++++-------
 3 files changed, 22 insertions(+), 21 deletions(-)

diff --git a/docs/examples/compute/gce/gce_service_account_infile.py b/docs/examples/compute/gce/gce_service_account_infile.py
index e4d329b..0c64d38 100644
--- a/docs/examples/compute/gce/gce_service_account_infile.py
+++ b/docs/examples/compute/gce/gce_service_account_infile.py
@@ -2,13 +2,14 @@ from libcloud.compute.types import Provider
 from libcloud.compute.providers import get_driver
 
 credentials = {
-    'type': 'service_account',
-    'project_id': 'my_project',
-    'private_key': '-----BEGIN PRIVATE KEY-----\nmy_private_key_data\n'
-    '-----END PRIVATE KEY-----\n',
-    'client_email': 'my_email',
+    "type": "service_account",
+    "project_id": "my_project",
+    "private_key": "-----BEGIN PRIVATE KEY-----\nmy_private_key_data\n"
+    "-----END PRIVATE KEY-----\n",
+    "client_email": "my_email",
 }
 
 ComputeEngine = get_driver(Provider.GCE)
-driver = ComputeEngine('your_service_account_email', credentials,
-                       project='your_project_id')
+driver = ComputeEngine(
+    "your_service_account_email", credentials, project="your_project_id"
+)
diff --git a/docs/examples/dns/google/dns_service_account_infile.py b/docs/examples/dns/google/dns_service_account_infile.py
index b28f783..d446e2a 100644
--- a/docs/examples/dns/google/dns_service_account_infile.py
+++ b/docs/examples/dns/google/dns_service_account_infile.py
@@ -2,13 +2,12 @@ from libcloud.dns.types import Provider
 from libcloud.dns.providers import get_driver
 
 credentials = {
-    'type': 'service_account',
-    'project_id': 'my_project',
-    'private_key': '-----BEGIN PRIVATE KEY-----\nmy_private_key_data\n'
-    '-----END PRIVATE KEY-----\n',
-    'client_email': 'my_email',
+    "type": "service_account",
+    "project_id": "my_project",
+    "private_key": "-----BEGIN PRIVATE KEY-----\nmy_private_key_data\n"
+    "-----END PRIVATE KEY-----\n",
+    "client_email": "my_email",
 }
 
 DNSDriver = get_driver(Provider.GOOGLE)
-driver = DNSDriver('your_service_account_email', credentials,
-                   'your_project_id')
+driver = DNSDriver("your_service_account_email", credentials, "your_project_id")
diff --git a/docs/examples/loadbalancer/gce/gce_service_account_infile.py b/docs/examples/loadbalancer/gce/gce_service_account_infile.py
index 5cc5b44..05425db 100644
--- a/docs/examples/loadbalancer/gce/gce_service_account_infile.py
+++ b/docs/examples/loadbalancer/gce/gce_service_account_infile.py
@@ -2,13 +2,14 @@ from libcloud.loadbalancer.types import Provider
 from libcloud.loadbalancer.providers import get_driver
 
 credentials = {
-    'type': 'service_account',
-    'project_id': 'my_project',
-    'private_key': '-----BEGIN PRIVATE KEY-----\nmy_private_key_data\n'
-    '-----END PRIVATE KEY-----\n',
-    'client_email': 'my_email',
+    "type": "service_account",
+    "project_id": "my_project",
+    "private_key": "-----BEGIN PRIVATE KEY-----\nmy_private_key_data\n"
+    "-----END PRIVATE KEY-----\n",
+    "client_email": "my_email",
 }
 
 LoadBalancer = get_driver(Provider.GCE)
-driver = LoadBalancer('your_service_account_email', credentials,
-                      project='your_project_id')
+driver = LoadBalancer(
+    "your_service_account_email", credentials, project="your_project_id"
+)