-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Initial commit of Resource Manager API #933
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
.. toctree:: | ||
:maxdepth: 1 | ||
:hidden: | ||
|
||
Resource Manager | ||
---------------- | ||
|
||
Overview | ||
~~~~~~~~ | ||
|
||
The Cloud Resource Manager API provides methods that you can use | ||
to programmatically manage your projects in the Google Cloud Platform. | ||
With this API, you can do the following: | ||
|
||
- Get a list of all projects associated with an account | ||
- Create new projects | ||
- Update existing projects | ||
- Delete projects | ||
- Undelete, or recover, projects that you don't want to delete | ||
|
||
.. note:: | ||
|
||
Don't forget to look at the **Authentication** section below. | ||
It's slightly different from the rest of this library. | ||
|
||
Here's a quick example of the full life-cycle:: | ||
|
||
>>> from gcloud import resource_manager | ||
|
||
>>> # List all projects you have access to | ||
>>> client = resource_manager.Client() | ||
>>> for project in client.list_projects(): | ||
... print project | ||
|
||
>>> # Create a new project | ||
>>> new_project = client.project('your-project-id-here') | ||
>>> new_project.name = 'My new project' | ||
>>> new_project.create() | ||
|
||
>>> # Update an existing project | ||
>>> project = client.get_project('my-existing-project') | ||
>>> print project | ||
<Project: Existing Project (my-existing-project)> | ||
>>> project.name = 'Modified name' | ||
>>> project.update() | ||
>>> print project | ||
<Project: Modified name (my-existing-project)> | ||
|
||
>>> # Delete a project | ||
>>> project = client.get_project('my-existing-project') | ||
>>> project.delete() | ||
|
||
>>> # Undelete a project | ||
>>> project = client.get_project('my-existing-project') | ||
>>> project.undelete() | ||
|
||
Authentication | ||
~~~~~~~~~~~~~~ | ||
|
||
Unlike the other APIs, the Resource Manager API is focused on managing your | ||
various projects inside Google Cloud Platform. What this means (currently) is | ||
that you can't use a Service Account to work with some parts of this API | ||
(for example, creating projects). | ||
|
||
The reason is actually pretty simple: if your API call is trying to do | ||
something like create a project, what project's Service Account can you use? | ||
Currently none. | ||
|
||
This means that for this API you should always use the credentials | ||
provided by the Cloud SDK, which you can get by running ``gcloud auth login`` | ||
(if you're not familiar with this, take a look at http://cloud.google.com/sdk). | ||
|
||
Once you run that command, ``gcloud`` will automatically pick up the | ||
credentials from the Cloud SDK, and you can use the "automatic discovery" | ||
feature of the library. | ||
|
||
Start by authenticating:: | ||
|
||
$ gcloud auth login | ||
|
||
And then simply create a client:: | ||
|
||
>>> from gcloud import resource_manager | ||
>>> client = resource_manager.Client() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
.. toctree:: | ||
:maxdepth: 0 | ||
:hidden: | ||
|
||
Client | ||
------ | ||
|
||
.. automodule:: gcloud.resource_manager.client | ||
:members: | ||
:undoc-members: | ||
:show-inheritance: | ||
|
||
Connection | ||
~~~~~~~~~~ | ||
|
||
.. automodule:: gcloud.resource_manager.connection | ||
:members: | ||
:undoc-members: | ||
:show-inheritance: |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
Projects | ||
~~~~~~~~ | ||
|
||
.. automodule:: gcloud.resource_manager.project | ||
:members: | ||
:undoc-members: | ||
:show-inheritance: |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# Copyright 2015 Google Inc. All rights reserved. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
"""Cloud ResourceManager API wrapper. | ||
|
||
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
Sorry, something went wrong. |
||
The main concepts with this API are: | ||
|
||
- :class:`gcloud.resource_manager.project.Project` represents | ||
a Google Cloud project. | ||
""" | ||
|
||
from gcloud.resource_manager.client import Client | ||
from gcloud.resource_manager.connection import SCOPE | ||
from gcloud.resource_manager.project import Project |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,238 @@ | ||
# Copyright 2015 Google Inc. All rights reserved. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
"""A Client for interacting with the Resource Manager API. | ||
|
||
Overview | ||
~~~~~~~~ | ||
|
||
There are three main methods in the ``Client`` class: | ||
|
||
- :func:`gcloud.resource_manager.client.Client.list_projects` | ||
- :func:`gcloud.resource_manager.client.Client.project` | ||
- :func:`gcloud.resource_manager.client.Client.get_project` | ||
This comment was marked as spam.
Sorry, something went wrong. |
||
|
||
``project()`` versus ``get_project()`` | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
The difference between ``project`` and ``get_project`` is subtle, | ||
so it might be worthwhile to make a quick distinction. | ||
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
Sorry, something went wrong. |
||
|
||
If you want to simply "get a hold of a Project" object, | ||
but **don't** want to actually retrieve any metadata about that project | ||
(for example, when you want to create a new project, or delete a project | ||
in a single API request), ``project()`` is the best method to use:: | ||
|
||
>>> from gcloud import resource_manager | ||
>>> client = resource_manager.Client() | ||
>>> project = client.project('purple-spaceship-123') | ||
>>> project.number is None | ||
True | ||
|
||
The ``project`` referenced above has no extra metadata associated with it, | ||
however you can still operate on it (ie, ``project.create()`` or | ||
``project.delete()``). | ||
|
||
If you want to retrieve a project and all of it's metadata, the best method | ||
to use is ``get_project()``, which will return ``None`` if the project | ||
doesn't exist:: | ||
|
||
>>> from gcloud import resource_manager | ||
>>> client = resource_manager.Client() | ||
>>> project = client.get_project('purple-spaceship-123') | ||
>>> project.number is None | ||
False | ||
>>> project = client.get_project('doesnt-exist') | ||
>>> project is None | ||
True | ||
""" | ||
|
||
|
||
from gcloud.client import Client as BaseClient | ||
from gcloud.exceptions import NotFound | ||
from gcloud.iterator import Iterator | ||
from gcloud.resource_manager.connection import Connection | ||
from gcloud.resource_manager.project import Project | ||
|
||
|
||
class Client(BaseClient): | ||
"""Client to bundle configuration needed for API requests. | ||
|
||
See | ||
https://cloud.google.com/resource-manager/reference/rest/ | ||
for more information on this API. | ||
|
||
Automatically get credentials:: | ||
|
||
>>> from gcloud.resource_manager import Client | ||
>>> client = Client() | ||
|
||
.. note:: | ||
|
||
Chances are you want to use either the constructor with no arguments, | ||
or one of the factory methods (like | ||
:func:`gcloud.resource_manager.client.Client.from_service_account_json` | ||
or similar). | ||
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
Sorry, something went wrong. |
||
|
||
Even more likely is that you want to use the Cloud SDK to get | ||
credentials for these API calls (that is, run ``gcloud auth login``). | ||
|
||
:type credentials: :class:`oauth2client.client.OAuth2Credentials` or | ||
:class:`NoneType` | ||
:param credentials: The OAuth2 Credentials to use for the connection | ||
owned by this client. If not passed (and if no ``http`` | ||
object is passed), falls back to the default inferred | ||
from the environment. | ||
|
||
:type http: :class:`httplib2.Http` or class that defines ``request()``. | ||
:param http: An optional HTTP object to make requests. If not passed, an | ||
``http`` object is created that is bound to the | ||
``credentials`` for the current object. | ||
""" | ||
|
||
_connection_class = Connection | ||
|
||
def list_projects(self, filter_params=None, page_size=None): | ||
"""List the projects visible to this client. | ||
|
||
Example:: | ||
|
||
>>> from gcloud import resource_manager | ||
>>> client = resource_manager.Client() | ||
>>> for project in client.list_projects(): | ||
... print project.project_id | ||
|
||
List all projects with label ``'environment'`` set to ``'prod'`` | ||
(filtering by labels):: | ||
|
||
>>> from gcloud import resource_manager | ||
>>> client = resource_manager.Client() | ||
>>> env_filter = {'labels.environment': 'prod'} | ||
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
Sorry, something went wrong. |
||
>>> for project in client.list_projects(env_filter): | ||
... print project.project_id | ||
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
Sorry, something went wrong. |
||
|
||
See: | ||
https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects/list | ||
|
||
Complete filtering example:: | ||
|
||
>>> project_filter = { # Return projects with... | ||
... 'name': 'My Project', # name set to 'My Project'. | ||
... 'id': 'my-project-id', # id set to 'my-project-id'. | ||
... 'labels.stage': 'prod', # the label 'stage' set to 'prod' | ||
... # set to prod. | ||
... 'labels.color': '*' # a label 'color' set to anything. | ||
... } | ||
>>> client.list_projects(project_filter) | ||
|
||
:type filter_params: dict | ||
:param filter_params: A dictionary of filter options where the keys are | ||
the property to filter on, and the value is the | ||
case-insensitive value to check (or * to check | ||
for existence of the property). See the example | ||
above for more details. | ||
Note that property values are case-insensitive. | ||
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
Sorry, something went wrong. |
||
|
||
:type page_size: int | ||
:param page_size: maximum number of projects to return in a single | ||
page. If not passed, defaults to a value set by the | ||
API. | ||
|
||
:rtype: :class:`gcloud.resource_manager.iterator.ProjectIterator` | ||
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
Sorry, something went wrong. |
||
:returns: A ProjectIterator class, which allows you to iterate through | ||
all of the results without thinking about pagination. | ||
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
Sorry, something went wrong. |
||
Each item will be a :class:`.project.Project` object. | ||
""" | ||
params = {} | ||
|
||
if page_size is not None: | ||
params['pageSize'] = page_size | ||
|
||
if filter_params is not None: | ||
params['filter'] = filter_params | ||
|
||
client = self | ||
|
||
class ProjectIterator(Iterator): | ||
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
Sorry, something went wrong. |
||
"""An iterator over a list of Project resources.""" | ||
|
||
def get_items_from_response(self, response): | ||
"""Yield :class:`.resource_manager.project.Project` items | ||
from response. | ||
|
||
:type response: dict | ||
:param response: The JSON API response for a page of projects. | ||
""" | ||
for resource in response.get('projects', []): | ||
item = Project.from_api_repr(resource, client=client) | ||
yield item | ||
|
||
return ProjectIterator(connection=self.connection, extra_params=params, | ||
path='/projects') | ||
|
||
def project(self, project_id): | ||
"""Get a Project instance without making an API call. | ||
|
||
Typically used when creating a new project. | ||
|
||
See :func:`gcloud.resource_manager.client.Client.get_project` if you | ||
want to load a project and its metadata using an API call. | ||
|
||
Example:: | ||
|
||
>>> client = Client() | ||
>>> project = client.project('purple-spaceship-123') | ||
>>> print project.name | ||
None | ||
>>> print project.project_id | ||
purple-spaceship-123 | ||
|
||
:type project_id: str | ||
:param project_id: The ID for this project. | ||
|
||
:rtype: :class:`gcloud.resource_manager.project.Project` | ||
:returns: A new instance of a :class:`.project.Project` **without** | ||
any metadata loaded. | ||
""" | ||
return Project(project_id=project_id, client=self) | ||
|
||
def get_project(self, project_id): | ||
"""Get a Project instance and its metadata via an API call. | ||
|
||
Example:: | ||
|
||
>>> client = Client() | ||
>>> project = client.get_project('purple-spaceship-123') | ||
>>> print project.name | ||
Purple Spaceship 123 | ||
>>> print project.project_id | ||
purple-spaceship-123 | ||
|
||
See :func:`gcloud.resource_manager.client.Client.project` if you | ||
want to load a project **without** its metadata (aka, without an | ||
API call). | ||
|
||
:type project_id: str | ||
:param project_id: The ID for this project. | ||
|
||
:rtype: :class:`gcloud.resource_manager.project.Project` | ||
:returns: A new instance of a :class:`.project.Project` with all | ||
its metadata loaded. | ||
""" | ||
try: | ||
project = self.project(project_id) | ||
project.reload() | ||
except NotFound: | ||
This comment was marked as spam.
Sorry, something went wrong. |
||
project = None | ||
return project |
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
Sorry, something went wrong.