From e84d22dd4a5b647ea283e11d0f4fe6ece9fe1d16 Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Tue, 21 Mar 2023 09:15:21 -0400 Subject: [PATCH] feat: Update Compute Engine API to revision 20230307 (#786) (#403) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: Update Compute Engine API to revision 20230307 (#786) Source-Link: https://github.com/googleapis/googleapis/commit/f64a3c8418e2e4e493b6a432220d774e7942141a Source-Link: https://github.com/googleapis/googleapis-gen/commit/808541b7e7697e2984a0ea0eba1adb5560dade97 Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiODA4NTQxYjdlNzY5N2UyOTg0YTBlYTBlYmExYWRiNTU2MGRhZGU5NyJ9 * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --------- Co-authored-by: Owl Bot --- .../google/cloud/compute/__init__.py | 4 + .../google/cloud/compute_v1/__init__.py | 4 + .../cloud/compute_v1/gapic_metadata.json | 5 + .../compute_v1/services/node_groups/client.py | 277 +++++++ .../services/node_groups/transports/base.py | 14 + .../services/node_groups/transports/rest.py | 157 ++++ .../google/cloud/compute_v1/types/__init__.py | 4 + .../google/cloud/compute_v1/types/compute.py | 89 ++- .../unit/gapic/compute_v1/test_node_groups.py | 682 ++++++++++++++++++ 9 files changed, 1232 insertions(+), 4 deletions(-) diff --git a/packages/google-cloud-compute/google/cloud/compute/__init__.py b/packages/google-cloud-compute/google/cloud/compute/__init__.py index 853aec1a773f..41dcd4d3346f 100644 --- a/packages/google-cloud-compute/google/cloud/compute/__init__.py +++ b/packages/google-cloud-compute/google/cloud/compute/__init__.py @@ -1029,6 +1029,7 @@ NodeGroupsListNodes, NodeGroupsScopedList, NodeGroupsSetNodeTemplateRequest, + NodeGroupsSimulateMaintenanceEventRequest, NodeTemplate, NodeTemplateAggregatedList, NodeTemplateList, @@ -1365,6 +1366,7 @@ ShieldedInstanceIntegrityPolicy, SignedUrlKey, SimulateMaintenanceEventInstanceRequest, + SimulateMaintenanceEventNodeGroupRequest, Snapshot, SnapshotList, SourceDiskEncryptionKey, @@ -2449,6 +2451,7 @@ "NodeGroupsListNodes", "NodeGroupsScopedList", "NodeGroupsSetNodeTemplateRequest", + "NodeGroupsSimulateMaintenanceEventRequest", "NodeTemplate", "NodeTemplateAggregatedList", "NodeTemplateList", @@ -2785,6 +2788,7 @@ "ShieldedInstanceIntegrityPolicy", "SignedUrlKey", "SimulateMaintenanceEventInstanceRequest", + "SimulateMaintenanceEventNodeGroupRequest", "Snapshot", "SnapshotList", "SourceDiskEncryptionKey", diff --git a/packages/google-cloud-compute/google/cloud/compute_v1/__init__.py b/packages/google-cloud-compute/google/cloud/compute_v1/__init__.py index 5aa96998f8a4..8e991e838288 100644 --- a/packages/google-cloud-compute/google/cloud/compute_v1/__init__.py +++ b/packages/google-cloud-compute/google/cloud/compute_v1/__init__.py @@ -925,6 +925,7 @@ NodeGroupsListNodes, NodeGroupsScopedList, NodeGroupsSetNodeTemplateRequest, + NodeGroupsSimulateMaintenanceEventRequest, NodeTemplate, NodeTemplateAggregatedList, NodeTemplateList, @@ -1261,6 +1262,7 @@ ShieldedInstanceIntegrityPolicy, SignedUrlKey, SimulateMaintenanceEventInstanceRequest, + SimulateMaintenanceEventNodeGroupRequest, Snapshot, SnapshotList, SourceDiskEncryptionKey, @@ -2293,6 +2295,7 @@ "NodeGroupsListNodes", "NodeGroupsScopedList", "NodeGroupsSetNodeTemplateRequest", + "NodeGroupsSimulateMaintenanceEventRequest", "NodeTemplate", "NodeTemplateAggregatedList", "NodeTemplateList", @@ -2665,6 +2668,7 @@ "ShieldedInstanceIntegrityPolicy", "SignedUrlKey", "SimulateMaintenanceEventInstanceRequest", + "SimulateMaintenanceEventNodeGroupRequest", "Snapshot", "SnapshotList", "SnapshotsClient", diff --git a/packages/google-cloud-compute/google/cloud/compute_v1/gapic_metadata.json b/packages/google-cloud-compute/google/cloud/compute_v1/gapic_metadata.json index b64a921f2859..471015961947 100644 --- a/packages/google-cloud-compute/google/cloud/compute_v1/gapic_metadata.json +++ b/packages/google-cloud-compute/google/cloud/compute_v1/gapic_metadata.json @@ -1954,6 +1954,11 @@ "set_node_template" ] }, + "SimulateMaintenanceEvent": { + "methods": [ + "simulate_maintenance_event" + ] + }, "TestIamPermissions": { "methods": [ "test_iam_permissions" diff --git a/packages/google-cloud-compute/google/cloud/compute_v1/services/node_groups/client.py b/packages/google-cloud-compute/google/cloud/compute_v1/services/node_groups/client.py index 8db1836a1135..d5b6c1867d5f 100644 --- a/packages/google-cloud-compute/google/cloud/compute_v1/services/node_groups/client.py +++ b/packages/google-cloud-compute/google/cloud/compute_v1/services/node_groups/client.py @@ -2601,6 +2601,283 @@ def error_code(self): # Done; return the response. return response + def simulate_maintenance_event_unary( + self, + request: Optional[ + Union[compute.SimulateMaintenanceEventNodeGroupRequest, dict] + ] = None, + *, + project: Optional[str] = None, + zone: Optional[str] = None, + node_group: Optional[str] = None, + node_groups_simulate_maintenance_event_request_resource: Optional[ + compute.NodeGroupsSimulateMaintenanceEventRequest + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> compute.Operation: + r"""Simulates maintenance event on specified nodes from + the node group. + + Args: + request (Union[google.cloud.compute_v1.types.SimulateMaintenanceEventNodeGroupRequest, dict]): + The request object. A request message for + NodeGroups.SimulateMaintenanceEvent. See the method + description for details. + project (str): + Project ID for this request. + This corresponds to the ``project`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + zone (str): + The name of the zone for this + request. + + This corresponds to the ``zone`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + node_group (str): + Name of the NodeGroup resource whose + nodes will go under maintenance + simulation. + + This corresponds to the ``node_group`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + node_groups_simulate_maintenance_event_request_resource (google.cloud.compute_v1.types.NodeGroupsSimulateMaintenanceEventRequest): + The body resource for this request + This corresponds to the ``node_groups_simulate_maintenance_event_request_resource`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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. + + Returns: + google.api_core.extended_operation.ExtendedOperation: + An object representing a extended + long-running operation. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any( + [ + project, + zone, + node_group, + node_groups_simulate_maintenance_event_request_resource, + ] + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a compute.SimulateMaintenanceEventNodeGroupRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, compute.SimulateMaintenanceEventNodeGroupRequest): + request = compute.SimulateMaintenanceEventNodeGroupRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if project is not None: + request.project = project + if zone is not None: + request.zone = zone + if node_group is not None: + request.node_group = node_group + if node_groups_simulate_maintenance_event_request_resource is not None: + request.node_groups_simulate_maintenance_event_request_resource = ( + node_groups_simulate_maintenance_event_request_resource + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.simulate_maintenance_event + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + ( + ("project", request.project), + ("zone", request.zone), + ("node_group", request.node_group), + ) + ), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def simulate_maintenance_event( + self, + request: Optional[ + Union[compute.SimulateMaintenanceEventNodeGroupRequest, dict] + ] = None, + *, + project: Optional[str] = None, + zone: Optional[str] = None, + node_group: Optional[str] = None, + node_groups_simulate_maintenance_event_request_resource: Optional[ + compute.NodeGroupsSimulateMaintenanceEventRequest + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> extended_operation.ExtendedOperation: + r"""Simulates maintenance event on specified nodes from + the node group. + + Args: + request (Union[google.cloud.compute_v1.types.SimulateMaintenanceEventNodeGroupRequest, dict]): + The request object. A request message for + NodeGroups.SimulateMaintenanceEvent. See the method + description for details. + project (str): + Project ID for this request. + This corresponds to the ``project`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + zone (str): + The name of the zone for this + request. + + This corresponds to the ``zone`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + node_group (str): + Name of the NodeGroup resource whose + nodes will go under maintenance + simulation. + + This corresponds to the ``node_group`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + node_groups_simulate_maintenance_event_request_resource (google.cloud.compute_v1.types.NodeGroupsSimulateMaintenanceEventRequest): + The body resource for this request + This corresponds to the ``node_groups_simulate_maintenance_event_request_resource`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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. + + Returns: + google.api_core.extended_operation.ExtendedOperation: + An object representing a extended + long-running operation. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any( + [ + project, + zone, + node_group, + node_groups_simulate_maintenance_event_request_resource, + ] + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a compute.SimulateMaintenanceEventNodeGroupRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, compute.SimulateMaintenanceEventNodeGroupRequest): + request = compute.SimulateMaintenanceEventNodeGroupRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if project is not None: + request.project = project + if zone is not None: + request.zone = zone + if node_group is not None: + request.node_group = node_group + if node_groups_simulate_maintenance_event_request_resource is not None: + request.node_groups_simulate_maintenance_event_request_resource = ( + node_groups_simulate_maintenance_event_request_resource + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.simulate_maintenance_event + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + ( + ("project", request.project), + ("zone", request.zone), + ("node_group", request.node_group), + ) + ), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + operation_service = self._transport._zone_operations_client + operation_request = compute.GetZoneOperationRequest() + operation_request.project = request.project + operation_request.zone = request.zone + operation_request.operation = response.name + + get_operation = functools.partial(operation_service.get, operation_request) + # Cancel is not part of extended operations yet. + cancel_operation = lambda: None + + # Note: this class is an implementation detail to provide a uniform + # set of names for certain fields in the extended operation proto message. + # See google.api_core.extended_operation.ExtendedOperation for details + # on these properties and the expected interface. + class _CustomOperation(extended_operation.ExtendedOperation): + @property + def error_message(self): + return self._extended_operation.http_error_message + + @property + def error_code(self): + return self._extended_operation.http_error_status_code + + response = _CustomOperation.make(get_operation, cancel_operation, response) + + # Done; return the response. + return response + def test_iam_permissions( self, request: Optional[ diff --git a/packages/google-cloud-compute/google/cloud/compute_v1/services/node_groups/transports/base.py b/packages/google-cloud-compute/google/cloud/compute_v1/services/node_groups/transports/base.py index 0e46897e58ec..10f618915d99 100644 --- a/packages/google-cloud-compute/google/cloud/compute_v1/services/node_groups/transports/base.py +++ b/packages/google-cloud-compute/google/cloud/compute_v1/services/node_groups/transports/base.py @@ -187,6 +187,11 @@ def _prep_wrapped_messages(self, client_info): default_timeout=None, client_info=client_info, ), + self.simulate_maintenance_event: gapic_v1.method.wrap_method( + self.simulate_maintenance_event, + default_timeout=None, + client_info=client_info, + ), self.test_iam_permissions: gapic_v1.method.wrap_method( self.test_iam_permissions, default_timeout=None, @@ -313,6 +318,15 @@ def set_node_template( ]: raise NotImplementedError() + @property + def simulate_maintenance_event( + self, + ) -> Callable[ + [compute.SimulateMaintenanceEventNodeGroupRequest], + Union[compute.Operation, Awaitable[compute.Operation]], + ]: + raise NotImplementedError() + @property def test_iam_permissions( self, diff --git a/packages/google-cloud-compute/google/cloud/compute_v1/services/node_groups/transports/rest.py b/packages/google-cloud-compute/google/cloud/compute_v1/services/node_groups/transports/rest.py index b9c3fa3f15ac..74df9b929d79 100644 --- a/packages/google-cloud-compute/google/cloud/compute_v1/services/node_groups/transports/rest.py +++ b/packages/google-cloud-compute/google/cloud/compute_v1/services/node_groups/transports/rest.py @@ -159,6 +159,14 @@ def post_set_node_template(self, response): logging.log(f"Received response: {response}") return response + def pre_simulate_maintenance_event(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_simulate_maintenance_event(self, response): + logging.log(f"Received response: {response}") + return response + def pre_test_iam_permissions(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -427,6 +435,31 @@ def post_set_node_template(self, response: compute.Operation) -> compute.Operati """ return response + def pre_simulate_maintenance_event( + self, + request: compute.SimulateMaintenanceEventNodeGroupRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[ + compute.SimulateMaintenanceEventNodeGroupRequest, Sequence[Tuple[str, str]] + ]: + """Pre-rpc interceptor for simulate_maintenance_event + + Override in a subclass to manipulate the request or metadata + before they are sent to the NodeGroups server. + """ + return request, metadata + + def post_simulate_maintenance_event( + self, response: compute.Operation + ) -> compute.Operation: + """Post-rpc interceptor for simulate_maintenance_event + + Override in a subclass to manipulate the response + after it is returned by the NodeGroups server but before + it is returned to user code. + """ + return response + def pre_test_iam_permissions( self, request: compute.TestIamPermissionsNodeGroupRequest, @@ -1838,6 +1871,120 @@ def __call__( resp = self._interceptor.post_set_node_template(resp) return resp + class _SimulateMaintenanceEvent(NodeGroupsRestStub): + def __hash__(self): + return hash("SimulateMaintenanceEvent") + + __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 + } + + def __call__( + self, + request: compute.SimulateMaintenanceEventNodeGroupRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> compute.Operation: + r"""Call the simulate maintenance + event method over HTTP. + + Args: + request (~.compute.SimulateMaintenanceEventNodeGroupRequest): + The request object. A request message for + NodeGroups.SimulateMaintenanceEvent. See + the method description for details. + + 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. + + Returns: + ~.compute.Operation: + Represents an Operation resource. Google Compute Engine + has three Operation resources: \* + `Global `__ + \* + `Regional `__ + \* + `Zonal `__ + You can use an operation resource to manage asynchronous + API requests. For more information, read Handling API + responses. Operations can be global, regional or zonal. + - For global operations, use the ``globalOperations`` + resource. - For regional operations, use the + ``regionOperations`` resource. - For zonal operations, + use the ``zonalOperations`` resource. For more + information, read Global, Regional, and Zonal Resources. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/compute/v1/projects/{project}/zones/{zone}/nodeGroups/{node_group}/simulateMaintenanceEvent", + "body": "node_groups_simulate_maintenance_event_request_resource", + }, + ] + request, metadata = self._interceptor.pre_simulate_maintenance_event( + request, metadata + ) + pb_request = compute.SimulateMaintenanceEventNodeGroupRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], + including_default_value_fields=False, + use_integers_for_enums=False, + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + including_default_value_fields=False, + use_integers_for_enums=False, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=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 = compute.Operation() + pb_resp = compute.Operation.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_simulate_maintenance_event(resp) + return resp + class _TestIamPermissions(NodeGroupsRestStub): def __hash__(self): return hash("TestIamPermissions") @@ -2024,6 +2171,16 @@ def set_node_template( # In C++ this would require a dynamic_cast return self._SetNodeTemplate(self._session, self._host, self._interceptor) # type: ignore + @property + def simulate_maintenance_event( + self, + ) -> Callable[ + [compute.SimulateMaintenanceEventNodeGroupRequest], compute.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._SimulateMaintenanceEvent(self._session, self._host, self._interceptor) # type: ignore + @property def test_iam_permissions( self, diff --git a/packages/google-cloud-compute/google/cloud/compute_v1/types/__init__.py b/packages/google-cloud-compute/google/cloud/compute_v1/types/__init__.py index f605578983a0..2b5dc2eafc77 100644 --- a/packages/google-cloud-compute/google/cloud/compute_v1/types/__init__.py +++ b/packages/google-cloud-compute/google/cloud/compute_v1/types/__init__.py @@ -827,6 +827,7 @@ NodeGroupsListNodes, NodeGroupsScopedList, NodeGroupsSetNodeTemplateRequest, + NodeGroupsSimulateMaintenanceEventRequest, NodeTemplate, NodeTemplateAggregatedList, NodeTemplateList, @@ -1163,6 +1164,7 @@ ShieldedInstanceIntegrityPolicy, SignedUrlKey, SimulateMaintenanceEventInstanceRequest, + SimulateMaintenanceEventNodeGroupRequest, Snapshot, SnapshotList, SourceDiskEncryptionKey, @@ -2158,6 +2160,7 @@ "NodeGroupsListNodes", "NodeGroupsScopedList", "NodeGroupsSetNodeTemplateRequest", + "NodeGroupsSimulateMaintenanceEventRequest", "NodeTemplate", "NodeTemplateAggregatedList", "NodeTemplateList", @@ -2494,6 +2497,7 @@ "ShieldedInstanceIntegrityPolicy", "SignedUrlKey", "SimulateMaintenanceEventInstanceRequest", + "SimulateMaintenanceEventNodeGroupRequest", "Snapshot", "SnapshotList", "SourceDiskEncryptionKey", diff --git a/packages/google-cloud-compute/google/cloud/compute_v1/types/compute.py b/packages/google-cloud-compute/google/cloud/compute_v1/types/compute.py index a1d7f7bb99e5..9282406c09f3 100644 --- a/packages/google-cloud-compute/google/cloud/compute_v1/types/compute.py +++ b/packages/google-cloud-compute/google/cloud/compute_v1/types/compute.py @@ -835,6 +835,7 @@ "NodeGroupsListNodes", "NodeGroupsScopedList", "NodeGroupsSetNodeTemplateRequest", + "NodeGroupsSimulateMaintenanceEventRequest", "NodeTemplate", "NodeTemplateAggregatedList", "NodeTemplateList", @@ -1172,6 +1173,7 @@ "ShieldedInstanceIntegrityPolicy", "SignedUrlKey", "SimulateMaintenanceEventInstanceRequest", + "SimulateMaintenanceEventNodeGroupRequest", "Snapshot", "SnapshotList", "SourceDiskEncryptionKey", @@ -30593,6 +30595,8 @@ class Type(proto.Enum): No description available. SEV_CAPABLE (87083793): No description available. + SEV_LIVE_MIGRATABLE (392039820): + No description available. SEV_SNP_CAPABLE (426919): No description available. UEFI_COMPATIBLE (195865408): @@ -30608,6 +30612,7 @@ class Type(proto.Enum): MULTI_IP_SUBNET = 151776719 SECURE_BOOT = 376811194 SEV_CAPABLE = 87083793 + SEV_LIVE_MIGRATABLE = 392039820 SEV_SNP_CAPABLE = 426919 UEFI_COMPATIBLE = 195865408 VIRTIO_SCSI_MULTIQUEUE = 201597069 @@ -32139,13 +32144,13 @@ class HealthState(proto.Enum): A value indicating that the enum field is not set. DRAINING (480455402): - No description available. + Endpoint is being drained. HEALTHY (439801213): - No description available. + Endpoint is healthy. UNHEALTHY (462118084): - No description available. + Endpoint is unhealthy. UNKNOWN (433141802): - No description available. + Health status of the endpoint is unknown. """ UNDEFINED_HEALTH_STATE = 0 DRAINING = 480455402 @@ -63360,6 +63365,21 @@ class NodeGroupsSetNodeTemplateRequest(proto.Message): ) +class NodeGroupsSimulateMaintenanceEventRequest(proto.Message): + r""" + + Attributes: + nodes (MutableSequence[str]): + Names of the nodes to go under maintenance + simulation. + """ + + nodes: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=104993457, + ) + + class NodeTemplate(proto.Message): r"""Represent a sole-tenant Node Template resource. You can use a template to define properties for nodes in a node group. For @@ -84880,6 +84900,67 @@ class SimulateMaintenanceEventInstanceRequest(proto.Message): ) +class SimulateMaintenanceEventNodeGroupRequest(proto.Message): + r"""A request message for NodeGroups.SimulateMaintenanceEvent. + See the method description for details. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + node_group (str): + Name of the NodeGroup resource whose nodes + will go under maintenance simulation. + node_groups_simulate_maintenance_event_request_resource (google.cloud.compute_v1.types.NodeGroupsSimulateMaintenanceEventRequest): + The body resource for this request + project (str): + Project ID for this request. + request_id (str): + An optional request ID to identify requests. + Specify a unique request ID so that if you must + retry your request, the server will know to + ignore the request if it has already been + completed. For example, consider a situation + where you make an initial request and the + request times out. If you make the request again + with the same request ID, the server can check + if original operation with the same request ID + was received, and if so, will ignore the second + request. This prevents clients from accidentally + creating duplicate commitments. The request ID + must be a valid UUID with the exception that + zero UUID is not supported ( + 00000000-0000-0000-0000-000000000000). + + This field is a member of `oneof`_ ``_request_id``. + zone (str): + The name of the zone for this request. + """ + + node_group: str = proto.Field( + proto.STRING, + number=469958146, + ) + node_groups_simulate_maintenance_event_request_resource: "NodeGroupsSimulateMaintenanceEventRequest" = proto.Field( + proto.MESSAGE, + number=351468764, + message="NodeGroupsSimulateMaintenanceEventRequest", + ) + project: str = proto.Field( + proto.STRING, + number=227560217, + ) + request_id: str = proto.Field( + proto.STRING, + number=37109963, + optional=True, + ) + zone: str = proto.Field( + proto.STRING, + number=3744684, + ) + + class Snapshot(proto.Message): r"""Represents a Persistent Disk Snapshot resource. You can use snapshots to back up data on a regular interval. For more diff --git a/packages/google-cloud-compute/tests/unit/gapic/compute_v1/test_node_groups.py b/packages/google-cloud-compute/tests/unit/gapic/compute_v1/test_node_groups.py index ed8caf216f6f..223fee2707c2 100644 --- a/packages/google-cloud-compute/tests/unit/gapic/compute_v1/test_node_groups.py +++ b/packages/google-cloud-compute/tests/unit/gapic/compute_v1/test_node_groups.py @@ -6916,6 +6916,684 @@ def test_set_node_template_unary_rest_error(): ) +@pytest.mark.parametrize( + "request_type", + [ + compute.SimulateMaintenanceEventNodeGroupRequest, + dict, + ], +) +def test_simulate_maintenance_event_rest(request_type): + client = NodeGroupsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"project": "sample1", "zone": "sample2", "node_group": "sample3"} + request_init["node_groups_simulate_maintenance_event_request_resource"] = { + "nodes": ["nodes_value1", "nodes_value2"] + } + 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 = compute.Operation( + client_operation_id="client_operation_id_value", + creation_timestamp="creation_timestamp_value", + description="description_value", + end_time="end_time_value", + http_error_message="http_error_message_value", + http_error_status_code=2374, + id=205, + insert_time="insert_time_value", + kind="kind_value", + name="name_value", + operation_group_id="operation_group_id_value", + operation_type="operation_type_value", + progress=885, + region="region_value", + self_link="self_link_value", + start_time="start_time_value", + status=compute.Operation.Status.DONE, + status_message="status_message_value", + target_id=947, + target_link="target_link_value", + user="user_value", + zone="zone_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = compute.Operation.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.simulate_maintenance_event(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, extended_operation.ExtendedOperation) + assert response.client_operation_id == "client_operation_id_value" + assert response.creation_timestamp == "creation_timestamp_value" + assert response.description == "description_value" + assert response.end_time == "end_time_value" + assert response.http_error_message == "http_error_message_value" + assert response.http_error_status_code == 2374 + assert response.id == 205 + assert response.insert_time == "insert_time_value" + assert response.kind == "kind_value" + assert response.name == "name_value" + assert response.operation_group_id == "operation_group_id_value" + assert response.operation_type == "operation_type_value" + assert response.progress == 885 + assert response.region == "region_value" + assert response.self_link == "self_link_value" + assert response.start_time == "start_time_value" + assert response.status == compute.Operation.Status.DONE + assert response.status_message == "status_message_value" + assert response.target_id == 947 + assert response.target_link == "target_link_value" + assert response.user == "user_value" + assert response.zone == "zone_value" + + +def test_simulate_maintenance_event_rest_required_fields( + request_type=compute.SimulateMaintenanceEventNodeGroupRequest, +): + transport_class = transports.NodeGroupsRestTransport + + request_init = {} + request_init["node_group"] = "" + request_init["project"] = "" + request_init["zone"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False, + ) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).simulate_maintenance_event._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["nodeGroup"] = "node_group_value" + jsonified_request["project"] = "project_value" + jsonified_request["zone"] = "zone_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).simulate_maintenance_event._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("request_id",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "nodeGroup" in jsonified_request + assert jsonified_request["nodeGroup"] == "node_group_value" + assert "project" in jsonified_request + assert jsonified_request["project"] == "project_value" + assert "zone" in jsonified_request + assert jsonified_request["zone"] == "zone_value" + + client = NodeGroupsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = compute.Operation() + # 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 + + pb_return_value = compute.Operation.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.simulate_maintenance_event(request) + + expected_params = [] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_simulate_maintenance_event_rest_unset_required_fields(): + transport = transports.NodeGroupsRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.simulate_maintenance_event._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(("requestId",)) + & set( + ( + "nodeGroup", + "nodeGroupsSimulateMaintenanceEventRequestResource", + "project", + "zone", + ) + ) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_simulate_maintenance_event_rest_interceptors(null_interceptor): + transport = transports.NodeGroupsRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.NodeGroupsRestInterceptor(), + ) + client = NodeGroupsClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.NodeGroupsRestInterceptor, "post_simulate_maintenance_event" + ) as post, mock.patch.object( + transports.NodeGroupsRestInterceptor, "pre_simulate_maintenance_event" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = compute.SimulateMaintenanceEventNodeGroupRequest.pb( + compute.SimulateMaintenanceEventNodeGroupRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = compute.Operation.to_json(compute.Operation()) + + request = compute.SimulateMaintenanceEventNodeGroupRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = compute.Operation() + + client.simulate_maintenance_event( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_simulate_maintenance_event_rest_bad_request( + transport: str = "rest", + request_type=compute.SimulateMaintenanceEventNodeGroupRequest, +): + client = NodeGroupsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"project": "sample1", "zone": "sample2", "node_group": "sample3"} + request_init["node_groups_simulate_maintenance_event_request_resource"] = { + "nodes": ["nodes_value1", "nodes_value2"] + } + 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 = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.simulate_maintenance_event(request) + + +def test_simulate_maintenance_event_rest_flattened(): + client = NodeGroupsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # 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 = compute.Operation() + + # get arguments that satisfy an http rule for this method + sample_request = { + "project": "sample1", + "zone": "sample2", + "node_group": "sample3", + } + + # get truthy value for each flattened field + mock_args = dict( + project="project_value", + zone="zone_value", + node_group="node_group_value", + node_groups_simulate_maintenance_event_request_resource=compute.NodeGroupsSimulateMaintenanceEventRequest( + nodes=["nodes_value"] + ), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = compute.Operation.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.simulate_maintenance_event(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/compute/v1/projects/{project}/zones/{zone}/nodeGroups/{node_group}/simulateMaintenanceEvent" + % client.transport._host, + args[1], + ) + + +def test_simulate_maintenance_event_rest_flattened_error(transport: str = "rest"): + client = NodeGroupsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.simulate_maintenance_event( + compute.SimulateMaintenanceEventNodeGroupRequest(), + project="project_value", + zone="zone_value", + node_group="node_group_value", + node_groups_simulate_maintenance_event_request_resource=compute.NodeGroupsSimulateMaintenanceEventRequest( + nodes=["nodes_value"] + ), + ) + + +def test_simulate_maintenance_event_rest_error(): + client = NodeGroupsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + compute.SimulateMaintenanceEventNodeGroupRequest, + dict, + ], +) +def test_simulate_maintenance_event_unary_rest(request_type): + client = NodeGroupsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"project": "sample1", "zone": "sample2", "node_group": "sample3"} + request_init["node_groups_simulate_maintenance_event_request_resource"] = { + "nodes": ["nodes_value1", "nodes_value2"] + } + 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 = compute.Operation( + client_operation_id="client_operation_id_value", + creation_timestamp="creation_timestamp_value", + description="description_value", + end_time="end_time_value", + http_error_message="http_error_message_value", + http_error_status_code=2374, + id=205, + insert_time="insert_time_value", + kind="kind_value", + name="name_value", + operation_group_id="operation_group_id_value", + operation_type="operation_type_value", + progress=885, + region="region_value", + self_link="self_link_value", + start_time="start_time_value", + status=compute.Operation.Status.DONE, + status_message="status_message_value", + target_id=947, + target_link="target_link_value", + user="user_value", + zone="zone_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = compute.Operation.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.simulate_maintenance_event_unary(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, compute.Operation) + + +def test_simulate_maintenance_event_unary_rest_required_fields( + request_type=compute.SimulateMaintenanceEventNodeGroupRequest, +): + transport_class = transports.NodeGroupsRestTransport + + request_init = {} + request_init["node_group"] = "" + request_init["project"] = "" + request_init["zone"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False, + ) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).simulate_maintenance_event._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["nodeGroup"] = "node_group_value" + jsonified_request["project"] = "project_value" + jsonified_request["zone"] = "zone_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).simulate_maintenance_event._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("request_id",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "nodeGroup" in jsonified_request + assert jsonified_request["nodeGroup"] == "node_group_value" + assert "project" in jsonified_request + assert jsonified_request["project"] == "project_value" + assert "zone" in jsonified_request + assert jsonified_request["zone"] == "zone_value" + + client = NodeGroupsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = compute.Operation() + # 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 + + pb_return_value = compute.Operation.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.simulate_maintenance_event_unary(request) + + expected_params = [] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_simulate_maintenance_event_unary_rest_unset_required_fields(): + transport = transports.NodeGroupsRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.simulate_maintenance_event._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(("requestId",)) + & set( + ( + "nodeGroup", + "nodeGroupsSimulateMaintenanceEventRequestResource", + "project", + "zone", + ) + ) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_simulate_maintenance_event_unary_rest_interceptors(null_interceptor): + transport = transports.NodeGroupsRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.NodeGroupsRestInterceptor(), + ) + client = NodeGroupsClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.NodeGroupsRestInterceptor, "post_simulate_maintenance_event" + ) as post, mock.patch.object( + transports.NodeGroupsRestInterceptor, "pre_simulate_maintenance_event" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = compute.SimulateMaintenanceEventNodeGroupRequest.pb( + compute.SimulateMaintenanceEventNodeGroupRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = compute.Operation.to_json(compute.Operation()) + + request = compute.SimulateMaintenanceEventNodeGroupRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = compute.Operation() + + client.simulate_maintenance_event_unary( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_simulate_maintenance_event_unary_rest_bad_request( + transport: str = "rest", + request_type=compute.SimulateMaintenanceEventNodeGroupRequest, +): + client = NodeGroupsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"project": "sample1", "zone": "sample2", "node_group": "sample3"} + request_init["node_groups_simulate_maintenance_event_request_resource"] = { + "nodes": ["nodes_value1", "nodes_value2"] + } + 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 = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.simulate_maintenance_event_unary(request) + + +def test_simulate_maintenance_event_unary_rest_flattened(): + client = NodeGroupsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # 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 = compute.Operation() + + # get arguments that satisfy an http rule for this method + sample_request = { + "project": "sample1", + "zone": "sample2", + "node_group": "sample3", + } + + # get truthy value for each flattened field + mock_args = dict( + project="project_value", + zone="zone_value", + node_group="node_group_value", + node_groups_simulate_maintenance_event_request_resource=compute.NodeGroupsSimulateMaintenanceEventRequest( + nodes=["nodes_value"] + ), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = compute.Operation.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.simulate_maintenance_event_unary(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/compute/v1/projects/{project}/zones/{zone}/nodeGroups/{node_group}/simulateMaintenanceEvent" + % client.transport._host, + args[1], + ) + + +def test_simulate_maintenance_event_unary_rest_flattened_error(transport: str = "rest"): + client = NodeGroupsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.simulate_maintenance_event_unary( + compute.SimulateMaintenanceEventNodeGroupRequest(), + project="project_value", + zone="zone_value", + node_group="node_group_value", + node_groups_simulate_maintenance_event_request_resource=compute.NodeGroupsSimulateMaintenanceEventRequest( + nodes=["nodes_value"] + ), + ) + + +def test_simulate_maintenance_event_unary_rest_error(): + client = NodeGroupsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + @pytest.mark.parametrize( "request_type", [ @@ -7345,6 +8023,7 @@ def test_node_groups_base_transport(): "patch", "set_iam_policy", "set_node_template", + "simulate_maintenance_event", "test_iam_permissions", ) for method in methods: @@ -7519,6 +8198,9 @@ def test_node_groups_client_transport_session_collision(transport_name): session1 = client1.transport.set_node_template._session session2 = client2.transport.set_node_template._session assert session1 != session2 + session1 = client1.transport.simulate_maintenance_event._session + session2 = client2.transport.simulate_maintenance_event._session + assert session1 != session2 session1 = client1.transport.test_iam_permissions._session session2 = client2.transport.test_iam_permissions._session assert session1 != session2