diff --git a/gcloud/connection.py b/gcloud/connection.py index c74001491082..392ed9347252 100644 --- a/gcloud/connection.py +++ b/gcloud/connection.py @@ -21,6 +21,9 @@ import httplib2 +from gcloud.credentials import get_credentials +from gcloud.credentials import get_for_service_account_json +from gcloud.credentials import get_for_service_account_p12 from gcloud.exceptions import make_exception @@ -112,6 +115,68 @@ def _create_scoped_credentials(credentials, scope): credentials = credentials.create_scoped(scope) return credentials + @classmethod + def from_service_account_json(cls, json_credentials_path, *args, **kwargs): + """Factory to retrieve JSON credentials while creating connection. + + :type json_credentials_path: string + :param json_credentials_path: The path to a private key file (this file + was given to you when you created the + service account). This file must contain + a JSON object with a private key and + other credentials information (downloaded + from the Google APIs console). + + :rtype: :class:`gcloud.connection.Connection` + :returns: The connection created with the retrieved JSON credentials. + """ + credentials = get_for_service_account_json(json_credentials_path) + if 'credentials' in kwargs: + raise TypeError('credentials must not be in keyword arguments') + kwargs['credentials'] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_p12(cls, client_email, private_key_path, + *args, **kwargs): + """Factory to retrieve P12 credentials while creating connection. + + .. note:: + Unless you have an explicit reason to use a PKCS12 key for your + service account, we recommend using a JSON key. + + :type client_email: string + :param client_email: The e-mail attached to the service account. + + :type private_key_path: string + :param private_key_path: The path to a private key file (this file was + given to you when you created the service + account). This file must be in P12 format. + + :rtype: :class:`gcloud.connection.Connection` + :returns: The connection created with the retrieved P12 credentials. + """ + credentials = get_for_service_account_p12(client_email, + private_key_path) + if 'credentials' in kwargs: + raise TypeError('credentials must not be in keyword arguments') + kwargs['credentials'] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_environment(cls, *args, **kwargs): + """Factory to retrieve implicit credentials while creating connection. + + :rtype: :class:`gcloud.connection.Connection` + :returns: The connection created with the retrieved implicit + credentials. + """ + credentials = get_credentials() + if 'credentials' in kwargs: + raise TypeError('credentials must not be in keyword arguments') + kwargs['credentials'] = credentials + return cls(*args, **kwargs) + class JSONConnection(Connection): """A connection to a Google JSON-based API. diff --git a/gcloud/datastore/_implicit_environ.py b/gcloud/datastore/_implicit_environ.py index d664d345161e..fd5ba9e5b8f9 100644 --- a/gcloud/datastore/_implicit_environ.py +++ b/gcloud/datastore/_implicit_environ.py @@ -23,7 +23,6 @@ from gcloud._helpers import _app_engine_id from gcloud._helpers import _compute_engine_id from gcloud._helpers import _lazy_property_deco -from gcloud.credentials import get_credentials from gcloud.datastore.connection import Connection @@ -122,8 +121,7 @@ def get_connection(): :rtype: :class:`gcloud.datastore.connection.Connection` :returns: A connection defined with the proper credentials. """ - credentials = get_credentials() - return Connection(credentials=credentials) + return Connection.from_environment() def set_default_connection(connection=None): diff --git a/gcloud/pubsub/__init__.py b/gcloud/pubsub/__init__.py index bef2522e7228..69bca901f2a9 100644 --- a/gcloud/pubsub/__init__.py +++ b/gcloud/pubsub/__init__.py @@ -26,7 +26,6 @@ from gcloud._helpers import get_default_project from gcloud._helpers import set_default_project -from gcloud.credentials import get_credentials from gcloud.pubsub import _implicit_environ from gcloud.pubsub._implicit_environ import get_default_connection from gcloud.pubsub.api import list_subscriptions @@ -75,5 +74,4 @@ def get_connection(): :rtype: :class:`gcloud.pubsub.connection.Connection` :returns: A connection defined with the proper credentials. """ - credentials = get_credentials() - return Connection(credentials=credentials) + return Connection.from_environment() diff --git a/gcloud/storage/_implicit_environ.py b/gcloud/storage/_implicit_environ.py index 7c630df6a3e2..b90f99ed67b8 100644 --- a/gcloud/storage/_implicit_environ.py +++ b/gcloud/storage/_implicit_environ.py @@ -20,7 +20,6 @@ from gcloud._helpers import _lazy_property_deco -from gcloud.credentials import get_credentials from gcloud.storage.connection import Connection @@ -78,8 +77,7 @@ def get_connection(): :rtype: :class:`gcloud.storage.connection.Connection` :returns: A connection defined with the proper credentials. """ - credentials = get_credentials() - return Connection(credentials=credentials) + return Connection.from_environment() def set_default_connection(connection=None): diff --git a/gcloud/test_connection.py b/gcloud/test_connection.py index 706e939d1cac..159f404b6746 100644 --- a/gcloud/test_connection.py +++ b/gcloud/test_connection.py @@ -71,6 +71,81 @@ def test_user_agent_format(self): conn = self._makeOne() self.assertEqual(conn.USER_AGENT, expected_ua) + def _from_service_account_json_helper(self, **kwargs): + from gcloud._testing import _Monkey + from gcloud import connection + + KLASS = self._getTargetClass() + CREDS = object() + _CALLED = [] + + def mock_creds(arg1): + _CALLED.append((arg1,)) + return CREDS + + FOO = object() + with _Monkey(connection, get_for_service_account_json=mock_creds): + conn = KLASS.from_service_account_json(FOO, **kwargs) + + self.assertTrue(conn.credentials is CREDS) + self.assertEqual(_CALLED, [(FOO,)]) + + def test_from_service_account_json(self): + self._from_service_account_json_helper() + + def test_from_service_account_json_fail(self): + with self.assertRaises(TypeError): + self._from_service_account_json_helper(credentials=None) + + def _from_service_account_p12_helper(self, **kwargs): + from gcloud._testing import _Monkey + from gcloud import connection + + KLASS = self._getTargetClass() + CREDS = object() + _CALLED = [] + + def mock_creds(arg1, arg2): + _CALLED.append((arg1, arg2)) + return CREDS + + FOO = object() + BAR = object() + with _Monkey(connection, get_for_service_account_p12=mock_creds): + conn = KLASS.from_service_account_p12(FOO, BAR, **kwargs) + + self.assertTrue(conn.credentials is CREDS) + self.assertEqual(_CALLED, [(FOO, BAR)]) + + def test_from_service_account_p12(self): + self._from_service_account_p12_helper() + + def test_from_service_account_p12_fail(self): + with self.assertRaises(TypeError): + self._from_service_account_p12_helper(credentials=None) + + def _from_environment_helper(self, **kwargs): + from gcloud._testing import _Monkey + from gcloud import connection + + KLASS = self._getTargetClass() + CREDS = object() + + def mock_creds(): + return CREDS + + with _Monkey(connection, get_credentials=mock_creds): + conn = KLASS.from_environment(**kwargs) + + self.assertTrue(conn.credentials is CREDS) + + def test_from_environment(self): + self._from_environment_helper() + + def test_from_environment_fail(self): + with self.assertRaises(TypeError): + self._from_environment_helper(credentials=None) + class TestJSONConnection(unittest2.TestCase):