Skip to content

Commit 25cdbb9

Browse files
authored
feat: add ability to configure and utilize soft-delete and restore buckets (#2566)
* Adds support for the restore token feature * description fix * lint fix * fetch softDeleted bucket list & details fetch softDeleted bucket list & details * initial commit for bucket restore initial commit for bucket restore * fix missing license headers fix missing license headers * lint fix * test case bug fix * added restore bucket unit test cases * added restore bucket system test added restore bucket system test * lint fix * format format * system test fix
1 parent 740d30d commit 25cdbb9

File tree

7 files changed

+392
-133
lines changed

7 files changed

+392
-133
lines changed

samples/getSoftDeletedBucket.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/**
2+
* Copyright 2024 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
function main(bucketName = 'my-bucket', generation = 123456789) {
18+
// [START storage_get_soft_deleted_bucket]
19+
/**
20+
* TODO(developer): Uncomment the following lines before running the sample.
21+
*/
22+
// The ID of your GCS bucket
23+
// const bucketName = 'your-unique-bucket-name';
24+
25+
// The generation of the bucket to restore
26+
// const generation = 123456789;
27+
28+
// Imports the Google Cloud client library
29+
const {Storage} = require('@google-cloud/storage');
30+
31+
// Creates a client
32+
const storage = new Storage();
33+
34+
async function getSoftDeletedBucket() {
35+
const options = {
36+
generation: generation,
37+
softDeleted: true,
38+
};
39+
40+
const [metadata] = await storage.bucket(bucketName).getMetadata(options);
41+
42+
console.log(`Bucket: ${metadata.name}`);
43+
console.log(`Generation: ${metadata.generation}`);
44+
console.log(`SoftDeleteTime: ${metadata.softDeleteTime}`);
45+
console.log(`HardDeleteTime: ${metadata.hardDeleteTime}`);
46+
}
47+
48+
getSoftDeletedBucket().catch(console.error);
49+
// [END storage_get_soft_deleted_bucket]
50+
}
51+
52+
main(...process.argv.slice(2));

samples/listSoftDeletedBucket.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**
2+
* Copyright 2024 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
function main() {
18+
// [START storage_list_soft_deleted_buckets]
19+
// Imports the Google Cloud client library
20+
const {Storage} = require('@google-cloud/storage');
21+
22+
// Creates a client
23+
const storage = new Storage();
24+
25+
async function listSoftDeletedBuckets() {
26+
const options = {
27+
softDeleted: true,
28+
};
29+
30+
const [buckets] = await storage.getBuckets(options);
31+
32+
console.log('Buckets:');
33+
buckets.forEach(bucket => {
34+
console.log(bucket.name);
35+
});
36+
}
37+
38+
listSoftDeletedBuckets().catch(console.error);
39+
// [END storage_list_soft_deleted_buckets]
40+
}
41+
42+
main(...process.argv.slice(2));
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**
2+
* Copyright 2024 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
function main(bucketName = 'my-bucket', generation = 123456789) {
18+
// [START storage_restore_soft_deleted_bucket]
19+
/**
20+
* TODO(developer): Uncomment the following lines before running the sample.
21+
*/
22+
// The ID of your GCS bucket
23+
// const bucketName = 'your-unique-bucket-name';
24+
25+
// The generation of the bucket to restore
26+
// const generation = 123456789;
27+
28+
// Imports the Google Cloud client library
29+
const {Storage} = require('@google-cloud/storage');
30+
31+
// Creates a client
32+
const storage = new Storage();
33+
34+
async function restoreSoftDeletedBucket() {
35+
const options = {
36+
generation: generation,
37+
};
38+
39+
await storage.bucket(bucketName).restore(options);
40+
41+
console.log(`Soft deleted bucket ${bucketName} was restored.`);
42+
}
43+
44+
restoreSoftDeletedBucket().catch(console.error);
45+
// [END storage_restore_soft_deleted_bucket]
46+
}
47+
48+
main(...process.argv.slice(2));

src/bucket.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,10 @@ export interface GetLabelsCallback {
293293
(err: Error | null, labels: object | null): void;
294294
}
295295

296+
export interface RestoreOptions {
297+
generation: string;
298+
projection?: 'full' | 'noAcl';
299+
}
296300
export interface BucketMetadata extends BaseMetadata {
297301
acl?: AclMetadata[] | null;
298302
autoclass?: {
@@ -335,6 +339,7 @@ export interface BucketMetadata extends BaseMetadata {
335339
logBucket?: string;
336340
logObjectPrefix?: string;
337341
};
342+
generation?: string;
338343
metageneration?: string;
339344
name?: string;
340345
objectRetention?: {
@@ -351,6 +356,8 @@ export interface BucketMetadata extends BaseMetadata {
351356
retentionPeriod?: string | number;
352357
} | null;
353358
rpo?: string;
359+
softDeleteTime?: string;
360+
hardDeleteTime?: string;
354361
softDeletePolicy?: {
355362
retentionDurationSeconds?: string | number;
356363
readonly effectiveTime?: string;
@@ -3250,6 +3257,27 @@ class Bucket extends ServiceObject<Bucket, BucketMetadata> {
32503257
);
32513258
}
32523259

3260+
/**
3261+
* @typedef {object} RestoreOptions Options for Bucket#restore(). See an
3262+
* {@link https://cloud.google.com/storage/docs/json_api/v1/buckets/restore#resource| Object resource}.
3263+
* @param {number} [generation] If present, selects a specific revision of this object.
3264+
* @param {string} [projection] Specifies the set of properties to return. If used, must be 'full' or 'noAcl'.
3265+
*/
3266+
/**
3267+
* Restores a soft-deleted bucket
3268+
* @param {RestoreOptions} options Restore options.
3269+
* @returns {Promise<Bucket>}
3270+
*/
3271+
async restore(options: RestoreOptions): Promise<Bucket> {
3272+
const [bucket] = await this.request({
3273+
method: 'POST',
3274+
uri: '/restore',
3275+
qs: options,
3276+
});
3277+
3278+
return bucket as Bucket;
3279+
}
3280+
32533281
makePrivate(
32543282
options?: MakeBucketPrivateOptions
32553283
): Promise<MakeBucketPrivateResponse>;
@@ -4550,7 +4578,7 @@ paginator.extend(Bucket, 'getFiles');
45504578
* that a callback is omitted.
45514579
*/
45524580
promisifyAll(Bucket, {
4553-
exclude: ['cloudStorageURI', 'request', 'file', 'notification'],
4581+
exclude: ['cloudStorageURI', 'request', 'file', 'notification', 'restore'],
45544582
});
45554583

45564584
/**

src/storage.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ export interface BucketOptions {
105105
kmsKeyName?: string;
106106
preconditionOpts?: PreconditionOptions;
107107
userProject?: string;
108+
generation?: number;
109+
softDeleted?: boolean;
108110
}
109111

110112
export interface Cors {
@@ -185,6 +187,8 @@ export interface GetBucketsRequest {
185187
maxResults?: number;
186188
pageToken?: string;
187189
userProject?: string;
190+
softDeleted?: boolean;
191+
generation?: number;
188192
}
189193

190194
export interface HmacKeyResourceResponse {
@@ -1242,6 +1246,8 @@ export class Storage extends Service {
12421246
* representing part of the larger set of results to view.
12431247
* @property {string} [userProject] The ID of the project which will be billed
12441248
* for the request.
1249+
* @param {boolean} [softDeleted] If true, returns the soft-deleted object.
1250+
* Object `generation` is required if `softDeleted` is set to True.
12451251
*/
12461252
/**
12471253
* @typedef {array} GetBucketsResponse

0 commit comments

Comments
 (0)