Skip to content

Commit b662978

Browse files
committed
feat(storage): introduce IAM samples and tests for migration
1 parent 3b66abe commit b662978

13 files changed

Lines changed: 642 additions & 0 deletions
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
// Copyright 2020 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
'use strict';
16+
17+
/**
18+
* This application demonstrates how to perform basic operations on bucket and
19+
* file Access Control Lists with the Google Cloud Storage API.
20+
*
21+
* For more information, see the README.md under /storage and the documentation
22+
* at https://cloud.google.com/storage/docs.
23+
*/
24+
25+
function main(
26+
bucketName = 'my-bucket',
27+
roleName = 'roles/storage.objectViewer',
28+
title = 'match-prefix',
29+
description = 'Applies to objects matching a prefix',
30+
expression = 'resource.name.startsWith("projects/_/buckets/bucket-name/objects/prefix-a-")',
31+
members = 'user:test@example.com'
32+
) {
33+
members = members.split(',');
34+
// [START storage_add_bucket_conditional_iam_binding]
35+
/**
36+
* TODO(developer): Uncomment the following lines before running the sample.
37+
*/
38+
// The ID of your GCS bucket
39+
// const bucketName = 'your-unique-bucket-name';
40+
41+
// The role to grant
42+
// const roleName = 'roles/storage.objectViewer';
43+
44+
// The members to grant the new role to
45+
// const members = [
46+
// 'user:jdoe@example.com',
47+
// 'group:admins@example.com',
48+
// ];
49+
50+
// Create a condition
51+
// const title = 'Title';
52+
// const description = 'Description';
53+
// const expression = 'resource.name.startsWith(\"projects/_/buckets/bucket-name/objects/prefix-a-\")';
54+
55+
// Imports the Google Cloud client library
56+
const {Storage} = require('@google-cloud/storage');
57+
58+
// Creates a client
59+
const storage = new Storage();
60+
61+
async function addBucketConditionalBinding() {
62+
try {
63+
// Get a reference to a Google Cloud Storage bucket
64+
const bucket = storage.bucket(bucketName);
65+
66+
// Gets and updates the bucket's IAM policy
67+
const [policy] = await bucket.iam.getPolicy({requestedPolicyVersion: 3});
68+
69+
// Set the policy's version to 3 to use condition in bindings.
70+
policy.version = 3;
71+
72+
// Adds the new roles to the bucket's IAM policy
73+
policy.bindings.push({
74+
role: roleName,
75+
members: members,
76+
condition: {
77+
title: title,
78+
description: description,
79+
expression: expression,
80+
},
81+
});
82+
83+
// Updates the bucket's IAM policy
84+
await bucket.iam.setPolicy(policy);
85+
86+
console.log(
87+
`Added the following member(s) with role ${roleName} to ${bucketName}:`
88+
);
89+
90+
members.forEach(member => {
91+
console.log(` ${member}`);
92+
});
93+
94+
console.log('with condition:');
95+
console.log(` Title: ${title}`);
96+
console.log(` Description: ${description}`);
97+
console.log(` Expression: ${expression}`);
98+
} catch (error) {
99+
console.error(
100+
'Error executing add bucket conditional binding:',
101+
error.message || error
102+
);
103+
}
104+
}
105+
106+
addBucketConditionalBinding();
107+
// [END storage_add_bucket_conditional_iam_binding]
108+
}
109+
main(...process.argv.slice(2));

storage/addBucketIamMember.js

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// Copyright 2020 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
'use strict';
16+
17+
function main(
18+
bucketName = 'my-bucket',
19+
roleName = 'roles/storage.objectViewer',
20+
members = 'user:test@example.com'
21+
) {
22+
//including this logic so as to not use yargs
23+
members = members.split(',');
24+
// [START storage_add_bucket_iam_member]
25+
/**
26+
* TODO(developer): Uncomment the following lines before running the sample.
27+
*/
28+
// The ID of your GCS bucket
29+
// const bucketName = 'your-unique-bucket-name';
30+
31+
// The role to grant
32+
// const roleName = 'roles/storage.objectViewer';
33+
34+
// The members to grant the new role to
35+
// const members = [
36+
// 'user:jdoe@example.com',
37+
// 'group:admins@example.com',
38+
// ];
39+
40+
// Imports the Google Cloud client library
41+
const {Storage} = require('@google-cloud/storage');
42+
43+
// Creates a client
44+
const storage = new Storage();
45+
46+
async function addBucketIamMember() {
47+
try {
48+
// Get a reference to a Google Cloud Storage bucket
49+
const bucket = storage.bucket(bucketName);
50+
51+
// For more information please read:
52+
// https://cloud.google.com/storage/docs/access-control/iam
53+
const [policy] = await bucket.iam.getPolicy({requestedPolicyVersion: 3});
54+
55+
// Adds the new roles to the bucket's IAM policy
56+
policy.bindings.push({
57+
role: roleName,
58+
members: members,
59+
});
60+
61+
// Updates the bucket's IAM policy
62+
await bucket.iam.setPolicy(policy);
63+
64+
console.log(
65+
`Added the following member(s) with role ${roleName} to ${bucketName}:`
66+
);
67+
68+
members.forEach(member => {
69+
console.log(` ${member}`);
70+
});
71+
} catch (error) {
72+
console.error(
73+
'Error executing add bucket iam member:',
74+
error.message || error
75+
);
76+
}
77+
}
78+
79+
addBucketIamMember();
80+
// [END storage_add_bucket_iam_member]
81+
}
82+
main(...process.argv.slice(2));

storage/package.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"name": "@google-cloud/storage-samples",
3+
"description": "Samples for the Cloud Storage Client Library for Node.js.",
4+
"license": "Apache-2.0",
5+
"author": "Google Inc.",
6+
"engines": {
7+
"node": ">=12"
8+
},
9+
"repository": "googleapis/nodejs-storage",
10+
"private": true,
11+
"files": [
12+
"*.js"
13+
],
14+
"scripts": {
15+
"cleanup": "node scripts/cleanup",
16+
"test": "mocha system-test/*.js --timeout 800000"
17+
},
18+
"dependencies": {
19+
"@google-cloud/pubsub": "^4.0.0",
20+
"@google-cloud/storage": "^7.19.0",
21+
"node-fetch": "^2.6.7",
22+
"uuid": "^8.0.0",
23+
"yargs": "^16.0.0"
24+
},
25+
"devDependencies": {
26+
"chai": "^4.2.0",
27+
"mocha": "^8.0.0",
28+
"p-limit": "^3.1.0"
29+
}
30+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// Copyright 2020 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
'use strict';
16+
17+
/**
18+
* This application demonstrates how to perform basic operations on bucket and
19+
* file Access Control Lists with the Google Cloud Storage API.
20+
*
21+
* For more information, see the README.md under /storage and the documentation
22+
* at https://cloud.google.com/storage/docs.
23+
*/
24+
25+
function main(
26+
bucketName = 'my-bucket',
27+
roleName = 'roles/storage.objectViewer',
28+
title = 'match-prefix',
29+
description = 'Applies to objects matching a prefix',
30+
expression = 'resource.name.startsWith("projects/_/buckets/bucket-name/objects/prefix-a-")'
31+
) {
32+
// [START storage_remove_bucket_conditional_iam_binding]
33+
/**
34+
* TODO(developer): Uncomment the following lines before running the sample.
35+
*/
36+
// The ID of your GCS bucket
37+
// const bucketName = 'your-unique-bucket-name';
38+
39+
// The role to grant
40+
// const roleName = 'roles/storage.objectViewer';
41+
42+
// The members to grant the new role to
43+
// const members = [
44+
// 'user:jdoe@example.com',
45+
// 'group:admins@example.com',
46+
// ];
47+
48+
// Create a condition
49+
// const title = 'Title';
50+
// const description = 'Description';
51+
// const expression = 'resource.name.startsWith(\"projects/_/buckets/bucket-name/objects/prefix-a-\")';
52+
53+
// Imports the Google Cloud client library
54+
const {Storage} = require('@google-cloud/storage');
55+
56+
// Creates a client
57+
const storage = new Storage();
58+
59+
async function removeBucketConditionalBinding() {
60+
try {
61+
// Get a reference to a Google Cloud Storage bucket
62+
const bucket = storage.bucket(bucketName);
63+
64+
// Gets and updates the bucket's IAM policy
65+
const [policy] = await bucket.iam.getPolicy({requestedPolicyVersion: 3});
66+
67+
// Set the policy's version to 3 to use condition in bindings.
68+
policy.version = 3;
69+
70+
// Finds and removes the appropriate role-member group with specific condition.
71+
const index = policy.bindings.findIndex(
72+
binding =>
73+
binding.role === roleName &&
74+
binding.condition &&
75+
binding.condition.title === title &&
76+
binding.condition.description === description &&
77+
binding.condition.expression === expression
78+
);
79+
80+
const binding = policy.bindings[index];
81+
if (binding) {
82+
policy.bindings.splice(index, 1);
83+
84+
// Updates the bucket's IAM policy
85+
await bucket.iam.setPolicy(policy);
86+
87+
console.log('Conditional Binding was removed.');
88+
} else {
89+
// No matching role-member group with specific condition were found
90+
throw new Error('No matching binding group found.');
91+
}
92+
} catch (error) {
93+
console.error(
94+
'Error executing remove bucket conditional binding:',
95+
error.message || error
96+
);
97+
}
98+
}
99+
100+
removeBucketConditionalBinding();
101+
// [END storage_remove_bucket_conditional_iam_binding]
102+
}
103+
main(...process.argv.slice(2));

0 commit comments

Comments
 (0)