Skip to content

Commit d103a57

Browse files
docs(storage): add samples (#3687)
1 parent 3d67b73 commit d103a57

12 files changed

+547
-15
lines changed

storage/cloud-client/encryption_test.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,12 @@
2424

2525
import storage_download_encrypted_file
2626
import storage_generate_encryption_key
27+
import storage_object_csek_to_cmek
2728
import storage_rotate_encryption_key
2829
import storage_upload_encrypted_file
2930

30-
3131
BUCKET = os.environ["CLOUD_STORAGE_BUCKET"]
32+
KMS_KEY = os.environ["CLOUD_KMS_KEY"]
3233

3334
TEST_ENCRYPTION_KEY = "brtJUWneL92g5q0N2gyDSnlPSYAiIVZ/cWgjyZNeMy0="
3435
TEST_ENCRYPTION_KEY_DECODED = base64.b64decode(TEST_ENCRYPTION_KEY)
@@ -113,3 +114,12 @@ def test_rotate_encryption_key(test_blob):
113114

114115
downloaded_content = dest_file.read().decode("utf-8")
115116
assert downloaded_content == test_blob_content
117+
118+
119+
def test_object_csek_to_cmek(test_blob):
120+
test_blob_name, test_blob_content = test_blob
121+
cmek_blob = storage_object_csek_to_cmek.object_csek_to_cmek(
122+
BUCKET, test_blob_name, TEST_ENCRYPTION_KEY_2, KMS_KEY
123+
)
124+
125+
assert cmek_blob.download_as_string(), test_blob_content

storage/cloud-client/iam_test.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@
2323
import storage_add_bucket_iam_member
2424
import storage_remove_bucket_conditional_iam_binding
2525
import storage_remove_bucket_iam_member
26+
import storage_set_bucket_public_iam
2627
import storage_view_bucket_iam_members
2728

28-
2929
MEMBER = "group:[email protected]"
3030
ROLE = "roles/storage.legacyBucketReader"
3131

@@ -112,3 +112,16 @@ def test_remove_bucket_conditional_iam_binding(bucket):
112112
(binding["role"] == ROLE and binding.get("condition") == condition)
113113
for binding in policy.bindings
114114
)
115+
116+
117+
def test_set_bucket_public_iam(bucket):
118+
role = "roles/storage.objectViewer"
119+
member = "allUsers"
120+
storage_set_bucket_public_iam.set_bucket_public_iam(
121+
bucket.name, role, member
122+
)
123+
policy = bucket.get_iam_policy(requested_policy_version=3)
124+
assert any(
125+
binding["role"] == role and member in binding["members"]
126+
for binding in policy.bindings
127+
)

storage/cloud-client/snippets_test.py

Lines changed: 108 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,16 @@
2323
import requests
2424

2525
import storage_add_bucket_label
26+
import storage_bucket_delete_default_kms_key
27+
import storage_compose_file
2628
import storage_copy_file
29+
import storage_create_bucket_class_location
30+
import storage_define_bucket_website_configuration
2731
import storage_delete_file
2832
import storage_disable_bucket_lifecycle_management
2933
import storage_disable_versioning
3034
import storage_download_file
35+
import storage_download_public_file
3136
import storage_enable_bucket_lifecycle_management
3237
import storage_enable_versioning
3338
import storage_generate_signed_post_policy_v4
@@ -37,11 +42,13 @@
3742
import storage_get_bucket_labels
3843
import storage_get_bucket_metadata
3944
import storage_get_metadata
45+
import storage_get_service_account
4046
import storage_list_buckets
4147
import storage_list_files
4248
import storage_list_files_with_prefix
4349
import storage_make_public
4450
import storage_move_file
51+
import storage_object_get_kms_key
4552
import storage_remove_bucket_label
4653
import storage_set_bucket_default_kms_key
4754
import storage_set_metadata
@@ -100,6 +107,17 @@ def test_blob(test_bucket):
100107
yield blob
101108

102109

110+
@pytest.fixture
111+
def test_bucket_create():
112+
"""Yields a bucket object that is deleted after the test completes."""
113+
bucket = None
114+
while bucket is None or bucket.exists():
115+
bucket_name = "storage-snippets-test-{}".format(uuid.uuid4())
116+
bucket = storage.Client().bucket(bucket_name)
117+
yield bucket
118+
bucket.delete(force=True)
119+
120+
103121
def test_list_buckets(test_bucket, capsys):
104122
storage_list_buckets.list_buckets()
105123
out, _ = capsys.readouterr()
@@ -204,9 +222,7 @@ def test_generate_upload_signed_url_v4(test_bucket, capsys):
204222
)
205223

206224
requests.put(
207-
url,
208-
data=content,
209-
headers={"content-type": "application/octet-stream"},
225+
url, data=content, headers={"content-type": "application/octet-stream"},
210226
)
211227

212228
bucket = storage.Client().bucket(test_bucket.name)
@@ -217,9 +233,7 @@ def test_generate_upload_signed_url_v4(test_bucket, capsys):
217233
def test_generate_signed_policy_v4(test_bucket, capsys):
218234
blob_name = "storage_snippets_test_form"
219235
short_name = storage_generate_signed_post_policy_v4
220-
form = short_name.generate_signed_post_policy_v4(
221-
test_bucket.name, blob_name
222-
)
236+
form = short_name.generate_signed_post_policy_v4(test_bucket.name, blob_name)
223237
assert "name='key' value='{}'".format(blob_name) in form
224238
assert "name='x-goog-signature'" in form
225239
assert "name='x-goog-date'" in form
@@ -238,9 +252,7 @@ def test_rename_blob(test_blob):
238252
except google.cloud.exceptions.exceptions.NotFound:
239253
pass
240254

241-
storage_move_file.rename_blob(
242-
bucket.name, test_blob.name, "test_rename_blob"
243-
)
255+
storage_move_file.rename_blob(bucket.name, test_blob.name, "test_rename_blob")
244256

245257
assert bucket.get_blob("test_rename_blob") is not None
246258
assert bucket.get_blob(test_blob.name) is None
@@ -275,15 +287,98 @@ def test_versioning(test_bucket, capsys):
275287

276288

277289
def test_bucket_lifecycle_management(test_bucket, capsys):
278-
bucket = storage_enable_bucket_lifecycle_management.\
279-
enable_bucket_lifecycle_management(test_bucket)
290+
bucket = storage_enable_bucket_lifecycle_management.enable_bucket_lifecycle_management(
291+
test_bucket
292+
)
280293
out, _ = capsys.readouterr()
281294
assert "[]" in out
282295
assert "Lifecycle management is enable" in out
283296
assert len(list(bucket.lifecycle_rules)) > 0
284297

285-
bucket = storage_disable_bucket_lifecycle_management.\
286-
disable_bucket_lifecycle_management(test_bucket)
298+
bucket = storage_disable_bucket_lifecycle_management.disable_bucket_lifecycle_management(
299+
test_bucket
300+
)
287301
out, _ = capsys.readouterr()
288302
assert "[]" in out
289303
assert len(list(bucket.lifecycle_rules)) == 0
304+
305+
306+
def test_create_bucket_class_location(test_bucket_create):
307+
bucket = storage_create_bucket_class_location.create_bucket_class_location(
308+
test_bucket_create.name
309+
)
310+
311+
assert bucket.location == "US"
312+
assert bucket.storage_class == "COLDLINE"
313+
314+
315+
def test_bucket_delete_default_kms_key(test_bucket, capsys):
316+
test_bucket.default_kms_key_name = KMS_KEY
317+
test_bucket.patch()
318+
319+
assert test_bucket.default_kms_key_name == KMS_KEY
320+
321+
bucket = storage_bucket_delete_default_kms_key.bucket_delete_default_kms_key(
322+
test_bucket.name
323+
)
324+
325+
out, _ = capsys.readouterr()
326+
assert bucket.default_kms_key_name is None
327+
assert bucket.name in out
328+
329+
330+
def test_get_service_account(capsys):
331+
storage_get_service_account.get_service_account()
332+
333+
out, _ = capsys.readouterr()
334+
335+
assert "@gs-project-accounts.iam.gserviceaccount.com" in out
336+
337+
338+
def test_download_public_file(test_blob):
339+
storage_make_public.make_blob_public(test_blob.bucket.name, test_blob.name)
340+
with tempfile.NamedTemporaryFile() as dest_file:
341+
storage_download_public_file.download_public_file(
342+
test_blob.bucket.name, test_blob.name, dest_file.name
343+
)
344+
345+
assert dest_file.read() == b"Hello, is it me you're looking for?"
346+
347+
348+
def test_define_bucket_website_configuration(test_bucket):
349+
bucket = storage_define_bucket_website_configuration.define_bucket_website_configuration(
350+
test_bucket.name, "index.html", "404.html"
351+
)
352+
353+
website_val = {"mainPageSuffix": "index.html", "notFoundPage": "404.html"}
354+
355+
assert bucket._properties["website"] == website_val
356+
357+
358+
def test_object_get_kms_key(test_bucket):
359+
with tempfile.NamedTemporaryFile() as source_file:
360+
storage_upload_with_kms_key.upload_blob_with_kms(
361+
test_bucket.name, source_file.name, "test_upload_blob_encrypted", KMS_KEY
362+
)
363+
kms_key = storage_object_get_kms_key.object_get_kms_key(
364+
test_bucket.name, "test_upload_blob_encrypted"
365+
)
366+
367+
assert kms_key.startswith(KMS_KEY)
368+
369+
370+
def test_storage_compose_file(test_bucket):
371+
source_files = ["test_upload_blob_1", "test_upload_blob_2"]
372+
blob_list = []
373+
for source in source_files:
374+
blob = test_bucket.blob(source)
375+
blob.upload_from_string(source)
376+
blob_list.append(blob)
377+
378+
with tempfile.NamedTemporaryFile() as dest_file:
379+
destination = storage_compose_file.compose_file(
380+
test_bucket.name, blob_list, dest_file.name
381+
)
382+
composed = destination.download_as_string()
383+
384+
assert composed.decode("utf-8") == source_files[0] + source_files[1]
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright 2020 Google LLC. All Rights Reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the 'License');
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
import sys
18+
19+
# [START storage_bucket_delete_default_kms_key]
20+
from google.cloud import storage
21+
22+
23+
def bucket_delete_default_kms_key(bucket_name):
24+
"""Delete a default KMS key of bucket"""
25+
# bucket_name = "your-bucket-name"
26+
27+
storage_client = storage.Client()
28+
29+
bucket = storage_client.get_bucket(bucket_name)
30+
bucket.default_kms_key_name = None
31+
bucket.patch()
32+
33+
print("Default KMS key was removed from {}".format(bucket.name))
34+
return bucket
35+
36+
37+
# [END storage_bucket_delete_default_kms_key]
38+
39+
if __name__ == "__main__":
40+
bucket_delete_default_kms_key(bucket_name=sys.argv[1])
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright 2020 Google LLC. All Rights Reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the 'License');
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
import sys
18+
19+
# [START storage_compose_file]
20+
from google.cloud import storage
21+
22+
23+
def compose_file(bucket_name, sources, destination_blob_name):
24+
"""Concatenate source blobs into destination blob."""
25+
# bucket_name = "your-bucket-name"
26+
# sources = [blob_1, blob_2]
27+
# destination_blob_name = "destination-object-name"
28+
29+
storage_client = storage.Client()
30+
bucket = storage_client.bucket(bucket_name)
31+
destination = bucket.blob(destination_blob_name)
32+
destination.content_type = "text/plain"
33+
destination.compose(sources)
34+
35+
print(
36+
"Composed new object {} in the bucket {}".format(
37+
destination_blob_name, bucket.name
38+
)
39+
)
40+
return destination
41+
42+
43+
# [END storage_compose_file]
44+
45+
if __name__ == "__main__":
46+
compose_file(
47+
bucket_name=sys.argv[1], sources=sys.argv[2], destination_blob_name=sys.argv[3],
48+
)
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright 2020 Google LLC. All Rights Reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the 'License');
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
import sys
18+
19+
# [START storage_create_bucket_class_location]
20+
from google.cloud import storage
21+
22+
23+
def create_bucket_class_location(bucket_name):
24+
"""Create a new bucket in specific location with storage class"""
25+
# bucket_name = "your-new-bucket-name"
26+
27+
storage_client = storage.Client()
28+
29+
bucket = storage_client.bucket(bucket_name)
30+
bucket.storage_class = "COLDLINE"
31+
new_bucket = storage_client.create_bucket(bucket, location="us")
32+
33+
print(
34+
"Created bucket {} in {} with storage class {}".format(
35+
new_bucket.name, new_bucket.location, new_bucket.storage_class
36+
)
37+
)
38+
return new_bucket
39+
40+
41+
# [END storage_create_bucket_class_location]
42+
43+
if __name__ == "__main__":
44+
create_bucket_class_location(bucket_name=sys.argv[1])

0 commit comments

Comments
 (0)