1# -*- coding: utf-8 -*-
2# Copyright 2022 Google LLC
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16from collections import OrderedDict
17import functools
18import re
19from typing import (
20 Dict,
21 Mapping,
22 MutableMapping,
23 MutableSequence,
24 Optional,
25 Sequence,
26 Tuple,
27 Type,
28 Union,
29)
30
31from google.api_core import exceptions as core_exceptions
32from google.api_core import gapic_v1
33from google.api_core import retry as retries
34from google.api_core.client_options import ClientOptions
35from google.auth import credentials as ga_credentials # type: ignore
36from google.oauth2 import service_account # type: ignore
37
38from google.cloud.resourcemanager_v3 import gapic_version as package_version
39
40try:
41 OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault]
42except AttributeError: # pragma: NO COVER
43 OptionalRetry = Union[retries.Retry, object] # type: ignore
44
45from google.api_core import operation # type: ignore
46from google.api_core import operation_async # type: ignore
47from google.longrunning import operations_pb2
48from google.protobuf import empty_pb2 # type: ignore
49
50from google.cloud.resourcemanager_v3.services.tag_holds import pagers
51from google.cloud.resourcemanager_v3.types import tag_holds
52
53from .client import TagHoldsClient
54from .transports.base import DEFAULT_CLIENT_INFO, TagHoldsTransport
55from .transports.grpc_asyncio import TagHoldsGrpcAsyncIOTransport
56
57
58class TagHoldsAsyncClient:
59 """Allow users to create and manage TagHolds for TagValues.
60 TagHolds represent the use of a Tag Value that is not captured
61 by TagBindings but should still block TagValue deletion (such as
62 a reference in a policy condition). This service provides
63 isolated failure domains by cloud location so that TagHolds can
64 be managed in the same location as their usage.
65 """
66
67 _client: TagHoldsClient
68
69 DEFAULT_ENDPOINT = TagHoldsClient.DEFAULT_ENDPOINT
70 DEFAULT_MTLS_ENDPOINT = TagHoldsClient.DEFAULT_MTLS_ENDPOINT
71
72 tag_hold_path = staticmethod(TagHoldsClient.tag_hold_path)
73 parse_tag_hold_path = staticmethod(TagHoldsClient.parse_tag_hold_path)
74 common_billing_account_path = staticmethod(
75 TagHoldsClient.common_billing_account_path
76 )
77 parse_common_billing_account_path = staticmethod(
78 TagHoldsClient.parse_common_billing_account_path
79 )
80 common_folder_path = staticmethod(TagHoldsClient.common_folder_path)
81 parse_common_folder_path = staticmethod(TagHoldsClient.parse_common_folder_path)
82 common_organization_path = staticmethod(TagHoldsClient.common_organization_path)
83 parse_common_organization_path = staticmethod(
84 TagHoldsClient.parse_common_organization_path
85 )
86 common_project_path = staticmethod(TagHoldsClient.common_project_path)
87 parse_common_project_path = staticmethod(TagHoldsClient.parse_common_project_path)
88 common_location_path = staticmethod(TagHoldsClient.common_location_path)
89 parse_common_location_path = staticmethod(TagHoldsClient.parse_common_location_path)
90
91 @classmethod
92 def from_service_account_info(cls, info: dict, *args, **kwargs):
93 """Creates an instance of this client using the provided credentials
94 info.
95
96 Args:
97 info (dict): The service account private key info.
98 args: Additional arguments to pass to the constructor.
99 kwargs: Additional arguments to pass to the constructor.
100
101 Returns:
102 TagHoldsAsyncClient: The constructed client.
103 """
104 return TagHoldsClient.from_service_account_info.__func__(TagHoldsAsyncClient, info, *args, **kwargs) # type: ignore
105
106 @classmethod
107 def from_service_account_file(cls, filename: str, *args, **kwargs):
108 """Creates an instance of this client using the provided credentials
109 file.
110
111 Args:
112 filename (str): The path to the service account private key json
113 file.
114 args: Additional arguments to pass to the constructor.
115 kwargs: Additional arguments to pass to the constructor.
116
117 Returns:
118 TagHoldsAsyncClient: The constructed client.
119 """
120 return TagHoldsClient.from_service_account_file.__func__(TagHoldsAsyncClient, filename, *args, **kwargs) # type: ignore
121
122 from_service_account_json = from_service_account_file
123
124 @classmethod
125 def get_mtls_endpoint_and_cert_source(
126 cls, client_options: Optional[ClientOptions] = None
127 ):
128 """Return the API endpoint and client cert source for mutual TLS.
129
130 The client cert source is determined in the following order:
131 (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the
132 client cert source is None.
133 (2) if `client_options.client_cert_source` is provided, use the provided one; if the
134 default client cert source exists, use the default one; otherwise the client cert
135 source is None.
136
137 The API endpoint is determined in the following order:
138 (1) if `client_options.api_endpoint` if provided, use the provided one.
139 (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the
140 default mTLS endpoint; if the environment variable is "never", use the default API
141 endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise
142 use the default API endpoint.
143
144 More details can be found at https://google.aip.dev/auth/4114.
145
146 Args:
147 client_options (google.api_core.client_options.ClientOptions): Custom options for the
148 client. Only the `api_endpoint` and `client_cert_source` properties may be used
149 in this method.
150
151 Returns:
152 Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the
153 client cert source to use.
154
155 Raises:
156 google.auth.exceptions.MutualTLSChannelError: If any errors happen.
157 """
158 return TagHoldsClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore
159
160 @property
161 def transport(self) -> TagHoldsTransport:
162 """Returns the transport used by the client instance.
163
164 Returns:
165 TagHoldsTransport: The transport used by the client instance.
166 """
167 return self._client.transport
168
169 get_transport_class = functools.partial(
170 type(TagHoldsClient).get_transport_class, type(TagHoldsClient)
171 )
172
173 def __init__(
174 self,
175 *,
176 credentials: Optional[ga_credentials.Credentials] = None,
177 transport: Union[str, TagHoldsTransport] = "grpc_asyncio",
178 client_options: Optional[ClientOptions] = None,
179 client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
180 ) -> None:
181 """Instantiates the tag holds client.
182
183 Args:
184 credentials (Optional[google.auth.credentials.Credentials]): The
185 authorization credentials to attach to requests. These
186 credentials identify the application to the service; if none
187 are specified, the client will attempt to ascertain the
188 credentials from the environment.
189 transport (Union[str, ~.TagHoldsTransport]): The
190 transport to use. If set to None, a transport is chosen
191 automatically.
192 client_options (ClientOptions): Custom options for the client. It
193 won't take effect if a ``transport`` instance is provided.
194 (1) The ``api_endpoint`` property can be used to override the
195 default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
196 environment variable can also be used to override the endpoint:
197 "always" (always use the default mTLS endpoint), "never" (always
198 use the default regular endpoint) and "auto" (auto switch to the
199 default mTLS endpoint if client certificate is present, this is
200 the default value). However, the ``api_endpoint`` property takes
201 precedence if provided.
202 (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
203 is "true", then the ``client_cert_source`` property can be used
204 to provide client certificate for mutual TLS transport. If
205 not provided, the default SSL client certificate will be used if
206 present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
207 set, no client certificate will be used.
208
209 Raises:
210 google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport
211 creation failed for any reason.
212 """
213 self._client = TagHoldsClient(
214 credentials=credentials,
215 transport=transport,
216 client_options=client_options,
217 client_info=client_info,
218 )
219
220 async def create_tag_hold(
221 self,
222 request: Optional[Union[tag_holds.CreateTagHoldRequest, dict]] = None,
223 *,
224 parent: Optional[str] = None,
225 tag_hold: Optional[tag_holds.TagHold] = None,
226 retry: OptionalRetry = gapic_v1.method.DEFAULT,
227 timeout: Union[float, object] = gapic_v1.method.DEFAULT,
228 metadata: Sequence[Tuple[str, str]] = (),
229 ) -> operation_async.AsyncOperation:
230 r"""Creates a TagHold. Returns ALREADY_EXISTS if a TagHold with the
231 same resource and origin exists under the same TagValue.
232
233 .. code-block:: python
234
235 # This snippet has been automatically generated and should be regarded as a
236 # code template only.
237 # It will require modifications to work:
238 # - It may require correct/in-range values for request initialization.
239 # - It may require specifying regional endpoints when creating the service
240 # client as shown in:
241 # https://googleapis.dev/python/google-api-core/latest/client_options.html
242 from google.cloud import resourcemanager_v3
243
244 async def sample_create_tag_hold():
245 # Create a client
246 client = resourcemanager_v3.TagHoldsAsyncClient()
247
248 # Initialize request argument(s)
249 tag_hold = resourcemanager_v3.TagHold()
250 tag_hold.holder = "holder_value"
251
252 request = resourcemanager_v3.CreateTagHoldRequest(
253 parent="parent_value",
254 tag_hold=tag_hold,
255 )
256
257 # Make the request
258 operation = client.create_tag_hold(request=request)
259
260 print("Waiting for operation to complete...")
261
262 response = (await operation).result()
263
264 # Handle the response
265 print(response)
266
267 Args:
268 request (Optional[Union[google.cloud.resourcemanager_v3.types.CreateTagHoldRequest, dict]]):
269 The request object. The request message to create a
270 TagHold.
271 parent (:class:`str`):
272 Required. The resource name of the TagHold's parent
273 TagValue. Must be of the form:
274 ``tagValues/{tag-value-id}``.
275
276 This corresponds to the ``parent`` field
277 on the ``request`` instance; if ``request`` is provided, this
278 should not be set.
279 tag_hold (:class:`google.cloud.resourcemanager_v3.types.TagHold`):
280 Required. The TagHold to be created.
281 This corresponds to the ``tag_hold`` field
282 on the ``request`` instance; if ``request`` is provided, this
283 should not be set.
284 retry (google.api_core.retry.Retry): Designation of what errors, if any,
285 should be retried.
286 timeout (float): The timeout for this request.
287 metadata (Sequence[Tuple[str, str]]): Strings which should be
288 sent along with the request as metadata.
289
290 Returns:
291 google.api_core.operation_async.AsyncOperation:
292 An object representing a long-running operation.
293
294 The result type for the operation will be :class:`google.cloud.resourcemanager_v3.types.TagHold` A TagHold represents the use of a TagValue that is not captured by
295 TagBindings. If a TagValue has any TagHolds, deletion
296 will be blocked. This resource is intended to be
297 created in the same cloud location as the holder.
298
299 """
300 # Create or coerce a protobuf request object.
301 # Quick check: If we got a request object, we should *not* have
302 # gotten any keyword arguments that map to the request.
303 has_flattened_params = any([parent, tag_hold])
304 if request is not None and has_flattened_params:
305 raise ValueError(
306 "If the `request` argument is set, then none of "
307 "the individual field arguments should be set."
308 )
309
310 request = tag_holds.CreateTagHoldRequest(request)
311
312 # If we have keyword arguments corresponding to fields on the
313 # request, apply these.
314 if parent is not None:
315 request.parent = parent
316 if tag_hold is not None:
317 request.tag_hold = tag_hold
318
319 # Wrap the RPC method; this adds retry and timeout information,
320 # and friendly error handling.
321 rpc = gapic_v1.method_async.wrap_method(
322 self._client._transport.create_tag_hold,
323 default_timeout=None,
324 client_info=DEFAULT_CLIENT_INFO,
325 )
326
327 # Certain fields should be provided within the metadata header;
328 # add these here.
329 metadata = tuple(metadata) + (
330 gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
331 )
332
333 # Send the request.
334 response = await rpc(
335 request,
336 retry=retry,
337 timeout=timeout,
338 metadata=metadata,
339 )
340
341 # Wrap the response in an operation future.
342 response = operation_async.from_gapic(
343 response,
344 self._client._transport.operations_client,
345 tag_holds.TagHold,
346 metadata_type=tag_holds.CreateTagHoldMetadata,
347 )
348
349 # Done; return the response.
350 return response
351
352 async def delete_tag_hold(
353 self,
354 request: Optional[Union[tag_holds.DeleteTagHoldRequest, dict]] = None,
355 *,
356 name: Optional[str] = None,
357 retry: OptionalRetry = gapic_v1.method.DEFAULT,
358 timeout: Union[float, object] = gapic_v1.method.DEFAULT,
359 metadata: Sequence[Tuple[str, str]] = (),
360 ) -> operation_async.AsyncOperation:
361 r"""Deletes a TagHold.
362
363 .. code-block:: python
364
365 # This snippet has been automatically generated and should be regarded as a
366 # code template only.
367 # It will require modifications to work:
368 # - It may require correct/in-range values for request initialization.
369 # - It may require specifying regional endpoints when creating the service
370 # client as shown in:
371 # https://googleapis.dev/python/google-api-core/latest/client_options.html
372 from google.cloud import resourcemanager_v3
373
374 async def sample_delete_tag_hold():
375 # Create a client
376 client = resourcemanager_v3.TagHoldsAsyncClient()
377
378 # Initialize request argument(s)
379 request = resourcemanager_v3.DeleteTagHoldRequest(
380 name="name_value",
381 )
382
383 # Make the request
384 operation = client.delete_tag_hold(request=request)
385
386 print("Waiting for operation to complete...")
387
388 response = (await operation).result()
389
390 # Handle the response
391 print(response)
392
393 Args:
394 request (Optional[Union[google.cloud.resourcemanager_v3.types.DeleteTagHoldRequest, dict]]):
395 The request object. The request message to delete a
396 TagHold.
397 name (:class:`str`):
398 Required. The resource name of the TagHold to delete.
399 Must be of the form:
400 ``tagValues/{tag-value-id}/tagHolds/{tag-hold-id}``.
401
402 This corresponds to the ``name`` field
403 on the ``request`` instance; if ``request`` is provided, this
404 should not be set.
405 retry (google.api_core.retry.Retry): Designation of what errors, if any,
406 should be retried.
407 timeout (float): The timeout for this request.
408 metadata (Sequence[Tuple[str, str]]): Strings which should be
409 sent along with the request as metadata.
410
411 Returns:
412 google.api_core.operation_async.AsyncOperation:
413 An object representing a long-running operation.
414
415 The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated
416 empty messages in your APIs. A typical example is to
417 use it as the request or the response type of an API
418 method. For instance:
419
420 service Foo {
421 rpc Bar(google.protobuf.Empty) returns
422 (google.protobuf.Empty);
423
424 }
425
426 """
427 # Create or coerce a protobuf request object.
428 # Quick check: If we got a request object, we should *not* have
429 # gotten any keyword arguments that map to the request.
430 has_flattened_params = any([name])
431 if request is not None and has_flattened_params:
432 raise ValueError(
433 "If the `request` argument is set, then none of "
434 "the individual field arguments should be set."
435 )
436
437 request = tag_holds.DeleteTagHoldRequest(request)
438
439 # If we have keyword arguments corresponding to fields on the
440 # request, apply these.
441 if name is not None:
442 request.name = name
443
444 # Wrap the RPC method; this adds retry and timeout information,
445 # and friendly error handling.
446 rpc = gapic_v1.method_async.wrap_method(
447 self._client._transport.delete_tag_hold,
448 default_timeout=None,
449 client_info=DEFAULT_CLIENT_INFO,
450 )
451
452 # Certain fields should be provided within the metadata header;
453 # add these here.
454 metadata = tuple(metadata) + (
455 gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
456 )
457
458 # Send the request.
459 response = await rpc(
460 request,
461 retry=retry,
462 timeout=timeout,
463 metadata=metadata,
464 )
465
466 # Wrap the response in an operation future.
467 response = operation_async.from_gapic(
468 response,
469 self._client._transport.operations_client,
470 empty_pb2.Empty,
471 metadata_type=tag_holds.DeleteTagHoldMetadata,
472 )
473
474 # Done; return the response.
475 return response
476
477 async def list_tag_holds(
478 self,
479 request: Optional[Union[tag_holds.ListTagHoldsRequest, dict]] = None,
480 *,
481 parent: Optional[str] = None,
482 retry: OptionalRetry = gapic_v1.method.DEFAULT,
483 timeout: Union[float, object] = gapic_v1.method.DEFAULT,
484 metadata: Sequence[Tuple[str, str]] = (),
485 ) -> pagers.ListTagHoldsAsyncPager:
486 r"""Lists TagHolds under a TagValue.
487
488 .. code-block:: python
489
490 # This snippet has been automatically generated and should be regarded as a
491 # code template only.
492 # It will require modifications to work:
493 # - It may require correct/in-range values for request initialization.
494 # - It may require specifying regional endpoints when creating the service
495 # client as shown in:
496 # https://googleapis.dev/python/google-api-core/latest/client_options.html
497 from google.cloud import resourcemanager_v3
498
499 async def sample_list_tag_holds():
500 # Create a client
501 client = resourcemanager_v3.TagHoldsAsyncClient()
502
503 # Initialize request argument(s)
504 request = resourcemanager_v3.ListTagHoldsRequest(
505 parent="parent_value",
506 )
507
508 # Make the request
509 page_result = client.list_tag_holds(request=request)
510
511 # Handle the response
512 async for response in page_result:
513 print(response)
514
515 Args:
516 request (Optional[Union[google.cloud.resourcemanager_v3.types.ListTagHoldsRequest, dict]]):
517 The request object. The request message for listing the
518 TagHolds under a TagValue.
519 parent (:class:`str`):
520 Required. The resource name of the parent TagValue. Must
521 be of the form: ``tagValues/{tag-value-id}``.
522
523 This corresponds to the ``parent`` field
524 on the ``request`` instance; if ``request`` is provided, this
525 should not be set.
526 retry (google.api_core.retry.Retry): Designation of what errors, if any,
527 should be retried.
528 timeout (float): The timeout for this request.
529 metadata (Sequence[Tuple[str, str]]): Strings which should be
530 sent along with the request as metadata.
531
532 Returns:
533 google.cloud.resourcemanager_v3.services.tag_holds.pagers.ListTagHoldsAsyncPager:
534 The ListTagHolds response.
535 Iterating over this object will yield
536 results and resolve additional pages
537 automatically.
538
539 """
540 # Create or coerce a protobuf request object.
541 # Quick check: If we got a request object, we should *not* have
542 # gotten any keyword arguments that map to the request.
543 has_flattened_params = any([parent])
544 if request is not None and has_flattened_params:
545 raise ValueError(
546 "If the `request` argument is set, then none of "
547 "the individual field arguments should be set."
548 )
549
550 request = tag_holds.ListTagHoldsRequest(request)
551
552 # If we have keyword arguments corresponding to fields on the
553 # request, apply these.
554 if parent is not None:
555 request.parent = parent
556
557 # Wrap the RPC method; this adds retry and timeout information,
558 # and friendly error handling.
559 rpc = gapic_v1.method_async.wrap_method(
560 self._client._transport.list_tag_holds,
561 default_timeout=None,
562 client_info=DEFAULT_CLIENT_INFO,
563 )
564
565 # Certain fields should be provided within the metadata header;
566 # add these here.
567 metadata = tuple(metadata) + (
568 gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
569 )
570
571 # Send the request.
572 response = await rpc(
573 request,
574 retry=retry,
575 timeout=timeout,
576 metadata=metadata,
577 )
578
579 # This method is paged; wrap the response in a pager, which provides
580 # an `__aiter__` convenience method.
581 response = pagers.ListTagHoldsAsyncPager(
582 method=rpc,
583 request=request,
584 response=response,
585 metadata=metadata,
586 )
587
588 # Done; return the response.
589 return response
590
591 async def get_operation(
592 self,
593 request: Optional[operations_pb2.GetOperationRequest] = None,
594 *,
595 retry: OptionalRetry = gapic_v1.method.DEFAULT,
596 timeout: Union[float, object] = gapic_v1.method.DEFAULT,
597 metadata: Sequence[Tuple[str, str]] = (),
598 ) -> operations_pb2.Operation:
599 r"""Gets the latest state of a long-running operation.
600
601 Args:
602 request (:class:`~.operations_pb2.GetOperationRequest`):
603 The request object. Request message for
604 `GetOperation` method.
605 retry (google.api_core.retry.Retry): Designation of what errors,
606 if any, should be retried.
607 timeout (float): The timeout for this request.
608 metadata (Sequence[Tuple[str, str]]): Strings which should be
609 sent along with the request as metadata.
610 Returns:
611 ~.operations_pb2.Operation:
612 An ``Operation`` object.
613 """
614 # Create or coerce a protobuf request object.
615 # The request isn't a proto-plus wrapped type,
616 # so it must be constructed via keyword expansion.
617 if isinstance(request, dict):
618 request = operations_pb2.GetOperationRequest(**request)
619
620 # Wrap the RPC method; this adds retry and timeout information,
621 # and friendly error handling.
622 rpc = gapic_v1.method.wrap_method(
623 self._client._transport.get_operation,
624 default_timeout=None,
625 client_info=DEFAULT_CLIENT_INFO,
626 )
627
628 # Certain fields should be provided within the metadata header;
629 # add these here.
630 metadata = tuple(metadata) + (
631 gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
632 )
633
634 # Send the request.
635 response = await rpc(
636 request,
637 retry=retry,
638 timeout=timeout,
639 metadata=metadata,
640 )
641
642 # Done; return the response.
643 return response
644
645 async def __aenter__(self):
646 return self
647
648 async def __aexit__(self, exc_type, exc, tb):
649 await self.transport.close()
650
651
652DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
653 gapic_version=package_version.__version__
654)
655
656
657__all__ = ("TagHoldsAsyncClient",)