Skip to content

Commit 202f202

Browse files
committed
Initial commit of Resource Manager API
1 parent baf58f2 commit 202f202

File tree

12 files changed

+1269
-1
lines changed

12 files changed

+1269
-1
lines changed

docs/_static/js/main.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ $('.headerlink').parent().each(function() {
1616
$('.side-nav').children('ul:nth-child(2)').children().each(function() {
1717
var itemName = $(this).text();
1818
if (itemName !== 'Datastore' && itemName !== 'Storage' &&
19-
itemName !== 'Pub/Sub') {
19+
itemName !== 'Pub/Sub' && itemName !== 'Resource Manager') {
2020
$(this).css('padding-left','2em');
2121
}
2222
});

docs/index.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
pubsub-usage
1818
pubsub-subscription
1919
pubsub-topic
20+
resource-manager-api
21+
resource-manager-client
22+
resource-manager-project
2023

2124

2225
Getting started

docs/resource-manager-api.rst

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
.. toctree::
2+
:maxdepth: 1
3+
:hidden:
4+
5+
Resource Manager
6+
----------------
7+
8+
Overview
9+
~~~~~~~~
10+
11+
The Cloud Resource Manager API provides methods that you can use
12+
to programmatically manage your projects in the Google Cloud Platform.
13+
With this API, you can do the following:
14+
15+
- Get a list of all projects associated with an account
16+
- Create new projects
17+
- Update existing projects
18+
- Delete projects
19+
- Undelete, or recover, projects that you don't want to delete
20+
21+
.. note::
22+
23+
Don't forget to look at the **Authentication** section below.
24+
It's slightly different from the rest of this library.
25+
26+
Here's a quick example of the full life-cycle::
27+
28+
>>> from gcloud import resource_manager
29+
30+
>>> # List all projects you have access to
31+
>>> client = resource_manager.Client()
32+
>>> for project in client.list_projects():
33+
... print project
34+
35+
>>> # Create a new project
36+
>>> new_project = client.project('your-project-id-here')
37+
>>> new_project.name = 'My new project'
38+
>>> new_project.create()
39+
40+
>>> # Update an existing project
41+
>>> project = client.get_project('my-existing-project')
42+
>>> print project
43+
<Project: Existing Project (my-existing-project)>
44+
>>> project.name = 'Modified name'
45+
>>> project.update()
46+
>>> print project
47+
<Project: Modified name (my-existing-project)>
48+
49+
>>> # Delete a project
50+
>>> project = client.get_project('my-existing-project')
51+
>>> project.delete()
52+
53+
>>> # Undelete a project
54+
>>> project = client.get_project('my-existing-project')
55+
>>> project.undelete()
56+
57+
Authentication
58+
~~~~~~~~~~~~~~
59+
60+
Unlike the other APIs, the Resource Manager API is focused on managing your
61+
various projects inside Google Cloud Platform. What this means (currently) is
62+
that you can't use a Service Account to work with some parts of this API
63+
(for example, creating projects).
64+
65+
The reason is actually pretty simple: if your API call is trying to do
66+
something like create a project, what project's Service Account can you use?
67+
Currently none.
68+
69+
This means that for this API you should always use the credentials
70+
provided by the Cloud SDK, which you can get by running ``gcloud auth login``
71+
(if you're not familiar with this, take a look at http://cloud.google.com/sdk).
72+
73+
Once you run that command, ``gcloud`` will automatically pick up the
74+
credentials from the Cloud SDK, and you can use the "automatic discovery"
75+
feature of the library.
76+
77+
Start by authenticating::
78+
79+
$ gcloud auth login
80+
81+
And then simply create a client::
82+
83+
>>> from gcloud import resource_manager
84+
>>> client = resource_manager.Client()

docs/resource-manager-client.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
.. toctree::
2+
:maxdepth: 0
3+
:hidden:
4+
5+
Client
6+
------
7+
8+
.. automodule:: gcloud.resource_manager.client
9+
:members:
10+
:undoc-members:
11+
:show-inheritance:
12+
13+
Connection
14+
~~~~~~~~~~
15+
16+
.. automodule:: gcloud.resource_manager.connection
17+
:members:
18+
:undoc-members:
19+
:show-inheritance:

docs/resource-manager-project.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Projects
2+
~~~~~~~~
3+
4+
.. automodule:: gcloud.resource_manager.project
5+
:members:
6+
:undoc-members:
7+
:show-inheritance:

gcloud/resource_manager/__init__.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Copyright 2015 Google Inc. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""Cloud ResourceManager API wrapper.
16+
17+
The main concepts with this API are:
18+
19+
- :class:`gcloud.resource_manager.project.Project` represents
20+
a Google Cloud project.
21+
"""
22+
23+
from gcloud.resource_manager.client import Client
24+
from gcloud.resource_manager.connection import SCOPE
25+
from gcloud.resource_manager.project import Project

gcloud/resource_manager/client.py

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
# Copyright 2015 Google Inc. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""A Client for interacting with the Resource Manager API.
16+
17+
Overview
18+
~~~~~~~~
19+
20+
There are three main methods in the ``Client`` class:
21+
22+
- :func:`gcloud.resource_manager.client.Client.list_projects`
23+
- :func:`gcloud.resource_manager.client.Client.project`
24+
- :func:`gcloud.resource_manager.client.Client.get_project`
25+
26+
``project()`` versus ``get_project()``
27+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
28+
29+
The difference between ``project`` and ``get_project`` is subtle,
30+
so it might be worthwhile to make a quick distinction.
31+
32+
If you want to simply "get a hold of a Project" object,
33+
but **don't** want to actually retrieve any metadata about that project
34+
(for example, when you want to create a new project, or delete a project
35+
in a single API request), ``project()`` is the best method to use::
36+
37+
>>> from gcloud import resource_manager
38+
>>> client = resource_manager.Client()
39+
>>> project = client.project('purple-spaceship-123')
40+
>>> project.number is None
41+
True
42+
43+
The ``project`` referenced above has no extra metadata associated with it,
44+
however you can still operate on it (ie, ``project.create()`` or
45+
``project.delete()``).
46+
47+
If you want to retrieve a project and all of it's metadata, the best method
48+
to use is ``get_project()``, which will return ``None`` if the project
49+
doesn't exist::
50+
51+
>>> from gcloud import resource_manager
52+
>>> client = resource_manager.Client()
53+
>>> project = client.get_project('purple-spaceship-123')
54+
>>> project.number is None
55+
False
56+
>>> project = client.get_project('doesnt-exist')
57+
>>> project is None
58+
True
59+
"""
60+
61+
62+
from gcloud.client import Client as BaseClient
63+
from gcloud.exceptions import NotFound
64+
from gcloud.iterator import Iterator
65+
from gcloud.resource_manager.connection import Connection
66+
from gcloud.resource_manager.project import Project
67+
68+
69+
class Client(BaseClient):
70+
"""Client to bundle configuration needed for API requests.
71+
72+
See
73+
https://cloud.google.com/resource-manager/reference/rest/
74+
for more information on this API.
75+
76+
Automatically get credentials::
77+
78+
>>> from gcloud.resource_manager import Client
79+
>>> client = Client()
80+
81+
.. note::
82+
83+
Chances are you want to use either the constructor with no arguments,
84+
or one of the factory methods (like
85+
:func:`gcloud.resource_manager.client.Client.from_service_account_json`
86+
or similar).
87+
88+
Even more likely is that you want to use the Cloud SDK to get
89+
credentials for these API calls (that is, run ``gcloud auth login``).
90+
91+
:type credentials: :class:`oauth2client.client.OAuth2Credentials` or
92+
:class:`NoneType`
93+
94+
:param credentials: The OAuth2 Credentials to use for the connection
95+
owned by this client. If not passed (and if no ``http``
96+
object is passed), falls back to the default inferred
97+
from the environment.
98+
99+
:type http: :class:`httplib2.Http` or class that defines ``request()``.
100+
:param http: An optional HTTP object to make requests. If not passed, an
101+
``http`` object is created that is bound to the
102+
``credentials`` for the current object.
103+
"""
104+
105+
_connection_class = Connection
106+
107+
def list_projects(self, filter_params=None, page_size=None):
108+
"""List the projects visible to this client.
109+
110+
Example::
111+
112+
>>> from gcloud import resource_manager
113+
>>> client = resource_manager.Client()
114+
>>> for project in client.list_projects():
115+
... print project.project_id
116+
117+
List all projects with label ``'environment'`` set to ``'prod'``
118+
(filtering by labels)::
119+
120+
>>> from gcloud import resource_manager
121+
>>> client = resource_manager.Client()
122+
>>> env_filter = {'labels.environment': 'prod'}
123+
>>> for project in client.list_projects(env_filter):
124+
... print project.project_id
125+
126+
See:
127+
https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects/list
128+
129+
Complete filtering example::
130+
131+
>>> project_filter = { # Return projects with...
132+
... 'name': 'My Project', # name set to 'My Project'.
133+
... 'id': 'my-project-id', # id set to 'my-project-id'.
134+
... 'labels.stage': 'prod', # the label 'stage' set to 'prod'
135+
... # set to prod.
136+
... 'labels.color': '*' # a label 'color' set to anything.
137+
... }
138+
>>> client.list_projects(project_filter)
139+
140+
:type filter_params: dict
141+
:param filter_params: A dictionary of filter options where the keys are
142+
the property to filter on, and the value is the
143+
case-insensitive value to check (or * to check
144+
for existence of the property). See the example
145+
above for more details.
146+
Note that property values are case-insensitive.
147+
148+
:type page_size: int
149+
:param page_size: maximum number of projects to return in a single
150+
page. If not passed, defaults to a value set by the
151+
API.
152+
153+
:rtype: :class:`gcloud.resource_manager.iterator.ProjectIterator`
154+
:returns: A ProjectIterator class, which allows you to iterate through
155+
all of the results without thinking about pagination.
156+
Each item will be a :class:`.project.Project` object.
157+
"""
158+
params = {}
159+
160+
if page_size is not None:
161+
params['pageSize'] = page_size
162+
163+
if filter_params is not None:
164+
params['filter'] = filter_params
165+
166+
client = self
167+
168+
class ProjectIterator(Iterator):
169+
"""An iterator over a list of Project resources."""
170+
171+
def get_items_from_response(self, response):
172+
"""Yield :class:`.resource_manager.project.Project` items
173+
from response.
174+
175+
:type response: dict
176+
:param response: The JSON API response for a page of projects.
177+
"""
178+
for resource in response.get('projects', []):
179+
item = Project.from_api_repr(resource, client=client)
180+
yield item
181+
182+
return ProjectIterator(connection=self.connection, extra_params=params,
183+
path='/projects')
184+
185+
def project(self, project_id):
186+
"""Get a Project instance without making an API call.
187+
188+
Typically used when creating a new project.
189+
190+
See :func:`gcloud.resource_manager.client.Client.get_project` if you
191+
want to load a project and its metadata using an API call.
192+
193+
Example::
194+
195+
>>> client = Client()
196+
>>> project = client.project('purple-spaceship-123')
197+
>>> print project.name
198+
None
199+
>>> print project.project_id
200+
purple-spaceship-123
201+
202+
:type project_id: str
203+
:param project_id: The ID for this project.
204+
205+
:rtype: :class:`gcloud.resource_manager.project.Project`
206+
:returns: A new instance of a :class:`.project.Project` **without**
207+
any metadata loaded.
208+
"""
209+
return Project(project_id=project_id, client=self)
210+
211+
def get_project(self, project_id):
212+
"""Get a Project instance and its metadata via an API call.
213+
214+
Example::
215+
216+
>>> client = Client()
217+
>>> project = client.get_project('purple-spaceship-123')
218+
>>> print project.name
219+
Purple Spaceship 123
220+
>>> print project.project_id
221+
purple-spaceship-123
222+
223+
See :func:`gcloud.resource_manager.client.Client.project` if you
224+
want to load a project **without** its metadata (aka, without an
225+
API call).
226+
227+
:type project_id: str
228+
:param project_id: The ID for this project.
229+
230+
:rtype: :class:`gcloud.resource_manager.project.Project`
231+
:returns: A new instance of a :class:`.project.Project` with all
232+
its metadata loaded.
233+
"""
234+
try:
235+
project = self.project(project_id)
236+
project.reload()
237+
except NotFound:
238+
project = None
239+
return project

0 commit comments

Comments
 (0)