Skip to content

Commit b4c605a

Browse files
committed
Changing auth to use implicit environment.
1 parent 31799c3 commit b4c605a

28 files changed

+405
-268
lines changed

CONTRIBUTING.rst

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -164,23 +164,19 @@ Running Regression Tests
164164
bamboo-shift-455).
165165
- ``GCLOUD_TESTS_DATASET_ID``: The name of the dataset your tests connect to.
166166
This is typically the same as ``GCLOUD_TESTS_PROJECT_ID``.
167-
- ``GCLOUD_TESTS_CLIENT_EMAIL``: The email for the service account you're
168-
authenticating with
169-
- ``GCLOUD_TESTS_KEY_FILE``: The path to an encrypted key file.
170-
See private key
167+
- ``GOOGLE_APPLICATION_CREDENTIALS``: The path to an encrypted JSON file;
168+
see ``regression/app_credentials.json.sample`` as an example. Such a file
169+
can be downloaded directly from the developer's console by clicking
170+
"Generate new JSON key". See private key
171171
`docs <https://cloud.google.com/storage/docs/authentication#generating-a-private-key>`__
172-
for explanation on how to get a private key.
172+
for more details.
173173

174174
- Examples of these can be found in ``regression/local_test_setup.sample``. We
175175
recommend copying this to ``regression/local_test_setup``, editing the values
176176
and sourcing them into your environment::
177177

178178
$ source regression/local_test_setup
179179

180-
- The ``GCLOUD_TESTS_KEY_FILE`` value should point to a valid path (relative or
181-
absolute) on your system where the key file for your service account can
182-
be found.
183-
184180
- For datastore tests, you'll need to create composite
185181
`indexes <https://cloud.google.com/datastore/docs/tools/indexconfig>`__
186182
with the ``gcloud`` command line
@@ -194,8 +190,10 @@ Running Regression Tests
194190
$ export CLOUDSDK_PYTHON_SITEPACKAGES=1
195191

196192
# Authenticate the gcloud tool with your account.
197-
$ gcloud auth activate-service-account $GCLOUD_TESTS_CLIENT_EMAIL \
198-
> --key-file=$GCLOUD_TESTS_KEY_FILE
193+
$ SERVICE_ACCOUNT_EMAIL="some-account@developer.gserviceaccount.com"
194+
$ P12_CREDENTIALS_FILE="path/to/keyfile.p12"
195+
$ gcloud auth activate-service-account $SERVICE_ACCOUNT_EMAIL \
196+
> --key-file=$P12_CREDENTIALS_FILE
199197

200198
# Create the indexes
201199
$ gcloud preview datastore create-indexes regression/data/ \

README.rst

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,7 @@ Library.
4848
.. code:: python
4949
5050
from gcloud import datastore
51-
dataset = datastore.get_dataset('dataset-id-here',
52-
'long-email@googleapis.com',
53-
'/path/to/private.key')
51+
dataset = datastore.get_dataset('dataset-id-here')
5452
# Then do other things...
5553
query = dataset.query().kind('EntityKind')
5654
entity = dataset.entity('EntityKind')
@@ -75,9 +73,7 @@ to learn how to connect to the Cloud Storage using this Client Library.
7573
.. code:: python
7674
7775
import gcloud.storage
78-
bucket = gcloud.storage.get_bucket('bucket-id-here',
79-
'long-email@googleapis.com',
80-
'/path/to/private.key')
76+
bucket = gcloud.storage.get_bucket('bucket-id-here', 'project-id')
8177
# Then do other things...
8278
key = bucket.get_key('/remote/path/to/file.txt')
8379
print key.get_contents_as_string()

docs/_components/datastore-getting-started.rst

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,7 @@ Add some data to your dataset
3838
Open a Python console and...
3939

4040
>>> from gcloud import datastore
41-
>>> dataset = datastore.get_dataset(
42-
>>> '<your-project-id-here',
43-
>>> '<the e-mail address you copied here>',
44-
>>> '/path/to/<your project>.key')
41+
>>> dataset = datastore.get_dataset('<your-dataset-id>')
4542
>>> dataset.query().fetch()
4643
[]
4744
>>> entity = dataset.entity('Person')

docs/_components/datastore-quickstart.rst

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ authentication to your project:
2222
bamboo-shift-455).
2323
- ``GCLOUD_TESTS_DATASET_ID``: The name of the dataset your tests connect to.
2424
This is typically the same as ``GCLOUD_TESTS_PROJECT_ID``.
25-
- ``GCLOUD_TESTS_CLIENT_EMAIL``: The email for the service account you're
26-
authenticating with
27-
- ``GCLOUD_TESTS_KEY_FILE``: The path to an encrypted key file.
28-
See private key
25+
- ``GOOGLE_APPLICATION_CREDENTIALS``: The path to an encrypted JSON file;
26+
see ``regression/app_credentials.json.sample`` as an example. Such a file
27+
can be downloaded directly from the developer's console by clicking
28+
"Generate new JSON key". See private key
2929
`docs <https://cloud.google.com/storage/docs/authentication#generating-a-private-key>`__
30-
for explanation on how to get a private key.
30+
for more details.
3131

3232
Run the
3333
`example script <https://github.com/GoogleCloudPlatform/gcloud-python/blob/master/gcloud/datastore/demo/demo.py>`_
@@ -68,7 +68,6 @@ you can create entities and save them::
6868

6969
>>> from gcloud import datastore
7070
>>> from gcloud.datastore import demo
71-
>>> dataset = datastore.get_dataset(
72-
>>> demo.DATASET_ID, demo.CLIENT_EMAIL, demo.PRIVATE_KEY_PATH)
71+
>>> dataset = datastore.get_dataset(demo.DATASET_ID)
7372

7473
----

docs/_components/storage-getting-started.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ The first step in accessing Cloud Storage
4545
is to create a connection to the service::
4646

4747
>>> from gcloud import storage
48-
>>> connection = storage.get_connection(project_name, email, key_path)
48+
>>> connection = storage.get_connection(project_name)
4949

5050
We're going to use this
5151
:class:`connection <gcloud.storage.connection.Connection>` object

docs/_components/storage-quickstart.rst

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ authentication to your project:
2222
bamboo-shift-455).
2323
- ``GCLOUD_TESTS_DATASET_ID``: The name of the dataset your tests connect to.
2424
This is typically the same as ``GCLOUD_TESTS_PROJECT_ID``.
25-
- ``GCLOUD_TESTS_CLIENT_EMAIL``: The email for the service account you're
26-
authenticating with
27-
- ``GCLOUD_TESTS_KEY_FILE``: The path to an encrypted key file.
28-
See private key
25+
- ``GOOGLE_APPLICATION_CREDENTIALS``: The path to an encrypted JSON file;
26+
see ``regression/app_credentials.json.sample`` as an example. Such a file
27+
can be downloaded directly from the developer's console by clicking
28+
"Generate new JSON key". See private key
2929
`docs <https://cloud.google.com/storage/docs/authentication#generating-a-private-key>`__
30-
for explanation on how to get a private key.
30+
for more details.
3131

3232
Run the
3333
`example script <https://github.com/GoogleCloudPlatform/gcloud-python/blob/master/gcloud/storage/demo/demo.py>`_
@@ -76,7 +76,6 @@ you can create buckets and keys::
7676

7777
>>> from gcloud import storage
7878
>>> from gcloud.storage import demo
79-
>>> connection = storage.get_connection(
80-
>>> demo.PROJECT_NAME, demo.CLIENT_EMAIL, demo.PRIVATE_KEY_PATH)
79+
>>> connection = storage.get_connection(demo.PROJECT_ID)
8180

8281
----

docs/index.rst

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,7 @@ Cloud Datastore
2929
.. code-block:: python
3030
3131
from gcloud import datastore
32-
dataset = datastore.get_dataset(
33-
'<your-project-id>',
34-
'<service-account-email>',
35-
'/path/to/your/key')
32+
dataset = datastore.get_dataset('<dataset-id>')
3633
entity = dataset.entity('Person')
3734
entity['name'] = 'Your name'
3835
entity['age'] = 25
@@ -46,13 +43,8 @@ Cloud Storage
4643
.. _Google Cloud Storage: https://developers.google.com/storage/
4744

4845
.. code-block:: python
49-
46+
5047
from gcloud import storage
51-
bucket = storage.get_bucket(
52-
'<your-bucket-name>',
53-
'<your-project-id>',
54-
'<service-account-email>',
55-
'/path/to/your/key')
48+
bucket = storage.get_bucket('<your-bucket-name>', '<your-project-id>')
5649
key = bucket.new_key('my-test-file.txt')
5750
key = key.upload_contents_from_string('this is test content!')
58-

gcloud/credentials.py

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,64 @@
1717
from oauth2client import client
1818

1919

20-
def get_for_service_account(client_email, private_key_path, scope=None):
20+
def get_credentials():
21+
"""Gets credentials implicitly from the current environment.
22+
23+
.. note::
24+
You should not need to use this function directly. Instead, use the
25+
helper methods provided in
26+
:func:`gcloud.datastore.__init__.get_connection` and
27+
:func:`gcloud.datastore.__init__.get_dataset` which use this method
28+
under the hood.
29+
30+
Checks environment in order of precedence:
31+
- Google App Engine (production and testing)
32+
- Environment variable GOOGLE_APPLICATION_CREDENTIALS pointing to
33+
a file with stored credentials information.
34+
- Stored "well known" file associated with `gcloud` command line tool.
35+
- Google Compute Engine production environment.
36+
37+
The file referred to in GOOGLE_APPLICATION_CREDENTIALS is expected to
38+
contain information about credentials that are ready to use. This means
39+
either service account information or user account information with
40+
a ready-to-use refresh token:
41+
{ {
42+
'type': 'authorized_user', 'type': 'service_account',
43+
'client_id': '...', 'client_id': '...',
44+
'client_secret': '...', OR 'client_email': '...',
45+
'refresh_token': '..., 'private_key_id': '...',
46+
} 'private_key': '...',
47+
}
48+
The second of these is simply a JSON key downloaded from the Google APIs
49+
console. The first is a close cousin of the "client secrets" JSON file
50+
used by `oauth2client.clientsecrets` but differs in formatting.
51+
52+
:rtype: :class:`oauth2client.client.GoogleCredentials`,
53+
:class:`oauth2client.appengine.AppAssertionCredentials`,
54+
:class:`oauth2client.gce.AppAssertionCredentials`,
55+
:class:`oauth2client.service_account._ServiceAccountCredentials`
56+
:returns: A new credentials instance corresponding to the implicit
57+
environment.
58+
"""
59+
return client.GoogleCredentials.get_application_default()
60+
61+
62+
def get_for_service_account_p12(client_email, private_key_path, scope=None):
2163
"""Gets the credentials for a service account.
2264
2365
.. note::
24-
You should not need to use this function directly.
25-
Instead, use the helper methods provided in
26-
:func:`gcloud.datastore.__init__.get_connection`
27-
and
28-
:func:`gcloud.datastore.__init__.get_dataset`
29-
which use this method under the hood.
66+
This method is not used by default, instead :func:`get_credentials`
67+
is used. This method is intended to be used when the environments is
68+
known explicitly and detecting the environment implicitly would be
69+
superfluous.
3070
3171
:type client_email: string
3272
:param client_email: The e-mail attached to the service account.
3373
3474
:type private_key_path: string
3575
:param private_key_path: The path to a private key file (this file was
3676
given to you when you created the service
37-
account).
77+
account). This file must be in P12 format.
3878
3979
:type scope: string or tuple of strings
4080
:param scope: The scope against which to authenticate. (Different services

gcloud/datastore/__init__.py

Lines changed: 13 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@
1717
You'll typically use these to get started with the API:
1818
1919
>>> from gcloud import datastore
20-
>>> dataset = datastore.get_dataset('dataset-id-here',
21-
... 'long-email@googleapis.com',
22-
... '/path/to/private.key')
20+
>>> dataset = datastore.get_dataset('dataset-id-here')
2321
>>> # Then do other things...
2422
>>> query = dataset.query().kind('EntityKind')
2523
>>> entity = dataset.entity('EntityKind')
@@ -53,37 +51,30 @@
5351
"""The scope required for authenticating as a Cloud Datastore consumer."""
5452

5553

56-
def get_connection(client_email, private_key_path):
54+
from gcloud import credentials
55+
from gcloud.datastore.connection import Connection
56+
57+
58+
def get_connection():
5759
"""Shortcut method to establish a connection to the Cloud Datastore.
5860
5961
Use this if you are going to access several datasets
6062
with the same set of credentials (unlikely):
6163
6264
>>> from gcloud import datastore
63-
>>> connection = datastore.get_connection(email, key_path)
65+
>>> connection = datastore.get_connection()
6466
>>> dataset1 = connection.dataset('dataset1')
6567
>>> dataset2 = connection.dataset('dataset2')
6668
67-
:type client_email: string
68-
:param client_email: The e-mail attached to the service account.
69-
70-
:type private_key_path: string
71-
:param private_key_path: The path to a private key file (this file was
72-
given to you when you created the service
73-
account).
74-
7569
:rtype: :class:`gcloud.datastore.connection.Connection`
7670
:returns: A connection defined with the proper credentials.
7771
"""
78-
from gcloud import credentials
79-
from gcloud.datastore.connection import Connection
72+
implicit_credentials = credentials.get_credentials()
73+
scoped_credentials = implicit_credentials.create_scoped(SCOPE)
74+
return Connection(credentials=scoped_credentials)
8075

81-
svc_account_credentials = credentials.get_for_service_account(
82-
client_email, private_key_path, scope=SCOPE)
83-
return Connection(credentials=svc_account_credentials)
8476

85-
86-
def get_dataset(dataset_id, client_email, private_key_path):
77+
def get_dataset(dataset_id):
8778
"""Establish a connection to a particular dataset in the Cloud Datastore.
8879
8980
This is a shortcut method for creating a connection and using it
@@ -92,7 +83,7 @@ def get_dataset(dataset_id, client_email, private_key_path):
9283
You'll generally use this as the first call to working with the API:
9384
9485
>>> from gcloud import datastore
95-
>>> dataset = datastore.get_dataset('dataset-id', email, key_path)
86+
>>> dataset = datastore.get_dataset('dataset-id')
9687
>>> # Now you can do things with the dataset.
9788
>>> dataset.query().kind('TestKind').fetch()
9889
[...]
@@ -103,16 +94,8 @@ def get_dataset(dataset_id, client_email, private_key_path):
10394
and is usually the same as your Cloud Datastore project
10495
name.
10596
106-
:type client_email: string
107-
:param client_email: The e-mail attached to the service account.
108-
109-
:type private_key_path: string
110-
:param private_key_path: The path to a private key file (this file was
111-
given to you when you created the service
112-
account).
113-
11497
:rtype: :class:`gcloud.datastore.dataset.Dataset`
11598
:returns: A dataset with a connection using the provided credentials.
11699
"""
117-
connection = get_connection(client_email, private_key_path)
100+
connection = get_connection()
118101
return connection.dataset(dataset_id)

gcloud/datastore/connection.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ def lookup(self, dataset_id, key_pbs):
180180
181181
>>> from gcloud import datastore
182182
>>> from gcloud.datastore.key import Key
183-
>>> connection = datastore.get_connection(email, key_path)
183+
>>> connection = datastore.get_connection()
184184
>>> dataset = connection.dataset('dataset-id')
185185
>>> key = Key(dataset=dataset).kind('MyKind').id(1234)
186186
@@ -248,7 +248,7 @@ def run_query(self, dataset_id, query_pb, namespace=None):
248248
uses this method to fetch data:
249249
250250
>>> from gcloud import datastore
251-
>>> connection = datastore.get_connection(email, key_path)
251+
>>> connection = datastore.get_connection()
252252
>>> dataset = connection.dataset('dataset-id')
253253
>>> query = dataset.query().kind('MyKind').filter('property =', 'val')
254254

0 commit comments

Comments
 (0)