diff --git a/packages/google-cloud-kms/docs/kms_v1/autokey.rst b/packages/google-cloud-kms/docs/kms_v1/autokey.rst index 2335ac5e9da8..266646a17c28 100644 --- a/packages/google-cloud-kms/docs/kms_v1/autokey.rst +++ b/packages/google-cloud-kms/docs/kms_v1/autokey.rst @@ -4,3 +4,7 @@ Autokey .. automodule:: google.cloud.kms_v1.services.autokey :members: :inherited-members: + +.. automodule:: google.cloud.kms_v1.services.autokey.pagers + :members: + :inherited-members: diff --git a/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey/async_client.py b/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey/async_client.py index 6f5a61fc292d..e79da53a08e6 100644 --- a/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey/async_client.py +++ b/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey/async_client.py @@ -49,6 +49,7 @@ from google.iam.v1 import policy_pb2 # type: ignore from google.longrunning import operations_pb2 # type: ignore +from google.cloud.kms_v1.services.autokey import pagers from google.cloud.kms_v1.types import autokey from .client import AutokeyClient @@ -57,8 +58,9 @@ class AutokeyAsyncClient: - """Provides interfaces for using Cloud KMS Autokey to provision new - [CryptoKeys][google.cloud.kms.v1.CryptoKey], ready for Customer + """Provides interfaces for using `Cloud KMS + Autokey `__ to provision + new [CryptoKeys][google.cloud.kms.v1.CryptoKey], ready for Customer Managed Encryption Key (CMEK) use, on-demand. To support certain client tooling, this feature is modeled around a [KeyHandle][google.cloud.kms.v1.KeyHandle] resource: creating a @@ -544,7 +546,7 @@ async def list_key_handles( retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, str]] = (), - ) -> autokey.ListKeyHandlesResponse: + ) -> pagers.ListKeyHandlesAsyncPager: r"""Lists [KeyHandles][google.cloud.kms.v1.KeyHandle]. .. code-block:: python @@ -568,10 +570,11 @@ async def sample_list_key_handles(): ) # Make the request - response = await client.list_key_handles(request=request) + page_result = client.list_key_handles(request=request) # Handle the response - print(response) + async for response in page_result: + print(response) Args: request (Optional[Union[google.cloud.kms_v1.types.ListKeyHandlesRequest, dict]]): @@ -593,10 +596,13 @@ async def sample_list_key_handles(): sent along with the request as metadata. Returns: - google.cloud.kms_v1.types.ListKeyHandlesResponse: + google.cloud.kms_v1.services.autokey.pagers.ListKeyHandlesAsyncPager: Response message for [Autokey.ListKeyHandles][google.cloud.kms.v1.Autokey.ListKeyHandles]. + Iterating over this object will yield results and + resolve additional pages automatically. + """ # Create or coerce a protobuf request object. # - Quick check: If we got a request object, we should *not* have @@ -641,6 +647,17 @@ async def sample_list_key_handles(): metadata=metadata, ) + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListKeyHandlesAsyncPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + # Done; return the response. return response @@ -855,6 +872,7 @@ async def set_iam_policy( **JSON Example** :: + { "bindings": [ { diff --git a/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey/client.py b/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey/client.py index e17e6a6fb76e..8656ffb6a4db 100644 --- a/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey/client.py +++ b/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey/client.py @@ -55,6 +55,7 @@ from google.iam.v1 import policy_pb2 # type: ignore from google.longrunning import operations_pb2 # type: ignore +from google.cloud.kms_v1.services.autokey import pagers from google.cloud.kms_v1.types import autokey from .transports.base import DEFAULT_CLIENT_INFO, AutokeyTransport @@ -99,8 +100,9 @@ def get_transport_class( class AutokeyClient(metaclass=AutokeyClientMeta): - """Provides interfaces for using Cloud KMS Autokey to provision new - [CryptoKeys][google.cloud.kms.v1.CryptoKey], ready for Customer + """Provides interfaces for using `Cloud KMS + Autokey `__ to provision + new [CryptoKeys][google.cloud.kms.v1.CryptoKey], ready for Customer Managed Encryption Key (CMEK) use, on-demand. To support certain client tooling, this feature is modeled around a [KeyHandle][google.cloud.kms.v1.KeyHandle] resource: creating a @@ -986,7 +988,7 @@ def list_key_handles( retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, str]] = (), - ) -> autokey.ListKeyHandlesResponse: + ) -> pagers.ListKeyHandlesPager: r"""Lists [KeyHandles][google.cloud.kms.v1.KeyHandle]. .. code-block:: python @@ -1010,10 +1012,11 @@ def sample_list_key_handles(): ) # Make the request - response = client.list_key_handles(request=request) + page_result = client.list_key_handles(request=request) # Handle the response - print(response) + for response in page_result: + print(response) Args: request (Union[google.cloud.kms_v1.types.ListKeyHandlesRequest, dict]): @@ -1035,10 +1038,13 @@ def sample_list_key_handles(): sent along with the request as metadata. Returns: - google.cloud.kms_v1.types.ListKeyHandlesResponse: + google.cloud.kms_v1.services.autokey.pagers.ListKeyHandlesPager: Response message for [Autokey.ListKeyHandles][google.cloud.kms.v1.Autokey.ListKeyHandles]. + Iterating over this object will yield results and + resolve additional pages automatically. + """ # Create or coerce a protobuf request object. # - Quick check: If we got a request object, we should *not* have @@ -1080,6 +1086,17 @@ def sample_list_key_handles(): metadata=metadata, ) + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListKeyHandlesPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + # Done; return the response. return response diff --git a/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey/pagers.py b/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey/pagers.py new file mode 100644 index 000000000000..5ba18404a1ec --- /dev/null +++ b/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey/pagers.py @@ -0,0 +1,193 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# 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. +# +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Iterator, + Optional, + Sequence, + Tuple, + Union, +) + +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import retry_async as retries_async + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] + OptionalAsyncRetry = Union[ + retries_async.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + OptionalAsyncRetry = Union[retries_async.AsyncRetry, object, None] # type: ignore + +from google.cloud.kms_v1.types import autokey + + +class ListKeyHandlesPager: + """A pager for iterating through ``list_key_handles`` requests. + + This class thinly wraps an initial + :class:`google.cloud.kms_v1.types.ListKeyHandlesResponse` object, and + provides an ``__iter__`` method to iterate through its + ``key_handles`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListKeyHandles`` requests and continue to iterate + through the ``key_handles`` field on the + corresponding responses. + + All the usual :class:`google.cloud.kms_v1.types.ListKeyHandlesResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[..., autokey.ListKeyHandlesResponse], + request: autokey.ListKeyHandlesRequest, + response: autokey.ListKeyHandlesResponse, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.kms_v1.types.ListKeyHandlesRequest): + The initial request object. + response (google.cloud.kms_v1.types.ListKeyHandlesResponse): + The initial response object. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = autokey.ListKeyHandlesRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[autokey.ListKeyHandlesResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method( + self._request, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __iter__(self) -> Iterator[autokey.KeyHandle]: + for page in self.pages: + yield from page.key_handles + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListKeyHandlesAsyncPager: + """A pager for iterating through ``list_key_handles`` requests. + + This class thinly wraps an initial + :class:`google.cloud.kms_v1.types.ListKeyHandlesResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``key_handles`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListKeyHandles`` requests and continue to iterate + through the ``key_handles`` field on the + corresponding responses. + + All the usual :class:`google.cloud.kms_v1.types.ListKeyHandlesResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[..., Awaitable[autokey.ListKeyHandlesResponse]], + request: autokey.ListKeyHandlesRequest, + response: autokey.ListKeyHandlesResponse, + *, + retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.kms_v1.types.ListKeyHandlesRequest): + The initial request object. + response (google.cloud.kms_v1.types.ListKeyHandlesResponse): + The initial response object. + retry (google.api_core.retry.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = autokey.ListKeyHandlesRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[autokey.ListKeyHandlesResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method( + self._request, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __aiter__(self) -> AsyncIterator[autokey.KeyHandle]: + async def async_generator(): + async for page in self.pages: + for response in page.key_handles: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey/transports/grpc.py b/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey/transports/grpc.py index daf4f02878d3..e248c23a9c2f 100644 --- a/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey/transports/grpc.py +++ b/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey/transports/grpc.py @@ -34,8 +34,9 @@ class AutokeyGrpcTransport(AutokeyTransport): """gRPC backend transport for Autokey. - Provides interfaces for using Cloud KMS Autokey to provision new - [CryptoKeys][google.cloud.kms.v1.CryptoKey], ready for Customer + Provides interfaces for using `Cloud KMS + Autokey `__ to provision + new [CryptoKeys][google.cloud.kms.v1.CryptoKey], ready for Customer Managed Encryption Key (CMEK) use, on-demand. To support certain client tooling, this feature is modeled around a [KeyHandle][google.cloud.kms.v1.KeyHandle] resource: creating a diff --git a/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey/transports/grpc_asyncio.py b/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey/transports/grpc_asyncio.py index 0028a1b6eb14..efd29a509e7f 100644 --- a/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey/transports/grpc_asyncio.py +++ b/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey/transports/grpc_asyncio.py @@ -37,8 +37,9 @@ class AutokeyGrpcAsyncIOTransport(AutokeyTransport): """gRPC AsyncIO backend transport for Autokey. - Provides interfaces for using Cloud KMS Autokey to provision new - [CryptoKeys][google.cloud.kms.v1.CryptoKey], ready for Customer + Provides interfaces for using `Cloud KMS + Autokey `__ to provision + new [CryptoKeys][google.cloud.kms.v1.CryptoKey], ready for Customer Managed Encryption Key (CMEK) use, on-demand. To support certain client tooling, this feature is modeled around a [KeyHandle][google.cloud.kms.v1.KeyHandle] resource: creating a diff --git a/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey/transports/rest.py b/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey/transports/rest.py index d53e8639b8d9..2d9832d218dc 100644 --- a/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey/transports/rest.py +++ b/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey/transports/rest.py @@ -316,8 +316,9 @@ class AutokeyRestStub: class AutokeyRestTransport(AutokeyTransport): """REST backend transport for Autokey. - Provides interfaces for using Cloud KMS Autokey to provision new - [CryptoKeys][google.cloud.kms.v1.CryptoKey], ready for Customer + Provides interfaces for using `Cloud KMS + Autokey `__ to provision + new [CryptoKeys][google.cloud.kms.v1.CryptoKey], ready for Customer Managed Encryption Key (CMEK) use, on-demand. To support certain client tooling, this feature is modeled around a [KeyHandle][google.cloud.kms.v1.KeyHandle] resource: creating a diff --git a/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey_admin/async_client.py b/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey_admin/async_client.py index 6c285d379502..af84851a3916 100644 --- a/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey_admin/async_client.py +++ b/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey_admin/async_client.py @@ -56,7 +56,8 @@ class AutokeyAdminAsyncClient: - """Provides interfaces for managing Cloud KMS Autokey folder-level + """Provides interfaces for managing `Cloud KMS + Autokey `__ folder-level configurations. A configuration is inherited by all descendent projects. A configuration at one folder overrides any other configurations in its ancestry. Setting a configuration on a folder @@ -825,6 +826,7 @@ async def set_iam_policy( **JSON Example** :: + { "bindings": [ { diff --git a/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey_admin/client.py b/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey_admin/client.py index ea8aa35437b3..9d2044169727 100644 --- a/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey_admin/client.py +++ b/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey_admin/client.py @@ -98,7 +98,8 @@ def get_transport_class( class AutokeyAdminClient(metaclass=AutokeyAdminClientMeta): - """Provides interfaces for managing Cloud KMS Autokey folder-level + """Provides interfaces for managing `Cloud KMS + Autokey `__ folder-level configurations. A configuration is inherited by all descendent projects. A configuration at one folder overrides any other configurations in its ancestry. Setting a configuration on a folder diff --git a/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey_admin/transports/grpc.py b/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey_admin/transports/grpc.py index 1b7ac8d3dc43..6ee4354598fb 100644 --- a/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey_admin/transports/grpc.py +++ b/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey_admin/transports/grpc.py @@ -34,7 +34,8 @@ class AutokeyAdminGrpcTransport(AutokeyAdminTransport): """gRPC backend transport for AutokeyAdmin. - Provides interfaces for managing Cloud KMS Autokey folder-level + Provides interfaces for managing `Cloud KMS + Autokey `__ folder-level configurations. A configuration is inherited by all descendent projects. A configuration at one folder overrides any other configurations in its ancestry. Setting a configuration on a folder diff --git a/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey_admin/transports/grpc_asyncio.py b/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey_admin/transports/grpc_asyncio.py index b1c8dfa31ad4..f6fcb383e2f5 100644 --- a/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey_admin/transports/grpc_asyncio.py +++ b/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey_admin/transports/grpc_asyncio.py @@ -37,7 +37,8 @@ class AutokeyAdminGrpcAsyncIOTransport(AutokeyAdminTransport): """gRPC AsyncIO backend transport for AutokeyAdmin. - Provides interfaces for managing Cloud KMS Autokey folder-level + Provides interfaces for managing `Cloud KMS + Autokey `__ folder-level configurations. A configuration is inherited by all descendent projects. A configuration at one folder overrides any other configurations in its ancestry. Setting a configuration on a folder diff --git a/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey_admin/transports/rest.py b/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey_admin/transports/rest.py index a6b03e22c972..e8affeb02ab6 100644 --- a/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey_admin/transports/rest.py +++ b/packages/google-cloud-kms/google/cloud/kms_v1/services/autokey_admin/transports/rest.py @@ -316,7 +316,8 @@ class AutokeyAdminRestStub: class AutokeyAdminRestTransport(AutokeyAdminTransport): """REST backend transport for AutokeyAdmin. - Provides interfaces for managing Cloud KMS Autokey folder-level + Provides interfaces for managing `Cloud KMS + Autokey `__ folder-level configurations. A configuration is inherited by all descendent projects. A configuration at one folder overrides any other configurations in its ancestry. Setting a configuration on a folder diff --git a/packages/google-cloud-kms/google/cloud/kms_v1/types/autokey.py b/packages/google-cloud-kms/google/cloud/kms_v1/types/autokey.py index 3a5e93a32f61..f94b8284eeb5 100644 --- a/packages/google-cloud-kms/google/cloud/kms_v1/types/autokey.py +++ b/packages/google-cloud-kms/google/cloud/kms_v1/types/autokey.py @@ -145,6 +145,19 @@ class ListKeyHandlesRequest(proto.Message): Required. Name of the resource project and location from which to list [KeyHandles][google.cloud.kms.v1.KeyHandle], e.g. ``projects/{PROJECT_ID}/locations/{LOCATION}``. + page_size (int): + Optional. Optional limit on the number of + [KeyHandles][google.cloud.kms.v1.KeyHandle] to include in + the response. The service may return fewer than this value. + Further [KeyHandles][google.cloud.kms.v1.KeyHandle] can + subsequently be obtained by including the + [ListKeyHandlesResponse.next_page_token][google.cloud.kms.v1.ListKeyHandlesResponse.next_page_token] + in a subsequent request. If unspecified, at most 100 + [KeyHandles][google.cloud.kms.v1.KeyHandle] will be + returned. + page_token (str): + Optional. Optional pagination token, returned earlier via + [ListKeyHandlesResponse.next_page_token][google.cloud.kms.v1.ListKeyHandlesResponse.next_page_token]. filter (str): Optional. Filter to apply when listing [KeyHandles][google.cloud.kms.v1.KeyHandle], e.g. @@ -155,6 +168,14 @@ class ListKeyHandlesRequest(proto.Message): proto.STRING, number=1, ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) filter: str = proto.Field( proto.STRING, number=4, @@ -168,13 +189,25 @@ class ListKeyHandlesResponse(proto.Message): Attributes: key_handles (MutableSequence[google.cloud.kms_v1.types.KeyHandle]): Resulting [KeyHandles][google.cloud.kms.v1.KeyHandle]. + next_page_token (str): + A token to retrieve next page of results. Pass this value in + [ListKeyHandlesRequest.page_token][google.cloud.kms.v1.ListKeyHandlesRequest.page_token] + to retrieve the next page of results. """ + @property + def raw_page(self): + return self + key_handles: MutableSequence["KeyHandle"] = proto.RepeatedField( proto.MESSAGE, number=1, message="KeyHandle", ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-kms/google/cloud/kms_v1/types/autokey_admin.py b/packages/google-cloud-kms/google/cloud/kms_v1/types/autokey_admin.py index b190c6d01c97..d99b60ed72cc 100644 --- a/packages/google-cloud-kms/google/cloud/kms_v1/types/autokey_admin.py +++ b/packages/google-cloud-kms/google/cloud/kms_v1/types/autokey_admin.py @@ -97,8 +97,33 @@ class AutokeyConfig(proto.Message): for this key project must be granted the ``cloudkms.admin`` role (or pertinent permissions). A request with an empty key project field will clear the configuration. + state (google.cloud.kms_v1.types.AutokeyConfig.State): + Output only. The state for the AutokeyConfig. """ + class State(proto.Enum): + r"""The states AutokeyConfig can be in. + + Values: + STATE_UNSPECIFIED (0): + The state of the AutokeyConfig is + unspecified. + ACTIVE (1): + The AutokeyConfig is currently active. + KEY_PROJECT_DELETED (2): + A previously configured key project has been + deleted and the current AutokeyConfig is + unusable. + UNINITIALIZED (3): + The AutokeyConfig is not yet initialized or + has been reset to its default uninitialized + state. + """ + STATE_UNSPECIFIED = 0 + ACTIVE = 1 + KEY_PROJECT_DELETED = 2 + UNINITIALIZED = 3 + name: str = proto.Field( proto.STRING, number=1, @@ -107,6 +132,11 @@ class AutokeyConfig(proto.Message): proto.STRING, number=2, ) + state: State = proto.Field( + proto.ENUM, + number=4, + enum=State, + ) class ShowEffectiveAutokeyConfigRequest(proto.Message): diff --git a/packages/google-cloud-kms/google/cloud/kms_v1/types/ekm_service.py b/packages/google-cloud-kms/google/cloud/kms_v1/types/ekm_service.py index 6e55bed6e26f..8fda5560ca60 100644 --- a/packages/google-cloud-kms/google/cloud/kms_v1/types/ekm_service.py +++ b/packages/google-cloud-kms/google/cloud/kms_v1/types/ekm_service.py @@ -348,7 +348,7 @@ class EkmConnection(proto.Message): [EkmConnection][google.cloud.kms.v1.EkmConnection] was created. service_resolvers (MutableSequence[google.cloud.kms_v1.types.EkmConnection.ServiceResolver]): - A list of + Optional. A list of [ServiceResolvers][google.cloud.kms.v1.EkmConnection.ServiceResolver] where the EKM can be reached. There should be one ServiceResolver per EKM replica. Currently, only a single diff --git a/packages/google-cloud-kms/google/cloud/kms_v1/types/resources.py b/packages/google-cloud-kms/google/cloud/kms_v1/types/resources.py index d7f70db29d1a..1cf5fc19392b 100644 --- a/packages/google-cloud-kms/google/cloud/kms_v1/types/resources.py +++ b/packages/google-cloud-kms/google/cloud/kms_v1/types/resources.py @@ -276,7 +276,7 @@ class CryptoKey(proto.Message): state before transitioning to [DESTROYED][google.cloud.kms.v1.CryptoKeyVersion.CryptoKeyVersionState.DESTROYED]. If not specified at creation time, the default duration is - 24 hours. + 30 days. crypto_key_backend (str): Immutable. The resource name of the backend environment where the key material for all diff --git a/packages/google-cloud-kms/samples/generated_samples/cloudkms_v1_generated_autokey_list_key_handles_async.py b/packages/google-cloud-kms/samples/generated_samples/cloudkms_v1_generated_autokey_list_key_handles_async.py index e7cfa3289ce7..bc76498134df 100644 --- a/packages/google-cloud-kms/samples/generated_samples/cloudkms_v1_generated_autokey_list_key_handles_async.py +++ b/packages/google-cloud-kms/samples/generated_samples/cloudkms_v1_generated_autokey_list_key_handles_async.py @@ -44,9 +44,10 @@ async def sample_list_key_handles(): ) # Make the request - response = await client.list_key_handles(request=request) + page_result = client.list_key_handles(request=request) # Handle the response - print(response) + async for response in page_result: + print(response) # [END cloudkms_v1_generated_Autokey_ListKeyHandles_async] diff --git a/packages/google-cloud-kms/samples/generated_samples/cloudkms_v1_generated_autokey_list_key_handles_sync.py b/packages/google-cloud-kms/samples/generated_samples/cloudkms_v1_generated_autokey_list_key_handles_sync.py index 78f4b24566a0..6a7ef9a327e8 100644 --- a/packages/google-cloud-kms/samples/generated_samples/cloudkms_v1_generated_autokey_list_key_handles_sync.py +++ b/packages/google-cloud-kms/samples/generated_samples/cloudkms_v1_generated_autokey_list_key_handles_sync.py @@ -44,9 +44,10 @@ def sample_list_key_handles(): ) # Make the request - response = client.list_key_handles(request=request) + page_result = client.list_key_handles(request=request) # Handle the response - print(response) + for response in page_result: + print(response) # [END cloudkms_v1_generated_Autokey_ListKeyHandles_sync] diff --git a/packages/google-cloud-kms/samples/generated_samples/snippet_metadata_google.cloud.kms.v1.json b/packages/google-cloud-kms/samples/generated_samples/snippet_metadata_google.cloud.kms.v1.json index d50814dbd477..a5e165bff4c4 100644 --- a/packages/google-cloud-kms/samples/generated_samples/snippet_metadata_google.cloud.kms.v1.json +++ b/packages/google-cloud-kms/samples/generated_samples/snippet_metadata_google.cloud.kms.v1.json @@ -879,7 +879,7 @@ "type": "Sequence[Tuple[str, str]" } ], - "resultType": "google.cloud.kms_v1.types.ListKeyHandlesResponse", + "resultType": "google.cloud.kms_v1.services.autokey.pagers.ListKeyHandlesAsyncPager", "shortName": "list_key_handles" }, "description": "Sample for ListKeyHandles", @@ -889,12 +889,12 @@ "regionTag": "cloudkms_v1_generated_Autokey_ListKeyHandles_async", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -914,7 +914,7 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } @@ -959,7 +959,7 @@ "type": "Sequence[Tuple[str, str]" } ], - "resultType": "google.cloud.kms_v1.types.ListKeyHandlesResponse", + "resultType": "google.cloud.kms_v1.services.autokey.pagers.ListKeyHandlesPager", "shortName": "list_key_handles" }, "description": "Sample for ListKeyHandles", @@ -969,12 +969,12 @@ "regionTag": "cloudkms_v1_generated_Autokey_ListKeyHandles_sync", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -994,7 +994,7 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } diff --git a/packages/google-cloud-kms/scripts/fixup_kms_v1_keywords.py b/packages/google-cloud-kms/scripts/fixup_kms_v1_keywords.py index 76ad33b20666..7a838e47d117 100644 --- a/packages/google-cloud-kms/scripts/fixup_kms_v1_keywords.py +++ b/packages/google-cloud-kms/scripts/fixup_kms_v1_keywords.py @@ -65,7 +65,7 @@ class kmsCallTransformer(cst.CSTTransformer): 'list_crypto_key_versions': ('parent', 'page_size', 'page_token', 'view', 'filter', 'order_by', ), 'list_ekm_connections': ('parent', 'page_size', 'page_token', 'filter', 'order_by', ), 'list_import_jobs': ('parent', 'page_size', 'page_token', 'filter', 'order_by', ), - 'list_key_handles': ('parent', 'filter', ), + 'list_key_handles': ('parent', 'page_size', 'page_token', 'filter', ), 'list_key_rings': ('parent', 'page_size', 'page_token', 'filter', 'order_by', ), 'mac_sign': ('name', 'data', 'data_crc32c', ), 'mac_verify': ('name', 'data', 'mac', 'data_crc32c', 'mac_crc32c', ), diff --git a/packages/google-cloud-kms/tests/unit/gapic/kms_v1/test_autokey.py b/packages/google-cloud-kms/tests/unit/gapic/kms_v1/test_autokey.py index 3e124c98ef19..6d5f1694bcd9 100644 --- a/packages/google-cloud-kms/tests/unit/gapic/kms_v1/test_autokey.py +++ b/packages/google-cloud-kms/tests/unit/gapic/kms_v1/test_autokey.py @@ -60,6 +60,7 @@ from google.cloud.kms_v1.services.autokey import ( AutokeyAsyncClient, AutokeyClient, + pagers, transports, ) from google.cloud.kms_v1.types import autokey @@ -1866,7 +1867,9 @@ def test_list_key_handles(request_type, transport: str = "grpc"): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object(type(client.transport.list_key_handles), "__call__") as call: # Designate an appropriate return value for the call. - call.return_value = autokey.ListKeyHandlesResponse() + call.return_value = autokey.ListKeyHandlesResponse( + next_page_token="next_page_token_value", + ) response = client.list_key_handles(request) # Establish that the underlying gRPC stub method was called. @@ -1876,7 +1879,8 @@ def test_list_key_handles(request_type, transport: str = "grpc"): assert args[0] == request # Establish that the response is the type that we expect. - assert isinstance(response, autokey.ListKeyHandlesResponse) + assert isinstance(response, pagers.ListKeyHandlesPager) + assert response.next_page_token == "next_page_token_value" def test_list_key_handles_empty_call(): @@ -1911,6 +1915,7 @@ def test_list_key_handles_non_empty_request_with_auto_populated_field(): # if they meet the requirements of AIP 4235. request = autokey.ListKeyHandlesRequest( parent="parent_value", + page_token="page_token_value", filter="filter_value", ) @@ -1924,6 +1929,7 @@ def test_list_key_handles_non_empty_request_with_auto_populated_field(): _, args, _ = call.mock_calls[0] assert args[0] == autokey.ListKeyHandlesRequest( parent="parent_value", + page_token="page_token_value", filter="filter_value", ) @@ -1978,7 +1984,9 @@ async def test_list_key_handles_empty_call_async(): with mock.patch.object(type(client.transport.list_key_handles), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - autokey.ListKeyHandlesResponse() + autokey.ListKeyHandlesResponse( + next_page_token="next_page_token_value", + ) ) response = await client.list_key_handles() call.assert_called() @@ -2045,7 +2053,9 @@ async def test_list_key_handles_async( with mock.patch.object(type(client.transport.list_key_handles), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - autokey.ListKeyHandlesResponse() + autokey.ListKeyHandlesResponse( + next_page_token="next_page_token_value", + ) ) response = await client.list_key_handles(request) @@ -2056,7 +2066,8 @@ async def test_list_key_handles_async( assert args[0] == request # Establish that the response is the type that we expect. - assert isinstance(response, autokey.ListKeyHandlesResponse) + assert isinstance(response, pagers.ListKeyHandlesAsyncPager) + assert response.next_page_token == "next_page_token_value" @pytest.mark.asyncio @@ -2207,6 +2218,200 @@ async def test_list_key_handles_flattened_error_async(): ) +def test_list_key_handles_pager(transport_name: str = "grpc"): + client = AutokeyClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_key_handles), "__call__") as call: + # Set the response to a series of pages. + call.side_effect = ( + autokey.ListKeyHandlesResponse( + key_handles=[ + autokey.KeyHandle(), + autokey.KeyHandle(), + autokey.KeyHandle(), + ], + next_page_token="abc", + ), + autokey.ListKeyHandlesResponse( + key_handles=[], + next_page_token="def", + ), + autokey.ListKeyHandlesResponse( + key_handles=[ + autokey.KeyHandle(), + ], + next_page_token="ghi", + ), + autokey.ListKeyHandlesResponse( + key_handles=[ + autokey.KeyHandle(), + autokey.KeyHandle(), + ], + ), + RuntimeError, + ) + + expected_metadata = () + retry = retries.Retry() + timeout = 5 + expected_metadata = tuple(expected_metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.list_key_handles(request={}, retry=retry, timeout=timeout) + + assert pager._metadata == expected_metadata + assert pager._retry == retry + assert pager._timeout == timeout + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, autokey.KeyHandle) for i in results) + + +def test_list_key_handles_pages(transport_name: str = "grpc"): + client = AutokeyClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_key_handles), "__call__") as call: + # Set the response to a series of pages. + call.side_effect = ( + autokey.ListKeyHandlesResponse( + key_handles=[ + autokey.KeyHandle(), + autokey.KeyHandle(), + autokey.KeyHandle(), + ], + next_page_token="abc", + ), + autokey.ListKeyHandlesResponse( + key_handles=[], + next_page_token="def", + ), + autokey.ListKeyHandlesResponse( + key_handles=[ + autokey.KeyHandle(), + ], + next_page_token="ghi", + ), + autokey.ListKeyHandlesResponse( + key_handles=[ + autokey.KeyHandle(), + autokey.KeyHandle(), + ], + ), + RuntimeError, + ) + pages = list(client.list_key_handles(request={}).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.asyncio +async def test_list_key_handles_async_pager(): + client = AutokeyAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_key_handles), "__call__", new_callable=mock.AsyncMock + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + autokey.ListKeyHandlesResponse( + key_handles=[ + autokey.KeyHandle(), + autokey.KeyHandle(), + autokey.KeyHandle(), + ], + next_page_token="abc", + ), + autokey.ListKeyHandlesResponse( + key_handles=[], + next_page_token="def", + ), + autokey.ListKeyHandlesResponse( + key_handles=[ + autokey.KeyHandle(), + ], + next_page_token="ghi", + ), + autokey.ListKeyHandlesResponse( + key_handles=[ + autokey.KeyHandle(), + autokey.KeyHandle(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_key_handles( + request={}, + ) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, autokey.KeyHandle) for i in responses) + + +@pytest.mark.asyncio +async def test_list_key_handles_async_pages(): + client = AutokeyAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_key_handles), "__call__", new_callable=mock.AsyncMock + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + autokey.ListKeyHandlesResponse( + key_handles=[ + autokey.KeyHandle(), + autokey.KeyHandle(), + autokey.KeyHandle(), + ], + next_page_token="abc", + ), + autokey.ListKeyHandlesResponse( + key_handles=[], + next_page_token="def", + ), + autokey.ListKeyHandlesResponse( + key_handles=[ + autokey.KeyHandle(), + ], + next_page_token="ghi", + ), + autokey.ListKeyHandlesResponse( + key_handles=[ + autokey.KeyHandle(), + autokey.KeyHandle(), + ], + ), + RuntimeError, + ) + pages = [] + # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` + # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 + async for page_ in ( # pragma: no branch + await client.list_key_handles(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + @pytest.mark.parametrize( "request_type", [ @@ -2910,7 +3115,9 @@ def test_list_key_handles_rest(request_type): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = autokey.ListKeyHandlesResponse() + return_value = autokey.ListKeyHandlesResponse( + next_page_token="next_page_token_value", + ) # Wrap the value into a proper Response obj response_value = Response() @@ -2924,7 +3131,8 @@ def test_list_key_handles_rest(request_type): response = client.list_key_handles(request) # Establish that the response is the type that we expect. - assert isinstance(response, autokey.ListKeyHandlesResponse) + assert isinstance(response, pagers.ListKeyHandlesPager) + assert response.next_page_token == "next_page_token_value" def test_list_key_handles_rest_use_cached_wrapped_rpc(): @@ -2993,7 +3201,13 @@ def test_list_key_handles_rest_required_fields( credentials=ga_credentials.AnonymousCredentials() ).list_key_handles._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("filter",)) + assert not set(unset_fields) - set( + ( + "filter", + "page_size", + "page_token", + ) + ) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -3047,7 +3261,16 @@ def test_list_key_handles_rest_unset_required_fields(): ) unset_fields = transport.list_key_handles._get_unset_required_fields({}) - assert set(unset_fields) == (set(("filter",)) & set(("parent",))) + assert set(unset_fields) == ( + set( + ( + "filter", + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) @pytest.mark.parametrize("null_interceptor", [True, False]) @@ -3183,11 +3406,66 @@ def test_list_key_handles_rest_flattened_error(transport: str = "rest"): ) -def test_list_key_handles_rest_error(): +def test_list_key_handles_rest_pager(transport: str = "rest"): client = AutokeyClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + autokey.ListKeyHandlesResponse( + key_handles=[ + autokey.KeyHandle(), + autokey.KeyHandle(), + autokey.KeyHandle(), + ], + next_page_token="abc", + ), + autokey.ListKeyHandlesResponse( + key_handles=[], + next_page_token="def", + ), + autokey.ListKeyHandlesResponse( + key_handles=[ + autokey.KeyHandle(), + ], + next_page_token="ghi", + ), + autokey.ListKeyHandlesResponse( + key_handles=[ + autokey.KeyHandle(), + autokey.KeyHandle(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(autokey.ListKeyHandlesResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1/locations/sample2"} + + pager = client.list_key_handles(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, autokey.KeyHandle) for i in results) + + pages = list(client.list_key_handles(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + def test_credentials_transport_error(): # It is an error to provide credentials and a transport instance. diff --git a/packages/google-cloud-kms/tests/unit/gapic/kms_v1/test_autokey_admin.py b/packages/google-cloud-kms/tests/unit/gapic/kms_v1/test_autokey_admin.py index 6155ff4520d9..0e7ca7eda0b3 100644 --- a/packages/google-cloud-kms/tests/unit/gapic/kms_v1/test_autokey_admin.py +++ b/packages/google-cloud-kms/tests/unit/gapic/kms_v1/test_autokey_admin.py @@ -1127,6 +1127,7 @@ def test_update_autokey_config(request_type, transport: str = "grpc"): call.return_value = autokey_admin.AutokeyConfig( name="name_value", key_project="key_project_value", + state=autokey_admin.AutokeyConfig.State.ACTIVE, ) response = client.update_autokey_config(request) @@ -1140,6 +1141,7 @@ def test_update_autokey_config(request_type, transport: str = "grpc"): assert isinstance(response, autokey_admin.AutokeyConfig) assert response.name == "name_value" assert response.key_project == "key_project_value" + assert response.state == autokey_admin.AutokeyConfig.State.ACTIVE def test_update_autokey_config_empty_call(): @@ -1247,6 +1249,7 @@ async def test_update_autokey_config_empty_call_async(): autokey_admin.AutokeyConfig( name="name_value", key_project="key_project_value", + state=autokey_admin.AutokeyConfig.State.ACTIVE, ) ) response = await client.update_autokey_config() @@ -1320,6 +1323,7 @@ async def test_update_autokey_config_async( autokey_admin.AutokeyConfig( name="name_value", key_project="key_project_value", + state=autokey_admin.AutokeyConfig.State.ACTIVE, ) ) response = await client.update_autokey_config(request) @@ -1334,6 +1338,7 @@ async def test_update_autokey_config_async( assert isinstance(response, autokey_admin.AutokeyConfig) assert response.name == "name_value" assert response.key_project == "key_project_value" + assert response.state == autokey_admin.AutokeyConfig.State.ACTIVE @pytest.mark.asyncio @@ -1527,6 +1532,7 @@ def test_get_autokey_config(request_type, transport: str = "grpc"): call.return_value = autokey_admin.AutokeyConfig( name="name_value", key_project="key_project_value", + state=autokey_admin.AutokeyConfig.State.ACTIVE, ) response = client.get_autokey_config(request) @@ -1540,6 +1546,7 @@ def test_get_autokey_config(request_type, transport: str = "grpc"): assert isinstance(response, autokey_admin.AutokeyConfig) assert response.name == "name_value" assert response.key_project == "key_project_value" + assert response.state == autokey_admin.AutokeyConfig.State.ACTIVE def test_get_autokey_config_empty_call(): @@ -1650,6 +1657,7 @@ async def test_get_autokey_config_empty_call_async(): autokey_admin.AutokeyConfig( name="name_value", key_project="key_project_value", + state=autokey_admin.AutokeyConfig.State.ACTIVE, ) ) response = await client.get_autokey_config() @@ -1722,6 +1730,7 @@ async def test_get_autokey_config_async( autokey_admin.AutokeyConfig( name="name_value", key_project="key_project_value", + state=autokey_admin.AutokeyConfig.State.ACTIVE, ) ) response = await client.get_autokey_config(request) @@ -1736,6 +1745,7 @@ async def test_get_autokey_config_async( assert isinstance(response, autokey_admin.AutokeyConfig) assert response.name == "name_value" assert response.key_project == "key_project_value" + assert response.state == autokey_admin.AutokeyConfig.State.ACTIVE @pytest.mark.asyncio @@ -2301,6 +2311,7 @@ def test_update_autokey_config_rest(request_type): request_init["autokey_config"] = { "name": "folders/sample1/autokeyConfig", "key_project": "key_project_value", + "state": 1, } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -2377,6 +2388,7 @@ def get_message_fields(field): return_value = autokey_admin.AutokeyConfig( name="name_value", key_project="key_project_value", + state=autokey_admin.AutokeyConfig.State.ACTIVE, ) # Wrap the value into a proper Response obj @@ -2394,6 +2406,7 @@ def get_message_fields(field): assert isinstance(response, autokey_admin.AutokeyConfig) assert response.name == "name_value" assert response.key_project == "key_project_value" + assert response.state == autokey_admin.AutokeyConfig.State.ACTIVE def test_update_autokey_config_rest_use_cached_wrapped_rpc(): @@ -2695,6 +2708,7 @@ def test_get_autokey_config_rest(request_type): return_value = autokey_admin.AutokeyConfig( name="name_value", key_project="key_project_value", + state=autokey_admin.AutokeyConfig.State.ACTIVE, ) # Wrap the value into a proper Response obj @@ -2712,6 +2726,7 @@ def test_get_autokey_config_rest(request_type): assert isinstance(response, autokey_admin.AutokeyConfig) assert response.name == "name_value" assert response.key_project == "key_project_value" + assert response.state == autokey_admin.AutokeyConfig.State.ACTIVE def test_get_autokey_config_rest_use_cached_wrapped_rpc():