Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[storage][stg74] container restore #11457

Merged
merged 2 commits into from
Sep 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions sdk/storage/storage-blob/review/storage-blob.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1028,6 +1028,10 @@ export class BlobServiceClient extends StorageClient {
getUserDelegationKey(startsOn: Date, expiresOn: Date, options?: ServiceGetUserDelegationKeyOptions): Promise<ServiceGetUserDelegationKeyResponse>;
listContainers(options?: ServiceListContainersOptions): PagedAsyncIterableIterator<ContainerItem, ServiceListContainersSegmentResponse>;
setProperties(properties: BlobServiceProperties, options?: ServiceSetPropertiesOptions): Promise<ServiceSetPropertiesResponse>;
undeleteContainer(deletedContainerName: string, destinationContainerName?: string, options?: ContainerUndeleteOptions): Promise<{
ljian3377 marked this conversation as resolved.
Show resolved Hide resolved
containerClient: ContainerClient;
containerUndeleteResponse: ContainerUndeleteResponse;
}>;
}

// @public
Expand Down Expand Up @@ -1877,6 +1881,29 @@ export type ContainerSetMetadataResponse = ContainerSetMetadataHeaders & {
};
};

// @public
export interface ContainerUndeleteHeaders {
clientRequestId?: string;
date?: Date;
// (undocumented)
errorCode?: string;
requestId?: string;
version?: string;
}

// @public
export interface ContainerUndeleteOptions extends CommonOptions {
abortSignal?: AbortSignalLike;
deletedContainerVersion?: string;
}

// @public
export type ContainerUndeleteResponse = ContainerUndeleteHeaders & {
_response: coreHttp.HttpResponse & {
parsedHeaders: ContainerUndeleteHeaders;
};
};

// @public
export type CopyPollerBlobClient = Pick<BlobClient, "abortCopyFromURL" | "getProperties"> & {
startCopyFromURL(copySource: string, options?: BlobStartCopyFromURLOptions): Promise<BlobBeginCopyFromURLResponse>;
Expand Down Expand Up @@ -2729,6 +2756,7 @@ export type ServiceGetUserDelegationKeyResponse = UserDelegationKey & ServiceGet
// @public
export interface ServiceListContainersOptions extends CommonOptions {
abortSignal?: AbortSignalLike;
includeDeleted?: boolean;
includeMetadata?: boolean;
prefix?: string;
}
Expand Down
91 changes: 88 additions & 3 deletions sdk/storage/storage-blob/src/BlobServiceClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ import {
ListContainersIncludeType,
UserDelegationKeyModel,
ServiceFindBlobsByTagsSegmentResponse,
FilterBlobItem
FilterBlobItem,
ContainerUndeleteResponse
} from "./generatedModels";
import { Service } from "./generated/src/operations";
import { Container, Service } from "./generated/src/operations";
import { newPipeline, StoragePipelineOptions, Pipeline } from "./Pipeline";
import { ContainerClient, ContainerCreateOptions, ContainerDeleteMethodOptions } from "./Clients";
import { appendToURLPath, extractConnectionStringParts } from "./utils/utils.common";
Expand Down Expand Up @@ -213,6 +214,14 @@ export interface ServiceListContainersOptions extends CommonOptions {
* should be returned as part of the response body.
*/
includeMetadata?: boolean;

/**
* Specifies whether soft deleted containers should be included in the response.
*
* @type {boolean}
* @memberof ServiceListContainersOptions
*/
includeDeleted?: boolean;
}

/**
Expand Down Expand Up @@ -313,6 +322,30 @@ export declare type ServiceGetUserDelegationKeyResponse = UserDelegationKey &
};
};

/**
* Options to configure {@link BlobServiceClient.undeleteContainer} operation.
*
* @export
* @interface ContainerUndeleteOptions
*/
export interface ContainerUndeleteOptions extends CommonOptions {
/**
* An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
* For example, use the &commat;azure/abort-controller to create an `AbortSignal`.
*
* @type {AbortSignalLike}
* @memberof ContainerUndeleteOptions
*/
abortSignal?: AbortSignalLike;
/**
* Optional. Specifies the version of the deleted container to restore.
*
* @type {string}
* @memberof ContainerUndeleteOptions
*/
deletedContainerVersion?: string;
}

/**
* A BlobServiceClient represents a Client to the Azure Storage Blob service allowing you
* to manipulate blob containers.
Expand Down Expand Up @@ -538,6 +571,49 @@ export class BlobServiceClient extends StorageClient {
}
}

/**
* Restore a previously deleted Blob container.
* This API is only functional if Container Soft Delete is enabled for the storage account associated with the container.
*
* @param {string} deletedContainerName Name of the previously deleted container.
* @param {ContainerUndeleteOptions} [options] Options to configure Container undelete operation.
* @returns {Promise<ContainerDeleteResponse>} Container deletion response.
* @memberof BlobServiceClient
*/
public async undeleteContainer(
deletedContainerName: string,
destinationContainerName?: string,
options: ContainerUndeleteOptions = {}
): Promise<{
containerClient: ContainerClient;
containerUndeleteResponse: ContainerUndeleteResponse;
}> {
const { span, spanOptions } = createSpan(
"BlobServiceClient-undeleteContainer",
options.tracingOptions
);
try {
const containerClient = this.getContainerClient(
destinationContainerName || deletedContainerName
);
const container = new Container((containerClient as any).storageClientContext);
const containerUndeleteResponse = await container.restore({
deletedContainerName,
...options,
tracingOptions: { ...options!.tracingOptions, spanOptions }
});
return { containerClient, containerUndeleteResponse };
} catch (e) {
span.setStatus({
code: CanonicalCode.UNKNOWN,
message: e.message
});
throw e;
} finally {
span.end();
}
}

/**
* Gets the properties of a storage account’s Blob service, including properties
* for Storage Analytics and CORS (Cross-Origin Resource Sharing) rules.
Expand Down Expand Up @@ -1071,10 +1147,19 @@ export class BlobServiceClient extends StorageClient {
if (options.prefix === "") {
options.prefix = undefined;
}

const include: ListContainersIncludeType[] = [];
if (options.includeDeleted) {
include.push("deleted");
}
if (options.includeMetadata) {
include.push("metadata");
}

// AsyncIterableIterator to iterate over containers
const listSegmentOptions: ServiceListContainersSegmentOptions = {
...options,
...(options.includeMetadata ? { include: "metadata" } : {})
include
};

const iter = this.listItems(listSegmentOptions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export class StorageClientContext extends coreHttp.ServiceClient {

super(undefined, options);

this.version = "2020-02-10";
this.version = '2020-02-10';
this.baseUri = "{url}";
this.requestContentType = "application/json; charset=utf-8";
this.url = url;
Expand Down
4 changes: 3 additions & 1 deletion sdk/storage/storage-blob/src/generatedModels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,5 +146,7 @@ export {
ServiceFilterBlobsResponse as ServiceFindBlobsByTagsSegmentResponse,
FilterBlobItem,
BlobQueryHeaders,
BlobQueryResponse as BlobQueryResponseModel
BlobQueryResponse as BlobQueryResponseModel,
ContainerRestoreResponse as ContainerUndeleteResponse,
ContainerRestoreHeaders as ContainerUndeleteHeaders
} from "./generated/src/models";