From d7146eb1ed826bcd1f2bb29b4de4793ff3105573 Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Tue, 9 Nov 2021 11:32:14 +0000 Subject: [PATCH] feat(v1beta1): Support Multiple Read Replicas when creating Instance (#136) - [ ] Regenerate this pull request now. PiperOrigin-RevId: 408360324 Source-Link: https://github.com/googleapis/googleapis/commit/78eb8a2bf5c5959e181c89529f04838103a16d5b Source-Link: https://github.com/googleapis/googleapis-gen/commit/89f136d01eb64da196145565f31855cf8c2a3968 Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiODlmMTM2ZDAxZWI2NGRhMTk2MTQ1NTY1ZjMxODU1Y2Y4YzJhMzk2OCJ9 --- google/cloud/redis_v1beta1/__init__.py | 2 + .../services/cloud_redis/async_client.py | 11 +- .../services/cloud_redis/client.py | 11 +- .../services/cloud_redis/transports/grpc.py | 8 +- .../cloud_redis/transports/grpc_asyncio.py | 8 +- google/cloud/redis_v1beta1/types/__init__.py | 2 + .../cloud/redis_v1beta1/types/cloud_redis.py | 117 ++++++++++++------ .../gapic/redis_v1beta1/test_cloud_redis.py | 22 ++++ 8 files changed, 127 insertions(+), 54 deletions(-) diff --git a/google/cloud/redis_v1beta1/__init__.py b/google/cloud/redis_v1beta1/__init__.py index c39dd68..03305e4 100644 --- a/google/cloud/redis_v1beta1/__init__.py +++ b/google/cloud/redis_v1beta1/__init__.py @@ -30,6 +30,7 @@ from .types.cloud_redis import ListInstancesRequest from .types.cloud_redis import ListInstancesResponse from .types.cloud_redis import LocationMetadata +from .types.cloud_redis import NodeInfo from .types.cloud_redis import OutputConfig from .types.cloud_redis import UpdateInstanceRequest from .types.cloud_redis import UpgradeInstanceRequest @@ -51,6 +52,7 @@ "ListInstancesRequest", "ListInstancesResponse", "LocationMetadata", + "NodeInfo", "OutputConfig", "UpdateInstanceRequest", "UpgradeInstanceRequest", diff --git a/google/cloud/redis_v1beta1/services/cloud_redis/async_client.py b/google/cloud/redis_v1beta1/services/cloud_redis/async_client.py index f247acb..8c93b09 100644 --- a/google/cloud/redis_v1beta1/services/cloud_redis/async_client.py +++ b/google/cloud/redis_v1beta1/services/cloud_redis/async_client.py @@ -59,7 +59,7 @@ class CloudRedisAsyncClient: - As such, Redis instances are resources of the form: ``/projects/{project_id}/locations/{location_id}/instances/{instance_id}`` - Note that location_id must be refering to a GCP ``region``; for + Note that location_id must be referring to a GCP ``region``; for example: - ``projects/redpepper-1290/locations/us-central1/instances/my-redis`` @@ -226,7 +226,7 @@ async def list_instances( Returns: google.cloud.redis_v1beta1.services.cloud_redis.pagers.ListInstancesAsyncPager: Response for - [ListInstances][google.cloud.redis.v1beta1.CloudRedis.ListInstances]. + [ListInstances][google.cloud.redis.v1beta1.CloudRedis.ListInstances]. Iterating over this object will yield results and resolve additional pages automatically. @@ -364,8 +364,8 @@ async def create_instance( The creation is executed asynchronously and callers may check the returned operation to track its progress. Once the operation - is completed the Redis instance will be fully functional. - Completed longrunning.Operation will contain the new instance + is completed the Redis instance will be fully functional. The + completed longrunning.Operation will contain the new instance object in the response field. The returned operation is automatically deleted after a few @@ -498,6 +498,7 @@ async def update_instance( - ``labels`` - ``memorySizeGb`` - ``redisConfig`` + - ``replica_count`` This corresponds to the ``update_mask`` field on the ``request`` instance; if ``request`` is provided, this @@ -875,7 +876,7 @@ async def failover_instance( timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> operation_async.AsyncOperation: - r"""Initiates a failover of the master node to current + r"""Initiates a failover of the primary node to current replica node for a specific STANDARD tier Cloud Memorystore for Redis instance. diff --git a/google/cloud/redis_v1beta1/services/cloud_redis/client.py b/google/cloud/redis_v1beta1/services/cloud_redis/client.py index 6cd9936..532263e 100644 --- a/google/cloud/redis_v1beta1/services/cloud_redis/client.py +++ b/google/cloud/redis_v1beta1/services/cloud_redis/client.py @@ -94,7 +94,7 @@ class CloudRedisClient(metaclass=CloudRedisClientMeta): - As such, Redis instances are resources of the form: ``/projects/{project_id}/locations/{location_id}/instances/{instance_id}`` - Note that location_id must be refering to a GCP ``region``; for + Note that location_id must be referring to a GCP ``region``; for example: - ``projects/redpepper-1290/locations/us-central1/instances/my-redis`` @@ -416,7 +416,7 @@ def list_instances( Returns: google.cloud.redis_v1beta1.services.cloud_redis.pagers.ListInstancesPager: Response for - [ListInstances][google.cloud.redis.v1beta1.CloudRedis.ListInstances]. + [ListInstances][google.cloud.redis.v1beta1.CloudRedis.ListInstances]. Iterating over this object will yield results and resolve additional pages automatically. @@ -554,8 +554,8 @@ def create_instance( The creation is executed asynchronously and callers may check the returned operation to track its progress. Once the operation - is completed the Redis instance will be fully functional. - Completed longrunning.Operation will contain the new instance + is completed the Redis instance will be fully functional. The + completed longrunning.Operation will contain the new instance object in the response field. The returned operation is automatically deleted after a few @@ -688,6 +688,7 @@ def update_instance( - ``labels`` - ``memorySizeGb`` - ``redisConfig`` + - ``replica_count`` This corresponds to the ``update_mask`` field on the ``request`` instance; if ``request`` is provided, this @@ -1065,7 +1066,7 @@ def failover_instance( timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> operation.Operation: - r"""Initiates a failover of the master node to current + r"""Initiates a failover of the primary node to current replica node for a specific STANDARD tier Cloud Memorystore for Redis instance. diff --git a/google/cloud/redis_v1beta1/services/cloud_redis/transports/grpc.py b/google/cloud/redis_v1beta1/services/cloud_redis/transports/grpc.py index 5c5374e..816fc2a 100644 --- a/google/cloud/redis_v1beta1/services/cloud_redis/transports/grpc.py +++ b/google/cloud/redis_v1beta1/services/cloud_redis/transports/grpc.py @@ -50,7 +50,7 @@ class CloudRedisGrpcTransport(CloudRedisTransport): - As such, Redis instances are resources of the form: ``/projects/{project_id}/locations/{location_id}/instances/{instance_id}`` - Note that location_id must be refering to a GCP ``region``; for + Note that location_id must be referring to a GCP ``region``; for example: - ``projects/redpepper-1290/locations/us-central1/instances/my-redis`` @@ -339,8 +339,8 @@ def create_instance( The creation is executed asynchronously and callers may check the returned operation to track its progress. Once the operation - is completed the Redis instance will be fully functional. - Completed longrunning.Operation will contain the new instance + is completed the Redis instance will be fully functional. The + completed longrunning.Operation will contain the new instance object in the response field. The returned operation is automatically deleted after a few @@ -492,7 +492,7 @@ def failover_instance( ) -> Callable[[cloud_redis.FailoverInstanceRequest], operations_pb2.Operation]: r"""Return a callable for the failover instance method over gRPC. - Initiates a failover of the master node to current + Initiates a failover of the primary node to current replica node for a specific STANDARD tier Cloud Memorystore for Redis instance. diff --git a/google/cloud/redis_v1beta1/services/cloud_redis/transports/grpc_asyncio.py b/google/cloud/redis_v1beta1/services/cloud_redis/transports/grpc_asyncio.py index 21ecf3b..c3ec320 100644 --- a/google/cloud/redis_v1beta1/services/cloud_redis/transports/grpc_asyncio.py +++ b/google/cloud/redis_v1beta1/services/cloud_redis/transports/grpc_asyncio.py @@ -51,7 +51,7 @@ class CloudRedisGrpcAsyncIOTransport(CloudRedisTransport): - As such, Redis instances are resources of the form: ``/projects/{project_id}/locations/{location_id}/instances/{instance_id}`` - Note that location_id must be refering to a GCP ``region``; for + Note that location_id must be referring to a GCP ``region``; for example: - ``projects/redpepper-1290/locations/us-central1/instances/my-redis`` @@ -345,8 +345,8 @@ def create_instance( The creation is executed asynchronously and callers may check the returned operation to track its progress. Once the operation - is completed the Redis instance will be fully functional. - Completed longrunning.Operation will contain the new instance + is completed the Redis instance will be fully functional. The + completed longrunning.Operation will contain the new instance object in the response field. The returned operation is automatically deleted after a few @@ -508,7 +508,7 @@ def failover_instance( ]: r"""Return a callable for the failover instance method over gRPC. - Initiates a failover of the master node to current + Initiates a failover of the primary node to current replica node for a specific STANDARD tier Cloud Memorystore for Redis instance. diff --git a/google/cloud/redis_v1beta1/types/__init__.py b/google/cloud/redis_v1beta1/types/__init__.py index 70064ba..23c4999 100644 --- a/google/cloud/redis_v1beta1/types/__init__.py +++ b/google/cloud/redis_v1beta1/types/__init__.py @@ -27,6 +27,7 @@ ListInstancesRequest, ListInstancesResponse, LocationMetadata, + NodeInfo, OutputConfig, UpdateInstanceRequest, UpgradeInstanceRequest, @@ -47,6 +48,7 @@ "ListInstancesRequest", "ListInstancesResponse", "LocationMetadata", + "NodeInfo", "OutputConfig", "UpdateInstanceRequest", "UpgradeInstanceRequest", diff --git a/google/cloud/redis_v1beta1/types/cloud_redis.py b/google/cloud/redis_v1beta1/types/cloud_redis.py index 43c8e3b..f21d25e 100644 --- a/google/cloud/redis_v1beta1/types/cloud_redis.py +++ b/google/cloud/redis_v1beta1/types/cloud_redis.py @@ -22,6 +22,7 @@ __protobuf__ = proto.module( package="google.cloud.redis.v1beta1", manifest={ + "NodeInfo", "Instance", "ListInstancesRequest", "ListInstancesResponse", @@ -43,6 +44,21 @@ ) +class NodeInfo(proto.Message): + r"""Node specific properties. + + Attributes: + id (str): + Output only. Node identifying string. e.g. + 'node-0', 'node-1' + zone (str): + Output only. Location of the node. + """ + + id = proto.Field(proto.STRING, number=1,) + zone = proto.Field(proto.STRING, number=2,) + + class Instance(proto.Message): r"""A Google Cloud Redis instance. @@ -68,19 +84,21 @@ class Instance(proto.Message): Resource labels to represent user provided metadata location_id (str): - Optional. The zone where the instance will be provisioned. - If not provided, the service will choose a zone for the - instance. For STANDARD_HA tier, instances will be created - across two zones for protection against zonal failures. If - [alternative_location_id][google.cloud.redis.v1beta1.Instance.alternative_location_id] - is also provided, it must be different from - [location_id][google.cloud.redis.v1beta1.Instance.location_id]. + Optional. The zone where the instance will be + provisioned. If not provided, the service will + choose a zone from the specified region for the + instance. For standard tier, additional nodes + will be added across multiple zones for + protection against zonal failures. If specified, + at least one node will be provisioned in this + zone. alternative_location_id (str): - Optional. Only applicable to STANDARD_HA tier which protects - the instance against zonal failures by provisioning it - across two zones. If provided, it must be a different zone - from the one provided in - [location_id][google.cloud.redis.v1beta1.Instance.location_id]. + Optional. If specified, at least one node will be + provisioned in this zone in addition to the zone specified + in location_id. Only applicable to standard tier. If + provided, it must be a different zone from the one provided + in [location_id]. Additional nodes beyond the first 2 will + be placed in zones selected by the service. redis_version (str): Optional. The version of Redis software. If not provided, latest supported version will be used. Currently, the @@ -89,32 +107,29 @@ class Instance(proto.Message): - ``REDIS_3_2`` for Redis 3.2 compatibility - ``REDIS_4_0`` for Redis 4.0 compatibility (default) - ``REDIS_5_0`` for Redis 5.0 compatibility + - ``REDIS_6_X`` for Redis 6.x compatibility reserved_ip_range (str): - Optional. The CIDR range of internal - addresses that are reserved for this instance. - If not provided, the service will choose an - unused /29 block, for example, 10.0.0.0/29 or - 192.168.0.0/29. Ranges must be unique and non- - overlapping with existing subnets in an - authorized network. + Optional. For DIRECT_PEERING mode, the CIDR range of + internal addresses that are reserved for this instance. + Range must be unique and non-overlapping with existing + subnets in an authorized network. For PRIVATE_SERVICE_ACCESS + mode, the name of one allocated IP address ranges associated + with this private service access connection. If not + provided, the service will choose an unused /29 block, for + example, 10.0.0.0/29 or 192.168.0.0/29. For + READ_REPLICAS_ENABLED the default block size is /28. host (str): Output only. Hostname or IP address of the - exposed Redis endpoint used by clients to + exposed Redis endpoint used by clients to connect to the service. port (int): Output only. The port number of the exposed Redis endpoint. current_location_id (str): - Output only. The current zone where the Redis endpoint is - placed. For Basic Tier instances, this will always be the - same as the - [location_id][google.cloud.redis.v1beta1.Instance.location_id] - provided by the user at creation time. For Standard Tier - instances, this can be either - [location_id][google.cloud.redis.v1beta1.Instance.location_id] - or - [alternative_location_id][google.cloud.redis.v1beta1.Instance.alternative_location_id] - and can change after a failover event. + Output only. The current zone where the Redis primary node + is located. In basic tier, this will always be the same as + [location_id]. In standard tier, this can be the zone of any + node in the instance. create_time (google.protobuf.timestamp_pb2.Timestamp): Output only. The time the instance was created. @@ -161,9 +176,27 @@ class Instance(proto.Message): change over time for a given instance so should be checked before each import/export operation. connect_mode (google.cloud.redis_v1beta1.types.Instance.ConnectMode): - Optional. The connect mode of Redis instance. If not - provided, default one will be used. Current default: - DIRECT_PEERING. + Optional. The network connect mode of the Redis instance. If + not provided, the connect mode defaults to DIRECT_PEERING. + replica_count (int): + Optional. The number of replica nodes. Valid range for + standard tier is [1-5] and defaults to 1. Valid value for + basic tier is 0 and defaults to 0. + nodes (Sequence[google.cloud.redis_v1beta1.types.NodeInfo]): + Output only. Info per node. + read_endpoint (str): + Output only. Hostname or IP address of the + exposed readonly Redis endpoint. Standard tier + only. Targets all healthy replica nodes in + instance. Replication is asynchronous and + replica nodes will exhibit some lag behind the + primary. Write requests must target 'host'. + read_endpoint_port (int): + Output only. The port number of the exposed + readonly redis endpoint. Standard tier only. + Write requests should target 'port'. + read_replicas_mode (google.cloud.redis_v1beta1.types.Instance.ReadReplicasMode): + Optional. Read replica mode. """ class State(proto.Enum): @@ -190,6 +223,12 @@ class ConnectMode(proto.Enum): DIRECT_PEERING = 1 PRIVATE_SERVICE_ACCESS = 2 + class ReadReplicasMode(proto.Enum): + r"""Read replicas mode.""" + READ_REPLICAS_MODE_UNSPECIFIED = 0 + READ_REPLICAS_DISABLED = 1 + READ_REPLICAS_ENABLED = 2 + name = proto.Field(proto.STRING, number=1,) display_name = proto.Field(proto.STRING, number=2,) labels = proto.MapField(proto.STRING, proto.STRING, number=3,) @@ -211,6 +250,11 @@ class ConnectMode(proto.Enum): authorized_network = proto.Field(proto.STRING, number=20,) persistence_iam_identity = proto.Field(proto.STRING, number=21,) connect_mode = proto.Field(proto.ENUM, number=22, enum=ConnectMode,) + replica_count = proto.Field(proto.INT32, number=31,) + nodes = proto.RepeatedField(proto.MESSAGE, number=32, message="NodeInfo",) + read_endpoint = proto.Field(proto.STRING, number=33,) + read_endpoint_port = proto.Field(proto.INT32, number=34,) + read_replicas_mode = proto.Field(proto.ENUM, number=35, enum=ReadReplicasMode,) class ListInstancesRequest(proto.Message): @@ -254,9 +298,9 @@ class ListInstancesResponse(proto.Message): If the ``location_id`` in the parent field of the request is "-", all regions available to the project are queried, and the results aggregated. If in such an aggregated query a - location is unavailable, a dummy Redis entry is included in - the response with the ``name`` field set to a value of the - form + location is unavailable, a placeholder Redis entry is + included in the response with the ``name`` field set to a + value of the form ``projects/{project_id}/locations/{location_id}/instances/``- and the ``status`` field set to ERROR and ``status_message`` field set to "location not available for ListInstances". @@ -334,6 +378,7 @@ class UpdateInstanceRequest(proto.Message): - ``labels`` - ``memorySizeGb`` - ``redisConfig`` + - ``replica_count`` instance (google.cloud.redis_v1beta1.types.Instance): Required. Update description. Only fields specified in update_mask are updated. diff --git a/tests/unit/gapic/redis_v1beta1/test_cloud_redis.py b/tests/unit/gapic/redis_v1beta1/test_cloud_redis.py index e7afaf9..f0d5179 100644 --- a/tests/unit/gapic/redis_v1beta1/test_cloud_redis.py +++ b/tests/unit/gapic/redis_v1beta1/test_cloud_redis.py @@ -843,6 +843,10 @@ def test_get_instance( authorized_network="authorized_network_value", persistence_iam_identity="persistence_iam_identity_value", connect_mode=cloud_redis.Instance.ConnectMode.DIRECT_PEERING, + replica_count=1384, + read_endpoint="read_endpoint_value", + read_endpoint_port=1920, + read_replicas_mode=cloud_redis.Instance.ReadReplicasMode.READ_REPLICAS_DISABLED, ) response = client.get_instance(request) @@ -869,6 +873,13 @@ def test_get_instance( assert response.authorized_network == "authorized_network_value" assert response.persistence_iam_identity == "persistence_iam_identity_value" assert response.connect_mode == cloud_redis.Instance.ConnectMode.DIRECT_PEERING + assert response.replica_count == 1384 + assert response.read_endpoint == "read_endpoint_value" + assert response.read_endpoint_port == 1920 + assert ( + response.read_replicas_mode + == cloud_redis.Instance.ReadReplicasMode.READ_REPLICAS_DISABLED + ) def test_get_instance_from_dict(): @@ -923,6 +934,10 @@ async def test_get_instance_async( authorized_network="authorized_network_value", persistence_iam_identity="persistence_iam_identity_value", connect_mode=cloud_redis.Instance.ConnectMode.DIRECT_PEERING, + replica_count=1384, + read_endpoint="read_endpoint_value", + read_endpoint_port=1920, + read_replicas_mode=cloud_redis.Instance.ReadReplicasMode.READ_REPLICAS_DISABLED, ) ) response = await client.get_instance(request) @@ -950,6 +965,13 @@ async def test_get_instance_async( assert response.authorized_network == "authorized_network_value" assert response.persistence_iam_identity == "persistence_iam_identity_value" assert response.connect_mode == cloud_redis.Instance.ConnectMode.DIRECT_PEERING + assert response.replica_count == 1384 + assert response.read_endpoint == "read_endpoint_value" + assert response.read_endpoint_port == 1920 + assert ( + response.read_replicas_mode + == cloud_redis.Instance.ReadReplicasMode.READ_REPLICAS_DISABLED + ) @pytest.mark.asyncio