Skip to content

Commit

Permalink
feat: add ability to configure and utilize soft-delete and restore bu…
Browse files Browse the repository at this point in the history
…ckets (#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
  • Loading branch information
thiyaguk09 authored Dec 20, 2024
1 parent 740d30d commit 25cdbb9
Show file tree
Hide file tree
Showing 7 changed files with 392 additions and 133 deletions.
52 changes: 52 additions & 0 deletions samples/getSoftDeletedBucket.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* Copyright 2024 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.
*/

function main(bucketName = 'my-bucket', generation = 123456789) {
// [START storage_get_soft_deleted_bucket]
/**
* TODO(developer): Uncomment the following lines before running the sample.
*/
// The ID of your GCS bucket
// const bucketName = 'your-unique-bucket-name';

// The generation of the bucket to restore
// const generation = 123456789;

// Imports the Google Cloud client library
const {Storage} = require('@google-cloud/storage');

// Creates a client
const storage = new Storage();

async function getSoftDeletedBucket() {
const options = {
generation: generation,
softDeleted: true,
};

const [metadata] = await storage.bucket(bucketName).getMetadata(options);

console.log(`Bucket: ${metadata.name}`);
console.log(`Generation: ${metadata.generation}`);
console.log(`SoftDeleteTime: ${metadata.softDeleteTime}`);
console.log(`HardDeleteTime: ${metadata.hardDeleteTime}`);
}

getSoftDeletedBucket().catch(console.error);
// [END storage_get_soft_deleted_bucket]
}

main(...process.argv.slice(2));
42 changes: 42 additions & 0 deletions samples/listSoftDeletedBucket.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* Copyright 2024 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.
*/

function main() {
// [START storage_list_soft_deleted_buckets]
// Imports the Google Cloud client library
const {Storage} = require('@google-cloud/storage');

// Creates a client
const storage = new Storage();

async function listSoftDeletedBuckets() {
const options = {
softDeleted: true,
};

const [buckets] = await storage.getBuckets(options);

console.log('Buckets:');
buckets.forEach(bucket => {
console.log(bucket.name);
});
}

listSoftDeletedBuckets().catch(console.error);
// [END storage_list_soft_deleted_buckets]
}

main(...process.argv.slice(2));
48 changes: 48 additions & 0 deletions samples/restoreSoftDeletedBucket.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* Copyright 2024 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.
*/

function main(bucketName = 'my-bucket', generation = 123456789) {
// [START storage_restore_soft_deleted_bucket]
/**
* TODO(developer): Uncomment the following lines before running the sample.
*/
// The ID of your GCS bucket
// const bucketName = 'your-unique-bucket-name';

// The generation of the bucket to restore
// const generation = 123456789;

// Imports the Google Cloud client library
const {Storage} = require('@google-cloud/storage');

// Creates a client
const storage = new Storage();

async function restoreSoftDeletedBucket() {
const options = {
generation: generation,
};

await storage.bucket(bucketName).restore(options);

console.log(`Soft deleted bucket ${bucketName} was restored.`);
}

restoreSoftDeletedBucket().catch(console.error);
// [END storage_restore_soft_deleted_bucket]
}

main(...process.argv.slice(2));
30 changes: 29 additions & 1 deletion src/bucket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,10 @@ export interface GetLabelsCallback {
(err: Error | null, labels: object | null): void;
}

export interface RestoreOptions {
generation: string;
projection?: 'full' | 'noAcl';
}
export interface BucketMetadata extends BaseMetadata {
acl?: AclMetadata[] | null;
autoclass?: {
Expand Down Expand Up @@ -335,6 +339,7 @@ export interface BucketMetadata extends BaseMetadata {
logBucket?: string;
logObjectPrefix?: string;
};
generation?: string;
metageneration?: string;
name?: string;
objectRetention?: {
Expand All @@ -351,6 +356,8 @@ export interface BucketMetadata extends BaseMetadata {
retentionPeriod?: string | number;
} | null;
rpo?: string;
softDeleteTime?: string;
hardDeleteTime?: string;
softDeletePolicy?: {
retentionDurationSeconds?: string | number;
readonly effectiveTime?: string;
Expand Down Expand Up @@ -3250,6 +3257,27 @@ class Bucket extends ServiceObject<Bucket, BucketMetadata> {
);
}

/**
* @typedef {object} RestoreOptions Options for Bucket#restore(). See an
* {@link https://cloud.google.com/storage/docs/json_api/v1/buckets/restore#resource| Object resource}.
* @param {number} [generation] If present, selects a specific revision of this object.
* @param {string} [projection] Specifies the set of properties to return. If used, must be 'full' or 'noAcl'.
*/
/**
* Restores a soft-deleted bucket
* @param {RestoreOptions} options Restore options.
* @returns {Promise<Bucket>}
*/
async restore(options: RestoreOptions): Promise<Bucket> {
const [bucket] = await this.request({
method: 'POST',
uri: '/restore',
qs: options,
});

return bucket as Bucket;
}

makePrivate(
options?: MakeBucketPrivateOptions
): Promise<MakeBucketPrivateResponse>;
Expand Down Expand Up @@ -4550,7 +4578,7 @@ paginator.extend(Bucket, 'getFiles');
* that a callback is omitted.
*/
promisifyAll(Bucket, {
exclude: ['cloudStorageURI', 'request', 'file', 'notification'],
exclude: ['cloudStorageURI', 'request', 'file', 'notification', 'restore'],
});

/**
Expand Down
6 changes: 6 additions & 0 deletions src/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ export interface BucketOptions {
kmsKeyName?: string;
preconditionOpts?: PreconditionOptions;
userProject?: string;
generation?: number;
softDeleted?: boolean;
}

export interface Cors {
Expand Down Expand Up @@ -185,6 +187,8 @@ export interface GetBucketsRequest {
maxResults?: number;
pageToken?: string;
userProject?: string;
softDeleted?: boolean;
generation?: number;
}

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

0 comments on commit 25cdbb9

Please sign in to comment.