Skip to content

Commit 3f42c3c

Browse files
feat: add iam methods to templates (googleapis#545)
* feat: add iam methods to templates * fix: fix typo * chore: fix formatting * fix: fix ref to option * chore(deps): add iam dependency * chore: add circleci * chore: take 2 * chore: only test with 3.8 Co-authored-by: Dov Shlachter <dovs@google.com>
1 parent bbc6b36 commit 3f42c3c

12 files changed

Lines changed: 1227 additions & 1 deletion

File tree

.circleci/config.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,14 @@ workflows:
6868
filters:
6969
tags:
7070
only: /^v\d+\.\d+\.\d+$/
71+
- showcase-unit-add-iam-methods:
72+
requires:
73+
- unit-3.6
74+
- unit-3.7
75+
- unit-3.8
76+
filters:
77+
tags:
78+
only: /^v\d+\.\d+\.\d+$/
7179
- showcase-mypy:
7280
requires:
7381
- mypy
@@ -502,6 +510,30 @@ jobs:
502510
- run:
503511
name: Run unit tests.
504512
command: nox -s showcase_unit_alternative_templates-3.8
513+
showcase-unit-add-iam-methods:
514+
docker:
515+
- image: python:3.8-slim
516+
steps:
517+
- checkout
518+
- run:
519+
name: Install system dependencies.
520+
command: |
521+
apt-get update
522+
apt-get install -y curl pandoc unzip
523+
- run:
524+
name: Install protoc 3.12.1.
525+
command: |
526+
mkdir -p /usr/src/protoc/
527+
curl --location https://github.com/google/protobuf/releases/download/v3.12.1/protoc-3.12.1-linux-x86_64.zip --output /usr/src/protoc/protoc-3.12.1.zip
528+
cd /usr/src/protoc/
529+
unzip protoc-3.12.1.zip
530+
ln -s /usr/src/protoc/bin/protoc /usr/local/bin/protoc
531+
- run:
532+
name: Install nox.
533+
command: pip install nox
534+
- run:
535+
name: Run unit tests.
536+
command: nox -s showcase_unit_add_iam_methods-3.8
505537
showcase-mypy:
506538
docker:
507539
- image: python:3.8-slim

gapic/generator/options.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class Options:
3939
templates: Tuple[str, ...] = dataclasses.field(default=('DEFAULT',))
4040
lazy_import: bool = False
4141
old_naming: bool = False
42+
add_iam_methods: bool = False
4243

4344
# Class constants
4445
PYTHON_GAPIC_PREFIX: str = 'python-gapic-'
@@ -47,6 +48,7 @@ class Options:
4748
'retry-config', # takes a path
4849
'samples', # output dir
4950
'lazy-import', # requires >= 3.7
51+
'add-iam-methods', # microgenerator implementation for `reroute_to_grpc_interface`
5052
))
5153

5254
@classmethod
@@ -131,6 +133,7 @@ def tweak_path(p):
131133
templates=tuple(path.expanduser(i) for i in templates),
132134
lazy_import=bool(opts.pop('lazy-import', False)),
133135
old_naming=bool(opts.pop('old-naming', False)),
136+
add_iam_methods=bool(opts.pop('add-iam-methods', False)),
134137
)
135138

136139
# Note: if we ever need to recursively check directories for sample

gapic/templates/%namespace/%name_%version/%sub/services/%service/async_client.py.j2

Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ from google.oauth2 import service_account # type: ignore
2020
{{ ref_type.ident.python_import }}
2121
{% endfor -%}
2222
{% endfor -%}
23+
{% if opts.add_iam_methods %}
24+
from google.iam.v1 import iam_policy_pb2 as iam_policy # type: ignore
25+
from google.iam.v1 import policy_pb2 as policy # type: ignore
26+
{% endif %}
2327
{% endfilter %}
2428
from .transports.base import {{ service.name }}Transport
2529
from .transports.grpc_asyncio import {{ service.grpc_asyncio_transport_name }}
@@ -256,6 +260,272 @@ class {{ service.async_client_name }}:
256260
{% endfor %}
257261

258262

263+
{% if opts.add_iam_methods %}
264+
async def set_iam_policy(
265+
self,
266+
request: iam_policy.SetIamPolicyRequest = None,
267+
*,
268+
retry: retries.Retry = gapic_v1.method.DEFAULT,
269+
timeout: float = None,
270+
metadata: Sequence[Tuple[str, str]] = (),
271+
) -> policy.Policy:
272+
r"""Sets the IAM access control policy on the specified
273+
function. Replaces any existing policy.
274+
Args:
275+
request (:class:`~.iam_policy.SetIamPolicyRequest`):
276+
The request object. Request message for `SetIamPolicy`
277+
method.
278+
retry (google.api_core.retry.Retry): Designation of what errors, if any,
279+
should be retried.
280+
timeout (float): The timeout for this request.
281+
metadata (Sequence[Tuple[str, str]]): Strings which should be
282+
sent along with the request as metadata.
283+
Returns:
284+
~.policy.Policy:
285+
Defines an Identity and Access Management (IAM) policy.
286+
It is used to specify access control policies for Cloud
287+
Platform resources.
288+
A ``Policy`` is a collection of ``bindings``. A
289+
``binding`` binds one or more ``members`` to a single
290+
``role``. Members can be user accounts, service
291+
accounts, Google groups, and domains (such as G Suite).
292+
A ``role`` is a named list of permissions (defined by
293+
IAM or configured by users). A ``binding`` can
294+
optionally specify a ``condition``, which is a logic
295+
expression that further constrains the role binding
296+
based on attributes about the request and/or target
297+
resource.
298+
**JSON Example**
299+
::
300+
{
301+
"bindings": [
302+
{
303+
"role": "roles/resourcemanager.organizationAdmin",
304+
"members": [
305+
"user:mike@example.com",
306+
"group:admins@example.com",
307+
"domain:google.com",
308+
"serviceAccount:my-project-id@appspot.gserviceaccount.com"
309+
]
310+
},
311+
{
312+
"role": "roles/resourcemanager.organizationViewer",
313+
"members": ["user:eve@example.com"],
314+
"condition": {
315+
"title": "expirable access",
316+
"description": "Does not grant access after Sep 2020",
317+
"expression": "request.time <
318+
timestamp('2020-10-01T00:00:00.000Z')",
319+
}
320+
}
321+
]
322+
}
323+
**YAML Example**
324+
::
325+
bindings:
326+
- members:
327+
- user:mike@example.com
328+
- group:admins@example.com
329+
- domain:google.com
330+
- serviceAccount:my-project-id@appspot.gserviceaccount.com
331+
role: roles/resourcemanager.organizationAdmin
332+
- members:
333+
- user:eve@example.com
334+
role: roles/resourcemanager.organizationViewer
335+
condition:
336+
title: expirable access
337+
description: Does not grant access after Sep 2020
338+
expression: request.time < timestamp('2020-10-01T00:00:00.000Z')
339+
For a description of IAM and its features, see the `IAM
340+
developer's
341+
guide <https://cloud.google.com/iam/docs>`__.
342+
"""
343+
# Create or coerce a protobuf request object.
344+
345+
# The request isn't a proto-plus wrapped type,
346+
# so it must be constructed via keyword expansion.
347+
if isinstance(request, dict):
348+
request = iam_policy.SetIamPolicyRequest(**request)
349+
350+
# Wrap the RPC method; this adds retry and timeout information,
351+
# and friendly error handling.
352+
rpc = gapic_v1.method_async.wrap_method(
353+
self._client._transport.set_iam_policy,
354+
default_timeout=None,
355+
client_info=_client_info,
356+
)
357+
358+
# Certain fields should be provided within the metadata header;
359+
# add these here.
360+
metadata = tuple(metadata) + (
361+
gapic_v1.routing_header.to_grpc_metadata((("resource", request.resource),)),
362+
)
363+
364+
# Send the request.
365+
response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
366+
367+
# Done; return the response.
368+
return response
369+
370+
async def get_iam_policy(
371+
self,
372+
request: iam_policy.GetIamPolicyRequest = None,
373+
*,
374+
retry: retries.Retry = gapic_v1.method.DEFAULT,
375+
timeout: float = None,
376+
metadata: Sequence[Tuple[str, str]] = (),
377+
) -> policy.Policy:
378+
r"""Gets the IAM access control policy for a function.
379+
Returns an empty policy if the function exists and does
380+
not have a policy set.
381+
Args:
382+
request (:class:`~.iam_policy.GetIamPolicyRequest`):
383+
The request object. Request message for `GetIamPolicy`
384+
method.
385+
retry (google.api_core.retry.Retry): Designation of what errors, if any,
386+
should be retried.
387+
timeout (float): The timeout for this request.
388+
metadata (Sequence[Tuple[str, str]]): Strings which should be
389+
sent along with the request as metadata.
390+
Returns:
391+
~.policy.Policy:
392+
Defines an Identity and Access Management (IAM) policy.
393+
It is used to specify access control policies for Cloud
394+
Platform resources.
395+
A ``Policy`` is a collection of ``bindings``. A
396+
``binding`` binds one or more ``members`` to a single
397+
``role``. Members can be user accounts, service
398+
accounts, Google groups, and domains (such as G Suite).
399+
A ``role`` is a named list of permissions (defined by
400+
IAM or configured by users). A ``binding`` can
401+
optionally specify a ``condition``, which is a logic
402+
expression that further constrains the role binding
403+
based on attributes about the request and/or target
404+
resource.
405+
**JSON Example**
406+
::
407+
{
408+
"bindings": [
409+
{
410+
"role": "roles/resourcemanager.organizationAdmin",
411+
"members": [
412+
"user:mike@example.com",
413+
"group:admins@example.com",
414+
"domain:google.com",
415+
"serviceAccount:my-project-id@appspot.gserviceaccount.com"
416+
]
417+
},
418+
{
419+
"role": "roles/resourcemanager.organizationViewer",
420+
"members": ["user:eve@example.com"],
421+
"condition": {
422+
"title": "expirable access",
423+
"description": "Does not grant access after Sep 2020",
424+
"expression": "request.time <
425+
timestamp('2020-10-01T00:00:00.000Z')",
426+
}
427+
}
428+
]
429+
}
430+
**YAML Example**
431+
::
432+
bindings:
433+
- members:
434+
- user:mike@example.com
435+
- group:admins@example.com
436+
- domain:google.com
437+
- serviceAccount:my-project-id@appspot.gserviceaccount.com
438+
role: roles/resourcemanager.organizationAdmin
439+
- members:
440+
- user:eve@example.com
441+
role: roles/resourcemanager.organizationViewer
442+
condition:
443+
title: expirable access
444+
description: Does not grant access after Sep 2020
445+
expression: request.time < timestamp('2020-10-01T00:00:00.000Z')
446+
For a description of IAM and its features, see the `IAM
447+
developer's
448+
guide <https://cloud.google.com/iam/docs>`__.
449+
"""
450+
# Create or coerce a protobuf request object.
451+
452+
# The request isn't a proto-plus wrapped type,
453+
# so it must be constructed via keyword expansion.
454+
if isinstance(request, dict):
455+
request = iam_policy.GetIamPolicyRequest(**request)
456+
457+
# Wrap the RPC method; this adds retry and timeout information,
458+
# and friendly error handling.
459+
rpc = gapic_v1.method_async.wrap_method(
460+
self._client._transport.get_iam_policy,
461+
default_timeout=None,
462+
client_info=_client_info,
463+
)
464+
465+
# Certain fields should be provided within the metadata header;
466+
# add these here.
467+
metadata = tuple(metadata) + (
468+
gapic_v1.routing_header.to_grpc_metadata((("resource", request.resource),)),
469+
)
470+
471+
# Send the request.
472+
response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
473+
474+
# Done; return the response.
475+
return response
476+
477+
async def test_iam_permissions(
478+
self,
479+
request: iam_policy.TestIamPermissionsRequest = None,
480+
*,
481+
retry: retries.Retry = gapic_v1.method.DEFAULT,
482+
timeout: float = None,
483+
metadata: Sequence[Tuple[str, str]] = (),
484+
) -> iam_policy.TestIamPermissionsResponse:
485+
r"""Tests the specified permissions against the IAM access control
486+
policy for a function. If the function does not exist, this will
487+
return an empty set of permissions, not a NOT_FOUND error.
488+
Args:
489+
request (:class:`~.iam_policy.TestIamPermissionsRequest`):
490+
The request object. Request message for
491+
`TestIamPermissions` method.
492+
retry (google.api_core.retry.Retry): Designation of what errors, if any,
493+
should be retried.
494+
timeout (float): The timeout for this request.
495+
metadata (Sequence[Tuple[str, str]]): Strings which should be
496+
sent along with the request as metadata.
497+
Returns:
498+
~.iam_policy.TestIamPermissionsResponse:
499+
Response message for ``TestIamPermissions`` method.
500+
"""
501+
# Create or coerce a protobuf request object.
502+
503+
# The request isn't a proto-plus wrapped type,
504+
# so it must be constructed via keyword expansion.
505+
if isinstance(request, dict):
506+
request = iam_policy.TestIamPermissionsRequest(**request)
507+
508+
# Wrap the RPC method; this adds retry and timeout information,
509+
# and friendly error handling.
510+
rpc = gapic_v1.method_async.wrap_method(
511+
self._client._transport.test_iam_permissions,
512+
default_timeout=None,
513+
client_info=_client_info,
514+
)
515+
516+
# Certain fields should be provided within the metadata header;
517+
# add these here.
518+
metadata = tuple(metadata) + (
519+
gapic_v1.routing_header.to_grpc_metadata((("resource", request.resource),)),
520+
)
521+
522+
# Send the request.
523+
response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
524+
525+
# Done; return the response.
526+
return response
527+
{% endif %}
528+
259529
try:
260530
_client_info = gapic_v1.client_info.ClientInfo(
261531
gapic_version=pkg_resources.get_distribution(

0 commit comments

Comments
 (0)