From 8c52477f694e481532c3002c527daa5203af5abb Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Mon, 14 Sep 2015 14:54:28 -0400 Subject: [PATCH 01/14] DNS devx sketch. --- docs/dns-usage.rst | 184 +++++++++++++++++++++++++++++++++++++++++++++ docs/index.rst | 7 ++ 2 files changed, 191 insertions(+) create mode 100644 docs/dns-usage.rst diff --git a/docs/dns-usage.rst b/docs/dns-usage.rst new file mode 100644 index 000000000000..0f5d456e9760 --- /dev/null +++ b/docs/dns-usage.rst @@ -0,0 +1,184 @@ +Using the API +============= + +Authorization / Configuration +----------------------------- + +- Use :class:`Client ` objects to configure + your applications. + +- :class:`Client ` objects hold both a ``project`` + and an authenticated connection to the PubSub service. + +- The authentication credentials can be implicitly determined from the + environment or directly via + :meth:`from_service_account_json ` + and + :meth:`from_service_account_p12 `. + +- After setting ``GOOGLE_APPLICATION_CREDENTIALS`` and ``GCLOUD_PROJECT`` + environment variables, create an instance of + :class:`Client `. + + .. doctest:: + + >>> from gcloud import dns + >>> client = dns.Client() + +- Override the credentials inferred from the environment by passing explicit + ``credentials`` to one of the alternative ``classmethod`` factories, + `:meth:gcloud.dns.client.Client.from_service_account_json`: + + .. doctest:: + + >>> from gcloud import dns + >>> client = dns.Client.from_service_account_json('/path/to/creds.json') + + or `:meth:gcloud.dns.client.Client.from_service_account_p12`: + + .. doctest:: + + >>> from gcloud import dns + >>> client = dns.Client.from_service_account_p12('/path/to/creds.p12', 'jrandom@example.com') + + +Projects +-------- + +A project is the top-level container in the ``DNS`` API: it is tied +closely to billing, and can provide default access control across all its +datasets. If no ``project`` is passed to the client container, the library +attempts to infer a project using the environment (including explicit +environment variables, GAE, and GCE). + +To override the project inferred from the environment, pass an explicit +``project`` to the constructor, or to either of the alternative +``classmethod`` factories: + + .. doctest:: + + >>> from gcloud import dns + >>> client = dns.Client(project='PROJECT_ID') + +Project Quotas +-------------- + +Query the quotas for a given project: + + .. doctest:: + + >>> from gcloud import dns + >>> client = dns.Client(project='PROJECT_ID') + >>> quotas = client.quotas() # API request + >>> for key, value in sorted(quotas.items()): + ... print('%s: %s' % (key, value)) + managedZones: 10000 + resourceRecordsPerRrset: 100 + rrsetsPerManagedZone: 10000 + rrsetAdditionsPerChange: 100 + rrsetDeletionsPerChange: 100 + totalRrdataSizePerChange: 10000 + +.. note:: + + See https://github.com/GoogleCloudPlatform/gcloud-python/issues/1136 + for whether to expose quotas. + +Project ACLs +~~~~~~~~~~~~ + +Each project has an access control list granting reader / writer / owner +permission to one or more entities. This list cannot be queried or set +via the API: it must be managed using the Google Developer Console. + + +Managed Zones +------------- + +A "managed zone" is the container for DNS records for the same DNS name +suffix and has a set of name servers that accept and responds to queries: + + .. doctest:: + + >>> from gcloud import dns + >>> client = dns.Client(project='PROJECT_ID') + >>> zone = client.zone('acme-co', description='Acme Company zone', + ... dns_name='example.com') + + >>> zone.exists() # API request + False + >>> zone.create() # API request + >>> zone.exists() # API request + True + +List the zones for a given project: + + .. doctest:: + + >>> from gcloud import dns + >>> client = dns.Client(project='PROJECT_ID') + >>> zones = client.list_zones() # API request + >>> [zone.name for zone in zones] + ['acme-co'>] + + +Resource Record Sets +-------------------- + +Each managed zone exposes a read-only set of resource records: + + .. doctest:: + + >>> from gcloud import dns + >>> client = dns.Client(project='PROJECT_ID') + >>> zone = client.zone('acme-co') + >>> records, page_token = zone.list_resources() # API request + >>> [(record.name, record.type, record.ttl, record.rrdatas) for record in records] + [('example.com.', 'SOA', 21600, ['ns-cloud1.googlecomains.com dns-admin.google.com 1 21600 3600 1209600 300')] + +.. note:: + + The ``page_token`` returned from ``zone.list_resources()`` will be + an opaque string if there are more resources than can be returned in a + single request. To enumerate them all, repeat calling + ``zone.list_resources()``, passing the ``page_token``, until the token + is None. + +Change requests +--------------- + +Update the resource record set for a zone by creating a change request +bundling additions to or deletions from the set. + + .. doctest:: + + >>> import time + >>> from gcloud import dns + >>> client = dns.Client(project='PROJECT_ID') + >>> zone = client.zone('acme-co') + >>> record = dns.ResourceRecord(name='www.example.com', type='CNAME') + >>> change = zone.change_request(additions=[record]) + >>> change.begin() # API request + >>> while change.status != 'done': + ... print('Waiting for change to complete') + ... time.sleep(60) + ... change.reload() # API request + + +List changes made to the resource record set for a given zone: + + .. doctest:: + + >>> from gcloud import dns + >>> client = dns.Client(project='PROJECT_ID') + >>> zone = client.zone('acme-co') + >>> changes = [] + >>> changes, page_token = zone.list_changes() # API request + +.. note:: + + The ``page_token`` returned from ``zone.list_changes()`` will be + an opaque string if there are more hcanges than can be returned in a + single request. To enumerate them all, repeat calling + ``zone.list_hcanges()``, passing the ``page_token``, until the token + is None. diff --git a/docs/index.rst b/docs/index.rst index 5ca3a44eafb5..a9b024ce9ad2 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -58,6 +58,13 @@ resource-manager-client resource-manager-project +.. toctree:: + :maxdepth: 0 + :hidden: + :caption: DNS + + dns-usage + .. toctree:: :maxdepth: 0 :hidden: From 1847126dd9ef093867599f530e824031a8040685 Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Tue, 15 Sep 2015 12:13:22 -0400 Subject: [PATCH 02/14] Rework/retitle section to link common authn doc, indicate usage. Addresses: https://github.com/GoogleCloudPlatform/gcloud-python/pull/1137#discussion_r39445606. --- docs/dns-usage.rst | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/docs/dns-usage.rst b/docs/dns-usage.rst index 0f5d456e9760..6d3a77dfb635 100644 --- a/docs/dns-usage.rst +++ b/docs/dns-usage.rst @@ -1,40 +1,34 @@ Using the API ============= -Authorization / Configuration ------------------------------ +Client +------ -- Use :class:`Client ` objects to configure - your applications. +:class:`Client ` objects provide a means +configure your DNS applications. Eash instance holds both a ``project`` +and an authenticated connection to the DNS service. -- :class:`Client ` objects hold both a ``project`` - and an authenticated connection to the PubSub service. +For an overview of authentication in ``gcloud-python``, see: +http://gcloud-python.readthedocs.org/en/latest/gcloud-auth.html -- The authentication credentials can be implicitly determined from the - environment or directly via - :meth:`from_service_account_json ` - and - :meth:`from_service_account_p12 `. - -- After setting ``GOOGLE_APPLICATION_CREDENTIALS`` and ``GCLOUD_PROJECT`` - environment variables, create an instance of - :class:`Client `. +Assuming your environment is set up as described in that document, +create an instance of :class:`Client `. .. doctest:: >>> from gcloud import dns >>> client = dns.Client() -- Override the credentials inferred from the environment by passing explicit - ``credentials`` to one of the alternative ``classmethod`` factories, - `:meth:gcloud.dns.client.Client.from_service_account_json`: +Override the credentials inferred from the environment by passing explicit +``credentials`` to one of the alternative ``classmethod`` factories, +`:meth:gcloud.dns.client.Client.from_service_account_json`: .. doctest:: >>> from gcloud import dns >>> client = dns.Client.from_service_account_json('/path/to/creds.json') - or `:meth:gcloud.dns.client.Client.from_service_account_p12`: +or `:meth:gcloud.dns.client.Client.from_service_account_p12`: .. doctest:: From ac8ae3b5c7e8577a267a1ee6004b7699b0805bcb Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Tue, 15 Sep 2015 12:13:33 -0400 Subject: [PATCH 03/14] Use 'or' rather than 'and' to indicate options. Addresses: https://github.com/GoogleCloudPlatform/gcloud-python/pull/1137#discussion_r39445839. --- docs/dns-usage.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dns-usage.rst b/docs/dns-usage.rst index 6d3a77dfb635..352a6b5b2f9f 100644 --- a/docs/dns-usage.rst +++ b/docs/dns-usage.rst @@ -43,7 +43,7 @@ A project is the top-level container in the ``DNS`` API: it is tied closely to billing, and can provide default access control across all its datasets. If no ``project`` is passed to the client container, the library attempts to infer a project using the environment (including explicit -environment variables, GAE, and GCE). +environment variables, GAE, or GCE). To override the project inferred from the environment, pass an explicit ``project`` to the constructor, or to either of the alternative From 5c7c93c8515c579906ecf963e23f3076304fc04f Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Tue, 15 Sep 2015 12:14:51 -0400 Subject: [PATCH 04/14] Remove in-line reference to #1136. Addresses: https://github.com/GoogleCloudPlatform/gcloud-python/pull/1137#discussion_r39446146 --- docs/dns-usage.rst | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/dns-usage.rst b/docs/dns-usage.rst index 352a6b5b2f9f..3ec5f4a98dca 100644 --- a/docs/dns-usage.rst +++ b/docs/dns-usage.rst @@ -73,10 +73,6 @@ Query the quotas for a given project: rrsetDeletionsPerChange: 100 totalRrdataSizePerChange: 10000 -.. note:: - - See https://github.com/GoogleCloudPlatform/gcloud-python/issues/1136 - for whether to expose quotas. Project ACLs ~~~~~~~~~~~~ From b4701ec46a977c0fa201889ad4101b7958d601a2 Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Tue, 15 Sep 2015 12:15:37 -0400 Subject: [PATCH 05/14] Remove stray '>'. Addresses: https://github.com/GoogleCloudPlatform/gcloud-python/pull/1137#discussion_r39446261 --- docs/dns-usage.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dns-usage.rst b/docs/dns-usage.rst index 3ec5f4a98dca..5c69cd8fd615 100644 --- a/docs/dns-usage.rst +++ b/docs/dns-usage.rst @@ -109,7 +109,7 @@ List the zones for a given project: >>> client = dns.Client(project='PROJECT_ID') >>> zones = client.list_zones() # API request >>> [zone.name for zone in zones] - ['acme-co'>] + ['acme-co'] Resource Record Sets From aea55fe4239af1b60d15092d89e6016d64d823e1 Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Tue, 15 Sep 2015 12:16:32 -0400 Subject: [PATCH 06/14] Add missing closing ']'. Addresses: https://github.com/GoogleCloudPlatform/gcloud-python/pull/1137#discussion_r39446405 --- docs/dns-usage.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dns-usage.rst b/docs/dns-usage.rst index 5c69cd8fd615..2b99b5c6b141 100644 --- a/docs/dns-usage.rst +++ b/docs/dns-usage.rst @@ -124,7 +124,7 @@ Each managed zone exposes a read-only set of resource records: >>> zone = client.zone('acme-co') >>> records, page_token = zone.list_resources() # API request >>> [(record.name, record.type, record.ttl, record.rrdatas) for record in records] - [('example.com.', 'SOA', 21600, ['ns-cloud1.googlecomains.com dns-admin.google.com 1 21600 3600 1209600 300')] + [('example.com.', 'SOA', 21600, ['ns-cloud1.googlecomains.com dns-admin.google.com 1 21600 3600 1209600 300')]] .. note:: From 8ce29a814ecefa705be1bdf9b5906b8681891463 Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Tue, 15 Sep 2015 12:21:59 -0400 Subject: [PATCH 07/14] Delineate 'None', show example of using page token. Addresses: https://github.com/GoogleCloudPlatform/gcloud-python/pull/1137#discussion_r39446517 --- docs/dns-usage.rst | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/dns-usage.rst b/docs/dns-usage.rst index 2b99b5c6b141..85768bbd40e2 100644 --- a/docs/dns-usage.rst +++ b/docs/dns-usage.rst @@ -132,7 +132,16 @@ Each managed zone exposes a read-only set of resource records: an opaque string if there are more resources than can be returned in a single request. To enumerate them all, repeat calling ``zone.list_resources()``, passing the ``page_token``, until the token - is None. + is ``None``. E.g. + + .. doctest:: + + >>> records, page_token = zone.list_resources() # API request + >>> while page_token is not None: + ... next_batch, page_token = zone.list_resources( + ... page_token=page_token) # API request + ... records.extend(next_batch) + Change requests --------------- From 4f96df0ce7ee7b16ae89c17308827248bc52f299 Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Tue, 15 Sep 2015 12:23:32 -0400 Subject: [PATCH 08/14] Add note about arbitrary 60-second interval. Addresses: https://github.com/GoogleCloudPlatform/gcloud-python/pull/1137#discussion_r39446565 --- docs/dns-usage.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dns-usage.rst b/docs/dns-usage.rst index 85768bbd40e2..cb9fe1c3904d 100644 --- a/docs/dns-usage.rst +++ b/docs/dns-usage.rst @@ -160,7 +160,7 @@ bundling additions to or deletions from the set. >>> change.begin() # API request >>> while change.status != 'done': ... print('Waiting for change to complete') - ... time.sleep(60) + ... time.sleep(60) # or whatever interval is appropriate ... change.reload() # API request From 5fe9d835f3fec5d095aa8e6147646ac6a31a6782 Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Tue, 15 Sep 2015 12:24:03 -0400 Subject: [PATCH 09/14] Typo. Addresses: https://github.com/GoogleCloudPlatform/gcloud-python/pull/1137#discussion_r39446615 --- docs/dns-usage.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/dns-usage.rst b/docs/dns-usage.rst index cb9fe1c3904d..ee10517284b8 100644 --- a/docs/dns-usage.rst +++ b/docs/dns-usage.rst @@ -177,7 +177,7 @@ List changes made to the resource record set for a given zone: .. note:: The ``page_token`` returned from ``zone.list_changes()`` will be - an opaque string if there are more hcanges than can be returned in a + an opaque string if there are more changes than can be returned in a single request. To enumerate them all, repeat calling - ``zone.list_hcanges()``, passing the ``page_token``, until the token + ``zone.list_changes()``, passing the ``page_token``, until the token is None. From 12c43ceb5be96f1324b89ea66c88b6f95c6c2c36 Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Tue, 15 Sep 2015 12:26:49 -0400 Subject: [PATCH 10/14] Emulate 8ce29a8 for 'list_changes'. --- docs/dns-usage.rst | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/dns-usage.rst b/docs/dns-usage.rst index ee10517284b8..bc2995df38d7 100644 --- a/docs/dns-usage.rst +++ b/docs/dns-usage.rst @@ -180,4 +180,12 @@ List changes made to the resource record set for a given zone: an opaque string if there are more changes than can be returned in a single request. To enumerate them all, repeat calling ``zone.list_changes()``, passing the ``page_token``, until the token - is None. + is ``None``. E.g.: + + .. doctest:: + + >>> changes, page_token = zone.list_changes() # API request + >>> while page_token is not None: + ... next_batch, page_token = zone.list_changes( + ... page_token=page_token) # API request + ... changes.extend(next_batch) From e97aa3b03d25871631d0c0bb06a4d59b852d67af Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Wed, 16 Sep 2015 16:40:31 -0400 Subject: [PATCH 11/14] Omitted word. Addresses: https://github.com/GoogleCloudPlatform/gcloud-python/pull/1137/files#r39584025 --- docs/dns-usage.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dns-usage.rst b/docs/dns-usage.rst index bc2995df38d7..470b47ffbb60 100644 --- a/docs/dns-usage.rst +++ b/docs/dns-usage.rst @@ -4,7 +4,7 @@ Using the API Client ------ -:class:`Client ` objects provide a means +:class:`Client ` objects provide a means to configure your DNS applications. Eash instance holds both a ``project`` and an authenticated connection to the DNS service. From d8a8b2eaef9534fb97b4ef9c899d1f4ea92c293c Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Wed, 16 Sep 2015 16:43:43 -0400 Subject: [PATCH 12/14] Use ':doc:' role to link authentication doc. Addresses: https://github.com/GoogleCloudPlatform/gcloud-python/pull/1137/files#r39583801 --- docs/dns-usage.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/dns-usage.rst b/docs/dns-usage.rst index 470b47ffbb60..750ef8e7f92e 100644 --- a/docs/dns-usage.rst +++ b/docs/dns-usage.rst @@ -8,8 +8,7 @@ Client configure your DNS applications. Eash instance holds both a ``project`` and an authenticated connection to the DNS service. -For an overview of authentication in ``gcloud-python``, see: -http://gcloud-python.readthedocs.org/en/latest/gcloud-auth.html +For an overview of authentication in ``gcloud-python``, see :doc:`gcloud-auth`. Assuming your environment is set up as described in that document, create an instance of :class:`Client `. From 12c12d3e3eb0d988e8726b8cbcb4a259f83b23d2 Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Wed, 16 Sep 2015 16:45:00 -0400 Subject: [PATCH 13/14] Drop alternate client factory exposition. Redundant with the standalone auth doc. Addresses: https://github.com/GoogleCloudPlatform/gcloud-python/pull/1137/files#r39584102 --- docs/dns-usage.rst | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/docs/dns-usage.rst b/docs/dns-usage.rst index 750ef8e7f92e..ca8c88bf522e 100644 --- a/docs/dns-usage.rst +++ b/docs/dns-usage.rst @@ -18,23 +18,6 @@ create an instance of :class:`Client `. >>> from gcloud import dns >>> client = dns.Client() -Override the credentials inferred from the environment by passing explicit -``credentials`` to one of the alternative ``classmethod`` factories, -`:meth:gcloud.dns.client.Client.from_service_account_json`: - - .. doctest:: - - >>> from gcloud import dns - >>> client = dns.Client.from_service_account_json('/path/to/creds.json') - -or `:meth:gcloud.dns.client.Client.from_service_account_p12`: - - .. doctest:: - - >>> from gcloud import dns - >>> client = dns.Client.from_service_account_p12('/path/to/creds.p12', 'jrandom@example.com') - - Projects -------- From abbba333d1ddb725d1609f44d015807adb788bb2 Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Wed, 16 Sep 2015 16:47:30 -0400 Subject: [PATCH 14/14] Fix example syntax for rrdatas. Addresses: https://github.com/GoogleCloudPlatform/gcloud-python/pull/1137/files#r39583968 --- docs/dns-usage.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dns-usage.rst b/docs/dns-usage.rst index ca8c88bf522e..78ec078c4c1e 100644 --- a/docs/dns-usage.rst +++ b/docs/dns-usage.rst @@ -106,7 +106,7 @@ Each managed zone exposes a read-only set of resource records: >>> zone = client.zone('acme-co') >>> records, page_token = zone.list_resources() # API request >>> [(record.name, record.type, record.ttl, record.rrdatas) for record in records] - [('example.com.', 'SOA', 21600, ['ns-cloud1.googlecomains.com dns-admin.google.com 1 21600 3600 1209600 300')]] + [('example.com.', 'SOA', 21600, ['ns-cloud1.googlecomains.com dns-admin.google.com 1 21600 3600 1209600 300'])] .. note::