Skip to content

Commit

Permalink
feat: add dual region bucket support and sample (#748)
Browse files Browse the repository at this point in the history
* feat: add dual region bucket support and tests

* add dual region bucket sample

* fix lint

* update docstrings and doc ref links

Co-authored-by: Daniel Bankhead <dan@danielbankhead.com>
  • Loading branch information
cojenco and danielbankhead committed Apr 6, 2022
1 parent 924b65f commit 752e8ab
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 3 deletions.
2 changes: 1 addition & 1 deletion google/cloud/storage/bucket.py
Expand Up @@ -2316,7 +2316,7 @@ def location(self):
"""Retrieve location configured for this bucket.
See https://cloud.google.com/storage/docs/json_api/v1/buckets and
https://cloud.google.com/storage/docs/bucket-locations
https://cloud.google.com/storage/docs/locations
Returns ``None`` if the property has not been set before creation,
or if the bucket's resource has not been loaded from the server.
Expand Down
5 changes: 3 additions & 2 deletions google/cloud/storage/client.py
Expand Up @@ -875,8 +875,9 @@ def create_bucket(
made via created bucket.
location (str):
(Optional) The location of the bucket. If not passed,
the default location, US, will be used. See
https://cloud.google.com/storage/docs/bucket-locations
the default location, US, will be used. If specifying a dual-region,
can be specified as a string, e.g., 'US-CENTRAL1+US-WEST1'. See:
https://cloud.google.com/storage/docs/locations
predefined_acl (str):
(Optional) Name of predefined ACL to apply to bucket. See:
https://cloud.google.com/storage/docs/access-control/lists#predefined-acl
Expand Down
10 changes: 10 additions & 0 deletions samples/README.md
Expand Up @@ -63,6 +63,7 @@ for more detailed instructions.
* [CORS Configuration](#cors-configuration)
* [Create Bucket](#create-bucket)
* [Create Bucket Class Location](#create-bucket-class-location)
* [Create Bucket Dual Region](#create-bucket-dual-region)
* [Create Bucket Notifications](#create-bucket-notifications)
* [Create Bucket Turbo Replication](#create-bucket-turbo-replication)
* [Create HMAC Key](#create-hmac-key)
Expand Down Expand Up @@ -316,6 +317,15 @@ View the [source code](https://github.com/googleapis/python-storage/blob/main/sa

`python storage_create_bucket_class_location.py <BUCKET_NAME>`

-----
### Create Bucket Dual Region
[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/python-storage&page=editor&open_in_editor=samples/snippets/storage_create_bucket_dual_region.py,samples/README.md)

View the [source code](https://github.com/googleapis/python-storage/blob/main/samples/snippets/storage_create_bucket_dual_region.py). To run this sample:


`python storage_create_bucket_dual_region.py <BUCKET_NAME> <REGION_1> <REGION_2>`

-----
### Create Bucket Notifications
[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/python-storage&page=editor&open_in_editor=samples/snippets/storage_create_bucket_notifications.py,samples/README.md)
Expand Down
11 changes: 11 additions & 0 deletions samples/snippets/snippets_test.py
Expand Up @@ -36,6 +36,7 @@
import storage_copy_file_archived_generation
import storage_cors_configuration
import storage_create_bucket_class_location
import storage_create_bucket_dual_region
import storage_define_bucket_website_configuration
import storage_delete_file
import storage_delete_file_archived_generation
Expand Down Expand Up @@ -433,6 +434,16 @@ def test_create_bucket_class_location(test_bucket_create):
assert bucket.storage_class == "COLDLINE"


def test_create_bucket_dual_region(test_bucket_create, capsys):
region_1 = "US-EAST1"
region_2 = "US-WEST1"
storage_create_bucket_dual_region.create_bucket_dual_region(
test_bucket_create.name, region_1, region_2
)
out, _ = capsys.readouterr()
assert f"Bucket {test_bucket_create.name} created in {region_1}+{region_2}" in out


def test_bucket_delete_default_kms_key(test_bucket, capsys):
test_bucket.default_kms_key_name = KMS_KEY
test_bucket.patch()
Expand Down
50 changes: 50 additions & 0 deletions samples/snippets/storage_create_bucket_dual_region.py
@@ -0,0 +1,50 @@
#!/usr/bin/env python

# Copyright 2022 Google LLC. All Rights Reserved.
#
# 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.

import sys

"""
Sample that creates a dual region bucket.
"""

# [START storage_create_bucket_dual_region]
from google.cloud import storage


def create_bucket_dual_region(bucket_name, region_1, region_2):
"""Creates a Dual-Region Bucket with provided locations."""
# The ID of your GCS bucket
# bucket_name = "your-bucket-name"

# The bucket's pair of regions. Case-insensitive.
# See this documentation for other valid locations:
# https://cloud.google.com/storage/docs/locations
# region_1 = "US-EAST1"
# region_2 = "US-WEST1"

storage_client = storage.Client()
storage_client.create_bucket(bucket_name, location=f"{region_1}+{region_2}")

print(f"Bucket {bucket_name} created in {region_1}+{region_2}.")


# [END storage_create_bucket_dual_region]


if __name__ == "__main__":
create_bucket_dual_region(
bucket_name=sys.argv[1], region_1=sys.argv[2], region_2=sys.argv[3]
)
21 changes: 21 additions & 0 deletions tests/system/test_client.py
Expand Up @@ -64,6 +64,27 @@ def test_create_bucket_simple(storage_client, buckets_to_delete):
assert created.name == new_bucket_name


def test_create_bucket_dual_region(storage_client, buckets_to_delete):
from google.cloud.storage.constants import DUAL_REGION_LOCATION_TYPE

new_bucket_name = _helpers.unique_name("dual-region-bucket")
region_1 = "US-EAST1"
region_2 = "US-WEST1"
dual_region = f"{region_1}+{region_2}"

with pytest.raises(exceptions.NotFound):
storage_client.get_bucket(new_bucket_name)

created = _helpers.retry_429_503(storage_client.create_bucket)(
new_bucket_name, location=dual_region
)
buckets_to_delete.append(created)

assert created.name == new_bucket_name
assert created.location == dual_region
assert created.location_type == DUAL_REGION_LOCATION_TYPE


def test_list_buckets(storage_client, buckets_to_delete):
buckets_to_create = [
_helpers.unique_name("new"),
Expand Down

0 comments on commit 752e8ab

Please sign in to comment.