From b187fe7c00db6e415ddf31fd352c4dd4626e6068 Mon Sep 17 00:00:00 2001 From: TheRoyalTnetennba Date: Tue, 24 Mar 2020 21:25:36 -0600 Subject: [PATCH] add storage samples --- google-cloud-storage/Rakefile | 34 + google-cloud-storage/samples/Gemfile | 35 ++ google-cloud-storage/samples/README.md | 149 +++++ google-cloud-storage/samples/Rakefile | 6 + .../samples/acceptance/acls_test.rb | 165 +++++ .../samples/acceptance/buckets_test.rb | 355 +++++++++++ .../samples/acceptance/data/file.txt | 1 + .../samples/acceptance/files_test.rb | 479 ++++++++++++++ .../samples/acceptance/helper.rb | 89 +++ .../samples/acceptance/hmac_test.rb | 112 ++++ .../samples/acceptance/iam_test.rb | 124 ++++ .../samples/acceptance/quickstart_test.rb | 33 + google-cloud-storage/samples/acls.rb | 260 ++++++++ google-cloud-storage/samples/buckets.rb | 478 ++++++++++++++ google-cloud-storage/samples/files.rb | 593 ++++++++++++++++++ google-cloud-storage/samples/hmac.rb | 180 ++++++ google-cloud-storage/samples/iam.rb | 199 ++++++ google-cloud-storage/samples/quickstart.rb | 34 + 18 files changed, 3326 insertions(+) create mode 100644 google-cloud-storage/samples/Gemfile create mode 100644 google-cloud-storage/samples/README.md create mode 100644 google-cloud-storage/samples/Rakefile create mode 100644 google-cloud-storage/samples/acceptance/acls_test.rb create mode 100644 google-cloud-storage/samples/acceptance/buckets_test.rb create mode 100644 google-cloud-storage/samples/acceptance/data/file.txt create mode 100644 google-cloud-storage/samples/acceptance/files_test.rb create mode 100644 google-cloud-storage/samples/acceptance/helper.rb create mode 100644 google-cloud-storage/samples/acceptance/hmac_test.rb create mode 100644 google-cloud-storage/samples/acceptance/iam_test.rb create mode 100644 google-cloud-storage/samples/acceptance/quickstart_test.rb create mode 100644 google-cloud-storage/samples/acls.rb create mode 100644 google-cloud-storage/samples/buckets.rb create mode 100644 google-cloud-storage/samples/files.rb create mode 100644 google-cloud-storage/samples/hmac.rb create mode 100644 google-cloud-storage/samples/iam.rb create mode 100644 google-cloud-storage/samples/quickstart.rb diff --git a/google-cloud-storage/Rakefile b/google-cloud-storage/Rakefile index 4840abdbc44a..47bcdaab6169 100644 --- a/google-cloud-storage/Rakefile +++ b/google-cloud-storage/Rakefile @@ -125,6 +125,40 @@ namespace :acceptance do end end +task :samples do + Rake::Task["samples:latest"].invoke +end + +namespace :samples do + task :latest do + if File.directory? "samples" + Dir.chdir "samples" do + Bundler.with_clean_env do + ENV["GOOGLE_CLOUD_SAMPLES_TEST"] = "not_master" + sh "bundle update" + sh "bundle exec rake test" + end + end + else + puts "The google-cloud-language gem has no samples to test." + end + end + + task :master do + if File.directory? "samples" + Dir.chdir "samples" do + Bundler.with_clean_env do + ENV["GOOGLE_CLOUD_SAMPLES_TEST"] = "master" + sh "bundle update" + sh "bundle exec rake test" + end + end + else + puts "The google-cloud-language gem has no samples to test." + end + end +end + desc "Run yard-doctest example tests." task :doctest do sh "bundle exec yard config load_plugins true && bundle exec yard doctest" diff --git a/google-cloud-storage/samples/Gemfile b/google-cloud-storage/samples/Gemfile new file mode 100644 index 000000000000..f98685b31aa7 --- /dev/null +++ b/google-cloud-storage/samples/Gemfile @@ -0,0 +1,35 @@ +# Copyright 2020 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. + +# [START storage_dependencies] +source "https://rubygems.org" + +# [END storage_dependencies] + +if ENV["GOOGLE_CLOUD_SAMPLES_TEST"] == "master" + gem "google-cloud-kms", group: :test, path: "../../google-cloud-kms" + gem "google-cloud-storage", path: "../../google-cloud-storage" +else + # rubocop:disable Bundler/DuplicatedGem + gem "google-cloud-kms", group: :test + # [START storage_dependencies] + gem "google-cloud-storage" + # [END storage_dependencies] + # rubocop:enable Bundler/DuplicatedGem +end + +group :test do + gem "minitest", "~> 5.13" + gem "rake" +end diff --git a/google-cloud-storage/samples/README.md b/google-cloud-storage/samples/README.md new file mode 100644 index 000000000000..e3dccde7c54f --- /dev/null +++ b/google-cloud-storage/samples/README.md @@ -0,0 +1,149 @@ +Google Cloud Platform logo + +# Google Cloud Storage Ruby Samples + +[Cloud Storage][storage_docs] allows world-wide storage and retrieval of any +amount of data at any time. + +[storage_docs]: https://cloud.google.com/storage/docs/ + +## Run sample + +To run the sample, first install dependencies: + + bundle install + +Run the sample: + + bundle exec ruby buckets.rb + bundle exec ruby files.rb + bundle exec ruby acls.rb + +## Samples + +### Buckets + +**Usage:** `bundle exec ruby buckets.rb [command] [arguments]` + +``` +Usage: bundle exec ruby buckets.rb [command] [arguments] + +Commands: + list List all buckets in the authenticated project + enable_requester_pays Enable requester pays for a bucket + disable_requester_pays Disable requester pays for a bucket + check_requester_pays Check status of requester pays for a bucket + enable_default_kms_key Enable default KMS encryption for bucket + create Create a new bucket with default storage class and location + create Create a new bucket with specific storage class and location + list_bucket_labels List bucket labels + add_bucket_label Add bucket label + delete_bucket_label Delete bucket label + delete Delete bucket with the provided name + set_retention_policy Set a retention policy on bucket with a retention period determined in seconds + remove_retention_policy Remove a retention policy from a bucket if policy is not locked + lock_retention_policy Lock retention policy + get_retention_policy Get retention policy for a bucket + enable_default_event_based_hold Enable event-based hold for a bucket + disable_default_event_based_hold Disable event-based hold for a bucket + get_default_event_based_hold Get state of event-based hold for a bucket + enable_uniform_bucket_level_access Enable uniform bucket-level access for a bucket + disable_uniform_bucket_level_access Disable uniform bucket-level access for a bucket + get_uniform_bucket_level_access Get uniform bucket-level access for a bucket + +Environment variables: + GOOGLE_CLOUD_PROJECT must be set to your Google Cloud project ID +``` + +### Files + +**Usage:** `bundle exec ruby files.rb [command] [arguments]` + +``` +Usage: bundle exec ruby files.rb [command] [arguments] + +Commands: + list List all files in the bucket + upload Upload local file to a bucket + encrypted_upload Upload local file as an encrypted file to a bucket + kms_upload Upload local file and encrypt service side using a KMS key + download Download a file from a bucket + download_public_file Download a publically accessible file from a bucket + encrypted_download Download an encrypted file from a bucket + download_with_requester_pays Download a file from a requester pays enabled bucket + rotate_encryption_key Update encryption key of an encrypted file. + generate_encryption_key Generate a sample encryption key + delete Delete a file from a bucket + metadata Display metadata for a file in a bucket + make_public Make a file in a bucket public + rename Rename a file in a bucket + copy Copy file to other bucket + generate_signed_url Generate a signed url for a file + set_event_based_hold Set an event-based hold on a file + release_event_based_hold Relase an event-based hold on a file + set_temporary_hold Set a temporary hold on a file + release_temporary_hold Release a temporary hold on a file + +Environment variables: + GOOGLE_CLOUD_PROJECT must be set to your Google Cloud project ID +``` + +### Access Control List + +**Usage:** `bundle exec ruby acls.rb [command] [arguments]` + +``` +Usage: bundle exec ruby acls.rb [command] [arguments] + +Commands: + print_bucket_acl Print bucket Access Control List + print_bucket_acl_for_user Print bucket ACL for an email + add_bucket_owner Add a new OWNER to a bucket + remove_bucket_acl Remove an entity from a bucket ACL + add_bucket_default_owner Add a default OWNER for a bucket + remove_bucket_default_acl Remove an entity from default bucket ACL + print_file_acl Print file ACL + print_file_acl_for_user Print file ACL for an email + add_file_owner Add an OWNER to a file + remove_file_acl Remove an entity from a file ACL + +Environment variables: + GOOGLE_CLOUD_PROJECT must be set to your Google Cloud project ID +``` + +### Cloud Storage Bucket-level Identity & Access Management + +**Usage:** `bundle exec ruby iam.rb [command] [arguments]` + +``` +Usage: bundle exec ruby iam.rb [command] [arguments] + +Commands: + view_bucket_iam_members View bucket-level IAM members + add_bucket_iam_member Add a bucket-level IAM member + add_bucket_conditional_iam_binding Add a conditional bucket-level binding + remove_bucket_iam_member Remove a bucket-level IAM member + remove_bucket_conditional_iam_binding Remove a conditional bucket-level binding + +Environment variables: + GOOGLE_CLOUD_PROJECT must be set to your Google Cloud project ID +``` + +### Cloud Storage Service Account HMAC Key Management + +**Usage:** `bundle exec ruby hmac.rb [commmand] [arguments]` + +``` +Usage: bundle exec ruby hmac.rb [command] [arguments] + +Commands: + list_hmac_keys List all HMAC keys for a project + create_hmac_key Create HMAC Key + get_hmac_key Get HMAC Key metadata + activate_hmac_key Activate an HMAC Key + deactivate_hmac_key Deactivate an HMAC Key + delete_hmac_key Delete a deactivated HMAC key + +Environment variables: + GOOGLE_CLOUD_PROJECT must be set to your Google Cloud project ID +``` diff --git a/google-cloud-storage/samples/Rakefile b/google-cloud-storage/samples/Rakefile new file mode 100644 index 000000000000..6326eebd9945 --- /dev/null +++ b/google-cloud-storage/samples/Rakefile @@ -0,0 +1,6 @@ +require "rake/testtask" + +Rake::TestTask.new "test" do |t| + t.test_files = FileList["**/*_test.rb"] + t.warning = false +end diff --git a/google-cloud-storage/samples/acceptance/acls_test.rb b/google-cloud-storage/samples/acceptance/acls_test.rb new file mode 100644 index 000000000000..e89e0b9e1bc9 --- /dev/null +++ b/google-cloud-storage/samples/acceptance/acls_test.rb @@ -0,0 +1,165 @@ +# Copyright 2020 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. + +require_relative "helper" +require_relative "../acls.rb" + +describe "ACL Snippets" do + parallelize_me! + + let :bucket do + create_bucket_helper "ruby_storage_sample_#{SecureRandom.hex}" + end + + let(:storage_client) { Google::Cloud::Storage.new } + let(:local_file) { File.expand_path "data/file.txt", __dir__ } + let(:email) { "user-test@test.com" } + let(:remote_file_name) { "path/file_name.txt" } + + after do + delete_bucket_helper bucket.name + end + + describe "print_bucket_acl" do + it "prints a bucket's acl" do + bucket.acl.add_owner email + + out, _err = capture_io do + print_bucket_acl bucket_name: bucket.name + end + + assert_includes out, "ACL for #{bucket.name}:" + assert_includes out, "OWNER #{email}" + end + end + + describe "print_bucket_acl_for_user" do + it "prints a bucket's acl for a user" do + bucket.acl.add_owner email + + expected_output = <<~OUTPUT + Permissions for #{email}: + OWNER + OUTPUT + + assert_output expected_output do + print_bucket_acl_for_user bucket_name: bucket.name, + email: email + end + end + end + + describe "add_bucket_owner" do + it "adds owner permissions to a user for a bucket" do + assert_output "Added OWNER permission for #{email} to #{bucket.name}\n" do + add_bucket_owner bucket_name: bucket.name, + email: email + end + assert_includes bucket.acl.owners, email + end + end + + describe "remove_bucket_acl" do + it "removes a user from a bucket's acl" do + bucket.acl.add_owner email + assert_output "Removed ACL permissions for #{email} from #{bucket.name}\n" do + remove_bucket_acl bucket_name: bucket.name, + email: email + end + refute_includes bucket.acl.owners, email + end + end + + describe "add_bucket_default_owner" do + it "adds a user as default owner for a bucket" do + assert_output "Added default OWNER permission for #{email} to #{bucket.name}\n" do + add_bucket_default_owner bucket_name: bucket.name, + email: email + end + assert_includes bucket.default_acl.owners, email + end + end + + describe "remove_bucket_default_acl" do + it "adds a user as default owner for a bucket" do + bucket.default_acl.add_owner email + assert_output "Removed default ACL permissions for #{email} from #{bucket.name}\n" do + remove_bucket_default_acl bucket_name: bucket.name, + email: email + end + refute_includes bucket.default_acl.owners, email + end + end + + describe "print_file_acl" do + it "prints the acl for a file in a bucket" do + bucket.create_file local_file, remote_file_name + owners = bucket.file(remote_file_name).acl.owners + readers = bucket.file(remote_file_name).acl.readers + + out, _err = capture_io do + print_file_acl bucket_name: bucket.name, + file_name: remote_file_name + end + + assert owners.all? do |owner| + out.includes? "OWNER #{owner}" + end + + assert readers.all? do |reader| + out.includes? "READER #{reader}" + end + end + end + + describe "print_file_acl_for_user" do + it "prints the permissions of a given user for a file in a bucket" do + bucket.create_file local_file, remote_file_name + bucket.file(remote_file_name).acl.add_owner email + + assert_output "Permissions for #{email}:\nOWNER\n" do + print_file_acl_for_user bucket_name: bucket.name, + file_name: remote_file_name, + email: email + end + end + end + + describe "add_file_owner" do + it "adds a user as an owner of for a file in a bucket" do + bucket.create_file local_file, remote_file_name + + assert_output "Added OWNER permission for #{email} to #{remote_file_name}\n" do + add_file_owner bucket_name: bucket.name, + file_name: remote_file_name, + email: email + end + assert_includes bucket.file(remote_file_name).acl.owners, email + end + end + + describe "remove_file_acl" do + it "removes a user from the acl for file in a bucket" do + bucket.create_file local_file, remote_file_name + bucket.file(remote_file_name).acl.add_owner email + + assert_output "Removed ACL permissions for #{email} from #{remote_file_name}\n" do + remove_file_acl bucket_name: bucket.name, + file_name: remote_file_name, + email: email + end + refute_includes bucket.file(remote_file_name).acl.owners, email + end + end +end diff --git a/google-cloud-storage/samples/acceptance/buckets_test.rb b/google-cloud-storage/samples/acceptance/buckets_test.rb new file mode 100644 index 000000000000..54a53b374276 --- /dev/null +++ b/google-cloud-storage/samples/acceptance/buckets_test.rb @@ -0,0 +1,355 @@ +# Copyright 2020 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. + +require_relative "helper" +require_relative "../buckets.rb" + +describe "Buckets Snippets" do + parallelize_me! + + let(:storage_client) { Google::Cloud::Storage.new } + let(:kms_key) { get_kms_key storage_client.project } + let(:retention_period) { rand 1..99 } + + let :bucket do + create_bucket_helper "ruby_storage_sample_#{SecureRandom.hex}" + end + + let :secondary_bucket do + create_bucket_helper "ruby_storage_sample_#{SecureRandom.hex}_secondary" + end + + after do + delete_bucket_helper bucket.name + delete_bucket_helper secondary_bucket.name + end + + describe "list_buckets" do + it "puts the buckets for a GCP project" do + bucket + secondary_bucket + + out, _err = capture_io do + list_buckets + end + + assert_includes out, bucket.name + assert_includes out, secondary_bucket.name + end + end + + describe "list_bucket_details" do + it "puts the details of a storage bucket" do + out, _err = capture_io do + list_bucket_details bucket_name: bucket.name + end + + assert_includes out, bucket.name + end + end + + describe "disable_requester_pays" do + it "disables requester_pays for a storage bucket" do + bucket.requester_pays = true + + assert_output "Requester pays has been disabled for #{bucket.name}\n" do + disable_requester_pays bucket_name: bucket.name + end + bucket.refresh! + refute bucket.requester_pays? + end + end + + describe "enable_requester_pays" do + it "enables requester_pays for a storage bucket" do + bucket.requester_pays = false + + assert_output "Requester pays has been enabled for #{bucket.name}\n" do + enable_requester_pays bucket_name: bucket.name + end + bucket.refresh! + assert bucket.requester_pays? + end + end + + describe "get_requester_pays_status" do + it "displays the status of requester_pays for a storage bucket" do + bucket.requester_pays = false + + assert_output "Requester Pays is disabled for #{bucket.name}\n" do + get_requester_pays_status bucket_name: bucket.name + end + + bucket.requester_pays = true + assert_output "Requester Pays is enabled for #{bucket.name}\n" do + get_requester_pays_status bucket_name: bucket.name + end + end + end + + describe "disable_uniform_bucket_level_access" do + it "disables uniform bucket level access for a storage bucket" do + bucket.uniform_bucket_level_access = true + + assert_output "Uniform bucket-level access was disabled for #{bucket.name}.\n" do + disable_uniform_bucket_level_access bucket_name: bucket.name + end + + bucket.refresh! + refute bucket.uniform_bucket_level_access? + end + end + + describe "enable_uniform_bucket_level_access" do + it "enables uniform bucket level access for a storage bucket" do + bucket.uniform_bucket_level_access = false + + assert_output "Uniform bucket-level access was enabled for #{bucket.name}.\n" do + enable_uniform_bucket_level_access bucket_name: bucket.name + end + + bucket.refresh! + assert bucket.uniform_bucket_level_access? + end + end + + describe "get_uniform_bucket_level_access" do + it "displays the status of uniform bucket level access for a storage bucket" do + bucket.uniform_bucket_level_access = false + + assert_output "Uniform bucket-level access is disabled for #{bucket.name}.\n" do + get_uniform_bucket_level_access bucket_name: bucket.name + end + refute bucket.uniform_bucket_level_access? + + bucket.uniform_bucket_level_access = true + + assert_output "Uniform bucket-level access is enabled for #{bucket.name}.\nBucket "\ + "will be locked on #{bucket.uniform_bucket_level_access_locked_at}.\n" do + get_uniform_bucket_level_access bucket_name: bucket.name + end + assert bucket.uniform_bucket_level_access? + end + end + + describe "enable_default_kms_key" do + it "sets a default kms key for a storage bucket" do + refute bucket.default_kms_key + + assert_output "Default KMS key for #{bucket.name} was set to #{kms_key}\n" do + enable_default_kms_key bucket_name: bucket.name, + default_kms_key: kms_key + end + + bucket.refresh! + assert_equal bucket.default_kms_key, kms_key + end + end + + describe "create_bucket" do + it "creates a storage bucket" do + bucket_name = "ruby_storage_sample_#{SecureRandom.hex}" + refute storage_client.bucket bucket_name + + retry_resource_exhaustion do + assert_output "Created bucket: #{bucket_name}\n" do + create_bucket bucket_name: bucket_name + end + end + + refute_nil storage_client.bucket bucket_name + delete_bucket_helper bucket_name + end + end + + describe "create_bucket_class_location" do + it "creates a storage bucket with a given class and location" do + bucket_name = "ruby_storage_sample_#{SecureRandom.hex}" + location = "US" + storage_class = "STANDARD" + refute storage_client.bucket bucket_name + + retry_resource_exhaustion do + assert_output "Created bucket #{bucket_name} in #{location} with #{storage_class} class\n" do + create_bucket_class_location bucket_name: bucket_name, + location: location, + storage_class: storage_class + end + end + + refute_nil storage_client.bucket bucket_name + assert_equal storage_client.bucket(bucket_name).location, location + assert_equal storage_client.bucket(bucket_name).storage_class, storage_class + delete_bucket_helper bucket_name + end + end + + describe "list_bucket_labels" do + it "puts the labels of a given bucket" do + label_key = "label_key" + label_value = "label_value" + bucket.update do |b| + b.labels[label_key] = label_value + end + + out, _err = capture_io do + list_bucket_labels bucket_name: bucket.name + end + + assert_includes out, "#{label_key} = #{label_value}" + end + end + + describe "add_bucket_label" do + it "adds a label to a given bucket" do + label_key = "label_key" + label_value = "label_value" + + assert_output "Added label #{label_key} with value #{label_value} to #{bucket.name}\n" do + add_bucket_label bucket_name: bucket.name, + label_value: label_value, + label_key: label_key + end + + bucket.refresh! + assert_equal bucket.labels[label_key], label_value + end + end + + describe "delete_bucket_label" do + it "deletes a label from a given bucket" do + label_key = "label_key" + label_value = "label_value" + bucket.update do |b| + b.labels[label_key] = label_value + end + + assert_output "Deleted label #{label_key} from #{bucket.name}\n" do + delete_bucket_label bucket_name: bucket.name, + label_key: label_key + end + + bucket.refresh! + assert bucket.labels.empty? + end + end + + describe "delete_bucket" do + it "deletes a label from a given bucket" do + assert_output "Deleted bucket: #{bucket.name}\n" do + delete_bucket bucket_name: bucket.name + end + + refute storage_client.bucket bucket.name + end + end + + describe "set_retention_policy" do + it "sets the retention policy for a given bucket" do + assert_output "Retention period for #{bucket.name} is now #{retention_period} seconds.\n" do + set_retention_policy bucket_name: bucket.name, + retention_period: retention_period + end + + bucket.refresh! + assert_equal bucket.retention_period, retention_period + end + end + + describe "lock_retention_policy" do + it "locks the retention policy for a given bucket" do + bucket.retention_period = retention_period + out, _err = capture_io do + lock_retention_policy bucket_name: bucket.name + end + + assert_includes out, "Retention policy for #{bucket.name} is now locked." + bucket.refresh! + assert bucket.retention_policy_locked? + end + end + + describe "remove_retention_policy" do + it "removes the retention policy for a given bucket" do + bucket.retention_period = retention_period + secondary_bucket.retention_period = retention_period + secondary_bucket.lock_retention_policy! + + assert_output "Retention policy for #{bucket.name} has been removed.\n" do + remove_retention_policy bucket_name: bucket.name + end + + bucket.refresh! + refute bucket.retention_period + + assert_output "Policy is locked and retention policy can't be removed.\n" do + remove_retention_policy bucket_name: secondary_bucket.name + end + end + end + + describe "get_retention_policy" do + it "gets the retention policy for a given bucket" do + bucket.retention_period = retention_period + + out, _err = capture_io do + get_retention_policy bucket_name: bucket.name + end + + assert_includes out, "period: #{retention_period}\n" + end + end + + describe "enable_default_event_based_hold" do + it "gets the retention policy for a given bucket" do + assert_output "Default event-based hold was enabled for #{bucket.name}.\n" do + enable_default_event_based_hold bucket_name: bucket.name + end + + bucket.refresh! + assert bucket.default_event_based_hold? + end + end + + describe "disable_default_event_based_hold" do + it "gets the retention policy for a given bucket" do + bucket.update do |b| + b.default_event_based_hold = true + end + + assert_output "Default event-based hold was disabled for #{bucket.name}.\n" do + disable_default_event_based_hold bucket_name: bucket.name + end + + bucket.refresh! + refute bucket.default_event_based_hold? + end + end + + describe "get_default_event_based_hold" do + it "gets the retention policy for a given bucket" do + bucket.update do |b| + b.default_event_based_hold = true + end + + assert_output "Default event-based hold is enabled for #{bucket.name}.\n" do + get_default_event_based_hold bucket_name: bucket.name + end + + assert_output "Default event-based hold is not enabled for #{secondary_bucket.name}.\n" do + get_default_event_based_hold bucket_name: secondary_bucket.name + end + end + end +end diff --git a/google-cloud-storage/samples/acceptance/data/file.txt b/google-cloud-storage/samples/acceptance/data/file.txt new file mode 100644 index 000000000000..2409b20a4514 --- /dev/null +++ b/google-cloud-storage/samples/acceptance/data/file.txt @@ -0,0 +1 @@ +Content of test file.txt diff --git a/google-cloud-storage/samples/acceptance/files_test.rb b/google-cloud-storage/samples/acceptance/files_test.rb new file mode 100644 index 000000000000..bf29be7aee6b --- /dev/null +++ b/google-cloud-storage/samples/acceptance/files_test.rb @@ -0,0 +1,479 @@ +# Copyright 2020 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. + +require_relative "helper" +require_relative "../files.rb" + +describe "Files Snippets" do + parallelize_me! + + let :bucket do + create_bucket_helper "ruby_storage_sample_#{SecureRandom.hex}" + end + + let :secondary_bucket do + create_bucket_helper "ruby_storage_sample_#{SecureRandom.hex}_secondary" + end + + let(:storage_client) { Google::Cloud::Storage.new } + let(:local_file) { File.expand_path "data/file.txt", __dir__ } + let(:encryption_key) { OpenSSL::Cipher.new("aes-256-cfb").encrypt.random_key } + let(:kms_key) { get_kms_key storage_client.project } + let(:remote_file_name) { "path/file_name.txt" } + let(:downloaded_file) { "test_download_#{SecureRandom.hex}" } + + after do + File.delete downloaded_file if File.file? downloaded_file + delete_bucket_helper bucket.name + delete_bucket_helper secondary_bucket.name + end + + describe "list_bucket_contents" do + it "puts the bucket's contents" do + bucket.create_file local_file, "foo.txt" + bucket.create_file local_file, "bar.txt" + + out, _err = capture_io do + list_bucket_contents bucket_name: bucket.name + end + + assert_match "foo.txt", out + assert_match "bar.txt", out + end + end + + describe "list_bucket_contents_with_prefix" do + it "puts the bucket's contents that begin with the prefix" do + ["foo/file.txt", "foo/data.txt", "bar/file.txt", "bar/data.txt"].each do |file| + bucket.create_file local_file, file + end + + out, _err = capture_io do + list_bucket_contents_with_prefix bucket_name: bucket.name, prefix: "foo/" + end + + assert_match "foo/file.txt", out + assert_match "foo/data.txt", out + end + + it "omits the bucket's contents that don't begin with the prefix" do + ["foo/file.txt", "foo/data.txt", "bar/file.txt", "bar/data.txt"].each do |file| + bucket.create_file local_file, file + end + + out, _err = capture_io do + list_bucket_contents_with_prefix bucket_name: bucket.name, prefix: "foo/" + end + + refute_match "bar/file.txt", out + refute_match "bar/data.txt", out + end + end + + describe "generate_encryption_key_base64" do + it "can generate a base64 encoded encryption key" do + mock_cipher = Minitest::Mock.new + + def mock_cipher.encrypt + self + end + + def mock_cipher.random_key + @key ||= OpenSSL::Cipher.new("aes-256-cfb").encrypt.random_key + end + + encryption_key_base64 = Base64.encode64 mock_cipher.random_key + + OpenSSL::Cipher.stub :new, mock_cipher do + assert_output "Sample encryption key: #{encryption_key_base64}" do + generate_encryption_key_base64 + end + end + end + end + + describe "upload_file" do + it "uploads a file to a storage bucket" do + assert_output "Uploaded #{remote_file_name}\n" do + upload_file bucket_name: bucket.name, local_file_path: local_file, storage_file_path: remote_file_name + end + + assert_equal bucket.files.first.name, remote_file_name + end + end + + describe "upload_encrypted_file" do + it "uploads a file to a storage bucket with an encryption key" do + assert_output "Uploaded #{remote_file_name} with encryption key\n" do + upload_encrypted_file bucket_name: bucket.name, + local_file_path: local_file, + storage_file_path: remote_file_name, + encryption_key: encryption_key + end + + assert_equal bucket.files.first.name, remote_file_name + refute_nil bucket.files.first.encryption_key_sha256 + end + end + + describe "upload_with_kms_key" do + it "uploads a file to a storage bucket with an encryption key" do + assert_output(/Uploaded #{remote_file_name} and encrypted service side using #{kms_key}/) do + upload_with_kms_key bucket_name: bucket.name, + local_file_path: local_file, + storage_file_path: remote_file_name, + kms_key: kms_key + end + + assert_equal bucket.files.first.name, remote_file_name + assert_match kms_key, bucket.files.first.kms_key + end + end + + describe "download_file" do + it "downloads a file from a storage bucket" do + bucket.create_file local_file, remote_file_name + + assert_output "Downloaded #{remote_file_name}\n" do + download_file bucket_name: bucket.name, + file_name: remote_file_name, + local_path: downloaded_file + end + + assert File.file? downloaded_file + end + end + + describe "download_public_file" do + it "downloads a file from a public storage bucket" do + bucket.create_file local_file, remote_file_name + + assert_output "Downloaded #{remote_file_name}\n" do + download_file bucket_name: bucket.name, + file_name: remote_file_name, + local_path: downloaded_file + end + + assert File.file? downloaded_file + end + end + + describe "download_file_requester_pays" do + it "downloads a file from a bucket using requester pays" do + bucket.requester_pays = true + bucket.create_file local_file, remote_file_name + + assert_output "Downloaded #{remote_file_name} using billing project #{storage_client.project}\n" do + download_file_requester_pays bucket_name: bucket.name, + file_name: remote_file_name, + local_path: downloaded_file + end + + assert File.file? downloaded_file + end + end + + describe "download_encrypted_file" do + it "downloads an encrypted file from storage bucket" do + bucket.create_file local_file, remote_file_name, encryption_key: encryption_key + + assert_output "Downloaded encrypted #{remote_file_name}\n" do + download_encrypted_file bucket_name: bucket.name, + storage_file_path: remote_file_name, + local_file_path: downloaded_file, + encryption_key: encryption_key + end + + assert File.file? downloaded_file + assert_equal File.read(local_file), File.read(downloaded_file) + end + end + + describe "delete_file" do + it "deletes a file from storage bucket" do + bucket.create_file local_file, remote_file_name + + assert_output "Deleted #{remote_file_name}\n" do + delete_file bucket_name: bucket.name, + file_name: remote_file_name + end + + assert_nil bucket.file remote_file_name + end + end + + describe "list_file_details" do + it "puts the details of a file from storage bucket" do + bucket.create_file local_file, remote_file_name + + file = bucket.file remote_file_name + expected_output = <<~OUTPUT + Name: #{file.name} + Bucket: #{bucket.name} + Storage class: #{bucket.storage_class} + ID: #{file.id} + Size: #{file.size} bytes + Created: #{file.created_at} + Updated: #{file.updated_at} + Generation: #{file.generation} + Metageneration: #{file.metageneration} + Etag: #{file.etag} + Owners: #{file.acl.owners.join ','} + Crc32c: #{file.crc32c} + md5_hash: #{file.md5} + Cache-control: #{file.cache_control} + Content-type: #{file.content_type} + Content-disposition: #{file.content_disposition} + Content-encoding: #{file.content_encoding} + Content-language: #{file.content_language} + KmsKeyName: #{file.kms_key} + Event-based hold enabled?: #{file.event_based_hold?} + Temporary hold enaled?: #{file.temporary_hold?} + Retention Expiration: #{file.retention_expires_at} + Metadata: + OUTPUT + + assert_output expected_output do + list_file_details bucket_name: bucket.name, + file_name: remote_file_name + end + end + end + + describe "set_metadata" do + it "sets the metadata for a file in a storage bucket" do + bucket.create_file local_file, remote_file_name + + metadata_key = "test-metadata-key" + metadata_value = "test-metadata-value" + content_type = "text/plain" + + assert_output "Metadata for #{remote_file_name} has been updated.\n" do + set_metadata bucket_name: bucket.name, + file_name: remote_file_name, + content_type: content_type, + metadata_key: metadata_key, + metadata_value: metadata_value + end + + assert_equal bucket.file(remote_file_name).metadata[metadata_key], metadata_value + end + end + + describe "make_file_public" do + it "makes a file from a storage bucket publicly accessible from a url" do + bucket.create_file local_file, remote_file_name + response = Net::HTTP.get URI(bucket.file(remote_file_name).public_url) + refute_equal File.read(local_file), response + + assert_output "#{remote_file_name} is publicly accessible at #{bucket.file(remote_file_name).public_url}\n" do + make_file_public bucket_name: bucket.name, + file_name: remote_file_name + end + + response = Net::HTTP.get URI(bucket.file(remote_file_name).public_url) + assert_equal File.read(local_file), response + end + end + + describe "rename_file" do + it "renames a file in a storage bucket" do + bucket.create_file local_file, remote_file_name + + new_name = "path/new_name.txt" + assert_nil bucket.file new_name + + assert_output "#{remote_file_name} has been renamed to #{new_name}\n" do + rename_file bucket_name: bucket.name, + file_name: remote_file_name, + new_name: new_name + end + + assert_nil bucket.file remote_file_name + refute_nil bucket.file new_name + end + end + + describe "copy_file" do + it "copies a file from one storage bucket to another" do + bucket.create_file local_file, remote_file_name + assert_nil secondary_bucket.file remote_file_name + + assert_output "#{remote_file_name} in #{bucket.name} copied to #{remote_file_name} in #{secondary_bucket.name}\n" do + copy_file source_bucket_name: bucket.name, + source_file_name: remote_file_name, + dest_bucket_name: secondary_bucket.name, + dest_file_name: remote_file_name + end + + refute_nil bucket.file remote_file_name + refute_nil secondary_bucket.file remote_file_name + end + end + + describe "rotate_encryption_key" do + it "changes the encryption key used for a file in a storage bucket" do + bucket.create_file local_file, remote_file_name, encryption_key: encryption_key + + new_encryption_key = OpenSSL::Cipher.new("aes-256-cfb").encrypt.random_key + file_contents = File.read local_file + + assert_output "The encryption key for #{remote_file_name} in #{bucket.name} was rotated.\n" do + rotate_encryption_key bucket_name: bucket.name, + file_name: remote_file_name, + current_encryption_key: encryption_key, + new_encryption_key: new_encryption_key + end + + bucket.file(remote_file_name).download downloaded_file, encryption_key: new_encryption_key + downloaded_contents = File.read downloaded_file + assert_equal file_contents, downloaded_contents + end + end + + describe "generate_signed_url" do + it "generates a signed url for a file in a bucket" do + bucket.create_file local_file, remote_file_name + + out, _err = capture_io do + generate_signed_url bucket_name: bucket.name, + file_name: remote_file_name + end + + assert_match "The signed url for #{remote_file_name} is", out + signed_url = out.scan(/http.*$/).first + refute_nil signed_url + + file_contents = Net::HTTP.get URI(signed_url) + assert_equal file_contents, File.read(local_file) + end + end + + describe "generate_signed_get_url_v4" do + it "generates a v4 signed get url for a file in a bucket" do + bucket.create_file local_file, remote_file_name + + out, _err = capture_io do + generate_signed_get_url_v4 bucket_name: bucket.name, + file_name: remote_file_name + end + + signed_url = out.scan(/http.*$/).first + refute_nil signed_url + + file_contents = Net::HTTP.get URI(signed_url) + assert_equal file_contents, File.read(local_file) + end + end + + describe "generate_signed_put_url_v4" do + it "generates a v4 signed put url for a file in a bucket" do + refute bucket.file remote_file_name + + out, _err = capture_io do + generate_signed_put_url_v4 bucket_name: bucket.name, + file_name: remote_file_name + end + + signed_url = out.scan(/http.*$/).first + refute_nil signed_url + + uri = URI.parse signed_url + http = Net::HTTP.new uri.host + request = Net::HTTP::Put.new uri.request_uri + request.body = File.read local_file + request["Content-Type"] = "text/plain" + request["Content-Length"] = File.size local_file + + response = http.request request + assert_equal response.code, "200" + + assert bucket.file remote_file_name + end + end + + describe "set_event_based_hold" do + it "sets an event-based hold for a file in a bucket" do + bucket.create_file local_file, remote_file_name + + assert_output "Event-based hold was set for #{remote_file_name}.\n" do + set_event_based_hold bucket_name: bucket.name, + file_name: remote_file_name + end + + assert bucket.file(remote_file_name).event_based_hold? + bucket.file(remote_file_name).release_event_based_hold! + end + end + + describe "release_event_based_hold" do + it "releases an event-based hold for a file in a bucket" do + bucket.create_file local_file, remote_file_name + bucket.file(remote_file_name).set_event_based_hold! + assert bucket.file(remote_file_name).event_based_hold? + + assert_output "Event-based hold was released for #{remote_file_name}.\n" do + release_event_based_hold bucket_name: bucket.name, + file_name: remote_file_name + end + + refute bucket.file(remote_file_name).event_based_hold? + end + end + + describe "set_temporary_hold" do + it "sets a temporary hold for a file in a bucket" do + bucket.create_file local_file, remote_file_name + refute bucket.file(remote_file_name).temporary_hold? + + assert_output "Temporary hold was set for #{remote_file_name}.\n" do + set_temporary_hold bucket_name: bucket.name, + file_name: remote_file_name + end + + assert bucket.file(remote_file_name).temporary_hold? + bucket.file(remote_file_name).release_temporary_hold! + end + end + + describe "release_temporary_hold" do + it "releases a temporary hold for a file in a bucket" do + bucket.create_file local_file, remote_file_name + bucket.file(remote_file_name).set_temporary_hold! + assert bucket.file(remote_file_name).temporary_hold? + + assert_output "Temporary hold was released for #{remote_file_name}.\n" do + release_temporary_hold bucket_name: bucket.name, + file_name: remote_file_name + end + + refute bucket.file(remote_file_name).temporary_hold? + end + end + + describe "release_temporary_hold" do + it "releases a temporary hold for a file in a bucket" do + bucket.create_file local_file, remote_file_name + bucket.file(remote_file_name).set_temporary_hold! + assert bucket.file(remote_file_name).temporary_hold? + + assert_output "Temporary hold was released for #{remote_file_name}.\n" do + release_temporary_hold bucket_name: bucket.name, + file_name: remote_file_name + end + + refute bucket.file(remote_file_name).temporary_hold? + end + end +end diff --git a/google-cloud-storage/samples/acceptance/helper.rb b/google-cloud-storage/samples/acceptance/helper.rb new file mode 100644 index 000000000000..e3a3a29904ab --- /dev/null +++ b/google-cloud-storage/samples/acceptance/helper.rb @@ -0,0 +1,89 @@ +# Copyright 2020 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. + +require "google/cloud/errors" +require "google/cloud/kms" +require "google/cloud/storage" +require "minitest/autorun" +require "net/http" +require "securerandom" +require "uri" + +def create_bucket_helper bucket_name + storage_client = Google::Cloud::Storage.new + + retry_resource_exhaustion do + return storage_client.create_bucket bucket_name + end +end + +def delete_bucket_helper bucket_name + storage_client = Google::Cloud::Storage.new + + retry_resource_exhaustion do + bucket = storage_client.bucket bucket_name + return unless bucket + + bucket.files.each(&:delete) + bucket.delete + end +end + +def retry_resource_exhaustion + 5.times do + begin + yield + return + rescue Google::Cloud::ResourceExhaustedError => e + puts "\n#{e} Gonna try again" + sleep rand(3..5) + rescue StandardError => e + puts "\n#{e}" + return + end + end + raise Google::Cloud::ResourceExhaustedError, "Maybe take a break from creating and deleting buckets for a bit" +end + +def get_kms_key project_id + kms_client = Google::Cloud::Kms.new + + key_ring_id = "ruby_docs_test_ring_id" + location_path = kms_client.location_path project_id, "us" + key_ring_path = kms_client.key_ring_path project_id, "us", key_ring_id + begin + kms_client.get_key_ring key_ring_path + rescue Google::Gax::RetryError + kms_client.create_key_ring location_path, key_ring_id, {} + end + + crypto_key_id = "ruby_docs_test_key" + crypto_key = { + purpose: :ENCRYPT_DECRYPT + } + crypto_key_path = kms_client.crypto_key_path project_id, "us", key_ring_id, crypto_key_id + begin + kms_client.get_crypto_key(crypto_key_path).name + rescue Google::Gax::GaxError + kms_client.create_crypto_key(key_ring_path, crypto_key_id, crypto_key).name + end +end + +def delete_hmac_key_helper hmac_key + hmac_key.refresh! + return if hmac_key.deleted? + + hmac_key.inactive! if hmac_key.active? + hmac_key.delete! +end diff --git a/google-cloud-storage/samples/acceptance/hmac_test.rb b/google-cloud-storage/samples/acceptance/hmac_test.rb new file mode 100644 index 000000000000..63d0b7df4dfd --- /dev/null +++ b/google-cloud-storage/samples/acceptance/hmac_test.rb @@ -0,0 +1,112 @@ +# Copyright 2020 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. + +require_relative "helper" +require_relative "../hmac.rb" + +describe "HMAC Snippets" do + parallelize_me! + + let(:storage_client) { Google::Cloud::Storage.new } + let(:project_id) { storage_client.project } + let(:service_account_email) { "#{project_id}@appspot.gserviceaccount.com" } + + let :hmac_key do + hmac_key = storage_client.create_hmac_key service_account_email + hmac_key + end + + after do + delete_hmac_key_helper hmac_key + end + + describe "list_hmac_keys" do + it "lists the hmac keys for a GCP project" do + access_id = hmac_key.access_id + + out, _err = capture_io do + list_hmac_keys + end + + assert_includes out, "Service Account Email: #{service_account_email}" + assert_includes out, "Access ID: #{access_id}" + end + end + + describe "create_hmac_key" do + it "creates an hmac key" do + out, _err = capture_io do + create_hmac_key service_account_email: service_account_email + end + match = out.match(/Access ID:\s+(.*)\n/) + access_id = match[1] + # Raises error if no hmac_key found + delete_hmac_key_helper storage_client.hmac_key(access_id) + + assert_match(/Service Account Email:\s+#{service_account_email}/, out) + end + end + + describe "get_hmac_key" do + it "gets an hmac key from an access_id" do + access_id = hmac_key.access_id + + out, _err = capture_io do + get_hmac_key access_id: access_id + end + + assert_match(/Service Account Email:\s+#{service_account_email}/, out) + end + end + + describe "activate_hmac_key" do + it "activates an hmac key from an access_id" do + hmac_key.inactive! + + out, _err = capture_io do + activate_hmac_key access_id: hmac_key.access_id + end + + assert_match(/Service Account Email:\s+#{service_account_email}/, out) + hmac_key.refresh! + assert hmac_key.active? + end + end + + describe "deactivate_hmac_key" do + it "deactivates an hmac key from an access_id" do + out, _err = capture_io do + deactivate_hmac_key access_id: hmac_key.access_id + end + + assert_match(/Service Account Email:\s+#{service_account_email}/, out) + hmac_key.refresh! + assert hmac_key.inactive? + end + end + + describe "delete_hmac_key" do + it "deletes an hmac key from an access_id" do + hmac_key.inactive! + access_id = hmac_key.access_id + + assert_output "The key is deleted, though it may still appear in Client#hmac_keys results.\n" do + delete_hmac_key access_id: access_id + end + + hmac_key.refresh! + assert hmac_key.deleted? + end + end +end diff --git a/google-cloud-storage/samples/acceptance/iam_test.rb b/google-cloud-storage/samples/acceptance/iam_test.rb new file mode 100644 index 000000000000..f2c0d08f974d --- /dev/null +++ b/google-cloud-storage/samples/acceptance/iam_test.rb @@ -0,0 +1,124 @@ +# Copyright 2020 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. + +require_relative "helper" +require_relative "../iam.rb" + +describe "IAM Snippets" do + parallelize_me! + + let :bucket do + create_bucket_helper "ruby_storage_sample_#{SecureRandom.hex}" + end + + let(:role) { "roles/storage.admin" } + let(:member) { "user:test@test.com" } + + after do + delete_bucket_helper bucket.name + end + + describe "view_bucket_iam_members" do + it "puts the members for each IAM role" do + bucket.policy do |policy| + policy.add role, member + end + + out, _err = capture_io do + view_bucket_iam_members bucket_name: bucket.name + end + + assert_includes out, "Role: #{role}" + assert_includes out, member + end + end + + describe "add_bucket_iam_member" do + it "adds an IAM member" do + assert_output "Added #{member} with role #{role} to #{bucket.name}\n" do + add_bucket_iam_member bucket_name: bucket.name, + role: role, + member: member + end + + assert bucket.policy.roles.any? do |p_role, p_members| + p_role == role && p_members.includes?(member) + end + end + end + + describe "remove_bucket_iam_member" do + it "removes an IAM member" do + assert_output "Removed #{member} with role #{role} from #{bucket.name}\n" do + remove_bucket_iam_member bucket_name: bucket.name, + role: role, + member: member + end + + refute bucket.policy.roles.none? do |p_role, p_members| + p_role == role && p_members.includes?(member) + end + end + end + + describe "add_bucket_conditional_iam_binding" do + it "adds conditional IAM binding to a bucket" do + title = "title" + description = "description" + expression = "resource.name.startsWith(\"projects/_/buckets/bucket-name/objects/prefix-a-\")" + bucket.uniform_bucket_level_access = true + assert_output "Added #{member} with role #{role} to #{bucket.name} with condition #{title} #{description} #{expression}\n" do + add_bucket_conditional_iam_binding bucket_name: bucket.name, + role: role, + member: member, + title: title, + description: description, + expression: expression + end + + policy = bucket.policy(requested_policy_version: 3).bindings.select(&:condition).first + assert_equal policy.role, role + assert_includes policy.members, member + assert_equal policy.condition.title, title + assert_equal policy.condition.description, description + assert_equal policy.condition.expression, expression + end + end + + describe "remove_bucket_conditional_iam_binding" do + it "remove conditional IAM binding to a bucket" do + title = "title" + description = "description" + expression = "resource.name.startsWith('projects/_/buckets/bucket-name/objects/prefix-a-')" + bucket.uniform_bucket_level_access = true + capture_io do + add_bucket_conditional_iam_binding bucket_name: bucket.name, + role: role, + member: member, + title: title, + description: description, + expression: expression + end + assert_output "Conditional Binding was removed.\n" do + remove_bucket_conditional_iam_binding bucket_name: bucket.name, + role: role, + title: title, + description: description, + expression: expression + end + bindings = bucket.policy(requested_policy_version: 3).bindings.select(&:condition) + assert_equal bindings.size, 0 + end + end +end diff --git a/google-cloud-storage/samples/acceptance/quickstart_test.rb b/google-cloud-storage/samples/acceptance/quickstart_test.rb new file mode 100644 index 000000000000..74c2f83e87d8 --- /dev/null +++ b/google-cloud-storage/samples/acceptance/quickstart_test.rb @@ -0,0 +1,33 @@ +# Copyright 2020 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. + +require_relative "helper" +require_relative "../quickstart.rb" + +describe "Storage Quickstart" do + let(:storage_client) { Google::Cloud::Storage.new } + let(:bucket_name) { "ruby_storage_sample_#{SecureRandom.hex}" } + + after do + delete_bucket_helper bucket_name + end + + it "creates a new bucket" do + assert_output "Bucket #{bucket_name} was created.\n" do + quickstart bucket_name: bucket_name + end + + assert storage_client.bucket bucket_name + end +end diff --git a/google-cloud-storage/samples/acls.rb b/google-cloud-storage/samples/acls.rb new file mode 100644 index 000000000000..38a9511125bc --- /dev/null +++ b/google-cloud-storage/samples/acls.rb @@ -0,0 +1,260 @@ +# Copyright 2017 Google, Inc +# +# 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. + +def print_bucket_acl bucket_name: + # [START print_bucket_acl] + # bucket_name = "Your Google Cloud Storage bucket name" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + puts "ACL for #{bucket_name}:" + + bucket.acl.owners.each do |owner| + puts "OWNER #{owner}" + end + + bucket.acl.writers.each do |writer| + puts "WRITER #{writer}" + end + + bucket.acl.readers.each do |reader| + puts "READER #{reader}" + end + # [END print_bucket_acl] +end + +def print_bucket_acl_for_user bucket_name:, email: + # [START print_bucket_acl_for_user] + # bucket_name = "Your Google Cloud Storage bucket name" + # email = "Google Cloud Storage ACL Entity email" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + puts "Permissions for #{email}:" + puts "OWNER" if bucket.acl.owners.include? email + puts "WRITER" if bucket.acl.writers.include? email + puts "READER" if bucket.acl.readers.include? email + # [END print_bucket_acl_for_user] +end + +def add_bucket_owner bucket_name:, email: + # [START add_bucket_owner] + # bucket_name = "Your Google Cloud Storage bucket name" + # email = "Google Cloud Storage ACL Entity email" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + bucket.acl.add_owner email + + puts "Added OWNER permission for #{email} to #{bucket_name}" + # [END add_bucket_owner] +end + +def remove_bucket_acl bucket_name:, email: + # [START remove_bucket_acl] + # project_id = "Your Google Cloud project ID" + # bucket_name = "Your Google Cloud Storage bucket name" + # email = "Google Cloud Storage ACL Entity email" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + bucket.acl.delete email + + puts "Removed ACL permissions for #{email} from #{bucket_name}" + # [END remove_bucket_acl] +end + +def add_bucket_default_owner bucket_name:, email: + # [START add_bucket_default_owner] + # bucket_name = "Your Google Cloud Storage bucket name" + # email = "Google Cloud Storage ACL Entity email" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + bucket.default_acl.add_owner email + + puts "Added default OWNER permission for #{email} to #{bucket_name}" + # [END add_bucket_default_owner] +end + +def remove_bucket_default_acl bucket_name:, email: + # [START remove_bucket_default_acl] + # bucket_name = "Your Google Cloud Storage bucket name" + # email = "Google Cloud Storage ACL Entity email" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + bucket.default_acl.delete email + + puts "Removed default ACL permissions for #{email} from #{bucket_name}" + # [END remove_bucket_default_acl] +end + +def print_file_acl bucket_name:, file_name: + # [START print_file_acl] + # bucket_name = "Your Google Cloud Storage bucket name" + # file_name = "Name of a file in the Storage bucket" + # email = "Google Cloud Storage ACL Entity email" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + file = bucket.file file_name + + puts "ACL for #{file_name} in #{bucket_name}:" + + file.acl.owners.each do |owner| + puts "OWNER #{owner}" + end + + file.acl.readers.each do |reader| + puts "READER #{reader}" + end + # [END print_file_acl] +end + +def print_file_acl_for_user bucket_name:, file_name:, email: + # [START print_file_acl_for_user] + # bucket_name = "Your Google Cloud Storage bucket name" + # file_name = "Name of a file in the Storage bucket" + # email = "Google Cloud Storage ACL Entity email" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + file = bucket.file file_name + + puts "Permissions for #{email}:" + puts "OWNER" if file.acl.owners.include? email + puts "READER" if file.acl.readers.include? email + # [END print_file_acl_for_user] +end + +def add_file_owner bucket_name:, file_name:, email: + # [START add_file_owner] + # bucket_name = "Your Google Cloud Storage bucket name" + # file_name = "Name of a file in the Storage bucket" + # email = "Google Cloud Storage ACL Entity email" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + file = bucket.file file_name + + file.acl.add_owner email + + puts "Added OWNER permission for #{email} to #{file_name}" + # [END add_file_owner] +end + +def remove_file_acl bucket_name:, file_name:, email: + # [START remove_file_acl] + # bucket_name = "Your Google Cloud Storage bucket name" + # file_name = "Name of a file in the Storage bucket" + # email = "Google Cloud Storage ACL Entity email" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + file = bucket.file file_name + + file.acl.delete email + + puts "Removed ACL permissions for #{email} from #{file_name}" + # [END remove_file_acl] +end + +def run_sample arguments + command = arguments.shift + + case command + when "print_bucket_acl" + print_bucket_acl bucket_name: arguments.shift + when "print_bucket_acl_for_user" + print_bucket_acl_for_user bucket_name: arguments.shift, + email: arguments.shift + when "add_bucket_owner" + add_bucket_owner bucket_name: arguments.shift, + email: arguments.shift + when "remove_bucket_acl" + remove_bucket_acl bucket_name: arguments.shift, + email: arguments.shift + when "add_bucket_default_owner" + add_bucket_default_owner bucket_name: arguments.shift, + email: arguments.shift + when "remove_bucket_default_acl" + remove_bucket_default_acl bucket_name: arguments.shift, + email: arguments.shift + when "print_file_acl" + print_file_acl bucket_name: arguments.shift, + file_name: arguments.shift + when "print_file_acl_for_user" + print_file_acl_for_user bucket_name: arguments.shift, + file_name: arguments.shift, + email: arguments.shift + when "add_file_owner" + add_file_owner bucket_name: arguments.shift, + file_name: arguments.shift, + email: arguments.shift + when "remove_file_acl" + remove_file_acl bucket_name: arguments.shift, + file_name: arguments.shift, + email: arguments.shift + else + puts <<~USAGE + Usage: bundle exec ruby acls.rb [command] [arguments] + + Commands: + print_bucket_acl Print bucket Access Control List + print_bucket_acl_for_user Print bucket ACL for an email + add_bucket_owner Add a new OWNER to a bucket + remove_bucket_acl Remove an entity from a bucket ACL + add_bucket_default_owner Add a default OWNER for a bucket + remove_bucket_default_acl Remove an entity from default bucket ACL + print_file_acl Print file ACL + print_file_acl_for_user Print file ACL for an email + add_file_owner Add an OWNER to a file + remove_file_acl Remove an entity from a file ACL + + Environment variables: + GOOGLE_CLOUD_PROJECT must be set to your Google Cloud project ID + USAGE + end +end + +if $PROGRAM_NAME == __FILE__ + run_sample ARGV +end diff --git a/google-cloud-storage/samples/buckets.rb b/google-cloud-storage/samples/buckets.rb new file mode 100644 index 000000000000..7b2575b04935 --- /dev/null +++ b/google-cloud-storage/samples/buckets.rb @@ -0,0 +1,478 @@ +# Copyright 2016 Google, Inc +# +# 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. + +def list_buckets + # [START list_buckets] + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + + storage.buckets.each do |bucket| + puts bucket.name + end + # [END list_buckets] +end + +def list_bucket_details bucket_name: + # [START storage_get_bucket_metadata] + # bucket_name = "Your Google Cloud Storage bucket name" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + puts "ID: #{bucket.id}" + puts "Name: #{bucket.name}" + puts "Storage Class: #{bucket.storage_class}" + puts "Location: #{bucket.location}" + puts "Location Type: #{bucket.location_type}" + puts "Cors: #{bucket.cors}" + puts "Default Event Based Hold: #{bucket.default_event_based_hold?}" + puts "Default KMS Key Name: #{bucket.default_kms_key}" + puts "Logging Bucket: #{bucket.logging_bucket}" + puts "Logging Prefix: #{bucket.logging_prefix}" + puts "Metageneration: #{bucket.metageneration}" + puts "Retention Effective Time: #{bucket.retention_effective_at}" + puts "Retention Period: #{bucket.retention_period}" + puts "Retention Policy Locked: #{bucket.retention_policy_locked?}" + puts "Requester Pays: #{bucket.requester_pays}" + puts "Self Link: #{bucket.api_url}" + puts "Time Created: #{bucket.created_at}" + puts "Versioning Enabled: #{bucket.versioning?}" + puts "Index Page: #{bucket.website_main}" + puts "Not Found Page: #{bucket.website_404}" + puts "Labels:" + bucket.labels.each do |key, value| + puts " - #{key} = #{value}" + end + # [END storage_get_bucket_metadata] +end + +def disable_requester_pays bucket_name: + # [START disable_requester_pays] + # bucket_name = "Name of your Google Cloud Storage bucket" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + bucket.requester_pays = false + + puts "Requester pays has been disabled for #{bucket_name}" + # [END disable_requester_pays] +end + +def enable_requester_pays bucket_name: + # [START enable_requester_pays] + # bucket_name = "Name of your Google Cloud Storage bucket" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + bucket.requester_pays = true + + puts "Requester pays has been enabled for #{bucket_name}" + # [END enable_requester_pays] +end + +def get_requester_pays_status bucket_name: + # [START get_requester_pays_status] + # bucket_name = "Name of your Google Cloud Storage bucket" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + if bucket.requester_pays + puts "Requester Pays is enabled for #{bucket_name}" + else + puts "Requester Pays is disabled for #{bucket_name}" + end + # [END get_requester_pays_status] +end + +def disable_uniform_bucket_level_access bucket_name: + # [START storage_disable_uniform_bucket_level_access] + # bucket_name = "Name of your Google Cloud Storage bucket" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + bucket.uniform_bucket_level_access = false + + puts "Uniform bucket-level access was disabled for #{bucket_name}." + # [END storage_disable_uniform_bucket_level_access] +end + +def enable_uniform_bucket_level_access bucket_name: + # [START storage_enable_uniform_bucket_level_access] + # bucket_name = "Name of your Google Cloud Storage bucket" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + bucket.uniform_bucket_level_access = true + + puts "Uniform bucket-level access was enabled for #{bucket_name}." + # [END storage_enable_uniform_bucket_level_access] +end + +def get_uniform_bucket_level_access bucket_name: + # [START storage_get_uniform_bucket_level_access] + # bucket_name = "Name of your Google Cloud Storage bucket" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + if bucket.uniform_bucket_level_access? + puts "Uniform bucket-level access is enabled for #{bucket_name}." + puts "Bucket will be locked on #{bucket.uniform_bucket_level_access_locked_at}." + else + puts "Uniform bucket-level access is disabled for #{bucket_name}." + end + # [END storage_get_uniform_bucket_level_access] +end + +def enable_default_kms_key bucket_name:, default_kms_key: + # [START storage_set_bucket_default_kms_key] + # bucket_name = "Name of your Google Cloud Storage bucket" + # default_kms_key = "KMS key resource id" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + bucket.default_kms_key = default_kms_key + + puts "Default KMS key for #{bucket.name} was set to #{bucket.default_kms_key}" + # [END storage_set_bucket_default_kms_key] +end + +def create_bucket bucket_name: + # [START create_bucket] + # bucket_name = "Name of Google Cloud Storage bucket to create" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.create_bucket bucket_name + + puts "Created bucket: #{bucket.name}" + # [END create_bucket] +end + +def create_bucket_class_location bucket_name:, location:, storage_class: + # [START create_bucket_class_location] + # bucket_name = "Name of Google Cloud Storage bucket to create" + # location = "Location of where to create Cloud Storage bucket" + # storage_class = "Storage class of Cloud Storage bucket" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.create_bucket bucket_name, + location: location, + storage_class: storage_class + + puts "Created bucket #{bucket.name} in #{location}" + + " with #{storage_class} class" + # [END create_bucket_class_location] +end + +def list_bucket_labels bucket_name: + # [START get_bucket_labels] + # bucket_name = "Name of your Google Cloud Storage bucket" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + puts "Labels for #{bucket_name}" + bucket.labels.each do |key, value| + puts "#{key} = #{value}" + end + # [END get_bucket_labels] +end + +def add_bucket_label bucket_name:, label_key:, label_value: + # [START add_bucket_label] + # bucket_name = "Name of your Google Cloud Storage bucket" + # label_key = "Cloud Storage bucket Label Key" + # label_value = "Cloud Storage bucket Label Value" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + bucket.update do |bucket| + bucket.labels[label_key] = label_value + end + + puts "Added label #{label_key} with value #{label_value} to #{bucket_name}" + # [END add_bucket_label] +end + +def delete_bucket_label bucket_name:, label_key: + # [START remove_bucket_label] + # bucket_name = "Name of your Google Cloud Storage bucket" + # label_key = "Cloud Storage bucket Label Key" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + bucket.update do |bucket| + bucket.labels[label_key] = nil + end + + puts "Deleted label #{label_key} from #{bucket_name}" + # [END remove_bucket_label] +end + +def delete_bucket bucket_name: + # [START delete_bucket] + # bucket_name = "Name of your Google Cloud Storage bucket to delete" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + bucket.delete + + puts "Deleted bucket: #{bucket.name}" + # [END delete_bucket] +end + +def set_retention_policy bucket_name:, retention_period: + # [START storage_set_retention_policy] + # bucket_name = "Name of your Google Cloud Storage bucket" + # retention_period = "Object retention period defined in seconds" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + bucket.retention_period = retention_period + + puts "Retention period for #{bucket_name} is now #{bucket.retention_period} seconds." + # [END storage_set_retention_policy] +end + +def lock_retention_policy bucket_name: + # [START storage_lock_retention_policy] + # bucket_name = "Name of your Google Cloud Storage bucket" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + # Warning: Once a retention policy is locked it cannot be unlocked + # and retention period can only be increased. + # Uses Bucket#metageneration as a precondition. + bucket.lock_retention_policy! + + puts "Retention policy for #{bucket_name} is now locked." + puts "Retention policy effective as of #{bucket.retention_effective_at}." + # [END storage_lock_retention_policy] +end + +def remove_retention_policy bucket_name: + # [START storage_remove_retention_policy] + # bucket_name = "Name of your Google Cloud Storage bucket" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + if !bucket.retention_policy_locked? + bucket.retention_period = nil + puts "Retention policy for #{bucket_name} has been removed." + else + puts "Policy is locked and retention policy can't be removed." + end + # [END storage_remove_retention_policy] +end + +def get_retention_policy bucket_name: + # [START storage_get_retention_policy] + # bucket_name = "Name of your Google Cloud Storage bucket" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + puts "Retention policy:" + puts "period: #{bucket.retention_period}" + puts "effective time: #{bucket.retention_effective_at}" + puts "policy locked: #{bucket.retention_policy_locked?}" + # [END storage_get_retention_policy] +end + +def enable_default_event_based_hold bucket_name: + # [START storage_enable_default_event_based_hold] + # bucket_name = "Name of your Google Cloud Storage bucket" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + bucket.update do |b| + b.default_event_based_hold = true + end + + puts "Default event-based hold was enabled for #{bucket_name}." + # [END storage_enable_default_event_based_hold] +end + +def disable_default_event_based_hold bucket_name: + # [START storage_disable_default_event_based_hold] + # bucket_name = "Name of your Google Cloud Storage bucket" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + bucket.update do |b| + b.default_event_based_hold = false + end + + puts "Default event-based hold was disabled for #{bucket_name}." + # [END storage_disable_default_event_based_hold] +end + +def get_default_event_based_hold bucket_name: + # [START storage_get_default_event_based_hold] + # bucket_name = "Name of your Google Cloud Storage bucket" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + if bucket.default_event_based_hold? + puts "Default event-based hold is enabled for #{bucket_name}." + else + puts "Default event-based hold is not enabled for #{bucket_name}." + end + # [END storage_get_default_event_based_hold] +end + +if $PROGRAM_NAME == __FILE__ + case ARGV.shift + when "list" + list_buckets + when "metadata" + list_bucket_details bucket_name: ARGV.shift + when "create" + if ARGV.size == 1 + create_bucket bucket_name: ARGV.shift + elsif ARGV.size == 3 + create_bucket_class_location bucket_name: ARGV.shift, + location: ARGV.shift, + storage_class: ARGV.shift + end + when "delete" + delete_bucket bucket_name: ARGV.shift + when "enable_requester_pays" + enable_requester_pays bucket_name: ARGV.shift + when "disable_requester_pays" + disable_requester_pays bucket_name: ARGV.shift + when "enable_default_kms_key" + enable_default_kms_key bucket_name: ARGV.shift, + default_kms_key: ARGV.shift + when "check_requester_pays" + check_requester_pays bucket_name: ARGV.shift + when "list_bucket_labels" + list_bucket_labels + when "add_bucket_label" + add_bucket_label bucket_name: ARGV.shift, + label_key: ARGV.shift, + label_value: ARGV.shift + when "delete_bucket_label" + delete_bucket_label bucket_name: ARGV.shift, + label_key: ARGV.shift + when "set_retention_policy" + set_retention_policy bucket_name: ARGV.shift, + retention_period: ARGV.shift + when "get_retention_policy" + get_retention_policy bucket_name: ARGV.shift + when "lock_retention_policy" + lock_retention_policy bucket_name: ARGV.shift + when "enable_default_event_based_hold" + enable_default_event_based_hold bucket_name: ARGV.shift + when "disable_default_event_based_hold" + disable_default_event_based_hold bucket_name: ARGV.shift + when "get_default_event_based_hold" + get_default_event_based_hold bucket_name: ARGV.shift + when "enable_uniform_bucket_level_access" + enable_uniform_bucket_level_access bucket_name: ARGV.shift + when "disable_uniform_bucket_level_access" + disable_uniform_bucket_level_access bucket_name: ARGV.shift + when "get_uniform_bucket_level_access" + get_uniform_bucket_level_access bucket_name: ARGV.shift + else + puts <<~USAGE + Usage: bundle exec ruby buckets.rb [command] [arguments] + + Commands: + list List all buckets in the authenticated project + enable_requester_pays Enable requester pays for a bucket + disable_requester_pays Disable requester pays for a bucket + check_requester_pays Check status of requester pays for a bucket + enable_default_kms_key Enable default KMS encryption for bucket + create Create a new bucket with default storage class and location + create Create a new bucket with specific storage class and location + list_bucket_labels List bucket labels + add_bucket_label Add bucket label + delete_bucket_label Delete bucket label + delete Delete bucket with the provided name + set_retention_policy Set a retention policy on bucket with a retention period determined in seconds + remove_retention_policy Remove a retention policy from a bucket if policy is not locked + lock_retention_policy Lock retention policy + get_retention_policy Get retention policy for a bucket + enable_default_event_based_hold Enable event-based hold for a bucket + disable_default_event_based_hold Disable event-based hold for a bucket + get_default_event_based_hold Get state of event-based hold for a bucket + enable_uniform_bucket_level_access Enable uniform bucket-level access for a bucket + disable_uniform_bucket_level_access Disable uniform bucket-level access for a bucket + get_uniform_bucket_level_access Get uniform bucket-level access for a bucket + + Environment variables: + GOOGLE_CLOUD_PROJECT must be set to your Google Cloud project ID + USAGE + end +end diff --git a/google-cloud-storage/samples/files.rb b/google-cloud-storage/samples/files.rb new file mode 100644 index 000000000000..ef52f51281a5 --- /dev/null +++ b/google-cloud-storage/samples/files.rb @@ -0,0 +1,593 @@ +# Copyright 2016 Google, Inc +# +# 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. + +def list_bucket_contents bucket_name: + # [START list_bucket_contents] + # bucket_name = "Your Google Cloud Storage bucket name" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + bucket.files.each do |file| + puts file.name + end + # [END list_bucket_contents] +end + +def list_bucket_contents_with_prefix bucket_name:, prefix: + # [START list_bucket_contents_with_prefix] + # bucket_name = "Your Google Cloud Storage bucket name" + # prefix = "Filter results to files whose names begin with this prefix" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + files = bucket.files prefix: prefix + + files.each do |file| + puts file.name + end + # [END list_bucket_contents_with_prefix] +end + +def generate_encryption_key_base64 + # [START generate_encryption_key_base64] + require "base64" + require "openssl" + + encryption_key = OpenSSL::Cipher.new("aes-256-cfb").encrypt.random_key + encoded_enc_key = Base64.encode64 encryption_key + + puts "Sample encryption key: #{encoded_enc_key}" + # [END generate_encryption_key_base64] +end + +def upload_file bucket_name:, local_file_path:, storage_file_path: nil + # [START upload_file] + # bucket_name = "Your Google Cloud Storage bucket name" + # local_file_path = "Path to local file to upload" + # storage_file_path = "Path to store the file in Google Cloud Storage" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + file = bucket.create_file local_file_path, storage_file_path + + puts "Uploaded #{file.name}" + # [END upload_file] +end + +def upload_encrypted_file bucket_name:, local_file_path:, storage_file_path: nil, encryption_key: + # [START upload_encrypted_file] + # bucket_name = "Your Google Cloud Storage bucket name" + # local_file_path = "Path to local file to upload" + # storage_file_path = "Path to store the file in Google Cloud Storage" + # encryption_key = "AES-256 encryption key" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + + bucket = storage.bucket bucket_name + + file = bucket.create_file local_file_path, storage_file_path, + encryption_key: encryption_key + + puts "Uploaded #{file.name} with encryption key" + # [END upload_encrypted_file] +end + +def upload_with_kms_key bucket_name:, local_file_path:, storage_file_path: nil, kms_key: + # [START storage_upload_with_kms_key] + # bucket_name = "Your Google Cloud Storage bucket name" + # local_file_path = "Path to local file to upload" + # storage_file_path = "Path to store the file in Google Cloud Storage" + # kms_key = "KMS key resource id" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + + bucket = storage.bucket bucket_name + + file = bucket.create_file local_file_path, storage_file_path, + kms_key: kms_key + + puts "Uploaded #{file.name} and encrypted service side using #{file.kms_key}" + # [END storage_upload_with_kms_key] +end + +def download_file bucket_name:, file_name:, local_path: + # [START download_file] + # bucket_name = "Your Google Cloud Storage bucket name" + # file_name = "Name of file in Google Cloud Storage to download locally" + # local_path = "Destination path for downloaded file" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + file = bucket.file file_name + + file.download local_path + + puts "Downloaded #{file.name}" + # [END download_file] +end + +def download_public_file bucket_name:, file_name:, local_path: + # [START download_public_file] + # bucket_name = "A public Google Cloud Storage bucket name" + # file_name = "Name of a file in the Cloud Storage bucket" + # local_path = "Destination path for downloaded file" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.anonymous + bucket = storage.bucket bucket_name, skip_lookup: true + file = bucket.file file_name + + file.download local_path + + puts "Downloaded #{file.name}" + # [END download_public_file] +end + +def download_file_requester_pays bucket_name:, file_name:, local_path: + # [START download_file_requester_pays] + # bucket_name = "A Google Cloud Storage bucket name" + # file_name = "Name of file in Google Cloud Storage to download locally" + # local_path = "Destination path for downloaded file" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name, skip_lookup: true, user_project: true + file = bucket.file file_name + + file.download local_path + + puts "Downloaded #{file.name} using billing project #{storage.project}" + # [END download_file_requester_pays] +end + +def download_encrypted_file(bucket_name:, storage_file_path:, + local_file_path:, encryption_key:) + # [START download_encrypted_file] + # bucket_name = "Your Google Cloud Storage bucket name" + # file_name = "Name of file in Google Cloud Storage to download locally" + # local_path = "Destination path for downloaded file" + # encryption_key = "AES-256 encryption key" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + + bucket = storage.bucket bucket_name + + file = bucket.file storage_file_path, encryption_key: encryption_key + file.download local_file_path, encryption_key: encryption_key + + puts "Downloaded encrypted #{file.name}" + # [END download_encrypted_file] +end + +def delete_file bucket_name:, file_name: + # [START delete_file] + # bucket_name = "Your Google Cloud Storage bucket name" + # file_name = "Name of file in Google Cloud Storage to delete" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + file = bucket.file file_name + + file.delete + + puts "Deleted #{file.name}" + # [END delete_file] +end + +def list_file_details bucket_name:, file_name: + # [START list_file_details] + # bucket_name = "Your Google Cloud Storage bucket name" + # file_name = "Name of file in Google Cloud Storage" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + file = bucket.file file_name + + puts "Name: #{file.name}" + puts "Bucket: #{bucket.name}" + puts "Storage class: #{bucket.storage_class}" + puts "ID: #{file.id}" + puts "Size: #{file.size} bytes" + puts "Created: #{file.created_at}" + puts "Updated: #{file.updated_at}" + puts "Generation: #{file.generation}" + puts "Metageneration: #{file.metageneration}" + puts "Etag: #{file.etag}" + puts "Owners: #{file.acl.owners.join ','}" + puts "Crc32c: #{file.crc32c}" + puts "md5_hash: #{file.md5}" + puts "Cache-control: #{file.cache_control}" + puts "Content-type: #{file.content_type}" + puts "Content-disposition: #{file.content_disposition}" + puts "Content-encoding: #{file.content_encoding}" + puts "Content-language: #{file.content_language}" + puts "KmsKeyName: #{file.kms_key}" + puts "Event-based hold enabled?: #{file.event_based_hold?}" + puts "Temporary hold enaled?: #{file.temporary_hold?}" + puts "Retention Expiration: #{file.retention_expires_at}" + puts "Metadata:" + file.metadata.each do |key, value| + puts " - #{key} = #{value}" + end + # [END list_file_details] +end + +def set_metadata bucket_name:, file_name:, content_type:, metadata_key:, metadata_value: + # [START set_metadata] + # bucket_name = "Your Google Cloud Storage bucket name" + # file_name = "Name of file in Google Cloud Storage" + # content_type = "file Content-Type" + # metadata_key = "Custom metadata key" + # metadata_value = "Custom metadata value" + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + file = bucket.file file_name + + file.update do |file| + # Fixed key file metadata + file.content_type = content_type + + # Custom file metadata + file.metadata[metadata_key] = metadata_value + end + + puts "Metadata for #{file_name} has been updated." + # [END set_metadata] +end + +def make_file_public bucket_name:, file_name: + # [START make_file_public] + # bucket_name = "Your Google Cloud Storage bucket name" + # file_name = "Name of file in Google Cloud Storage to make public" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + file = bucket.file file_name + + file.acl.public! + + puts "#{file.name} is publicly accessible at #{file.public_url}" + # [END make_file_public] +end + +def rename_file bucket_name:, file_name:, new_name: + # [START rename_file] + # bucket_name = "Your Google Cloud Storage bucket name" + # file_name = "Name of file in Google Cloud Storage to rename" + # new_name = "File will be renamed to this new name" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + file = bucket.file file_name + + renamed_file = file.copy new_name + + file.delete + + puts "#{file_name} has been renamed to #{renamed_file.name}" + # [END rename_file] +end + +def copy_file source_bucket_name:, source_file_name:, dest_bucket_name:, dest_file_name: + # [START copy_file] + # source_bucket_name = "Source bucket to copy file from" + # source_file_name = "Source file name" + # dest_bucket_name = "Destination bucket to copy file to" + # dest_file_name = "Destination file name" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket source_bucket_name + file = bucket.file source_file_name + + destination_bucket = storage.bucket dest_bucket_name + destination_file = file.copy destination_bucket.name, dest_file_name + + puts "#{file.name} in #{bucket.name} copied to " + + "#{destination_file.name} in #{destination_bucket.name}" + # [END copy_file] +end + +def rotate_encryption_key bucket_name:, file_name:, current_encryption_key:, new_encryption_key: + # [START rotate_encryption_key] + # bucket_name = "Your Google Cloud Storage bucket name" + # file_name = "Name of a file in the Cloud Storage bucket" + # current_encryption_key = "Encryption key currently being used" + # new_encryption_key = "New encryption key to use" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + file = bucket.file file_name, encryption_key: current_encryption_key + + file.rotate encryption_key: current_encryption_key, + new_encryption_key: new_encryption_key + + puts "The encryption key for #{file.name} in #{bucket.name} was rotated." + # [END rotate_encryption_key] +end + +def generate_signed_url bucket_name:, file_name: + # [START generate_signed_url] + # bucket_name = "Your Google Cloud Storage bucket name" + # file_name = "Name of a file in the Cloud Storage bucket" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + file = bucket.file file_name + + url = file.signed_url + + puts "The signed url for #{file_name} is #{url}" + # [END generate_signed_url] +end + +def generate_signed_get_url_v4 bucket_name:, file_name: + # [START storage_generate_signed_url_v4] + # bucket_name = "Your Google Cloud Storage bucket name" + # file_name = "Name of a file in the Google Cloud Storage bucket" + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + storage_expiry_time = 5 * 60 # 5 minutes + + url = storage.signed_url bucket_name, file_name, method: "GET", + expires: storage_expiry_time, version: :v4 + + puts "Generated GET signed url:" + puts url + puts "You can use this URL with any user agent, for example:" + puts "curl #{url}" + # [END storage_generate_signed_url_v4] +end + +def generate_signed_put_url_v4 bucket_name:, file_name: + # [START storage_generate_upload_signed_url_v4] + # bucket_name = "Your Google Cloud Storage bucket name" + # file_name = "Name of a file in the Cloud Storage bucket" + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + storage_expiry_time = 5 * 60 # 5 minutes + + url = storage.signed_url bucket_name, file_name, method: "PUT", + expires: storage_expiry_time, version: :v4, + headers: { "Content-Type" => "text/plain" } + puts "Generated PUT signed URL:" + puts url + puts "You can use this URL with any user agent, for example:" + puts "curl -X PUT -H 'Content-Type: text/plain' --upload-file my-file '#{url}'" + # [END storage_generate_upload_signed_url_v4] +end + +def set_event_based_hold bucket_name:, file_name: + # [START storage_set_event_based_hold] + # bucket_name = "Your Google Cloud Storage bucket name" + # file_name = "Name of a file in the Cloud Storage bucket" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + file = bucket.file file_name + + file.set_event_based_hold! + + puts "Event-based hold was set for #{file_name}." + # [END storage_set_event_based_hold] +end + +def release_event_based_hold bucket_name:, file_name: + # [START storage_release_event_based_hold] + # bucket_name = "Your Google Cloud Storage bucket name" + # file_name = "Name of a file in the Cloud Storage bucket" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + file = bucket.file file_name + + file.release_event_based_hold! + + puts "Event-based hold was released for #{file_name}." + # [END storage_release_event_based_hold] +end + +def set_temporary_hold bucket_name:, file_name: + # [START storage_set_temporary_hold] + # bucket_name = "Your Google Cloud Storage bucket name" + # file_name = "Name of a file in the Cloud Storage bucket" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + file = bucket.file file_name + + file.set_temporary_hold! + + puts "Temporary hold was set for #{file_name}." + # [END storage_set_temporary_hold] +end + +def release_temporary_hold bucket_name:, file_name: + # [START storage_release_temporary_hold] + # bucket_name = "Your Google Cloud Storage bucket name" + # file_name = "Name of a file in the Cloud Storage bucket" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + file = bucket.file file_name + + file.release_temporary_hold! + + puts "Temporary hold was released for #{file_name}." + # [END storage_release_temporary_hold] +end + +def run_sample arguments + command = arguments.shift + + case command + when "list" + list_bucket_contents bucket_name: arguments.shift + when "upload" + upload_file bucket_name: arguments.shift, + local_file_path: arguments.shift, + storage_file_path: arguments.shift + when "encrypted_upload" + upload_encrypted_file bucket_name: arguments.shift, + local_file_path: arguments.shift, + storage_file_path: arguments.shift, + encryption_key: Base64.decode64(arguments.shift) + when "kms_upload" + upload_with_kms_key bucket_name: arguments.shift, + local_file_path: arguments.shift, + storage_file_path: arguments.shift, + kms_key: arguments.shift + when "download" + download_file bucket_name: arguments.shift, + file_name: arguments.shift, + local_path: arguments.shift + when "download_public_file" + download_public_file bucket_name: arguments.shift, + file_name: arguments.shift, + local_path: arguments.shift + when "encrypted_download" + download_file bucket_name: arguments.shift, + file_name: arguments.shift, + local_path: arguments.shift, + encrypted_key: Base64.decode64(arguments.shift) + when "download_with_requester_pays" + download_file_requester_pays bucket_name: arguments.shift, + file_name: arguments.shift, + local_path: arguments.shift + when "rotate_encryption_key" + rotate_encryption_key bucket_name: arguments.shift, + file_name: arguments.shift, + current_encryption_key: arguments.shift, + new_encryption_key: arguments.shift + when "generate_encryption_key" + generate_encryption_key_base64 + when "delete" + delete_file bucket_name: arguments.shift, + file_name: arguments.shift + when "metadata" + list_file_details bucket_name: arguments.shift, + file_name: arguments.shift + when "make_public" + make_file_public bucket_name: arguments.shift, + file_name: arguments.shift + when "rename" + rename_file bucket_name: arguments.shift, + file_name: arguments.shift, + new_name: arguments.shift + when "copy" + copy_file source_bucket_name: arguments.shift, + source_file_name: arguments.shift, + dest_bucket_name: arguments.shift, + dest_file_name: arguments.shift + when "generate_signed_url" + generate_signed_url bucket_name: arguments.shift, + file_name: arguments.shift + when "generate_signed_get_url_v4" + generate_signed_get_url_v4 bucket_name: arguments.shift, + file_name: arguments.shift + when "generate_signed_put_url_v4" + generate_signed_put_url_v4 bucket_name: arguments.shift, + file_name: arguments.shift + when "set_event_based_hold" + set_event_based_hold bucket_name: arguments.shift, + file_name: arguments.shift + when "release_event_based_hold" + release_event_based_hold bucket_name: arguments.shift, + file_name: arguments.shift + when "set_temporary_hold" + set_temporary_hold bucket_name: arguments.shift, + file_name: arguments.shift + when "release_temporary_hold" + release_temporary_hold bucket_name: arguments.shift, + file_name: arguments.shift + else + puts <<~USAGE + Usage: bundle exec ruby files.rb [command] [arguments] + + Commands: + list List all files in the bucket + upload Upload local file to a bucket + encrypted_upload Upload local file as an encrypted file to a bucket + kms_upload Upload local file and encrypt service side using a KMS key + download Download a file from a bucket + download_public_file Download a publically accessible file from a bucket + encrypted_download Download an encrypted file from a bucket + download_with_requester_pays Download a file from a requester pays enabled bucket + rotate_encryption_key Update encryption key of an encrypted file. + generate_encryption_key Generate a sample encryption key + delete Delete a file from a bucket + metadata Display metadata for a file in a bucket + make_public Make a file in a bucket public + rename Rename a file in a bucket + copy Copy file to other bucket + generate_signed_url Generate a V2 signed url for a file + generate_signed_get_url_v4 Generate a V4 signed get url for a file + generate_signed_put_url_v4 Generate a V4 signed put url for a file + set_event_based_hold Set an event-based hold on a file + release_event_based_hold Relase an event-based hold on a file + set_temporary_hold Set a temporary hold on a file + release_temporary_hold Release a temporary hold on a file + + Environment variables: + GOOGLE_CLOUD_PROJECT must be set to your Google Cloud project ID + USAGE + end +end + +if $PROGRAM_NAME == __FILE__ + run_sample ARGV +end diff --git a/google-cloud-storage/samples/hmac.rb b/google-cloud-storage/samples/hmac.rb new file mode 100644 index 000000000000..5db8f092e7a8 --- /dev/null +++ b/google-cloud-storage/samples/hmac.rb @@ -0,0 +1,180 @@ +# Copyright 2019 Google, Inc +# +# 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. + +def list_hmac_keys + # [START storage_list_hmac_keys] + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + + # By default Storage#hmac_keys uses the Storage client project_id + hmac_keys = storage.hmac_keys + + puts "HMAC Keys:" + hmac_keys.all do |hmac_key| + puts "Service Account Email: #{hmac_key.service_account_email}" + puts "Access ID: #{hmac_key.access_id}" + end + # [END storage_list_hmac_keys] +end + +def create_hmac_key service_account_email: + # [START storage_create_hmac_key] + # service_account_email = "Service account used to associate generate HMAC key" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + + # By default Storage#create_hmac_key uses the Storage client project_id + hmac_key = storage.create_hmac_key service_account_email + + puts "The base64 encoded secret is: #{hmac_key.secret}" + puts "Do not miss that secret, there is no API to recover it." + puts "\nThe HMAC key metadata is:" + puts "Key ID: #{hmac_key.id}" + puts "Service Account Email: #{hmac_key.service_account_email}" + puts "Access ID: #{hmac_key.access_id}" + puts "Project ID: #{hmac_key.project_id}" + puts "Active: #{hmac_key.active?}" + puts "Created At: #{hmac_key.created_at}" + puts "Updated At: #{hmac_key.updated_at}" + puts "Etag: #{hmac_key.etag}" + # [END storage_create_hmac_key] +end + +def get_hmac_key access_id: + # [START storage_get_hmac_key] + # access_id = "ID of an HMAC key" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + + # By default Storage#hmac_keys uses the Storage client project_id + hmac_key = storage.hmac_key access_id + + puts "The HMAC key metadata is:" + puts "Key ID: #{hmac_key.id}" + puts "Service Account Email: #{hmac_key.service_account_email}" + puts "Access ID: #{hmac_key.access_id}" + puts "Project ID: #{hmac_key.project_id}" + puts "Active: #{hmac_key.active?}" + puts "Created At: #{hmac_key.created_at}" + puts "Updated At: #{hmac_key.updated_at}" + puts "Etag: #{hmac_key.etag}" + # [END storage_get_hmac_key] +end + +def activate_hmac_key access_id: + # [START storage_activate_hmac_key] + # access_id = "ID of an inactive HMAC key" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + + # By default Storage#hmac_keys uses the Storage client project_id + hmac_key = storage.hmac_key access_id + + hmac_key.active! + + puts "The HMAC key is now active." + puts "The HMAC key metadata is:" + puts "Key ID: #{hmac_key.id}" + puts "Service Account Email: #{hmac_key.service_account_email}" + puts "Access ID: #{hmac_key.access_id}" + puts "Project ID: #{hmac_key.project_id}" + puts "Active: #{hmac_key.active?}" + puts "Created At: #{hmac_key.created_at}" + puts "Updated At: #{hmac_key.updated_at}" + puts "Etag: #{hmac_key.etag}" + # [END storage_activate_hmac_key] +end + +def deactivate_hmac_key access_id: + # [START storage_deactivate_hmac_key] + # access_id = "ID of an inactive HMAC key" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + + # By default Storage#hmac_keys uses the Storage client project_id + hmac_key = storage.hmac_key access_id + + hmac_key.inactive! + + puts "The HMAC key is now inactive." + puts "The HMAC key metadata is:" + puts "Key ID: #{hmac_key.id}" + puts "Service Account Email: #{hmac_key.service_account_email}" + puts "Access ID: #{hmac_key.access_id}" + puts "Project ID: #{hmac_key.project_id}" + puts "Active: #{hmac_key.active?}" + puts "Created At: #{hmac_key.created_at}" + puts "Updated At: #{hmac_key.updated_at}" + puts "Etag: #{hmac_key.etag}" + # [END storage_deactivate_hmac_key] +end + +def delete_hmac_key access_id: + # [START storage_delete_hmac_key] + # access_id = "ID of an inactive HMAC key" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + + # By default Storage#hmac_keys uses the Storage client project_id + hmac_key = storage.hmac_key access_id + + hmac_key.delete! + + puts "The key is deleted, though it may still appear in Client#hmac_keys results." + # [END storage_delete_hmac_key] +end + +if $PROGRAM_NAME == __FILE__ + case ARGV.shift + when "list_hmac_keys" + list_hmac_keys + when "create_hmac_key" + create_hmac_key service_account_email: ARGV.shift + when "get_hmac_key" + get_hmac_key access_id: ARGV.shift + when "activate_hmac_key" + activate_hmac_key access_id: ARGV.shift + when "deactivate_hmac_key" + deactivate_hmac_key access_id: ARGV.shift + when "delete_hmac_key" + delete_hmac_key access_id: ARGV.shift + else + puts <<~USAGE + Usage: bundle exec ruby hmac.rb [command] [arguments] + + Commands: + list_hmac_keys List all HMAC keys for a project + create_hmac_key Create HMAC Key + get_hmac_key Get HMAC Key metadata + activate_hmac_key Activate an HMAC Key + deactivate_hmac_key Deactivate an HMAC Key + delete_hmac_key Delete a deactivated HMAC key + + Environment variables: + GOOGLE_CLOUD_PROJECT must be set to your Google Cloud project ID + USAGE + end +end diff --git a/google-cloud-storage/samples/iam.rb b/google-cloud-storage/samples/iam.rb new file mode 100644 index 000000000000..efebb51d7c68 --- /dev/null +++ b/google-cloud-storage/samples/iam.rb @@ -0,0 +1,199 @@ +# Copyright 2017 Google, Inc +# +# 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. + +def view_bucket_iam_members bucket_name: + # [START view_bucket_iam_members] + # bucket_name = "Your Google Cloud Storage bucket name" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + policy = bucket.policy requested_policy_version: 3 + policy.bindings.each do |binding| + puts "Role: #{binding.role}" + puts "Members: #{binding.members}" + + # if a conditional binding exists print the condition. + if binding.condition + puts "Condition Title: #{binding.condition.title}" + puts "Condition Description: #{binding.condition.description}" + puts "Condition Expression: #{binding.condition.expression}" + end + end + # [END view_bucket_iam_members] +end + +def add_bucket_iam_member bucket_name:, role:, member: + # [START add_bucket_iam_member] + # bucket_name = "Your Google Cloud Storage bucket name" + # role = "Bucket-level IAM role" + # member = "Bucket-level IAM member" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + bucket.policy requested_policy_version: 3 do |policy| + policy.bindings.insert role: role, members: [member] + end + + puts "Added #{member} with role #{role} to #{bucket_name}" + # [END add_bucket_iam_member] +end + +def remove_bucket_iam_member bucket_name:, role:, member: + # [START remove_bucket_iam_member] + # bucket_name = "Your Google Cloud Storage bucket name" + # role = "Bucket-level IAM role" + # member = "Bucket-level IAM member" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + bucket.policy requested_policy_version: 3 do |policy| + policy.bindings.each do |binding| + if binding.role == role && binding.condition.nil? + binding.members.delete member + end + end + end + + puts "Removed #{member} with role #{role} from #{bucket_name}" + # [END remove_bucket_iam_member] +end + +def add_bucket_conditional_iam_binding bucket_name:, role:, member:, title:, description:, expression: + # [START storage_add_bucket_conditional_iam_binding] + # bucket_name = "Your Google Cloud Storage bucket name" + # role = "Bucket-level IAM role" + # member = "Bucket-level IAM member" + # title = "Condition Title" + # description = "Condition Description" + # expression = "Condition Expression" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + bucket.policy requested_policy_version: 3 do |policy| + policy.version = 3 + policy.bindings.insert( + role: role, + members: member, + condition: { + title: title, + description: description, + expression: expression + } + ) + end + + puts "Added #{member} with role #{role} to #{bucket_name} with condition #{title} #{description} #{expression}" + # [END storage_add_bucket_conditional_iam_binding] +end + +def remove_bucket_conditional_iam_binding bucket_name:, role:, title:, description:, expression: + # [START storage_remove_bucket_conditional_iam_binding] + # bucket_name = "Your Google Cloud Storage bucket name" + # role = "Bucket-level IAM role" + # title = "Condition Title" + # description = "Condition Description" + # expression = "Condition Expression" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + bucket.policy requested_policy_version: 3 do |policy| + policy.version = 3 + + binding_to_remove = nil + policy.bindings.each do |b| + condition = { + title: title, + description: description, + expression: expression + } + if (b.role == role) && (b.condition && + b.condition.title == title && + b.condition.description == description && + b.condition.expression == expression) + binding_to_remove = b + end + end + if binding_to_remove + policy.bindings.remove binding_to_remove + puts "Conditional Binding was removed." + else + puts "No matching conditional binding found." + end + end + # [END storage_remove_bucket_conditional_iam_binding] +end + +def run_sample arguments + command = arguments.shift + + case command + when "view_bucket_iam_members" + view_bucket_iam_members bucket_name: arguments.shift + when "add_bucket_iam_member" + add_bucket_iam_member bucket_name: arguments.shift, + role: arguments.shift, + member: arguments.shift + when "add_bucket_conditional_iam_binding" + add_bucket_conditional_iam_binding project_id: project_id, + bucket_name: arguments.shift, + role: arguments.shift, + member: arguments.shift, + title: arguments.shift, + description: arguments.shift, + expression: arguments.shift + when "remove_bucket_iam_member" + remove_bucket_iam_member bucket_name: arguments.shift, + role: arguments.shift, + member: arguments.shift + when "remove_bucket_conditional_iam_binding" + remove_bucket_conditional_iam_binding bucket_name: arguments.shift, + role: arguments.shift, + title: arguments.shift, + description: arguments.shift, + expression: arguments.shift + else + puts <<~USAGE + Usage: bundle exec ruby iam.rb [command] [arguments] + + Commands: + view_bucket_iam_members View bucket-level IAM members + add_bucket_iam_member Add a bucket-level IAM member + add_bucket_conditional_iam_binding Add a conditional bucket-level binding + remove_bucket_iam_member Remove a bucket-level IAM member + remove_bucket_conditional_iam_binding Remove a conditional bucket-level binding + + Environment variables: + GOOGLE_CLOUD_PROJECT must be set to your Google Cloud project ID + USAGE + end +end + +if $PROGRAM_NAME == __FILE__ + run_sample ARGV +end diff --git a/google-cloud-storage/samples/quickstart.rb b/google-cloud-storage/samples/quickstart.rb new file mode 100644 index 000000000000..fbb3cc7ef4d6 --- /dev/null +++ b/google-cloud-storage/samples/quickstart.rb @@ -0,0 +1,34 @@ +# Copyright 2016 Google, Inc +# +# 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. + +def quickstart bucket_name: + # [START storage_quickstart] + # Imports the Google Cloud client library + require "google/cloud/storage" + + # Instantiates a client + storage = Google::Cloud::Storage.new + + # bucket_name = "The name of the bucket to be created, i.e. 'new-bucket'" + + # Creates the new bucket + bucket = storage.create_bucket bucket_name + + puts "Bucket #{bucket.name} was created." + # [END storage_quickstart] +end + +if $PROGRAM_NAME == __FILE__ + quickstart "quickstart_bucket" +end