From a36d7d6122d7fb6b16bec4a014e74ad394705f50 Mon Sep 17 00:00:00 2001 From: Maciej Strzelczyk Date: Tue, 15 Jun 2021 15:20:26 +0200 Subject: [PATCH 1/6] feat: adding samples for default values Featuring the usage report API. --- samples/snippets/sample_default_values.py | 114 ++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 samples/snippets/sample_default_values.py diff --git a/samples/snippets/sample_default_values.py b/samples/snippets/sample_default_values.py new file mode 100644 index 000000000..8f116f631 --- /dev/null +++ b/samples/snippets/sample_default_values.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python + +# Copyright 2021 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. +""" +A sample script showing how to handle default values when communicating +with the Compute Engine API. +""" +# [START compute_instances_verify_default_value] +# [START compute_usage_report_set] +# [START compute_usage_report_get] +# [START compute_usage_report_disable] +from google.cloud import compute_v1 +# [END compute_usage_report_disable] +# [END compute_usage_report_get] +# [END compute_usage_report_set] + + +# [START compute_usage_report_set] +def set_usage_export_bucket(project_id: str, bucket_name: str, + report_name_prefix: str = "") -> None: + """ + Set Compute Engine usage export bucket for the Cloud Project. + This sample presents how to interpret default value for the name prefix + parameter. + + Params: + project_id: project ID or project number of the project to update. + bucket_name: Google Cloud Storage Bucket used to store Compute Engine + usage reports. An existing Google Cloud Storage bucket is required. + report_name_prefix: Report Name Prefix which defaults to an empty string + to showcase default values behaviour. + """ + usage_export_location = compute_v1.UsageExportLocation({ + 'bucket_name': bucket_name, + 'report_name_prefix': report_name_prefix + }) + + if not report_name_prefix: + # Sending empty value for report_name_prefix, will result with the + # next usage report generated will have the default prefix value + # "usage_gce". (ref: https://cloud.google.com/compute/docs/reference/rest/v1/projects/get) + print("Setting report_name_prefix to empty value will cause the report " + "to have the default prefix of `usage_gce`.") + + projects_client = compute_v1.ProjectsClient() + projects_client.set_usage_export_bucket( + project=project_id, usage_export_location_resource=usage_export_location) + return +# [END compute_usage_report_set] + + +# [START compute_usage_report_get] +def get_usage_export_bucket(project_id: str) -> compute_v1.UsageExportLocation: + """ + Retrieve Compute Engine usage export bucket for the Cloud Project. + Replaces the empty value returned by the API with the default value used + to generate report file names. + + Params: + project_id: project ID or project number of the project to update. + Returns: + UsageExportLocation object describing the current usage export settings + for project project_id. + """ + projects_client = compute_v1.ProjectsClient() + project_data = projects_client.get(project=project_id) + + uel = project_data.usage_export_location + + if not uel.bucket_name: + # The Usage Reports are disabled. + return uel + if not uel.report_name_prefix: + # Although the server sent the empty value, the next usage report + # generated with these settings still has the default prefix value + # "usage_gce". (ref: https://cloud.google.com/compute/docs/reference/rest/v1/projects/get) + print('Report name prefix not set, replacing with default value of ' + '`usage_gce`.') + uel.report_name_prefix = 'usage_gce' + return uel +# [END compute_usage_report_get] +# [END compute_instances_verify_default_value] + + +# [START compute_usage_report_disable] +def disable_usage_export(project_id: str) -> None: + """ + Disable Compute Engine usage export bucket for the Cloud Project. + + Params: + project_id: project ID or project number of the project to update. + """ + projects_client = compute_v1.ProjectsClient() + export_location = compute_v1.UsageExportLocation( + {'bucket_name': '', 'report_name_prefix': ''}) + + # Updating the setting with empty bucket name will disable the + # usage report generation. + projects_client.set_usage_export_bucket( + project=project_id, usage_export_location_resource=export_location) + return +# [END compute_usage_report_disable] From 1b9ef96e57eb0517b722b5dd1f4ff34769641138 Mon Sep 17 00:00:00 2001 From: Maciej Strzelczyk Date: Thu, 17 Jun 2021 16:18:05 +0200 Subject: [PATCH 2/6] chore: Applying changes from review --- samples/snippets/sample_default_values.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/samples/snippets/sample_default_values.py b/samples/snippets/sample_default_values.py index 8f116f631..41728390b 100644 --- a/samples/snippets/sample_default_values.py +++ b/samples/snippets/sample_default_values.py @@ -48,9 +48,9 @@ def set_usage_export_bucket(project_id: str, bucket_name: str, }) if not report_name_prefix: - # Sending empty value for report_name_prefix, will result with the - # next usage report generated will have the default prefix value - # "usage_gce". (ref: https://cloud.google.com/compute/docs/reference/rest/v1/projects/get) + # Sending an empty value for report_name_prefix will result in the + # next usage report generated to have the default prefix value + # "usage_gce". (ref: https://cloud.google.com/compute/docs/reference/rest/v1/projects/setUsageExportBucket) print("Setting report_name_prefix to empty value will cause the report " "to have the default prefix of `usage_gce`.") @@ -103,12 +103,10 @@ def disable_usage_export(project_id: str) -> None: project_id: project ID or project number of the project to update. """ projects_client = compute_v1.ProjectsClient() - export_location = compute_v1.UsageExportLocation( - {'bucket_name': '', 'report_name_prefix': ''}) - # Updating the setting with empty bucket name will disable the + # Updating the setting with None will disable the # usage report generation. projects_client.set_usage_export_bucket( - project=project_id, usage_export_location_resource=export_location) + project=project_id, usage_export_location_resource=None) return # [END compute_usage_report_disable] From 7e6674985816387f20316a7c3d7ab96c254d0a1d Mon Sep 17 00:00:00 2001 From: Maciej Strzelczyk Date: Tue, 22 Jun 2021 14:29:30 +0200 Subject: [PATCH 3/6] feat: Adding tests to default values samples. --- samples/snippets/requirements-test.txt | 3 +- samples/snippets/sample_default_values.py | 11 +++- .../snippets/test_sample_default_values.py | 65 +++++++++++++++++++ 3 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 samples/snippets/test_sample_default_values.py diff --git a/samples/snippets/requirements-test.txt b/samples/snippets/requirements-test.txt index 11b890fae..1441d3a37 100644 --- a/samples/snippets/requirements-test.txt +++ b/samples/snippets/requirements-test.txt @@ -1 +1,2 @@ -pytest==6.2.4 \ No newline at end of file +pytest==6.2.4 +google-cloud-storage==1.39.0 \ No newline at end of file diff --git a/samples/snippets/sample_default_values.py b/samples/snippets/sample_default_values.py index 41728390b..5d0cb3404 100644 --- a/samples/snippets/sample_default_values.py +++ b/samples/snippets/sample_default_values.py @@ -55,8 +55,11 @@ def set_usage_export_bucket(project_id: str, bucket_name: str, "to have the default prefix of `usage_gce`.") projects_client = compute_v1.ProjectsClient() - projects_client.set_usage_export_bucket( + operation = projects_client.set_usage_export_bucket( project=project_id, usage_export_location_resource=usage_export_location) + + op_client = compute_v1.GlobalOperationsClient() + op_client.wait(project=project_id, operation=operation.name) return # [END compute_usage_report_set] @@ -82,6 +85,7 @@ def get_usage_export_bucket(project_id: str) -> compute_v1.UsageExportLocation: if not uel.bucket_name: # The Usage Reports are disabled. return uel + if not uel.report_name_prefix: # Although the server sent the empty value, the next usage report # generated with these settings still has the default prefix value @@ -106,7 +110,10 @@ def disable_usage_export(project_id: str) -> None: # Updating the setting with None will disable the # usage report generation. - projects_client.set_usage_export_bucket( + operation = projects_client.set_usage_export_bucket( project=project_id, usage_export_location_resource=None) + + op_client = compute_v1.GlobalOperationsClient() + op_client.wait(project=project_id, operation=operation.name) return # [END compute_usage_report_disable] diff --git a/samples/snippets/test_sample_default_values.py b/samples/snippets/test_sample_default_values.py new file mode 100644 index 000000000..b6d2f0acc --- /dev/null +++ b/samples/snippets/test_sample_default_values.py @@ -0,0 +1,65 @@ +# Copyright 2021 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. +import typing +import uuid + +import google.auth +import google.cloud.storage as storage +import pytest + +from sample_default_values import \ + disable_usage_export, get_usage_export_bucket, set_usage_export_bucket + +PROJECT = google.auth.default()[1] +BUCKET_NAME = "test" + uuid.uuid4().hex[:10] +TEST_PREFIX = 'some-prefix' + + +@pytest.fixture +def temp_bucket(): + storage_client = storage.Client() + bucket = storage_client.create_bucket(BUCKET_NAME) + yield bucket + bucket.delete(force=True) + + +def test_set_usage_export_bucket_default(capsys: typing.Any, + temp_bucket: storage.Bucket) -> None: + set_usage_export_bucket(project_id=PROJECT, bucket_name=temp_bucket.name) + uel = get_usage_export_bucket(project_id=PROJECT) + assert(uel.bucket_name == temp_bucket.name) + assert(uel.report_name_prefix == 'usage_gce') + out, _ = capsys.readouterr() + assert('default prefix of `usage_gce`.' in out) + + disable_usage_export(project_id=PROJECT) + uel = get_usage_export_bucket(project_id=PROJECT) + assert(uel.bucket_name == '') + assert(uel.report_name_prefix == '') + + +def test_set_usage_export_bucket_custom(capsys: typing.Any, + temp_bucket: storage.Bucket) -> None: + set_usage_export_bucket(project_id=PROJECT, bucket_name=temp_bucket.name, + report_name_prefix=TEST_PREFIX) + uel = get_usage_export_bucket(project_id=PROJECT) + assert(uel.bucket_name == temp_bucket.name) + assert(uel.report_name_prefix == TEST_PREFIX) + out, _ = capsys.readouterr() + assert('usage_gce' not in out) + + disable_usage_export(project_id=PROJECT) + uel = get_usage_export_bucket(project_id=PROJECT) + assert(uel.bucket_name == '') + assert(uel.report_name_prefix == '') From 0fa1d4d4ad6c56d360d40a1515765fd4bb701f96 Mon Sep 17 00:00:00 2001 From: Maciej Strzelczyk Date: Fri, 25 Jun 2021 14:52:58 +0200 Subject: [PATCH 4/6] chore: Applying changes after tech-writer review. --- samples/snippets/sample_default_values.py | 24 +++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/samples/snippets/sample_default_values.py b/samples/snippets/sample_default_values.py index 41728390b..6c9193530 100644 --- a/samples/snippets/sample_default_values.py +++ b/samples/snippets/sample_default_values.py @@ -31,15 +31,15 @@ def set_usage_export_bucket(project_id: str, bucket_name: str, report_name_prefix: str = "") -> None: """ - Set Compute Engine usage export bucket for the Cloud Project. - This sample presents how to interpret default value for the name prefix - parameter. + Set Compute Engine usage export bucket for the Cloud project. + This sample presents how to interpret the default value for the + report name prefix parameter. Params: project_id: project ID or project number of the project to update. - bucket_name: Google Cloud Storage Bucket used to store Compute Engine + bucket_name: Google Cloud Storage bucket used to store Compute Engine usage reports. An existing Google Cloud Storage bucket is required. - report_name_prefix: Report Name Prefix which defaults to an empty string + report_name_prefix: Prefix of the usage report name which defaults to an empty string to showcase default values behaviour. """ usage_export_location = compute_v1.UsageExportLocation({ @@ -48,10 +48,10 @@ def set_usage_export_bucket(project_id: str, bucket_name: str, }) if not report_name_prefix: - # Sending an empty value for report_name_prefix will result in the - # next usage report generated to have the default prefix value + # Sending an empty value for report_name_prefix results in the + # next usage report being generated with the default prefix value # "usage_gce". (ref: https://cloud.google.com/compute/docs/reference/rest/v1/projects/setUsageExportBucket) - print("Setting report_name_prefix to empty value will cause the report " + print("Setting report_name_prefix to empty value causes the report " "to have the default prefix of `usage_gce`.") projects_client = compute_v1.ProjectsClient() @@ -64,7 +64,7 @@ def set_usage_export_bucket(project_id: str, bucket_name: str, # [START compute_usage_report_get] def get_usage_export_bucket(project_id: str) -> compute_v1.UsageExportLocation: """ - Retrieve Compute Engine usage export bucket for the Cloud Project. + Retrieve Compute Engine usage export bucket for the Cloud project. Replaces the empty value returned by the API with the default value used to generate report file names. @@ -80,12 +80,12 @@ def get_usage_export_bucket(project_id: str) -> compute_v1.UsageExportLocation: uel = project_data.usage_export_location if not uel.bucket_name: - # The Usage Reports are disabled. + # The usage reports are disabled. return uel if not uel.report_name_prefix: - # Although the server sent the empty value, the next usage report + # Although the server sent the empty string value, the next usage report # generated with these settings still has the default prefix value - # "usage_gce". (ref: https://cloud.google.com/compute/docs/reference/rest/v1/projects/get) + # "usage_gce". (see https://cloud.google.com/compute/docs/reference/rest/v1/projects/get) print('Report name prefix not set, replacing with default value of ' '`usage_gce`.') uel.report_name_prefix = 'usage_gce' From a977b36725554a81fe178a14fde0aa474fb045eb Mon Sep 17 00:00:00 2001 From: Maciej Strzelczyk Date: Mon, 28 Jun 2021 13:20:01 +0200 Subject: [PATCH 5/6] fix: Make the tests run in different projects --- samples/snippets/noxfile.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/snippets/noxfile.py b/samples/snippets/noxfile.py index 5ff9e1db5..dc9beecef 100644 --- a/samples/snippets/noxfile.py +++ b/samples/snippets/noxfile.py @@ -48,8 +48,8 @@ # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a # build specific Cloud project. You can also use your own string # to use your own Cloud project. - 'gcloud_project_env': 'GOOGLE_CLOUD_PROJECT', - # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', + # 'gcloud_project_env': 'GOOGLE_CLOUD_PROJECT', + 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', # If you need to use a specific version of pip, # change pip_version_override to the string representation # of the version number, for example, "20.2.4" From d9d327d149a56902729e56ee49374ae6a87a0159 Mon Sep 17 00:00:00 2001 From: Maciej Strzelczyk Date: Tue, 29 Jun 2021 18:51:37 +0200 Subject: [PATCH 6/6] chore: Review suggestions applied. --- samples/snippets/sample_default_values.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/samples/snippets/sample_default_values.py b/samples/snippets/sample_default_values.py index 5d0cb3404..ad6fd8305 100644 --- a/samples/snippets/sample_default_values.py +++ b/samples/snippets/sample_default_values.py @@ -35,17 +35,17 @@ def set_usage_export_bucket(project_id: str, bucket_name: str, This sample presents how to interpret default value for the name prefix parameter. - Params: + Args: project_id: project ID or project number of the project to update. bucket_name: Google Cloud Storage Bucket used to store Compute Engine usage reports. An existing Google Cloud Storage bucket is required. report_name_prefix: Report Name Prefix which defaults to an empty string to showcase default values behaviour. """ - usage_export_location = compute_v1.UsageExportLocation({ - 'bucket_name': bucket_name, - 'report_name_prefix': report_name_prefix - }) + usage_export_location = compute_v1.UsageExportLocation( + bucket_name=bucket_name, + report_name_prefix=report_name_prefix + ) if not report_name_prefix: # Sending an empty value for report_name_prefix will result in the @@ -60,7 +60,6 @@ def set_usage_export_bucket(project_id: str, bucket_name: str, op_client = compute_v1.GlobalOperationsClient() op_client.wait(project=project_id, operation=operation.name) - return # [END compute_usage_report_set] @@ -71,7 +70,7 @@ def get_usage_export_bucket(project_id: str) -> compute_v1.UsageExportLocation: Replaces the empty value returned by the API with the default value used to generate report file names. - Params: + Args: project_id: project ID or project number of the project to update. Returns: UsageExportLocation object describing the current usage export settings @@ -103,7 +102,7 @@ def disable_usage_export(project_id: str) -> None: """ Disable Compute Engine usage export bucket for the Cloud Project. - Params: + Args: project_id: project ID or project number of the project to update. """ projects_client = compute_v1.ProjectsClient() @@ -115,5 +114,4 @@ def disable_usage_export(project_id: str) -> None: op_client = compute_v1.GlobalOperationsClient() op_client.wait(project=project_id, operation=operation.name) - return # [END compute_usage_report_disable]