From b45a11db722f709f055d703f4ef7fd4cbf8655fa Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Wed, 8 Jan 2025 21:19:51 +0000 Subject: [PATCH] feat: [google-cloud-netapp] Add ValidateDirectoryService API for testing AD connection of a storage pool (#13412) - [ ] Regenerate this pull request now. BEGIN_COMMIT_OVERRIDE feat: Add ValidateDirectoryService API for testing AD connection of a storage pool docs: Remove the format for `replication` in message `google.cloud.netapp.v1.HybridReplicationParameters` END_COMMIT_OVERRIDE docs: Removed the format for `replication` in message `google.cloud.netapp.v1.HybridReplicationParameters` PiperOrigin-RevId: 713157619 Source-Link: https://github.com/googleapis/googleapis/commit/7f2db36e5eb3c0ca633bd9600317c74bc26344b1 Source-Link: https://github.com/googleapis/googleapis-gen/commit/33068cc50b39cb01ecc6d175f464e138491711f2 Copy-Tag: eyJwIjoicGFja2FnZXMvZ29vZ2xlLWNsb3VkLW5ldGFwcC8uT3dsQm90LnlhbWwiLCJoIjoiMzMwNjhjYzUwYjM5Y2IwMWVjYzZkMTc1ZjQ2NGUxMzg0OTE3MTFmMiJ9 --------- Co-authored-by: Owl Bot Co-authored-by: Victor Chudnovsky --- .../google/cloud/netapp/__init__.py | 4 + .../google/cloud/netapp/gapic_version.py | 2 +- .../google/cloud/netapp_v1/__init__.py | 10 +- .../cloud/netapp_v1/gapic_metadata.json | 15 + .../google/cloud/netapp_v1/gapic_version.py | 2 +- .../services/net_app/async_client.py | 113 ++++ .../netapp_v1/services/net_app/client.py | 113 ++++ .../services/net_app/transports/base.py | 14 + .../services/net_app/transports/grpc.py | 32 + .../net_app/transports/grpc_asyncio.py | 38 ++ .../services/net_app/transports/rest.py | 196 ++++++ .../services/net_app/transports/rest_base.py | 57 ++ .../google/cloud/netapp_v1/types/__init__.py | 5 +- .../google/cloud/netapp_v1/types/common.py | 15 + .../cloud/netapp_v1/types/storage_pool.py | 24 + .../google/cloud/netapp_v1/types/volume.py | 5 +- ...et_app_validate_directory_service_async.py | 56 ++ ...net_app_validate_directory_service_sync.py | 56 ++ ...ippet_metadata_google.cloud.netapp.v1.json | 155 ++++- .../scripts/fixup_netapp_v1_keywords.py | 1 + .../unit/gapic/netapp_v1/test_net_app.py | 580 ++++++++++++++++++ 21 files changed, 1485 insertions(+), 8 deletions(-) create mode 100644 packages/google-cloud-netapp/samples/generated_samples/netapp_v1_generated_net_app_validate_directory_service_async.py create mode 100644 packages/google-cloud-netapp/samples/generated_samples/netapp_v1_generated_net_app_validate_directory_service_sync.py diff --git a/packages/google-cloud-netapp/google/cloud/netapp/__init__.py b/packages/google-cloud-netapp/google/cloud/netapp/__init__.py index 3034c916ee24..4f9477398688 100644 --- a/packages/google-cloud-netapp/google/cloud/netapp/__init__.py +++ b/packages/google-cloud-netapp/google/cloud/netapp/__init__.py @@ -58,6 +58,7 @@ ) from google.cloud.netapp_v1.types.cloud_netapp_service import OperationMetadata from google.cloud.netapp_v1.types.common import ( + DirectoryServiceType, EncryptionType, LocationMetadata, ServiceLevel, @@ -109,6 +110,7 @@ StoragePool, SwitchActiveReplicaZoneRequest, UpdateStoragePoolRequest, + ValidateDirectoryServiceRequest, ) from google.cloud.netapp_v1.types.volume import ( AccessType, @@ -171,6 +173,7 @@ "UpdateBackupVaultRequest", "OperationMetadata", "LocationMetadata", + "DirectoryServiceType", "EncryptionType", "ServiceLevel", "CreateKmsConfigRequest", @@ -213,6 +216,7 @@ "StoragePool", "SwitchActiveReplicaZoneRequest", "UpdateStoragePoolRequest", + "ValidateDirectoryServiceRequest", "BackupConfig", "CreateVolumeRequest", "DailySchedule", diff --git a/packages/google-cloud-netapp/google/cloud/netapp/gapic_version.py b/packages/google-cloud-netapp/google/cloud/netapp/gapic_version.py index ecc96ea8b67d..558c8aab67c5 100644 --- a/packages/google-cloud-netapp/google/cloud/netapp/gapic_version.py +++ b/packages/google-cloud-netapp/google/cloud/netapp/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.3.17" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-netapp/google/cloud/netapp_v1/__init__.py b/packages/google-cloud-netapp/google/cloud/netapp_v1/__init__.py index e965d1d2a391..7ddf41230df3 100644 --- a/packages/google-cloud-netapp/google/cloud/netapp_v1/__init__.py +++ b/packages/google-cloud-netapp/google/cloud/netapp_v1/__init__.py @@ -56,7 +56,12 @@ UpdateBackupVaultRequest, ) from .types.cloud_netapp_service import OperationMetadata -from .types.common import EncryptionType, LocationMetadata, ServiceLevel +from .types.common import ( + DirectoryServiceType, + EncryptionType, + LocationMetadata, + ServiceLevel, +) from .types.kms import ( CreateKmsConfigRequest, DeleteKmsConfigRequest, @@ -104,6 +109,7 @@ StoragePool, SwitchActiveReplicaZoneRequest, UpdateStoragePoolRequest, + ValidateDirectoryServiceRequest, ) from .types.volume import ( AccessType, @@ -161,6 +167,7 @@ "DeleteStoragePoolRequest", "DeleteVolumeRequest", "DestinationVolumeParameters", + "DirectoryServiceType", "EncryptVolumesRequest", "EncryptionType", "EstablishPeeringRequest", @@ -229,6 +236,7 @@ "UpdateSnapshotRequest", "UpdateStoragePoolRequest", "UpdateVolumeRequest", + "ValidateDirectoryServiceRequest", "VerifyKmsConfigRequest", "VerifyKmsConfigResponse", "Volume", diff --git a/packages/google-cloud-netapp/google/cloud/netapp_v1/gapic_metadata.json b/packages/google-cloud-netapp/google/cloud/netapp_v1/gapic_metadata.json index f4b797d0fdf6..64025b572e7b 100644 --- a/packages/google-cloud-netapp/google/cloud/netapp_v1/gapic_metadata.json +++ b/packages/google-cloud-netapp/google/cloud/netapp_v1/gapic_metadata.json @@ -275,6 +275,11 @@ "update_volume" ] }, + "ValidateDirectoryService": { + "methods": [ + "validate_directory_service" + ] + }, "VerifyKmsConfig": { "methods": [ "verify_kms_config" @@ -550,6 +555,11 @@ "update_volume" ] }, + "ValidateDirectoryService": { + "methods": [ + "validate_directory_service" + ] + }, "VerifyKmsConfig": { "methods": [ "verify_kms_config" @@ -825,6 +835,11 @@ "update_volume" ] }, + "ValidateDirectoryService": { + "methods": [ + "validate_directory_service" + ] + }, "VerifyKmsConfig": { "methods": [ "verify_kms_config" diff --git a/packages/google-cloud-netapp/google/cloud/netapp_v1/gapic_version.py b/packages/google-cloud-netapp/google/cloud/netapp_v1/gapic_version.py index ecc96ea8b67d..558c8aab67c5 100644 --- a/packages/google-cloud-netapp/google/cloud/netapp_v1/gapic_version.py +++ b/packages/google-cloud-netapp/google/cloud/netapp_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.3.17" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-netapp/google/cloud/netapp_v1/services/net_app/async_client.py b/packages/google-cloud-netapp/google/cloud/netapp_v1/services/net_app/async_client.py index 9be45393690a..5301eff71c07 100644 --- a/packages/google-cloud-netapp/google/cloud/netapp_v1/services/net_app/async_client.py +++ b/packages/google-cloud-netapp/google/cloud/netapp_v1/services/net_app/async_client.py @@ -982,6 +982,119 @@ async def sample_delete_storage_pool(): # Done; return the response. return response + async def validate_directory_service( + self, + request: Optional[ + Union[storage_pool.ValidateDirectoryServiceRequest, dict] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation_async.AsyncOperation: + r"""ValidateDirectoryService does a connectivity check + for a directory service policy attached to the storage + pool. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import netapp_v1 + + async def sample_validate_directory_service(): + # Create a client + client = netapp_v1.NetAppAsyncClient() + + # Initialize request argument(s) + request = netapp_v1.ValidateDirectoryServiceRequest( + name="name_value", + ) + + # Make the request + operation = client.validate_directory_service(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.netapp_v1.types.ValidateDirectoryServiceRequest, dict]]): + The request object. ValidateDirectoryServiceRequest + validates the directory service policy + attached to the storage pool. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + 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 + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, storage_pool.ValidateDirectoryServiceRequest): + request = storage_pool.ValidateDirectoryServiceRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.validate_directory_service + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + empty_pb2.Empty, + metadata_type=cloud_netapp_service.OperationMetadata, + ) + + # Done; return the response. + return response + async def switch_active_replica_zone( self, request: Optional[ diff --git a/packages/google-cloud-netapp/google/cloud/netapp_v1/services/net_app/client.py b/packages/google-cloud-netapp/google/cloud/netapp_v1/services/net_app/client.py index ccef5605e2c4..5b96d298b1a7 100644 --- a/packages/google-cloud-netapp/google/cloud/netapp_v1/services/net_app/client.py +++ b/packages/google-cloud-netapp/google/cloud/netapp_v1/services/net_app/client.py @@ -1549,6 +1549,119 @@ def sample_delete_storage_pool(): # Done; return the response. return response + def validate_directory_service( + self, + request: Optional[ + Union[storage_pool.ValidateDirectoryServiceRequest, dict] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation.Operation: + r"""ValidateDirectoryService does a connectivity check + for a directory service policy attached to the storage + pool. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import netapp_v1 + + def sample_validate_directory_service(): + # Create a client + client = netapp_v1.NetAppClient() + + # Initialize request argument(s) + request = netapp_v1.ValidateDirectoryServiceRequest( + name="name_value", + ) + + # Make the request + operation = client.validate_directory_service(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.netapp_v1.types.ValidateDirectoryServiceRequest, dict]): + The request object. ValidateDirectoryServiceRequest + validates the directory service policy + attached to the storage pool. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + 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 + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, storage_pool.ValidateDirectoryServiceRequest): + request = storage_pool.ValidateDirectoryServiceRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.validate_directory_service + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + empty_pb2.Empty, + metadata_type=cloud_netapp_service.OperationMetadata, + ) + + # Done; return the response. + return response + def switch_active_replica_zone( self, request: Optional[ diff --git a/packages/google-cloud-netapp/google/cloud/netapp_v1/services/net_app/transports/base.py b/packages/google-cloud-netapp/google/cloud/netapp_v1/services/net_app/transports/base.py index 8f6a2f59cb21..7bca0088614c 100644 --- a/packages/google-cloud-netapp/google/cloud/netapp_v1/services/net_app/transports/base.py +++ b/packages/google-cloud-netapp/google/cloud/netapp_v1/services/net_app/transports/base.py @@ -189,6 +189,11 @@ def _prep_wrapped_messages(self, client_info): default_timeout=60.0, client_info=client_info, ), + self.validate_directory_service: gapic_v1.method.wrap_method( + self.validate_directory_service, + default_timeout=None, + client_info=client_info, + ), self.switch_active_replica_zone: gapic_v1.method.wrap_method( self.switch_active_replica_zone, default_timeout=None, @@ -672,6 +677,15 @@ def delete_storage_pool( ]: raise NotImplementedError() + @property + def validate_directory_service( + self, + ) -> Callable[ + [storage_pool.ValidateDirectoryServiceRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + @property def switch_active_replica_zone( self, diff --git a/packages/google-cloud-netapp/google/cloud/netapp_v1/services/net_app/transports/grpc.py b/packages/google-cloud-netapp/google/cloud/netapp_v1/services/net_app/transports/grpc.py index ba662d345fa0..12dd2ae284e8 100644 --- a/packages/google-cloud-netapp/google/cloud/netapp_v1/services/net_app/transports/grpc.py +++ b/packages/google-cloud-netapp/google/cloud/netapp_v1/services/net_app/transports/grpc.py @@ -495,6 +495,38 @@ def delete_storage_pool( ) return self._stubs["delete_storage_pool"] + @property + def validate_directory_service( + self, + ) -> Callable[ + [storage_pool.ValidateDirectoryServiceRequest], operations_pb2.Operation + ]: + r"""Return a callable for the validate directory service method over gRPC. + + ValidateDirectoryService does a connectivity check + for a directory service policy attached to the storage + pool. + + Returns: + Callable[[~.ValidateDirectoryServiceRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "validate_directory_service" not in self._stubs: + self._stubs[ + "validate_directory_service" + ] = self._logged_channel.unary_unary( + "/google.cloud.netapp.v1.NetApp/ValidateDirectoryService", + request_serializer=storage_pool.ValidateDirectoryServiceRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["validate_directory_service"] + @property def switch_active_replica_zone( self, diff --git a/packages/google-cloud-netapp/google/cloud/netapp_v1/services/net_app/transports/grpc_asyncio.py b/packages/google-cloud-netapp/google/cloud/netapp_v1/services/net_app/transports/grpc_asyncio.py index 79066314fde4..c4644f8a607b 100644 --- a/packages/google-cloud-netapp/google/cloud/netapp_v1/services/net_app/transports/grpc_asyncio.py +++ b/packages/google-cloud-netapp/google/cloud/netapp_v1/services/net_app/transports/grpc_asyncio.py @@ -507,6 +507,39 @@ def delete_storage_pool( ) return self._stubs["delete_storage_pool"] + @property + def validate_directory_service( + self, + ) -> Callable[ + [storage_pool.ValidateDirectoryServiceRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the validate directory service method over gRPC. + + ValidateDirectoryService does a connectivity check + for a directory service policy attached to the storage + pool. + + Returns: + Callable[[~.ValidateDirectoryServiceRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "validate_directory_service" not in self._stubs: + self._stubs[ + "validate_directory_service" + ] = self._logged_channel.unary_unary( + "/google.cloud.netapp.v1.NetApp/ValidateDirectoryService", + request_serializer=storage_pool.ValidateDirectoryServiceRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["validate_directory_service"] + @property def switch_active_replica_zone( self, @@ -1931,6 +1964,11 @@ def _prep_wrapped_messages(self, client_info): default_timeout=60.0, client_info=client_info, ), + self.validate_directory_service: self._wrap_method( + self.validate_directory_service, + default_timeout=None, + client_info=client_info, + ), self.switch_active_replica_zone: self._wrap_method( self.switch_active_replica_zone, default_timeout=None, diff --git a/packages/google-cloud-netapp/google/cloud/netapp_v1/services/net_app/transports/rest.py b/packages/google-cloud-netapp/google/cloud/netapp_v1/services/net_app/transports/rest.py index c980324799b1..c8386ffa878c 100644 --- a/packages/google-cloud-netapp/google/cloud/netapp_v1/services/net_app/transports/rest.py +++ b/packages/google-cloud-netapp/google/cloud/netapp_v1/services/net_app/transports/rest.py @@ -510,6 +510,14 @@ def post_update_volume(self, response): logging.log(f"Received response: {response}") return response + def pre_validate_directory_service(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_validate_directory_service(self, response): + logging.log(f"Received response: {response}") + return response + def pre_verify_kms_config(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -1816,6 +1824,32 @@ def post_update_volume( """ return response + def pre_validate_directory_service( + self, + request: storage_pool.ValidateDirectoryServiceRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + storage_pool.ValidateDirectoryServiceRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for validate_directory_service + + Override in a subclass to manipulate the request or metadata + before they are sent to the NetApp server. + """ + return request, metadata + + def post_validate_directory_service( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for validate_directory_service + + Override in a subclass to manipulate the response + after it is returned by the NetApp server but before + it is returned to user code. + """ + return response + def pre_verify_kms_config( self, request: kms.VerifyKmsConfigRequest, @@ -10052,6 +10086,158 @@ def __call__( ) return resp + class _ValidateDirectoryService( + _BaseNetAppRestTransport._BaseValidateDirectoryService, NetAppRestStub + ): + def __hash__(self): + return hash("NetAppRestTransport.ValidateDirectoryService") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: storage_pool.ValidateDirectoryServiceRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the validate directory + service method over HTTP. + + Args: + request (~.storage_pool.ValidateDirectoryServiceRequest): + The request object. ValidateDirectoryServiceRequest + validates the directory service policy + attached to the storage pool. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = ( + _BaseNetAppRestTransport._BaseValidateDirectoryService._get_http_options() + ) + + request, metadata = self._interceptor.pre_validate_directory_service( + request, metadata + ) + transcoded_request = _BaseNetAppRestTransport._BaseValidateDirectoryService._get_transcoded_request( + http_options, request + ) + + body = _BaseNetAppRestTransport._BaseValidateDirectoryService._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseNetAppRestTransport._BaseValidateDirectoryService._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.netapp_v1.NetAppClient.ValidateDirectoryService", + extra={ + "serviceName": "google.cloud.netapp.v1.NetApp", + "rpcName": "ValidateDirectoryService", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = NetAppRestTransport._ValidateDirectoryService._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_validate_directory_service(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.netapp_v1.NetAppClient.validate_directory_service", + extra={ + "serviceName": "google.cloud.netapp.v1.NetApp", + "rpcName": "ValidateDirectoryService", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + class _VerifyKmsConfig( _BaseNetAppRestTransport._BaseVerifyKmsConfig, NetAppRestStub ): @@ -10662,6 +10848,16 @@ def update_volume( # In C++ this would require a dynamic_cast return self._UpdateVolume(self._session, self._host, self._interceptor) # type: ignore + @property + def validate_directory_service( + self, + ) -> Callable[ + [storage_pool.ValidateDirectoryServiceRequest], operations_pb2.Operation + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ValidateDirectoryService(self._session, self._host, self._interceptor) # type: ignore + @property def verify_kms_config( self, diff --git a/packages/google-cloud-netapp/google/cloud/netapp_v1/services/net_app/transports/rest_base.py b/packages/google-cloud-netapp/google/cloud/netapp_v1/services/net_app/transports/rest_base.py index ce68cb870bf6..9ee59f45789c 100644 --- a/packages/google-cloud-netapp/google/cloud/netapp_v1/services/net_app/transports/rest_base.py +++ b/packages/google-cloud-netapp/google/cloud/netapp_v1/services/net_app/transports/rest_base.py @@ -2892,6 +2892,63 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params + class _BaseValidateDirectoryService: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{name=projects/*/locations/*/storagePools/*}:validateDirectoryService", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = storage_pool.ValidateDirectoryServiceRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseNetAppRestTransport._BaseValidateDirectoryService._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + class _BaseVerifyKmsConfig: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") diff --git a/packages/google-cloud-netapp/google/cloud/netapp_v1/types/__init__.py b/packages/google-cloud-netapp/google/cloud/netapp_v1/types/__init__.py index 8aedbeffc706..a34a75fccb0b 100644 --- a/packages/google-cloud-netapp/google/cloud/netapp_v1/types/__init__.py +++ b/packages/google-cloud-netapp/google/cloud/netapp_v1/types/__init__.py @@ -50,7 +50,7 @@ UpdateBackupVaultRequest, ) from .cloud_netapp_service import OperationMetadata -from .common import EncryptionType, LocationMetadata, ServiceLevel +from .common import DirectoryServiceType, EncryptionType, LocationMetadata, ServiceLevel from .kms import ( CreateKmsConfigRequest, DeleteKmsConfigRequest, @@ -98,6 +98,7 @@ StoragePool, SwitchActiveReplicaZoneRequest, UpdateStoragePoolRequest, + ValidateDirectoryServiceRequest, ) from .volume import ( AccessType, @@ -158,6 +159,7 @@ "UpdateBackupVaultRequest", "OperationMetadata", "LocationMetadata", + "DirectoryServiceType", "EncryptionType", "ServiceLevel", "CreateKmsConfigRequest", @@ -200,6 +202,7 @@ "StoragePool", "SwitchActiveReplicaZoneRequest", "UpdateStoragePoolRequest", + "ValidateDirectoryServiceRequest", "BackupConfig", "CreateVolumeRequest", "DailySchedule", diff --git a/packages/google-cloud-netapp/google/cloud/netapp_v1/types/common.py b/packages/google-cloud-netapp/google/cloud/netapp_v1/types/common.py index 72cff8db6750..b3e11c23a49c 100644 --- a/packages/google-cloud-netapp/google/cloud/netapp_v1/types/common.py +++ b/packages/google-cloud-netapp/google/cloud/netapp_v1/types/common.py @@ -24,6 +24,7 @@ manifest={ "ServiceLevel", "EncryptionType", + "DirectoryServiceType", "LocationMetadata", }, ) @@ -69,6 +70,20 @@ class EncryptionType(proto.Enum): CLOUD_KMS = 2 +class DirectoryServiceType(proto.Enum): + r"""Type of directory service + + Values: + DIRECTORY_SERVICE_TYPE_UNSPECIFIED (0): + Directory service type is not specified. + ACTIVE_DIRECTORY (1): + Active directory policy attached to the + storage pool. + """ + DIRECTORY_SERVICE_TYPE_UNSPECIFIED = 0 + ACTIVE_DIRECTORY = 1 + + class LocationMetadata(proto.Message): r"""Metadata for a given [google.cloud.location.Location][google.cloud.location.Location]. diff --git a/packages/google-cloud-netapp/google/cloud/netapp_v1/types/storage_pool.py b/packages/google-cloud-netapp/google/cloud/netapp_v1/types/storage_pool.py index 0b8f6606d5fc..1b1768dd797a 100644 --- a/packages/google-cloud-netapp/google/cloud/netapp_v1/types/storage_pool.py +++ b/packages/google-cloud-netapp/google/cloud/netapp_v1/types/storage_pool.py @@ -34,6 +34,7 @@ "DeleteStoragePoolRequest", "SwitchActiveReplicaZoneRequest", "StoragePool", + "ValidateDirectoryServiceRequest", }, ) @@ -401,4 +402,27 @@ class State(proto.Enum): ) +class ValidateDirectoryServiceRequest(proto.Message): + r"""ValidateDirectoryServiceRequest validates the directory + service policy attached to the storage pool. + + Attributes: + name (str): + Required. Name of the storage pool + directory_service_type (google.cloud.netapp_v1.types.DirectoryServiceType): + Type of directory service policy attached to + the storage pool. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + directory_service_type: common.DirectoryServiceType = proto.Field( + proto.ENUM, + number=2, + enum=common.DirectoryServiceType, + ) + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-netapp/google/cloud/netapp_v1/types/volume.py b/packages/google-cloud-netapp/google/cloud/netapp_v1/types/volume.py index 0d4388486c7c..b7f72d6374e2 100644 --- a/packages/google-cloud-netapp/google/cloud/netapp_v1/types/volume.py +++ b/packages/google-cloud-netapp/google/cloud/netapp_v1/types/volume.py @@ -1252,9 +1252,8 @@ class HybridReplicationParameters(proto.Message): Attributes: replication (str): - Required. Desired Identifier (name) of the replication which - will be created for this volume. Format: - ``projects/{project_id}/locations/{location}/volumes/{volume_id}/replications/{replication_id}`` + Required. Desired name for the replication of + this volume. peer_volume_name (str): Required. Name of the user's local source volume to be peered with the destination volume. diff --git a/packages/google-cloud-netapp/samples/generated_samples/netapp_v1_generated_net_app_validate_directory_service_async.py b/packages/google-cloud-netapp/samples/generated_samples/netapp_v1_generated_net_app_validate_directory_service_async.py new file mode 100644 index 000000000000..0d0baa61d3e1 --- /dev/null +++ b/packages/google-cloud-netapp/samples/generated_samples/netapp_v1_generated_net_app_validate_directory_service_async.py @@ -0,0 +1,56 @@ +# -*- 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ValidateDirectoryService +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-netapp + + +# [START netapp_v1_generated_NetApp_ValidateDirectoryService_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import netapp_v1 + + +async def sample_validate_directory_service(): + # Create a client + client = netapp_v1.NetAppAsyncClient() + + # Initialize request argument(s) + request = netapp_v1.ValidateDirectoryServiceRequest( + name="name_value", + ) + + # Make the request + operation = client.validate_directory_service(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END netapp_v1_generated_NetApp_ValidateDirectoryService_async] diff --git a/packages/google-cloud-netapp/samples/generated_samples/netapp_v1_generated_net_app_validate_directory_service_sync.py b/packages/google-cloud-netapp/samples/generated_samples/netapp_v1_generated_net_app_validate_directory_service_sync.py new file mode 100644 index 000000000000..51d026b4ec1d --- /dev/null +++ b/packages/google-cloud-netapp/samples/generated_samples/netapp_v1_generated_net_app_validate_directory_service_sync.py @@ -0,0 +1,56 @@ +# -*- 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ValidateDirectoryService +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-netapp + + +# [START netapp_v1_generated_NetApp_ValidateDirectoryService_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import netapp_v1 + + +def sample_validate_directory_service(): + # Create a client + client = netapp_v1.NetAppClient() + + # Initialize request argument(s) + request = netapp_v1.ValidateDirectoryServiceRequest( + name="name_value", + ) + + # Make the request + operation = client.validate_directory_service(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END netapp_v1_generated_NetApp_ValidateDirectoryService_sync] diff --git a/packages/google-cloud-netapp/samples/generated_samples/snippet_metadata_google.cloud.netapp.v1.json b/packages/google-cloud-netapp/samples/generated_samples/snippet_metadata_google.cloud.netapp.v1.json index 64b581a85ee9..a6b3a1cfcacf 100644 --- a/packages/google-cloud-netapp/samples/generated_samples/snippet_metadata_google.cloud.netapp.v1.json +++ b/packages/google-cloud-netapp/samples/generated_samples/snippet_metadata_google.cloud.netapp.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-netapp", - "version": "0.3.17" + "version": "0.1.0" }, "snippets": [ { @@ -8696,6 +8696,159 @@ ], "title": "netapp_v1_generated_net_app_update_volume_sync.py" }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.netapp_v1.NetAppAsyncClient", + "shortName": "NetAppAsyncClient" + }, + "fullName": "google.cloud.netapp_v1.NetAppAsyncClient.validate_directory_service", + "method": { + "fullName": "google.cloud.netapp.v1.NetApp.ValidateDirectoryService", + "service": { + "fullName": "google.cloud.netapp.v1.NetApp", + "shortName": "NetApp" + }, + "shortName": "ValidateDirectoryService" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.netapp_v1.types.ValidateDirectoryServiceRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "validate_directory_service" + }, + "description": "Sample for ValidateDirectoryService", + "file": "netapp_v1_generated_net_app_validate_directory_service_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "netapp_v1_generated_NetApp_ValidateDirectoryService_async", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "netapp_v1_generated_net_app_validate_directory_service_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.netapp_v1.NetAppClient", + "shortName": "NetAppClient" + }, + "fullName": "google.cloud.netapp_v1.NetAppClient.validate_directory_service", + "method": { + "fullName": "google.cloud.netapp.v1.NetApp.ValidateDirectoryService", + "service": { + "fullName": "google.cloud.netapp.v1.NetApp", + "shortName": "NetApp" + }, + "shortName": "ValidateDirectoryService" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.netapp_v1.types.ValidateDirectoryServiceRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "validate_directory_service" + }, + "description": "Sample for ValidateDirectoryService", + "file": "netapp_v1_generated_net_app_validate_directory_service_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "netapp_v1_generated_NetApp_ValidateDirectoryService_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "netapp_v1_generated_net_app_validate_directory_service_sync.py" + }, { "canonical": true, "clientMethod": { diff --git a/packages/google-cloud-netapp/scripts/fixup_netapp_v1_keywords.py b/packages/google-cloud-netapp/scripts/fixup_netapp_v1_keywords.py index aa328f7e91ee..4262af30138a 100644 --- a/packages/google-cloud-netapp/scripts/fixup_netapp_v1_keywords.py +++ b/packages/google-cloud-netapp/scripts/fixup_netapp_v1_keywords.py @@ -92,6 +92,7 @@ class netappCallTransformer(cst.CSTTransformer): 'update_snapshot': ('update_mask', 'snapshot', ), 'update_storage_pool': ('update_mask', 'storage_pool', ), 'update_volume': ('update_mask', 'volume', ), + 'validate_directory_service': ('name', 'directory_service_type', ), 'verify_kms_config': ('name', ), } diff --git a/packages/google-cloud-netapp/tests/unit/gapic/netapp_v1/test_net_app.py b/packages/google-cloud-netapp/tests/unit/gapic/netapp_v1/test_net_app.py index 452553d6ecbb..84bb991bd4d2 100644 --- a/packages/google-cloud-netapp/tests/unit/gapic/netapp_v1/test_net_app.py +++ b/packages/google-cloud-netapp/tests/unit/gapic/netapp_v1/test_net_app.py @@ -3034,6 +3034,267 @@ async def test_delete_storage_pool_flattened_error_async(): ) +@pytest.mark.parametrize( + "request_type", + [ + storage_pool.ValidateDirectoryServiceRequest, + dict, + ], +) +def test_validate_directory_service(request_type, transport: str = "grpc"): + client = NetAppClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.validate_directory_service), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.validate_directory_service(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = storage_pool.ValidateDirectoryServiceRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_validate_directory_service_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = NetAppClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = storage_pool.ValidateDirectoryServiceRequest( + name="name_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.validate_directory_service), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.validate_directory_service(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == storage_pool.ValidateDirectoryServiceRequest( + name="name_value", + ) + + +def test_validate_directory_service_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = NetAppClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.validate_directory_service + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.validate_directory_service + ] = mock_rpc + request = {} + client.validate_directory_service(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.validate_directory_service(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_validate_directory_service_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = NetAppAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.validate_directory_service + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.validate_directory_service + ] = mock_rpc + + request = {} + await client.validate_directory_service(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + await client.validate_directory_service(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_validate_directory_service_async( + transport: str = "grpc_asyncio", + request_type=storage_pool.ValidateDirectoryServiceRequest, +): + client = NetAppAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.validate_directory_service), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + response = await client.validate_directory_service(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = storage_pool.ValidateDirectoryServiceRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_validate_directory_service_async_from_dict(): + await test_validate_directory_service_async(request_type=dict) + + +def test_validate_directory_service_field_headers(): + client = NetAppClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = storage_pool.ValidateDirectoryServiceRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.validate_directory_service), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.validate_directory_service(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_validate_directory_service_field_headers_async(): + client = NetAppAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = storage_pool.ValidateDirectoryServiceRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.validate_directory_service), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.validate_directory_service(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + @pytest.mark.parametrize( "request_type", [ @@ -21978,6 +22239,133 @@ def test_delete_storage_pool_rest_flattened_error(transport: str = "rest"): ) +def test_validate_directory_service_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = NetAppClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.validate_directory_service + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.validate_directory_service + ] = mock_rpc + + request = {} + client.validate_directory_service(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.validate_directory_service(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_validate_directory_service_rest_required_fields( + request_type=storage_pool.ValidateDirectoryServiceRequest, +): + transport_class = transports.NetAppRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).validate_directory_service._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).validate_directory_service._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = NetAppClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.validate_directory_service(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_validate_directory_service_rest_unset_required_fields(): + transport = transports.NetAppRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.validate_directory_service._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + def test_switch_active_replica_zone_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -31524,6 +31912,29 @@ def test_delete_storage_pool_empty_call_grpc(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_validate_directory_service_empty_call_grpc(): + client = NetAppClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.validate_directory_service), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.validate_directory_service(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = storage_pool.ValidateDirectoryServiceRequest() + + assert args[0] == request_msg + + # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. def test_switch_active_replica_zone_empty_call_grpc(): @@ -32774,6 +33185,33 @@ async def test_delete_storage_pool_empty_call_grpc_asyncio(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_validate_directory_service_empty_call_grpc_asyncio(): + client = NetAppAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.validate_directory_service), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.validate_directory_service(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = storage_pool.ValidateDirectoryServiceRequest() + + assert args[0] == request_msg + + # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @pytest.mark.asyncio @@ -34998,6 +35436,122 @@ def test_delete_storage_pool_rest_interceptors(null_interceptor): post.assert_called_once() +def test_validate_directory_service_rest_bad_request( + request_type=storage_pool.ValidateDirectoryServiceRequest, +): + client = NetAppClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/locations/sample2/storagePools/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.validate_directory_service(request) + + +@pytest.mark.parametrize( + "request_type", + [ + storage_pool.ValidateDirectoryServiceRequest, + dict, + ], +) +def test_validate_directory_service_rest_call_success(request_type): + client = NetAppClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/locations/sample2/storagePools/sample3"} + request = request_type(**request_init) + + # 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 = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.validate_directory_service(request) + + # Establish that the response is the type that we expect. + json_return_value = json_format.MessageToJson(return_value) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_validate_directory_service_rest_interceptors(null_interceptor): + transport = transports.NetAppRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.NetAppRestInterceptor(), + ) + client = NetAppClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + operation.Operation, "_set_result_from_operation" + ), mock.patch.object( + transports.NetAppRestInterceptor, "post_validate_directory_service" + ) as post, mock.patch.object( + transports.NetAppRestInterceptor, "pre_validate_directory_service" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = storage_pool.ValidateDirectoryServiceRequest.pb( + storage_pool.ValidateDirectoryServiceRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = json_format.MessageToJson(operations_pb2.Operation()) + req.return_value.content = return_value + + request = storage_pool.ValidateDirectoryServiceRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.validate_directory_service( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + def test_switch_active_replica_zone_rest_bad_request( request_type=storage_pool.SwitchActiveReplicaZoneRequest, ): @@ -42991,6 +43545,28 @@ def test_delete_storage_pool_empty_call_rest(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_validate_directory_service_empty_call_rest(): + client = NetAppClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.validate_directory_service), "__call__" + ) as call: + client.validate_directory_service(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = storage_pool.ValidateDirectoryServiceRequest() + + assert args[0] == request_msg + + # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. def test_switch_active_replica_zone_empty_call_rest(): @@ -44078,6 +44654,7 @@ def test_net_app_base_transport(): "get_storage_pool", "update_storage_pool", "delete_storage_pool", + "validate_directory_service", "switch_active_replica_zone", "list_volumes", "get_volume", @@ -44408,6 +44985,9 @@ def test_net_app_client_transport_session_collision(transport_name): session1 = client1.transport.delete_storage_pool._session session2 = client2.transport.delete_storage_pool._session assert session1 != session2 + session1 = client1.transport.validate_directory_service._session + session2 = client2.transport.validate_directory_service._session + assert session1 != session2 session1 = client1.transport.switch_active_replica_zone._session session2 = client2.transport.switch_active_replica_zone._session assert session1 != session2