From 5497e96334d7863efde2b66df6858d13dcf3de9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Rodr=C3=ADguez?= Date: Thu, 3 Sep 2020 08:37:27 -0400 Subject: [PATCH 01/12] [Key Vault Admin] The Backup client source code --- .../keyvault-admin/src/backupClient.ts | 283 +++++++++++++++++ .../keyvault-admin/src/backupClientModels.ts | 48 +++ sdk/keyvault/keyvault-admin/src/index.ts | 9 +- .../src/lro/backup/operation.ts | 263 ++++++++++++++++ .../keyvault-admin/src/lro/backup/poller.ts | 93 ++++++ .../src/lro/restore/operation.ts | 272 +++++++++++++++++ .../keyvault-admin/src/lro/restore/poller.ts | 97 ++++++ .../src/lro/selectiveRestore/operation.ts | 288 ++++++++++++++++++ .../src/lro/selectiveRestore/poller.ts | 101 ++++++ 9 files changed, 1452 insertions(+), 2 deletions(-) create mode 100644 sdk/keyvault/keyvault-admin/src/backupClient.ts create mode 100644 sdk/keyvault/keyvault-admin/src/backupClientModels.ts create mode 100644 sdk/keyvault/keyvault-admin/src/lro/backup/operation.ts create mode 100644 sdk/keyvault/keyvault-admin/src/lro/backup/poller.ts create mode 100644 sdk/keyvault/keyvault-admin/src/lro/restore/operation.ts create mode 100644 sdk/keyvault/keyvault-admin/src/lro/restore/poller.ts create mode 100644 sdk/keyvault/keyvault-admin/src/lro/selectiveRestore/operation.ts create mode 100644 sdk/keyvault/keyvault-admin/src/lro/selectiveRestore/poller.ts diff --git a/sdk/keyvault/keyvault-admin/src/backupClient.ts b/sdk/keyvault/keyvault-admin/src/backupClient.ts new file mode 100644 index 000000000000..e0dfeca7ac19 --- /dev/null +++ b/sdk/keyvault/keyvault-admin/src/backupClient.ts @@ -0,0 +1,283 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { + createPipelineFromOptions, + isTokenCredential, + operationOptionsToRequestOptionsBase, + signingPolicy, + TokenCredential +} from "@azure/core-http"; +import { PollerLike, PollOperationState } from "@azure/core-lro"; + +import { challengeBasedAuthenticationPolicy } from "../../keyvault-common"; +import { KeyVaultClient } from "./generated/keyVaultClient"; +import { BackupClientOptions, BeginBackupOptions, BeginRestoreOptions } from "./backupClientModels"; +import { LATEST_API_VERSION, SDK_VERSION } from "./constants"; +import { logger } from "./log"; +import { BackupPoller } from "./lro/backup/poller"; +import { RestorePoller } from "./lro/restore/poller"; +import { SelectiveRestorePoller } from "./lro/selectiveRestore/poller"; + +/** + * The KeyVaultBackupClient provides methods to generate backups + * and restore backups of any given Azure Key Vault instance. + */ +export class KeyVaultBackupClient { + /** + * The base URL to the vault + */ + public readonly vaultUrl: string; + + /** + * @internal + * @ignore + * A reference to the auto-generated Key Vault HTTP client. + */ + private readonly client: KeyVaultClient; + + /** + * Creates an instance of the KeyVaultBackupClient. + * + * Example usage: + * ```ts + * import { KeyVaultBackupClient } from "@azure/keyvault-admin"; + * import { DefaultAzureCredential } from "@azure/identity"; + * + * let vaultUrl = `https://.vault.azure.net`; + * let credentials = new DefaultAzureCredential(); + * + * let client = new KeyVaultBackupClient(vaultUrl, credentials); + * ``` + * @param {string} vaultUrl the URL of the Key Vault. It should have this shape: https://${your-key-vault-name}.vault.azure.net + * @param {TokenCredential} credential An object that implements the `TokenCredential` interface used to authenticate requests to the service. Use the @azure/identity package to create a credential that suits your needs. + * @param {BackupClientOptions} [pipelineOptions] Pipeline options used to configure Key Vault API requests. Omit this parameter to use the default pipeline configuration. + * @memberof KeyVaultBackupClient + */ + constructor( + vaultUrl: string, + credential: TokenCredential, + pipelineOptions: BackupClientOptions = {} + ) { + this.vaultUrl = vaultUrl; + + const libInfo = `azsdk-js-keyvault-admin/${SDK_VERSION}`; + + const userAgentOptions = pipelineOptions.userAgentOptions; + + pipelineOptions.userAgentOptions = { + ...pipelineOptions.userAgentOptions, + userAgentPrefix: + userAgentOptions && userAgentOptions.userAgentPrefix + ? `${userAgentOptions.userAgentPrefix} ${libInfo}` + : libInfo + }; + + const authPolicy = isTokenCredential(credential) + ? challengeBasedAuthenticationPolicy(credential) + : signingPolicy(credential); + + const internalPipelineOptions = { + ...pipelineOptions, + ...{ + loggingOptions: { + logger: logger.info, + logPolicyOptions: { + allowedHeaderNames: [ + "x-ms-keyvault-region", + "x-ms-keyvault-network-info", + "x-ms-keyvault-service-version" + ] + } + } + } + }; + + const pipeline = createPipelineFromOptions(internalPipelineOptions, authPolicy); + this.client = new KeyVaultClient({ + apiVersion: pipelineOptions.serviceVersion || LATEST_API_VERSION, + ...pipeline + }); + } + + /** + * Starts generating a backup of an Azure Key Vault on the specified Storage Blob account. + * + * This function returns a Long Running Operation poller that allows you to wait indefinitely until the Key Vault backup is generated. + * + * Example usage: + * ```ts + * const client = new KeyVaultBackupClient(url, credentials); + * + * const blobStorageUri = ""; + * const sasToken = ""; + * const poller = await client.beginBackup(blobStorageUri, sasToken); + * + * // Serializing the poller + * const serialized = poller.toString(); + * // A new poller can be created with: + * // await client.beginBackup(blobStorageUri, sasToken, { resumeFrom: serialized }); + * + * // Waiting until it's done + * const backupUri = await poller.pollUntilDone(); + * console.log(backupUri); + * ``` + * @summary Creates a new role assignment. + * @param {string} blobStorageUri The URI of the blob storage account. + * @param {string} sasToken The SAS token. + * @param {CreateRoleAssignmentOptions} [options] The optional parameters. + */ + public async beginBackup( + blobStorageUri: string, + sasToken: string, + options: BeginBackupOptions = {} + ): Promise, string>> { + const requestOptions = operationOptionsToRequestOptionsBase(options); + + if (!(blobStorageUri && sasToken)) { + throw new Error( + "beginBackup requires non-empty strings for the parameters: blobStorageUri and sasToken." + ); + } + + const poller = new BackupPoller({ + blobStorageUri, + sasToken, + client: this.client, + vaultUrl: this.vaultUrl, + intervalInMs: options.intervalInMs, + resumeFrom: options.resumeFrom, + requestOptions + }); + + // This will initialize the poller's operation (the generation of the backup). + await poller.poll(); + + return poller; + } + + /** + * Starts restoring all key materials using the SAS token pointing to a previously stored Azure Blob storage + * backup folder. + * + * This function returns a Long Running Operation poller that allows you to wait indefinitely until the Key Vault backup is generated. + * + * Example usage: + * ```ts + * const client = new KeyVaultBackupClient(url, credentials); + * + * const blobStorageUri = ""; + * const sasToken = ""; + * const folderName = ""; + * const poller = await client.beginRestore(blobStorageUri, sasToken, folderName); + * + * // Serializing the poller + * const serialized = poller.toString(); + * // A new poller can be created with: + * // await client.beginRestore(blobStorageUri, sasToken, folderName, { resumeFrom: serialized }); + * + * // Waiting until it's done + * const backupUri = await poller.pollUntilDone(); + * console.log(backupUri); + * ``` + * @summary Creates a new role assignment. + * @param {string} blobStorageUri The URI of the blob storage account. + * @param {string} sasToken The SAS token. + * @param {string} folderName The Folder name of the blob where the previous successful full backup was stored. + * @param {CreateRoleAssignmentOptions} [options] The optional parameters. + */ + public async beginRestore( + blobStorageUri: string, + sasToken: string, + folderName: string, + options: BeginRestoreOptions = {} + ): Promise, undefined>> { + const requestOptions = operationOptionsToRequestOptionsBase(options); + + if (!(blobStorageUri && sasToken && folderName)) { + throw new Error( + "beginRestore requires non-empty strings for the parameters: blobStorageUri, sasToken and folderName." + ); + } + + const poller = new RestorePoller({ + blobStorageUri, + sasToken, + folderName, + client: this.client, + vaultUrl: this.vaultUrl, + intervalInMs: options.intervalInMs, + resumeFrom: options.resumeFrom, + requestOptions + }); + + // This will initialize the poller's operation (the generation of the backup). + await poller.poll(); + + return poller; + } + + /** + * Starts restoring all key versions of a given key using user supplied SAS token pointing to a previously + * stored Azure Blob storage backup folder. + * + * This function returns a Long Running Operation poller that allows you to wait indefinitely until the Key Vault backup is generated. + * + * Example usage: + * ```ts + * const client = new KeyVaultBackupClient(url, credentials); + * + * const keyName = ""; + * const blobStorageUri = ""; + * const sasToken = ""; + * const poller = await client.beginSelectiveRestore(keyName, blobStorageUri, sasToken); + * + * // Serializing the poller + * const serialized = poller.toString(); + * // A new poller can be created with: + * // await client.beginBackup(keyName, blobStorageUri, sasToken, { resumeFrom: serialized }); + * + * // Waiting until it's done + * const backupUri = await poller.pollUntilDone(); + * console.log(backupUri); + * ``` + * @summary Creates a new role assignment. + * @param {string} keyName The name of the key that wants to be restored. + * @param {string} blobStorageUri The URI of the blob storage account. + * @param {string} sasToken The SAS token. + * @param {string} folderName The Folder name of the blob where the previous successful full backup was stored. + * @param {CreateRoleAssignmentOptions} [options] The optional parameters. + */ + public async beginSelectiveRestore( + keyName: string, + blobStorageUri: string, + sasToken: string, + folderName: string, + options: BeginBackupOptions = {} + ): Promise, undefined>> { + const requestOptions = operationOptionsToRequestOptionsBase(options); + + if (!(keyName && blobStorageUri && sasToken && folderName)) { + throw new Error( + "beginSelectiveRestore requires non-empty strings for the parameters: keyName, blobStorageUri, sasToken and folderName." + ); + } + + const poller = new SelectiveRestorePoller({ + keyName, + blobStorageUri, + sasToken, + folderName, + client: this.client, + vaultUrl: this.vaultUrl, + intervalInMs: options.intervalInMs, + resumeFrom: options.resumeFrom, + requestOptions + }); + + // This will initialize the poller's operation (the generation of the backup). + await poller.poll(); + + return poller; + } +} diff --git a/sdk/keyvault/keyvault-admin/src/backupClientModels.ts b/sdk/keyvault/keyvault-admin/src/backupClientModels.ts new file mode 100644 index 000000000000..50dcf5ec12aa --- /dev/null +++ b/sdk/keyvault/keyvault-admin/src/backupClientModels.ts @@ -0,0 +1,48 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import * as coreHttp from "@azure/core-http"; +import { SUPPORTED_API_VERSIONS } from "./constants"; + +/** + * The optional parameters accepted by the KeyVaultBackupClient + */ +export interface BackupClientOptions extends coreHttp.PipelineOptions { + /** + * The accepted versions of the Key Vault's service API. + */ + serviceVersion?: SUPPORTED_API_VERSIONS; +} + +/** + * An interface representing the optional parameters that can be + * passed to {@link beginBackup} + */ +export interface BackupPollerOptions extends coreHttp.OperationOptions { + /** + * Time between each polling + */ + intervalInMs?: number; + /** + * A serialized poller, used to resume an existing operation + */ + resumeFrom?: string; +} + +/** + * An interface representing the optional parameters that can be + * passed to {@link beginBackup} + */ +export interface BeginBackupOptions extends BackupPollerOptions {} + +/** + * An interface representing the optional parameters that can be + * passed to {@link beginRestore} + */ +export interface BeginRestoreOptions extends BackupPollerOptions {} + +/** + * An interface representing the optional parameters that can be + * passed to {@link beginSelectiveRestore} + */ +export interface BeginSelectiveRestoreOptions extends BackupPollerOptions {} diff --git a/sdk/keyvault/keyvault-admin/src/index.ts b/sdk/keyvault/keyvault-admin/src/index.ts index b5ec5831c9a8..133961b78ca3 100644 --- a/sdk/keyvault/keyvault-admin/src/index.ts +++ b/sdk/keyvault/keyvault-admin/src/index.ts @@ -1,5 +1,10 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -export * from "./generated/keyVaultClient"; -export * from "./generated/keyVaultClientContext"; +export * from "./accessControlClient"; +export * from "./accessControlModels"; + +export * from "./backupClient"; +export * from "./backupClientModels"; + +export * from "./constants"; diff --git a/sdk/keyvault/keyvault-admin/src/lro/backup/operation.ts b/sdk/keyvault/keyvault-admin/src/lro/backup/operation.ts new file mode 100644 index 000000000000..1a224cd28b59 --- /dev/null +++ b/sdk/keyvault/keyvault-admin/src/lro/backup/operation.ts @@ -0,0 +1,263 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { AbortSignalLike } from "@azure/abort-controller"; +import { PollOperationState, PollOperation } from "@azure/core-lro"; +import { + OperationOptions, + operationOptionsToRequestOptionsBase, + RequestOptionsBase +} from "@azure/core-http"; +import { KeyVaultClient } from "../../generated/keyVaultClient"; +import { + KeyVaultClientFullBackupOptionalParams, + KeyVaultClientFullBackupResponse, + KeyVaultClientFullBackupStatusResponse +} from "../../generated/models"; +import { createSpan, setParentSpan } from "../../tracing"; + +/** + * An interface representing the publicly available properties of the state of a backup Key Vault's poll operation. + */ +export interface BackupOperationState extends PollOperationState { + /** + * The base URL to the vault + */ + vaultUrl: string; + /** + * The URI of the blob storage account. + */ + blobStorageUri: string; + /** + * The SAS token. + */ + sasToken: string; + /** + * Identifier for the full backup operation. + */ + jobId?: string; + /** + * Status of the backup operation. + */ + status?: string; + /** + * The status details of backup operation. + */ + statusDetails?: string; + /** + * The start time of the backup operation in UTC + */ + startTime?: Date; + /** + * The end time of the backup operation in UTC + */ + endTime?: Date; +} + +/** + * An internal interface representing the state of a backup Key Vault's poll operation. + * @internal + */ +export interface BackupPollOperationState extends PollOperationState { + /** + * Options for the core-http requests. + */ + requestOptions?: RequestOptionsBase; + /** + * An interface representing the internal KeyVaultClient. + */ + client?: KeyVaultClient; + /** + * The base URL to the vault + */ + vaultUrl: string; + /** + * The URI of the blob storage account. + */ + blobStorageUri: string; + /** + * The SAS token. + */ + sasToken: string; + /** + * The id returned as part of the backup request + */ + jobId?: string; + /** + * Status of the backup operation. + */ + status?: string; + /** + * The status details of backup operation. + */ + statusDetails?: string; + /** + * The start time of the backup operation in UTC + */ + startTime?: Date; + /** + * The end time of the backup operation in UTC + */ + endTime?: Date; +} + +/** + * An interface representing a backup Key Vault's poll operation. + */ +export interface BackupPollOperation extends PollOperation {} + +/** + * Tracing the fullBackup operation + */ +async function fullBackup( + client: KeyVaultClient, + vaultUrl: string, + options: KeyVaultClientFullBackupOptionalParams +): Promise { + const requestOptions = operationOptionsToRequestOptionsBase(options); + const span = createSpan("generatedClient.fullBackup", requestOptions); + + let response: KeyVaultClientFullBackupResponse; + try { + response = await client.fullBackup(vaultUrl, setParentSpan(span, requestOptions)); + } finally { + span.end(); + } + + return response; +} + +/** + * Tracing the fullBackupStatus operation + */ +async function fullBackupStatus( + client: KeyVaultClient, + vaultUrl: string, + jobId: string, + options: OperationOptions +): Promise { + const requestOptions = operationOptionsToRequestOptionsBase(options); + const span = createSpan("generatedClient.fullBackupStatus", requestOptions); + + let response: KeyVaultClientFullBackupStatusResponse; + try { + response = await client.fullBackupStatus(vaultUrl, jobId, setParentSpan(span, requestOptions)); + } finally { + span.end(); + } + + return response; +} + +/** + * @summary Reaches to the service and updates the delete key's poll operation. + * @param [options] The optional parameters, which are an abortSignal from @azure/abort-controller and a function that triggers the poller's onProgress function. + */ +async function update( + this: BackupPollOperation, + options: { + abortSignal?: AbortSignalLike; + fireProgress?: (state: BackupPollOperationState) => void; + } = {} +): Promise { + const state = this.state; + const { vaultUrl, blobStorageUri, sasToken } = state; + + // Internal properties, + // the reference is only potentially undefined in the public representation of the poller. + const client = state.client!; + + const requestOptions = state.requestOptions || {}; + if (options.abortSignal) { + requestOptions.abortSignal = options.abortSignal; + } + + if (!state.isStarted) { + const fullBackupOperation = await fullBackup(client, vaultUrl, { + ...requestOptions, + azureStorageBlobContainerUri: { + storageResourceUri: blobStorageUri, + token: sasToken + } + }); + + const { startTime, jobId, azureStorageBlobContainerUri, endTime, error } = fullBackupOperation; + + if (!startTime) { + state.error = new Error(`Missing "startTime" from the full backup operation.`); + state.isCompleted = true; + return makeBackupPollOperation(state); + } + + state.isStarted = true; + state.jobId = jobId; + state.endTime = endTime; + state.startTime = startTime; + state.status = fullBackupOperation.status; + state.statusDetails = fullBackupOperation.statusDetails; + state.result = azureStorageBlobContainerUri; + + if (endTime) { + state.isCompleted = true; + } + if (error) { + state.isCompleted = true; + state.error = new Error(error.message); + } + } + + if (!state.jobId) { + state.error = new Error(`Missing "jobId" from the full backup operation.`); + state.isCompleted = true; + return makeBackupPollOperation(state); + } + + if (!state.isCompleted) { + const fullBackupOperation = await fullBackupStatus(client, vaultUrl, state.jobId, { + requestOptions + }); + const { azureStorageBlobContainerUri, endTime, error } = fullBackupOperation; + state.result = azureStorageBlobContainerUri; + if (endTime) { + state.isCompleted = true; + } + if (error) { + state.isCompleted = true; + state.error = new Error(error.message); + } + } + + return makeBackupPollOperation(state); +} + +/** + * @summary Reaches to the service and cancels the key's operation, also updating the key's poll operation + * @param [options] The optional parameters, which is only an abortSignal from @azure/abort-controller + */ +async function cancel(this: BackupPollOperation): Promise { + throw new Error("Canceling the deletion of a key is not supported."); +} + +/** + * @summary Serializes the create key's poll operation + */ +function toString(this: BackupPollOperation): string { + return JSON.stringify({ + state: this.state + }); +} + +/** + * @summary Builds a create key's poll operation + * @param [state] A poll operation's state, in case the new one is intended to follow up where the previous one was left. + */ +export function makeBackupPollOperation(state: BackupPollOperationState): BackupPollOperation { + return { + state: { + ...state + }, + update, + cancel, + toString + }; +} diff --git a/sdk/keyvault/keyvault-admin/src/lro/backup/poller.ts b/sdk/keyvault/keyvault-admin/src/lro/backup/poller.ts new file mode 100644 index 000000000000..3aff2cabec1c --- /dev/null +++ b/sdk/keyvault/keyvault-admin/src/lro/backup/poller.ts @@ -0,0 +1,93 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { delay, RequestOptionsBase } from "@azure/core-http"; +import { Poller } from "@azure/core-lro"; +import { KeyVaultClient } from "../../generated/keyVaultClient"; +import { + BackupOperationState, + BackupPollOperationState, + makeBackupPollOperation +} from "./operation"; + +export interface BackupPollerOptions { + client: KeyVaultClient; + vaultUrl: string; + blobStorageUri: string; + sasToken: string; + requestOptions?: RequestOptionsBase; + intervalInMs?: number; + resumeFrom?: string; +} + +/** + * Class that creates a poller that waits until the backup of a Key Vault ends up being generated. + */ +export class BackupPoller extends Poller { + /** + * Defines how much time the poller is going to wait before making a new request to the service. + * @memberof BackupPoller + */ + public intervalInMs: number; + + constructor(options: BackupPollerOptions) { + const { + client, + vaultUrl, + blobStorageUri, + sasToken, + requestOptions, + intervalInMs = 2000, + resumeFrom + } = options; + + let state: BackupPollOperationState | undefined; + + if (resumeFrom) { + state = JSON.parse(resumeFrom).state; + } + + const operation = makeBackupPollOperation({ + ...state, + blobStorageUri, + sasToken, + requestOptions, + client, + vaultUrl + }); + + super(operation); + + this.intervalInMs = intervalInMs; + } + + /** + * The method used by the poller to wait before attempting to update its operation. + * @memberof BackupPoller + */ + async delay(): Promise { + return delay(this.intervalInMs); + } + + /** + * Gets the public state of the polling operation + */ + public getOperationState(): BackupOperationState { + const state: BackupOperationState = this.operation.state; + return { + vaultUrl: state.vaultUrl, + blobStorageUri: state.blobStorageUri, + sasToken: state.sasToken, + isStarted: state.isStarted, + isCompleted: state.isCompleted, + isCancelled: state.isCancelled, + error: state.error, + result: state.result, + jobId: state.jobId, + endTime: state.endTime, + startTime: state.startTime, + status: state.status, + statusDetails: state.statusDetails + }; + } +} diff --git a/sdk/keyvault/keyvault-admin/src/lro/restore/operation.ts b/sdk/keyvault/keyvault-admin/src/lro/restore/operation.ts new file mode 100644 index 000000000000..5296f8fd5a81 --- /dev/null +++ b/sdk/keyvault/keyvault-admin/src/lro/restore/operation.ts @@ -0,0 +1,272 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { AbortSignalLike } from "@azure/abort-controller"; +import { PollOperationState, PollOperation } from "@azure/core-lro"; +import { + OperationOptions, + operationOptionsToRequestOptionsBase, + RequestOptionsBase +} from "@azure/core-http"; +import { KeyVaultClient } from "../../generated/keyVaultClient"; +import { + KeyVaultClientFullBackupStatusResponse, + KeyVaultClientFullRestoreOperationOptionalParams +} from "../../generated/models"; +import { createSpan, setParentSpan } from "../../tracing"; +import { KeyVaultClientFullRestoreOperationResponse } from "../../generated/models"; + +/** + * An interface representing the publicly available properties of the state of a restore Key Vault's poll operation. + */ +export interface RestoreOperationState extends PollOperationState { + /** + * The base URL to the vault + */ + vaultUrl: string; + /** + * The URI of the blob storage account. + */ + blobStorageUri: string; + /** + * The SAS token. + */ + sasToken: string; + /** + * The Folder name of the blob where the previous successful full backup was stored. + */ + folderName: string; + /** + * Identifier for the full restore operation. + */ + jobId?: string; + /** + * Status of the restore operation. + */ + status?: string; + /** + * The status details of restore operation. + */ + statusDetails?: string; + /** + * The start time of the restore operation in UTC + */ + startTime?: Date; + /** + * The end time of the restore operation in UTC + */ + endTime?: Date; +} + +/** + * An internal interface representing the state of a restore Key Vault's poll operation. + * @internal + */ +export interface RestorePollOperationState extends PollOperationState { + /** + * Options for the core-http requests. + */ + requestOptions?: RequestOptionsBase; + /** + * An interface representing the internal KeyVaultClient. + */ + client?: KeyVaultClient; + /** + * The base URL to the vault + */ + vaultUrl: string; + /** + * The URI of the blob storage account. + */ + blobStorageUri: string; + /** + * The SAS token. + */ + sasToken: string; + /** + * The Folder name of the blob where the previous successful full backup was stored + */ + folderName: string; + /** + * The id returned as part of the restore request + */ + jobId?: string; + /** + * Status of the restore operation. + */ + status?: string; + /** + * The status details of restore operation. + */ + statusDetails?: string; + /** + * The start time of the restore operation in UTC + */ + startTime?: Date; + /** + * The end time of the restore operation in UTC + */ + endTime?: Date; +} + +/** + * An interface representing a restore Key Vault's poll operation. + */ +export interface RestorePollOperation extends PollOperation {} + +/** + * Tracing the fullRestore operation + */ +async function fullRestore( + client: KeyVaultClient, + vaultUrl: string, + options: KeyVaultClientFullRestoreOperationOptionalParams +): Promise { + const requestOptions = operationOptionsToRequestOptionsBase(options); + const span = createSpan("generatedClient.fullRestore", requestOptions); + + let response: KeyVaultClientFullRestoreOperationResponse; + try { + response = await client.fullRestoreOperation(vaultUrl, setParentSpan(span, requestOptions)); + } finally { + span.end(); + } + + return response; +} + +/** + * Tracing the fullRestoreStatus operation. + */ +async function fullRestoreStatus( + client: KeyVaultClient, + vaultUrl: string, + jobId: string, + options: OperationOptions +): Promise { + const requestOptions = operationOptionsToRequestOptionsBase(options); + const span = createSpan("generatedClient.fullRestoreStatus", requestOptions); + + let response: KeyVaultClientFullBackupStatusResponse; + try { + response = await client.fullBackupStatus(vaultUrl, jobId, setParentSpan(span, requestOptions)); + } finally { + span.end(); + } + + return response; +} + +/** + * @summary Reaches to the service and updates the delete key's poll operation. + * @param [options] The optional parameters, which are an abortSignal from @azure/abort-controller and a function that triggers the poller's onProgress function. + */ +async function update( + this: RestorePollOperation, + options: { + abortSignal?: AbortSignalLike; + fireProgress?: (state: RestorePollOperationState) => void; + } = {} +): Promise { + const state = this.state; + const { vaultUrl, blobStorageUri, sasToken, folderName } = state; + + // Internal properties, + // the reference is only potentially undefined in the public representation of the poller. + const client = state.client!; + + const requestOptions = state.requestOptions || {}; + if (options.abortSignal) { + requestOptions.abortSignal = options.abortSignal; + } + + if (!state.isStarted) { + const fullRestoreOperation = await fullRestore(client, vaultUrl, { + ...requestOptions, + restoreBlobDetails: { + folderToRestore: folderName, + sasTokenParameters: { + storageResourceUri: blobStorageUri, + token: sasToken + } + } + }); + + const { startTime, jobId, endTime, error } = fullRestoreOperation; + + if (!startTime) { + state.error = new Error(`Missing "startTime" from the full restore operation.`); + state.isCompleted = true; + return makeRestorePollOperation(state); + } + + state.isStarted = true; + state.jobId = jobId; + state.endTime = endTime; + state.startTime = startTime; + state.status = fullRestoreOperation.status; + state.statusDetails = fullRestoreOperation.statusDetails; + + if (endTime) { + state.isCompleted = true; + } + if (error) { + state.isCompleted = true; + state.error = new Error(error.message); + } + } + + if (!state.jobId) { + state.error = new Error(`Missing "jobId" from the full restore operation.`); + state.isCompleted = true; + return makeRestorePollOperation(state); + } + + if (!state.isCompleted) { + const fullRestoreOperation = await fullRestoreStatus(client, vaultUrl, state.jobId, { + requestOptions + }); + const { endTime, error } = fullRestoreOperation; + if (endTime) { + state.isCompleted = true; + } + if (error) { + state.isCompleted = true; + state.error = new Error(error.message); + } + } + + return makeRestorePollOperation(state); +} + +/** + * @summary Reaches to the service and cancels the key's operation, also updating the key's poll operation + * @param [options] The optional parameters, which is only an abortSignal from @azure/abort-controller + */ +async function cancel(this: RestorePollOperation): Promise { + throw new Error("Canceling the deletion of a key is not supported."); +} + +/** + * @summary Serializes the create key's poll operation + */ +function toString(this: RestorePollOperation): string { + return JSON.stringify({ + state: this.state + }); +} + +/** + * @summary Builds a create key's poll operation + * @param [state] A poll operation's state, in case the new one is intended to follow up where the previous one was left. + */ +export function makeRestorePollOperation(state: RestorePollOperationState): RestorePollOperation { + return { + state: { + ...state + }, + update, + cancel, + toString + }; +} diff --git a/sdk/keyvault/keyvault-admin/src/lro/restore/poller.ts b/sdk/keyvault/keyvault-admin/src/lro/restore/poller.ts new file mode 100644 index 000000000000..c30d00f92026 --- /dev/null +++ b/sdk/keyvault/keyvault-admin/src/lro/restore/poller.ts @@ -0,0 +1,97 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { delay, RequestOptionsBase } from "@azure/core-http"; +import { Poller } from "@azure/core-lro"; +import { KeyVaultClient } from "../../generated/keyVaultClient"; +import { + RestoreOperationState, + RestorePollOperationState, + makeRestorePollOperation +} from "./operation"; + +export interface RestorePollerOptions { + client: KeyVaultClient; + vaultUrl: string; + blobStorageUri: string; + sasToken: string; + folderName: string; + requestOptions?: RequestOptionsBase; + intervalInMs?: number; + resumeFrom?: string; +} + +/** + * Class that creates a poller that waits until a Key Vault ends up being restored. + */ +export class RestorePoller extends Poller { + /** + * Defines how much time the poller is going to wait before making a new request to the service. + * @memberof RestorePoller + */ + public intervalInMs: number; + + constructor(options: RestorePollerOptions) { + const { + client, + vaultUrl, + blobStorageUri, + sasToken, + folderName, + requestOptions, + intervalInMs = 2000, + resumeFrom + } = options; + + let state: RestorePollOperationState | undefined; + + if (resumeFrom) { + state = JSON.parse(resumeFrom).state; + } + + const operation = makeRestorePollOperation({ + ...state, + blobStorageUri, + sasToken, + folderName, + requestOptions, + client, + vaultUrl + }); + + super(operation); + + this.intervalInMs = intervalInMs; + } + + /** + * The method used by the poller to wait before attempting to update its operation. + * @memberof RestorePoller + */ + async delay(): Promise { + return delay(this.intervalInMs); + } + + /** + * Gets the public state of the polling operation + */ + public getOperationState(): RestoreOperationState { + const state: RestoreOperationState = this.operation.state; + return { + vaultUrl: state.vaultUrl, + blobStorageUri: state.blobStorageUri, + sasToken: state.sasToken, + folderName: state.folderName, + isStarted: state.isStarted, + isCompleted: state.isCompleted, + isCancelled: state.isCancelled, + error: state.error, + result: state.result, + jobId: state.jobId, + endTime: state.endTime, + startTime: state.startTime, + status: state.status, + statusDetails: state.statusDetails + }; + } +} diff --git a/sdk/keyvault/keyvault-admin/src/lro/selectiveRestore/operation.ts b/sdk/keyvault/keyvault-admin/src/lro/selectiveRestore/operation.ts new file mode 100644 index 000000000000..476c211f3309 --- /dev/null +++ b/sdk/keyvault/keyvault-admin/src/lro/selectiveRestore/operation.ts @@ -0,0 +1,288 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { AbortSignalLike } from "@azure/abort-controller"; +import { PollOperationState, PollOperation } from "@azure/core-lro"; +import { + OperationOptions, + operationOptionsToRequestOptionsBase, + RequestOptionsBase +} from "@azure/core-http"; +import { KeyVaultClient } from "../../generated/keyVaultClient"; +import { + KeyVaultClientFullBackupStatusResponse, + KeyVaultClientSelectiveKeyRestoreOperationOptionalParams, + KeyVaultClientSelectiveKeyRestoreOperationResponse +} from "../../generated/models"; +import { createSpan, setParentSpan } from "../../tracing"; + +/** + * An interface representing the publicly available properties of the state of a restore Key Vault's poll operation. + */ +export interface SelectiveRestoreOperationState extends PollOperationState { + /** + * The base URL to the vault + */ + vaultUrl: string; + /** + * The name of a Key Vault Key. + */ + keyName: string; + /** + * The URI of the blob storage account. + */ + blobStorageUri: string; + /** + * The SAS token. + */ + sasToken: string; + /** + * The Folder name of the blob where the previous successful full backup was stored. + */ + folderName: string; + /** + * Identifier for the full restore operation. + */ + jobId?: string; + /** + * Status of the restore operation. + */ + status?: string; + /** + * The status details of restore operation. + */ + statusDetails?: string; + /** + * The start time of the restore operation in UTC + */ + startTime?: Date; + /** + * The end time of the restore operation in UTC + */ + endTime?: Date; +} + +/** + * An internal interface representing the state of a restore Key Vault's poll operation. + * @internal + */ +export interface SelectiveRestorePollOperationState extends PollOperationState { + /** + * Options for the core-http requests. + */ + requestOptions?: RequestOptionsBase; + /** + * An interface representing the internal KeyVaultClient. + */ + client?: KeyVaultClient; + /** + * The base URL to the vault + */ + vaultUrl: string; + /** + * The name of a Key Vault Key. + */ + keyName: string; + /** + * The URI of the blob storage account. + */ + blobStorageUri: string; + /** + * The SAS token. + */ + sasToken: string; + /** + * The Folder name of the blob where the previous successful full backup was stored + */ + folderName: string; + /** + * The id returned as part of the restore request + */ + jobId?: string; + /** + * Status of the restore operation. + */ + status?: string; + /** + * The status details of restore operation. + */ + statusDetails?: string; + /** + * The start time of the restore operation in UTC + */ + startTime?: Date; + /** + * The end time of the restore operation in UTC + */ + endTime?: Date; +} + +/** + * An interface representing a restore Key Vault's poll operation. + */ +export interface SelectiveRestorePollOperation + extends PollOperation {} + +/** + * Tracing the selectiveRestore operation + */ +async function selectiveRestore( + client: KeyVaultClient, + vaultUrl: string, + keyName: string, + options: KeyVaultClientSelectiveKeyRestoreOperationOptionalParams +): Promise { + const requestOptions = operationOptionsToRequestOptionsBase(options); + const span = createSpan("generatedClient.selectiveRestore", requestOptions); + + let response: KeyVaultClientSelectiveKeyRestoreOperationResponse; + try { + response = await client.selectiveKeyRestoreOperation( + vaultUrl, + keyName, + setParentSpan(span, requestOptions) + ); + } finally { + span.end(); + } + + return response; +} + +/** + * Tracing the fullRestoreStatus operation. + */ +async function fullRestoreStatus( + client: KeyVaultClient, + vaultUrl: string, + jobId: string, + options: OperationOptions +): Promise { + const requestOptions = operationOptionsToRequestOptionsBase(options); + const span = createSpan("generatedClient.fullRestoreStatus", requestOptions); + + let response: KeyVaultClientFullBackupStatusResponse; + try { + response = await client.fullBackupStatus(vaultUrl, jobId, options); + } finally { + span.end(); + } + + return response; +} + +/** + * @summary Reaches to the service and updates the delete key's poll operation. + * @param [options] The optional parameters, which are an abortSignal from @azure/abort-controller and a function that triggers the poller's onProgress function. + */ +async function update( + this: SelectiveRestorePollOperation, + options: { + abortSignal?: AbortSignalLike; + fireProgress?: (state: SelectiveRestorePollOperationState) => void; + } = {} +): Promise { + const state = this.state; + const { vaultUrl, keyName, blobStorageUri, sasToken, folderName } = state; + + // Internal properties, + // the reference is only potentially undefined in the public representation of the poller. + const client = state.client!; + + const requestOptions = state.requestOptions || {}; + if (options.abortSignal) { + requestOptions.abortSignal = options.abortSignal; + } + + if (!state.isStarted) { + const selectiveRestoreOperation = await selectiveRestore(client, vaultUrl, keyName, { + ...requestOptions, + restoreBlobDetails: { + folder: folderName, + sasTokenParameters: { + storageResourceUri: blobStorageUri, + token: sasToken + } + } + }); + + const { startTime, jobId, endTime, error } = selectiveRestoreOperation; + + if (!startTime) { + state.error = new Error(`Missing "startTime" from the full restore operation.`); + state.isCompleted = true; + return makeSelectiveRestorePollOperation(state); + } + + state.isStarted = true; + state.jobId = jobId; + state.endTime = endTime; + state.startTime = startTime; + state.status = selectiveRestoreOperation.status; + state.statusDetails = selectiveRestoreOperation.statusDetails; + + if (endTime) { + state.isCompleted = true; + } + if (error) { + state.isCompleted = true; + state.error = new Error(error.message); + } + } + + if (!state.jobId) { + state.error = new Error(`Missing "jobId" from the full restore operation.`); + state.isCompleted = true; + return makeSelectiveRestorePollOperation(state); + } + + if (!state.isCompleted) { + const selectiveRestoreOperation = await fullRestoreStatus(client, vaultUrl, state.jobId, { + requestOptions + }); + const { endTime, error } = selectiveRestoreOperation; + if (endTime) { + state.isCompleted = true; + } + if (error) { + state.isCompleted = true; + state.error = new Error(error.message); + } + } + + return makeSelectiveRestorePollOperation(state); +} + +/** + * @summary Reaches to the service and cancels the key's operation, also updating the key's poll operation + * @param [options] The optional parameters, which is only an abortSignal from @azure/abort-controller + */ +async function cancel(this: SelectiveRestorePollOperation): Promise { + throw new Error("Canceling the deletion of a key is not supported."); +} + +/** + * @summary Serializes the SelectiveRestorePollOperation + */ +function toString(this: SelectiveRestorePollOperation): string { + return JSON.stringify({ + state: this.state + }); +} + +/** + * @summary Builds the SelectiveRestorePollOperation + * @param [state] A poll operation's state, in case the new one is intended to follow up where the previous one was left. + */ +export function makeSelectiveRestorePollOperation( + state: SelectiveRestorePollOperationState +): SelectiveRestorePollOperation { + return { + state: { + ...state + }, + update, + cancel, + toString + }; +} diff --git a/sdk/keyvault/keyvault-admin/src/lro/selectiveRestore/poller.ts b/sdk/keyvault/keyvault-admin/src/lro/selectiveRestore/poller.ts new file mode 100644 index 000000000000..29f1b517774e --- /dev/null +++ b/sdk/keyvault/keyvault-admin/src/lro/selectiveRestore/poller.ts @@ -0,0 +1,101 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { delay, RequestOptionsBase } from "@azure/core-http"; +import { Poller } from "@azure/core-lro"; +import { KeyVaultClient } from "../../generated/keyVaultClient"; +import { + SelectiveRestoreOperationState, + SelectiveRestorePollOperationState, + makeSelectiveRestorePollOperation +} from "./operation"; + +export interface SelectiveRestorePollerOptions { + client: KeyVaultClient; + keyName: string; + vaultUrl: string; + blobStorageUri: string; + sasToken: string; + folderName: string; + requestOptions?: RequestOptionsBase; + intervalInMs?: number; + resumeFrom?: string; +} + +/** + * Class that creates a poller that waits until a key of a Key Vault backup ends up being restored. + */ +export class SelectiveRestorePoller extends Poller { + /** + * Defines how much time the poller is going to wait before making a new request to the service. + * @memberof SelectiveRestorePoller + */ + public intervalInMs: number; + + constructor(options: SelectiveRestorePollerOptions) { + const { + client, + vaultUrl, + keyName, + blobStorageUri, + sasToken, + folderName, + requestOptions, + intervalInMs = 2000, + resumeFrom + } = options; + + let state: SelectiveRestorePollOperationState | undefined; + + if (resumeFrom) { + state = JSON.parse(resumeFrom).state; + } + + const operation = makeSelectiveRestorePollOperation({ + ...state, + keyName, + blobStorageUri, + sasToken, + folderName, + requestOptions, + client, + vaultUrl + }); + + super(operation); + + this.intervalInMs = intervalInMs; + } + + /** + * The method used by the poller to wait before attempting to update its operation. + * @memberof SelectiveRestorePoller + */ + async delay(): Promise { + return delay(this.intervalInMs); + } + + /** + * Gets the public state of the polling operation + */ + public getOperationState(): SelectiveRestoreOperationState { + const state: SelectiveRestoreOperationState = this.operation.state; + return { + vaultUrl: state.vaultUrl, + keyName: state.keyName, + blobStorageUri: state.blobStorageUri, + sasToken: state.sasToken, + folderName: state.folderName, + isStarted: state.isStarted, + isCompleted: state.isCompleted, + isCancelled: state.isCancelled, + error: state.error, + result: state.result, + jobId: state.jobId, + endTime: state.endTime, + startTime: state.startTime, + status: state.status, + statusDetails: state.statusDetails + }; + } +} From 63be7cf2af29cb812f121dbb92dc97b1967e138e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Rodr=C3=ADguez?= Date: Fri, 4 Sep 2020 10:20:08 -0400 Subject: [PATCH 02/12] Updates based on feedback, specially docs --- sdk/keyvault/keyvault-admin/package.json | 15 ++++-- .../keyvault-admin/src/backupClient.ts | 54 +++++++++---------- .../src/lro/backup/operation.ts | 49 +++++++++-------- .../keyvault-admin/src/lro/backup/poller.ts | 5 +- .../src/lro/restore/operation.ts | 30 +++++------ .../keyvault-admin/src/lro/restore/poller.ts | 6 +-- 6 files changed, 78 insertions(+), 81 deletions(-) diff --git a/sdk/keyvault/keyvault-admin/package.json b/sdk/keyvault/keyvault-admin/package.json index b11b1032d16d..a31db11ae8d8 100644 --- a/sdk/keyvault/keyvault-admin/package.json +++ b/sdk/keyvault/keyvault-admin/package.json @@ -20,7 +20,7 @@ "url": "https://github.com/Azure/azure-sdk-for-js/issues" }, "main": "./dist/index.js", - "module": "dist-esm/src/index.js", + "module": "dist-esm/keyvault-admin/src/index.js", "types": "./types/keyvault-admin.d.ts", "engine": { "node": ">=8.0.0" @@ -29,10 +29,11 @@ "node": ">=8.0.0" }, "files": [ - "types/", + "types/keyvault-admin.d.ts", "dist/", "dist-browser/", - "dist-esm/src", + "dist-esm/keyvault-admin/src", + "dist-esm/keyvault-common/src", "README.md", "LICENSE" ], @@ -52,13 +53,13 @@ "execute:js-samples": "echo skipped", "execute:ts-samples": "echo skipped", "execute:samples": "npm run build:samples && npm run execute:js-samples && npm run execute:ts-samples", - "extract-api": "echo skipped", + "extract-api": "tsc -p . && api-extractor run --local", "format": "prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", "integration-test:browser": "echo skipped", "integration-test:node": "echo skipped", "integration-test": "npm run integration-test:node && npm run integration-test:browser", "lint:fix": "eslint package.json src --ext .ts --fix --fix-type [problem,suggestion]", - "lint": "eslint package.json src --ext .ts -f html -o keyvault-admin-lintReport.html", + "lint": "eslint package.json api-extractor.json src --ext .ts", "lint:terminal": "eslint package.json src test --ext .ts", "pack": "npm pack 2>&1", "prebuild": "npm run clean", @@ -72,14 +73,18 @@ }, "sideEffects": false, "dependencies": { + "@azure/abort-controller": "^1.0.0", "@azure/core-http": "^1.1.6", "@azure/core-lro": "^1.0.2", + "@azure/core-paging": "^1.1.1", "@azure/core-tracing": "1.0.0-preview.9", + "@azure/logger": "^1.0.0", "@opentelemetry/api": "^0.10.2", "tslib": "^2.0.0" }, "devDependencies": { "@azure/eslint-plugin-azure-sdk": "^3.0.0", + "@microsoft/api-extractor": "7.7.11", "@rollup/plugin-commonjs": "11.0.2", "@rollup/plugin-json": "^4.0.0", "@rollup/plugin-multi-entry": "^3.0.0", diff --git a/sdk/keyvault/keyvault-admin/src/backupClient.ts b/sdk/keyvault/keyvault-admin/src/backupClient.ts index e0dfeca7ac19..ee12ecff8882 100644 --- a/sdk/keyvault/keyvault-admin/src/backupClient.ts +++ b/sdk/keyvault/keyvault-admin/src/backupClient.ts @@ -4,7 +4,6 @@ import { createPipelineFromOptions, isTokenCredential, - operationOptionsToRequestOptionsBase, signingPolicy, TokenCredential } from "@azure/core-http"; @@ -22,6 +21,8 @@ import { SelectiveRestorePoller } from "./lro/selectiveRestore/poller"; /** * The KeyVaultBackupClient provides methods to generate backups * and restore backups of any given Azure Key Vault instance. + * This client supports generating full backups, selective restores of specific keys + * and full restores of Key Vault instances. */ export class KeyVaultBackupClient { /** @@ -44,15 +45,14 @@ export class KeyVaultBackupClient { * import { KeyVaultBackupClient } from "@azure/keyvault-admin"; * import { DefaultAzureCredential } from "@azure/identity"; * - * let vaultUrl = `https://.vault.azure.net`; + * let vaultUrl = `https://.vault.azure.net`; * let credentials = new DefaultAzureCredential(); * * let client = new KeyVaultBackupClient(vaultUrl, credentials); * ``` - * @param {string} vaultUrl the URL of the Key Vault. It should have this shape: https://${your-key-vault-name}.vault.azure.net - * @param {TokenCredential} credential An object that implements the `TokenCredential` interface used to authenticate requests to the service. Use the @azure/identity package to create a credential that suits your needs. - * @param {BackupClientOptions} [pipelineOptions] Pipeline options used to configure Key Vault API requests. Omit this parameter to use the default pipeline configuration. - * @memberof KeyVaultBackupClient + * @param vaultUrl the URL of the Key Vault. It should have this shape: https://${your-key-vault-name}.vault.azure.net + * @param credential An object that implements the `TokenCredential` interface used to authenticate requests to the service. Use the @azure/identity package to create a credential that suits your needs. + * @param [pipelineOptions] Pipeline options used to configure Key Vault API requests. Omit this parameter to use the default pipeline configuration. */ constructor( vaultUrl: string, @@ -109,7 +109,7 @@ export class KeyVaultBackupClient { * ```ts * const client = new KeyVaultBackupClient(url, credentials); * - * const blobStorageUri = ""; + * const blobStorageUri = ""; // / * const sasToken = ""; * const poller = await client.beginBackup(blobStorageUri, sasToken); * @@ -123,17 +123,15 @@ export class KeyVaultBackupClient { * console.log(backupUri); * ``` * @summary Creates a new role assignment. - * @param {string} blobStorageUri The URI of the blob storage account. - * @param {string} sasToken The SAS token. - * @param {CreateRoleAssignmentOptions} [options] The optional parameters. + * @param blobStorageUri The URL of the blob storage resource, with the path to the folder name where the backup will end up being generated. + * @param sasToken The SAS token. + * @param [options] The optional parameters. */ public async beginBackup( blobStorageUri: string, sasToken: string, options: BeginBackupOptions = {} ): Promise, string>> { - const requestOptions = operationOptionsToRequestOptionsBase(options); - if (!(blobStorageUri && sasToken)) { throw new Error( "beginBackup requires non-empty strings for the parameters: blobStorageUri and sasToken." @@ -147,7 +145,7 @@ export class KeyVaultBackupClient { vaultUrl: this.vaultUrl, intervalInMs: options.intervalInMs, resumeFrom: options.resumeFrom, - requestOptions + requestOptions: options }); // This will initialize the poller's operation (the generation of the backup). @@ -166,7 +164,7 @@ export class KeyVaultBackupClient { * ```ts * const client = new KeyVaultBackupClient(url, credentials); * - * const blobStorageUri = ""; + * const blobStorageUri = ""; // / * const sasToken = ""; * const folderName = ""; * const poller = await client.beginRestore(blobStorageUri, sasToken, folderName); @@ -181,10 +179,10 @@ export class KeyVaultBackupClient { * console.log(backupUri); * ``` * @summary Creates a new role assignment. - * @param {string} blobStorageUri The URI of the blob storage account. - * @param {string} sasToken The SAS token. - * @param {string} folderName The Folder name of the blob where the previous successful full backup was stored. - * @param {CreateRoleAssignmentOptions} [options] The optional parameters. + * @param blobStorageUri The URL of the blob storage resource, with the folder name of the blob where the previous successful full backup was stored. + * @param sasToken The SAS token. + * @param folderName The folder name of the blob where the previous successful full backup was stored. + * @param [options] The optional parameters. */ public async beginRestore( blobStorageUri: string, @@ -192,8 +190,6 @@ export class KeyVaultBackupClient { folderName: string, options: BeginRestoreOptions = {} ): Promise, undefined>> { - const requestOptions = operationOptionsToRequestOptionsBase(options); - if (!(blobStorageUri && sasToken && folderName)) { throw new Error( "beginRestore requires non-empty strings for the parameters: blobStorageUri, sasToken and folderName." @@ -208,7 +204,7 @@ export class KeyVaultBackupClient { vaultUrl: this.vaultUrl, intervalInMs: options.intervalInMs, resumeFrom: options.resumeFrom, - requestOptions + requestOptions: options }); // This will initialize the poller's operation (the generation of the backup). @@ -235,18 +231,18 @@ export class KeyVaultBackupClient { * // Serializing the poller * const serialized = poller.toString(); * // A new poller can be created with: - * // await client.beginBackup(keyName, blobStorageUri, sasToken, { resumeFrom: serialized }); + * // await client.beginSelectiveRestore(keyName, blobStorageUri, sasToken, { resumeFrom: serialized }); * * // Waiting until it's done * const backupUri = await poller.pollUntilDone(); * console.log(backupUri); * ``` * @summary Creates a new role assignment. - * @param {string} keyName The name of the key that wants to be restored. - * @param {string} blobStorageUri The URI of the blob storage account. - * @param {string} sasToken The SAS token. - * @param {string} folderName The Folder name of the blob where the previous successful full backup was stored. - * @param {CreateRoleAssignmentOptions} [options] The optional parameters. + * @param keyName The name of the key that wants to be restored. + * @param blobStorageUri The URL of the blob storage resource, with the folder name of the blob where the previous successful full backup was stored. + * @param sasToken The SAS token. + * @param folderName The Folder name of the blob where the previous successful full backup was stored. + * @param [options] The optional parameters. */ public async beginSelectiveRestore( keyName: string, @@ -255,8 +251,6 @@ export class KeyVaultBackupClient { folderName: string, options: BeginBackupOptions = {} ): Promise, undefined>> { - const requestOptions = operationOptionsToRequestOptionsBase(options); - if (!(keyName && blobStorageUri && sasToken && folderName)) { throw new Error( "beginSelectiveRestore requires non-empty strings for the parameters: keyName, blobStorageUri, sasToken and folderName." @@ -272,7 +266,7 @@ export class KeyVaultBackupClient { vaultUrl: this.vaultUrl, intervalInMs: options.intervalInMs, resumeFrom: options.resumeFrom, - requestOptions + requestOptions: options }); // This will initialize the poller's operation (the generation of the backup). diff --git a/sdk/keyvault/keyvault-admin/src/lro/backup/operation.ts b/sdk/keyvault/keyvault-admin/src/lro/backup/operation.ts index 1a224cd28b59..5fd8daaf744f 100644 --- a/sdk/keyvault/keyvault-admin/src/lro/backup/operation.ts +++ b/sdk/keyvault/keyvault-admin/src/lro/backup/operation.ts @@ -3,11 +3,6 @@ import { AbortSignalLike } from "@azure/abort-controller"; import { PollOperationState, PollOperation } from "@azure/core-lro"; -import { - OperationOptions, - operationOptionsToRequestOptionsBase, - RequestOptionsBase -} from "@azure/core-http"; import { KeyVaultClient } from "../../generated/keyVaultClient"; import { KeyVaultClientFullBackupOptionalParams, @@ -15,6 +10,7 @@ import { KeyVaultClientFullBackupStatusResponse } from "../../generated/models"; import { createSpan, setParentSpan } from "../../tracing"; +import { BeginBackupOptions } from "../../backupClientModels"; /** * An interface representing the publicly available properties of the state of a backup Key Vault's poll operation. @@ -62,7 +58,7 @@ export interface BackupPollOperationState extends PollOperationState { /** * Options for the core-http requests. */ - requestOptions?: RequestOptionsBase; + requestOptions?: BeginBackupOptions; /** * An interface representing the internal KeyVaultClient. */ @@ -114,12 +110,11 @@ async function fullBackup( vaultUrl: string, options: KeyVaultClientFullBackupOptionalParams ): Promise { - const requestOptions = operationOptionsToRequestOptionsBase(options); - const span = createSpan("generatedClient.fullBackup", requestOptions); + const span = createSpan("generatedClient.fullBackup", options); let response: KeyVaultClientFullBackupResponse; try { - response = await client.fullBackup(vaultUrl, setParentSpan(span, requestOptions)); + response = await client.fullBackup(vaultUrl, setParentSpan(span, options)); } finally { span.end(); } @@ -134,14 +129,13 @@ async function fullBackupStatus( client: KeyVaultClient, vaultUrl: string, jobId: string, - options: OperationOptions + options: BeginBackupOptions ): Promise { - const requestOptions = operationOptionsToRequestOptionsBase(options); - const span = createSpan("generatedClient.fullBackupStatus", requestOptions); + const span = createSpan("generatedClient.fullBackupStatus", options); let response: KeyVaultClientFullBackupStatusResponse; try { - response = await client.fullBackupStatus(vaultUrl, jobId, setParentSpan(span, requestOptions)); + response = await client.fullBackupStatus(vaultUrl, jobId, setParentSpan(span, options)); } finally { span.end(); } @@ -173,7 +167,7 @@ async function update( } if (!state.isStarted) { - const fullBackupOperation = await fullBackup(client, vaultUrl, { + const serviceOperation = await fullBackup(client, vaultUrl, { ...requestOptions, azureStorageBlobContainerUri: { storageResourceUri: blobStorageUri, @@ -181,7 +175,7 @@ async function update( } }); - const { startTime, jobId, azureStorageBlobContainerUri, endTime, error } = fullBackupOperation; + const { startTime, jobId, azureStorageBlobContainerUri, endTime, error } = serviceOperation; if (!startTime) { state.error = new Error(`Missing "startTime" from the full backup operation.`); @@ -193,14 +187,14 @@ async function update( state.jobId = jobId; state.endTime = endTime; state.startTime = startTime; - state.status = fullBackupOperation.status; - state.statusDetails = fullBackupOperation.statusDetails; + state.status = serviceOperation.status; + state.statusDetails = serviceOperation.statusDetails; state.result = azureStorageBlobContainerUri; if (endTime) { state.isCompleted = true; } - if (error) { + if (error && error.message) { state.isCompleted = true; state.error = new Error(error.message); } @@ -213,15 +207,24 @@ async function update( } if (!state.isCompleted) { - const fullBackupOperation = await fullBackupStatus(client, vaultUrl, state.jobId, { - requestOptions - }); - const { azureStorageBlobContainerUri, endTime, error } = fullBackupOperation; + const serviceOperation = await fullBackupStatus(client, vaultUrl, state.jobId, requestOptions); + const { + azureStorageBlobContainerUri, + endTime, + status, + statusDetails, + error + } = serviceOperation; + + state.endTime = endTime; + state.status = status; + state.statusDetails = statusDetails; state.result = azureStorageBlobContainerUri; + if (endTime) { state.isCompleted = true; } - if (error) { + if (error && error.message) { state.isCompleted = true; state.error = new Error(error.message); } diff --git a/sdk/keyvault/keyvault-admin/src/lro/backup/poller.ts b/sdk/keyvault/keyvault-admin/src/lro/backup/poller.ts index 3aff2cabec1c..946cdd1ff6e4 100644 --- a/sdk/keyvault/keyvault-admin/src/lro/backup/poller.ts +++ b/sdk/keyvault/keyvault-admin/src/lro/backup/poller.ts @@ -1,8 +1,9 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { delay, RequestOptionsBase } from "@azure/core-http"; +import { delay } from "@azure/core-http"; import { Poller } from "@azure/core-lro"; +import { BeginBackupOptions } from "../../backupClientModels"; import { KeyVaultClient } from "../../generated/keyVaultClient"; import { BackupOperationState, @@ -15,7 +16,7 @@ export interface BackupPollerOptions { vaultUrl: string; blobStorageUri: string; sasToken: string; - requestOptions?: RequestOptionsBase; + requestOptions?: BeginBackupOptions; intervalInMs?: number; resumeFrom?: string; } diff --git a/sdk/keyvault/keyvault-admin/src/lro/restore/operation.ts b/sdk/keyvault/keyvault-admin/src/lro/restore/operation.ts index 5296f8fd5a81..a604090c7db9 100644 --- a/sdk/keyvault/keyvault-admin/src/lro/restore/operation.ts +++ b/sdk/keyvault/keyvault-admin/src/lro/restore/operation.ts @@ -3,11 +3,7 @@ import { AbortSignalLike } from "@azure/abort-controller"; import { PollOperationState, PollOperation } from "@azure/core-lro"; -import { - OperationOptions, - operationOptionsToRequestOptionsBase, - RequestOptionsBase -} from "@azure/core-http"; +import { OperationOptions, RequestOptionsBase } from "@azure/core-http"; import { KeyVaultClient } from "../../generated/keyVaultClient"; import { KeyVaultClientFullBackupStatusResponse, @@ -122,12 +118,11 @@ async function fullRestore( vaultUrl: string, options: KeyVaultClientFullRestoreOperationOptionalParams ): Promise { - const requestOptions = operationOptionsToRequestOptionsBase(options); - const span = createSpan("generatedClient.fullRestore", requestOptions); + const span = createSpan("generatedClient.fullRestore", options); let response: KeyVaultClientFullRestoreOperationResponse; try { - response = await client.fullRestoreOperation(vaultUrl, setParentSpan(span, requestOptions)); + response = await client.fullRestoreOperation(vaultUrl, setParentSpan(span, options)); } finally { span.end(); } @@ -138,18 +133,17 @@ async function fullRestore( /** * Tracing the fullRestoreStatus operation. */ -async function fullRestoreStatus( +async function fullBackupStatus( client: KeyVaultClient, vaultUrl: string, jobId: string, options: OperationOptions ): Promise { - const requestOptions = operationOptionsToRequestOptionsBase(options); - const span = createSpan("generatedClient.fullRestoreStatus", requestOptions); + const span = createSpan("generatedClient.fullBackupStatus", options); let response: KeyVaultClientFullBackupStatusResponse; try { - response = await client.fullBackupStatus(vaultUrl, jobId, setParentSpan(span, requestOptions)); + response = await client.fullBackupStatus(vaultUrl, jobId, setParentSpan(span, options)); } finally { span.end(); } @@ -181,7 +175,7 @@ async function update( } if (!state.isStarted) { - const fullRestoreOperation = await fullRestore(client, vaultUrl, { + const serviceOperation = await fullRestore(client, vaultUrl, { ...requestOptions, restoreBlobDetails: { folderToRestore: folderName, @@ -192,7 +186,7 @@ async function update( } }); - const { startTime, jobId, endTime, error } = fullRestoreOperation; + const { startTime, jobId, endTime, error } = serviceOperation; if (!startTime) { state.error = new Error(`Missing "startTime" from the full restore operation.`); @@ -204,8 +198,8 @@ async function update( state.jobId = jobId; state.endTime = endTime; state.startTime = startTime; - state.status = fullRestoreOperation.status; - state.statusDetails = fullRestoreOperation.statusDetails; + state.status = serviceOperation.status; + state.statusDetails = serviceOperation.statusDetails; if (endTime) { state.isCompleted = true; @@ -223,10 +217,10 @@ async function update( } if (!state.isCompleted) { - const fullRestoreOperation = await fullRestoreStatus(client, vaultUrl, state.jobId, { + const serviceOperation = await fullBackupStatus(client, vaultUrl, state.jobId, { requestOptions }); - const { endTime, error } = fullRestoreOperation; + const { endTime, error } = serviceOperation; if (endTime) { state.isCompleted = true; } diff --git a/sdk/keyvault/keyvault-admin/src/lro/restore/poller.ts b/sdk/keyvault/keyvault-admin/src/lro/restore/poller.ts index c30d00f92026..8f3aba696c02 100644 --- a/sdk/keyvault/keyvault-admin/src/lro/restore/poller.ts +++ b/sdk/keyvault/keyvault-admin/src/lro/restore/poller.ts @@ -1,8 +1,9 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { delay, RequestOptionsBase } from "@azure/core-http"; +import { delay } from "@azure/core-http"; import { Poller } from "@azure/core-lro"; +import { BeginRestoreOptions } from "../.."; import { KeyVaultClient } from "../../generated/keyVaultClient"; import { RestoreOperationState, @@ -16,7 +17,7 @@ export interface RestorePollerOptions { blobStorageUri: string; sasToken: string; folderName: string; - requestOptions?: RequestOptionsBase; + requestOptions?: BeginRestoreOptions; intervalInMs?: number; resumeFrom?: string; } @@ -30,7 +31,6 @@ export class RestorePoller extends Poller * @memberof RestorePoller */ public intervalInMs: number; - constructor(options: RestorePollerOptions) { const { client, From cd9bec86081bb151b8ffa632afd6556b18b44164 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Rodr=C3=ADguez?= Date: Fri, 4 Sep 2020 12:02:29 -0400 Subject: [PATCH 03/12] Apply suggestions from code review Co-authored-by: Christopher Scott --- sdk/keyvault/keyvault-admin/src/backupClient.ts | 15 +++++++-------- .../keyvault-admin/src/lro/backup/operation.ts | 2 +- .../keyvault-admin/src/lro/restore/operation.ts | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/sdk/keyvault/keyvault-admin/src/backupClient.ts b/sdk/keyvault/keyvault-admin/src/backupClient.ts index ee12ecff8882..ade71ea737df 100644 --- a/sdk/keyvault/keyvault-admin/src/backupClient.ts +++ b/sdk/keyvault/keyvault-admin/src/backupClient.ts @@ -122,8 +122,8 @@ export class KeyVaultBackupClient { * const backupUri = await poller.pollUntilDone(); * console.log(backupUri); * ``` - * @summary Creates a new role assignment. - * @param blobStorageUri The URL of the blob storage resource, with the path to the folder name where the backup will end up being generated. + * @summary Starts a full backup operation. + * @param blobStorageUri The URL of the blob storage resource, including the path to the container where the backup will end up being stored. * @param sasToken The SAS token. * @param [options] The optional parameters. */ @@ -158,7 +158,7 @@ export class KeyVaultBackupClient { * Starts restoring all key materials using the SAS token pointing to a previously stored Azure Blob storage * backup folder. * - * This function returns a Long Running Operation poller that allows you to wait indefinitely until the Key Vault backup is generated. + * This function returns a Long Running Operation poller that allows you to wait indefinitely until the Key Vault restore operation is complete. * * Example usage: * ```ts @@ -178,8 +178,8 @@ export class KeyVaultBackupClient { * const backupUri = await poller.pollUntilDone(); * console.log(backupUri); * ``` - * @summary Creates a new role assignment. - * @param blobStorageUri The URL of the blob storage resource, with the folder name of the blob where the previous successful full backup was stored. + * @summary Starts a full restore operation. + * @param blobStorageUri The URL of the blob storage resource where the previous successful full backup was stored. * @param sasToken The SAS token. * @param folderName The folder name of the blob where the previous successful full backup was stored. * @param [options] The optional parameters. @@ -217,7 +217,7 @@ export class KeyVaultBackupClient { * Starts restoring all key versions of a given key using user supplied SAS token pointing to a previously * stored Azure Blob storage backup folder. * - * This function returns a Long Running Operation poller that allows you to wait indefinitely until the Key Vault backup is generated. + * This function returns a Long Running Operation poller that allows you to wait indefinitely until the Key Vault selective restore is complete. * * Example usage: * ```ts @@ -234,8 +234,7 @@ export class KeyVaultBackupClient { * // await client.beginSelectiveRestore(keyName, blobStorageUri, sasToken, { resumeFrom: serialized }); * * // Waiting until it's done - * const backupUri = await poller.pollUntilDone(); - * console.log(backupUri); + * await poller.pollUntilDone(); * ``` * @summary Creates a new role assignment. * @param keyName The name of the key that wants to be restored. diff --git a/sdk/keyvault/keyvault-admin/src/lro/backup/operation.ts b/sdk/keyvault/keyvault-admin/src/lro/backup/operation.ts index 5fd8daaf744f..6cf752a485b1 100644 --- a/sdk/keyvault/keyvault-admin/src/lro/backup/operation.ts +++ b/sdk/keyvault/keyvault-admin/src/lro/backup/operation.ts @@ -144,7 +144,7 @@ async function fullBackupStatus( } /** - * @summary Reaches to the service and updates the delete key's poll operation. + * @summary Reaches to the service and updates the backup's poll operation. * @param [options] The optional parameters, which are an abortSignal from @azure/abort-controller and a function that triggers the poller's onProgress function. */ async function update( diff --git a/sdk/keyvault/keyvault-admin/src/lro/restore/operation.ts b/sdk/keyvault/keyvault-admin/src/lro/restore/operation.ts index a604090c7db9..2e56b351f7db 100644 --- a/sdk/keyvault/keyvault-admin/src/lro/restore/operation.ts +++ b/sdk/keyvault/keyvault-admin/src/lro/restore/operation.ts @@ -152,7 +152,7 @@ async function fullBackupStatus( } /** - * @summary Reaches to the service and updates the delete key's poll operation. + * @summary Reaches to the service and updates the restore's poll operation. * @param [options] The optional parameters, which are an abortSignal from @azure/abort-controller and a function that triggers the poller's onProgress function. */ async function update( From 7e393c28f4fedb1c1b7cda521e4b7779b84de8b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Rodr=C3=ADguez?= Date: Fri, 4 Sep 2020 13:21:29 -0400 Subject: [PATCH 04/12] Param feedback and comments --- .../keyvault-admin/src/backupClient.ts | 11 ++++---- .../src/lro/backup/operation.ts | 28 ++++++------------- .../keyvault-admin/src/lro/backup/poller.ts | 3 -- 3 files changed, 14 insertions(+), 28 deletions(-) diff --git a/sdk/keyvault/keyvault-admin/src/backupClient.ts b/sdk/keyvault/keyvault-admin/src/backupClient.ts index ade71ea737df..b6d9f0f59a11 100644 --- a/sdk/keyvault/keyvault-admin/src/backupClient.ts +++ b/sdk/keyvault/keyvault-admin/src/backupClient.ts @@ -223,31 +223,32 @@ export class KeyVaultBackupClient { * ```ts * const client = new KeyVaultBackupClient(url, credentials); * - * const keyName = ""; * const blobStorageUri = ""; * const sasToken = ""; - * const poller = await client.beginSelectiveRestore(keyName, blobStorageUri, sasToken); + * const folderName = ""; + * const keyName = ""; + * const poller = await client.beginSelectiveRestore(blobStorageUri, sasToken, folderName, keyName); * * // Serializing the poller * const serialized = poller.toString(); * // A new poller can be created with: - * // await client.beginSelectiveRestore(keyName, blobStorageUri, sasToken, { resumeFrom: serialized }); + * // await client.beginSelectiveRestore(blobStorageUri, sasToken, folderName, keyName, { resumeFrom: serialized }); * * // Waiting until it's done * await poller.pollUntilDone(); * ``` * @summary Creates a new role assignment. - * @param keyName The name of the key that wants to be restored. * @param blobStorageUri The URL of the blob storage resource, with the folder name of the blob where the previous successful full backup was stored. * @param sasToken The SAS token. * @param folderName The Folder name of the blob where the previous successful full backup was stored. + * @param keyName The name of the key that wants to be restored. * @param [options] The optional parameters. */ public async beginSelectiveRestore( - keyName: string, blobStorageUri: string, sasToken: string, folderName: string, + keyName: string, options: BeginBackupOptions = {} ): Promise, undefined>> { if (!(keyName && blobStorageUri && sasToken && folderName)) { diff --git a/sdk/keyvault/keyvault-admin/src/lro/backup/operation.ts b/sdk/keyvault/keyvault-admin/src/lro/backup/operation.ts index 6cf752a485b1..10f66e1d5443 100644 --- a/sdk/keyvault/keyvault-admin/src/lro/backup/operation.ts +++ b/sdk/keyvault/keyvault-admin/src/lro/backup/operation.ts @@ -16,18 +16,6 @@ import { BeginBackupOptions } from "../../backupClientModels"; * An interface representing the publicly available properties of the state of a backup Key Vault's poll operation. */ export interface BackupOperationState extends PollOperationState { - /** - * The base URL to the vault - */ - vaultUrl: string; - /** - * The URI of the blob storage account. - */ - blobStorageUri: string; - /** - * The SAS token. - */ - sasToken: string; /** * Identifier for the full backup operation. */ @@ -64,17 +52,17 @@ export interface BackupPollOperationState extends PollOperationState { */ client?: KeyVaultClient; /** - * The base URL to the vault + * The base URL to the vault. */ - vaultUrl: string; + vaultUrl?: string; /** * The URI of the blob storage account. */ - blobStorageUri: string; + blobStorageUri?: string; /** * The SAS token. */ - sasToken: string; + sasToken?: string; /** * The id returned as part of the backup request */ @@ -167,11 +155,11 @@ async function update( } if (!state.isStarted) { - const serviceOperation = await fullBackup(client, vaultUrl, { + const serviceOperation = await fullBackup(client, vaultUrl!, { ...requestOptions, azureStorageBlobContainerUri: { - storageResourceUri: blobStorageUri, - token: sasToken + storageResourceUri: blobStorageUri!, + token: sasToken! } }); @@ -207,7 +195,7 @@ async function update( } if (!state.isCompleted) { - const serviceOperation = await fullBackupStatus(client, vaultUrl, state.jobId, requestOptions); + const serviceOperation = await fullBackupStatus(client, vaultUrl!, state.jobId, requestOptions); const { azureStorageBlobContainerUri, endTime, diff --git a/sdk/keyvault/keyvault-admin/src/lro/backup/poller.ts b/sdk/keyvault/keyvault-admin/src/lro/backup/poller.ts index 946cdd1ff6e4..401eaac6d388 100644 --- a/sdk/keyvault/keyvault-admin/src/lro/backup/poller.ts +++ b/sdk/keyvault/keyvault-admin/src/lro/backup/poller.ts @@ -76,9 +76,6 @@ export class BackupPoller extends Poller { public getOperationState(): BackupOperationState { const state: BackupOperationState = this.operation.state; return { - vaultUrl: state.vaultUrl, - blobStorageUri: state.blobStorageUri, - sasToken: state.sasToken, isStarted: state.isStarted, isCompleted: state.isCompleted, isCancelled: state.isCancelled, From 896edaa8801070b23122155d88f50ba71b319a3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Rodr=C3=ADguez?= Date: Fri, 4 Sep 2020 13:41:36 -0400 Subject: [PATCH 05/12] api review update --- .../review/keyvault-admin.api.md | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/sdk/keyvault/keyvault-admin/review/keyvault-admin.api.md b/sdk/keyvault/keyvault-admin/review/keyvault-admin.api.md index 0cee2050dfc3..46a93d0504a9 100644 --- a/sdk/keyvault/keyvault-admin/review/keyvault-admin.api.md +++ b/sdk/keyvault/keyvault-admin/review/keyvault-admin.api.md @@ -6,6 +6,8 @@ import * as coreHttp from '@azure/core-http'; import { PagedAsyncIterableIterator } from '@azure/core-paging'; +import { PollerLike } from '@azure/core-lro'; +import { PollOperationState } from '@azure/core-lro'; import { TokenCredential } from '@azure/core-http'; // @public @@ -13,6 +15,29 @@ export interface AccessControlClientOptions extends coreHttp.PipelineOptions { serviceVersion?: SUPPORTED_API_VERSIONS; } +// @public +export interface BackupClientOptions extends coreHttp.PipelineOptions { + serviceVersion?: SUPPORTED_API_VERSIONS; +} + +// @public +export interface BackupPollerOptions extends coreHttp.OperationOptions { + intervalInMs?: number; + resumeFrom?: string; +} + +// @public +export interface BeginBackupOptions extends BackupPollerOptions { +} + +// @public +export interface BeginRestoreOptions extends BackupPollerOptions { +} + +// @public +export interface BeginSelectiveRestoreOptions extends BackupPollerOptions { +} + // @public export interface CreateRoleAssignmentOptions extends coreHttp.OperationOptions { } @@ -36,6 +61,15 @@ export class KeyVaultAccessControlClient { readonly vaultUrl: string; } +// @public +export class KeyVaultBackupClient { + constructor(vaultUrl: string, credential: TokenCredential, pipelineOptions?: BackupClientOptions); + beginBackup(blobStorageUri: string, sasToken: string, options?: BeginBackupOptions): Promise, string>>; + beginRestore(blobStorageUri: string, sasToken: string, folderName: string, options?: BeginRestoreOptions): Promise, undefined>>; + beginSelectiveRestore(blobStorageUri: string, sasToken: string, folderName: string, keyName: string, options?: BeginBackupOptions): Promise, undefined>>; + readonly vaultUrl: string; +} + // @public export interface KeyVaultPermission { actions?: string[]; From b8385cc3f9b115c39be99797c5f091fd6c4f2a03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Rodr=C3=ADguez?= Date: Fri, 4 Sep 2020 15:13:21 -0400 Subject: [PATCH 06/12] small update I did on lro/backup/operation, now on lro/restore/operation --- .../keyvault-admin/src/lro/restore/operation.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/sdk/keyvault/keyvault-admin/src/lro/restore/operation.ts b/sdk/keyvault/keyvault-admin/src/lro/restore/operation.ts index 2e56b351f7db..2ec3a08b82af 100644 --- a/sdk/keyvault/keyvault-admin/src/lro/restore/operation.ts +++ b/sdk/keyvault/keyvault-admin/src/lro/restore/operation.ts @@ -204,7 +204,7 @@ async function update( if (endTime) { state.isCompleted = true; } - if (error) { + if (error && error.message) { state.isCompleted = true; state.error = new Error(error.message); } @@ -220,11 +220,16 @@ async function update( const serviceOperation = await fullBackupStatus(client, vaultUrl, state.jobId, { requestOptions }); - const { endTime, error } = serviceOperation; + const { endTime, status, statusDetails, error } = serviceOperation; + + state.endTime = endTime; + state.status = status; + state.statusDetails = statusDetails; + if (endTime) { state.isCompleted = true; } - if (error) { + if (error && error.message) { state.isCompleted = true; state.error = new Error(error.message); } From bfda811a561f3537ce11475bac98728bcaca9574 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Rodr=C3=ADguez?= Date: Fri, 4 Sep 2020 15:37:43 -0400 Subject: [PATCH 07/12] Comment improvement, I think --- .../keyvault-admin/src/backupClient.ts | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/sdk/keyvault/keyvault-admin/src/backupClient.ts b/sdk/keyvault/keyvault-admin/src/backupClient.ts index b6d9f0f59a11..8228b14e12d4 100644 --- a/sdk/keyvault/keyvault-admin/src/backupClient.ts +++ b/sdk/keyvault/keyvault-admin/src/backupClient.ts @@ -114,9 +114,13 @@ export class KeyVaultBackupClient { * const poller = await client.beginBackup(blobStorageUri, sasToken); * * // Serializing the poller - * const serialized = poller.toString(); + * // + * // const serialized = poller.toString(); + * // * // A new poller can be created with: - * // await client.beginBackup(blobStorageUri, sasToken, { resumeFrom: serialized }); + * // + * // await client.beginBackup(blobStorageUri, sasToken, { resumeFrom: serialized }); + * // * * // Waiting until it's done * const backupUri = await poller.pollUntilDone(); @@ -169,10 +173,14 @@ export class KeyVaultBackupClient { * const folderName = ""; * const poller = await client.beginRestore(blobStorageUri, sasToken, folderName); * - * // Serializing the poller - * const serialized = poller.toString(); + * // The poller can be serialized with: + * // + * // const serialized = poller.toString(); + * // * // A new poller can be created with: - * // await client.beginRestore(blobStorageUri, sasToken, folderName, { resumeFrom: serialized }); + * // + * // await client.beginRestore(blobStorageUri, sasToken, folderName, { resumeFrom: serialized }); + * // * * // Waiting until it's done * const backupUri = await poller.pollUntilDone(); @@ -230,9 +238,13 @@ export class KeyVaultBackupClient { * const poller = await client.beginSelectiveRestore(blobStorageUri, sasToken, folderName, keyName); * * // Serializing the poller - * const serialized = poller.toString(); + * // + * // const serialized = poller.toString(); + * // * // A new poller can be created with: - * // await client.beginSelectiveRestore(blobStorageUri, sasToken, folderName, keyName, { resumeFrom: serialized }); + * // + * // await client.beginSelectiveRestore(blobStorageUri, sasToken, folderName, keyName, { resumeFrom: serialized }); + * // * * // Waiting until it's done * await poller.pollUntilDone(); From b3360d1cc132c47ce975bee4de2c9b966051c371 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Rodr=C3=ADguez?= Date: Fri, 4 Sep 2020 15:40:04 -0400 Subject: [PATCH 08/12] comment fix --- sdk/keyvault/keyvault-admin/src/lro/restore/operation.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/keyvault/keyvault-admin/src/lro/restore/operation.ts b/sdk/keyvault/keyvault-admin/src/lro/restore/operation.ts index 2ec3a08b82af..232dd0d7a5ec 100644 --- a/sdk/keyvault/keyvault-admin/src/lro/restore/operation.ts +++ b/sdk/keyvault/keyvault-admin/src/lro/restore/operation.ts @@ -152,7 +152,7 @@ async function fullBackupStatus( } /** - * @summary Reaches to the service and updates the restore's poll operation. + * @summary Reaches to the service and updates the restore poll operation. * @param [options] The optional parameters, which are an abortSignal from @azure/abort-controller and a function that triggers the poller's onProgress function. */ async function update( From d3400ebce2663be6a14ec066ce1bc98b63d88004 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Rodr=C3=ADguez?= Date: Wed, 9 Sep 2020 16:38:07 -0400 Subject: [PATCH 09/12] moving the internal properties to an options bag --- .../src/lro/backup/operation.ts | 54 ++++++------ .../keyvault-admin/src/lro/backup/poller.ts | 12 +-- .../src/lro/restore/operation.ts | 84 +++++++++---------- .../keyvault-admin/src/lro/restore/poller.ts | 23 +++-- 4 files changed, 83 insertions(+), 90 deletions(-) diff --git a/sdk/keyvault/keyvault-admin/src/lro/backup/operation.ts b/sdk/keyvault/keyvault-admin/src/lro/backup/operation.ts index 10f66e1d5443..ee39c14d5af4 100644 --- a/sdk/keyvault/keyvault-admin/src/lro/backup/operation.ts +++ b/sdk/keyvault/keyvault-admin/src/lro/backup/operation.ts @@ -3,6 +3,7 @@ import { AbortSignalLike } from "@azure/abort-controller"; import { PollOperationState, PollOperation } from "@azure/core-lro"; +import { RequestOptionsBase } from "@azure/core-http"; import { KeyVaultClient } from "../../generated/keyVaultClient"; import { KeyVaultClientFullBackupOptionalParams, @@ -36,6 +37,10 @@ export interface BackupOperationState extends PollOperationState { * The end time of the backup operation in UTC */ endTime?: Date; + /** + * Internal request parameters + */ + requestParameters?: any; } /** @@ -43,26 +48,28 @@ export interface BackupOperationState extends PollOperationState { * @internal */ export interface BackupPollOperationState extends PollOperationState { - /** - * Options for the core-http requests. - */ - requestOptions?: BeginBackupOptions; - /** - * An interface representing the internal KeyVaultClient. - */ - client?: KeyVaultClient; - /** - * The base URL to the vault. - */ - vaultUrl?: string; - /** - * The URI of the blob storage account. - */ - blobStorageUri?: string; - /** - * The SAS token. - */ - sasToken?: string; + requestParameters?: { + /** + * Options for the core-http requests. + */ + requestOptions: RequestOptionsBase; + /** + * An interface representing the internal KeyVaultClient. + */ + client: KeyVaultClient; + /** + * The base URL to the vault. + */ + vaultUrl: string; + /** + * The URI of the blob storage account. + */ + blobStorageUri: string; + /** + * The SAS token. + */ + sasToken: string; + }; /** * The id returned as part of the backup request */ @@ -143,13 +150,8 @@ async function update( } = {} ): Promise { const state = this.state; - const { vaultUrl, blobStorageUri, sasToken } = state; - - // Internal properties, - // the reference is only potentially undefined in the public representation of the poller. - const client = state.client!; + const { requestOptions, vaultUrl, blobStorageUri, sasToken, client } = state.requestParameters!; - const requestOptions = state.requestOptions || {}; if (options.abortSignal) { requestOptions.abortSignal = options.abortSignal; } diff --git a/sdk/keyvault/keyvault-admin/src/lro/backup/poller.ts b/sdk/keyvault/keyvault-admin/src/lro/backup/poller.ts index 401eaac6d388..6dd95d4280cd 100644 --- a/sdk/keyvault/keyvault-admin/src/lro/backup/poller.ts +++ b/sdk/keyvault/keyvault-admin/src/lro/backup/poller.ts @@ -50,11 +50,13 @@ export class BackupPoller extends Poller { const operation = makeBackupPollOperation({ ...state, - blobStorageUri, - sasToken, - requestOptions, - client, - vaultUrl + requestParameters: { + blobStorageUri, + sasToken, + requestOptions: requestOptions || {}, + client, + vaultUrl + } }); super(operation); diff --git a/sdk/keyvault/keyvault-admin/src/lro/restore/operation.ts b/sdk/keyvault/keyvault-admin/src/lro/restore/operation.ts index 232dd0d7a5ec..e9e39fe44e81 100644 --- a/sdk/keyvault/keyvault-admin/src/lro/restore/operation.ts +++ b/sdk/keyvault/keyvault-admin/src/lro/restore/operation.ts @@ -16,22 +16,6 @@ import { KeyVaultClientFullRestoreOperationResponse } from "../../generated/mode * An interface representing the publicly available properties of the state of a restore Key Vault's poll operation. */ export interface RestoreOperationState extends PollOperationState { - /** - * The base URL to the vault - */ - vaultUrl: string; - /** - * The URI of the blob storage account. - */ - blobStorageUri: string; - /** - * The SAS token. - */ - sasToken: string; - /** - * The Folder name of the blob where the previous successful full backup was stored. - */ - folderName: string; /** * Identifier for the full restore operation. */ @@ -52,6 +36,10 @@ export interface RestoreOperationState extends PollOperationState { * The end time of the restore operation in UTC */ endTime?: Date; + /** + * Internal request parameters + */ + requestParameters?: any; } /** @@ -59,30 +47,32 @@ export interface RestoreOperationState extends PollOperationState { * @internal */ export interface RestorePollOperationState extends PollOperationState { - /** - * Options for the core-http requests. - */ - requestOptions?: RequestOptionsBase; - /** - * An interface representing the internal KeyVaultClient. - */ - client?: KeyVaultClient; - /** - * The base URL to the vault - */ - vaultUrl: string; - /** - * The URI of the blob storage account. - */ - blobStorageUri: string; - /** - * The SAS token. - */ - sasToken: string; - /** - * The Folder name of the blob where the previous successful full backup was stored - */ - folderName: string; + requestParameters?: { + /** + * Options for the core-http requests. + */ + requestOptions: RequestOptionsBase; + /** + * An interface representing the internal KeyVaultClient. + */ + client: KeyVaultClient; + /** + * The base URL to the vault. + */ + vaultUrl: string; + /** + * The URI of the blob storage account. + */ + blobStorageUri: string; + /** + * The SAS token. + */ + sasToken: string; + /** + * The Folder name of the blob where the previous successful full backup was stored + */ + folderName: string; + }; /** * The id returned as part of the restore request */ @@ -163,13 +153,15 @@ async function update( } = {} ): Promise { const state = this.state; - const { vaultUrl, blobStorageUri, sasToken, folderName } = state; - - // Internal properties, - // the reference is only potentially undefined in the public representation of the poller. - const client = state.client!; + const { + client, + requestOptions, + vaultUrl, + blobStorageUri, + sasToken, + folderName + } = state.requestParameters!; - const requestOptions = state.requestOptions || {}; if (options.abortSignal) { requestOptions.abortSignal = options.abortSignal; } diff --git a/sdk/keyvault/keyvault-admin/src/lro/restore/poller.ts b/sdk/keyvault/keyvault-admin/src/lro/restore/poller.ts index 8f3aba696c02..f85ba7f51951 100644 --- a/sdk/keyvault/keyvault-admin/src/lro/restore/poller.ts +++ b/sdk/keyvault/keyvault-admin/src/lro/restore/poller.ts @@ -1,9 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { delay } from "@azure/core-http"; +import { delay, RequestOptionsBase } from "@azure/core-http"; import { Poller } from "@azure/core-lro"; -import { BeginRestoreOptions } from "../.."; import { KeyVaultClient } from "../../generated/keyVaultClient"; import { RestoreOperationState, @@ -17,7 +16,7 @@ export interface RestorePollerOptions { blobStorageUri: string; sasToken: string; folderName: string; - requestOptions?: BeginRestoreOptions; + requestOptions?: RequestOptionsBase; intervalInMs?: number; resumeFrom?: string; } @@ -51,12 +50,14 @@ export class RestorePoller extends Poller const operation = makeRestorePollOperation({ ...state, - blobStorageUri, - sasToken, - folderName, - requestOptions, - client, - vaultUrl + requestParameters: { + blobStorageUri, + sasToken, + folderName, + requestOptions: requestOptions || {}, + client, + vaultUrl + } }); super(operation); @@ -78,10 +79,6 @@ export class RestorePoller extends Poller public getOperationState(): RestoreOperationState { const state: RestoreOperationState = this.operation.state; return { - vaultUrl: state.vaultUrl, - blobStorageUri: state.blobStorageUri, - sasToken: state.sasToken, - folderName: state.folderName, isStarted: state.isStarted, isCompleted: state.isCompleted, isCancelled: state.isCancelled, From 18f4e43d1cd2ae04ae63a926d161351e6780678a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Rodr=C3=ADguez?= Date: Wed, 9 Sep 2020 17:06:38 -0400 Subject: [PATCH 10/12] no need for requestParameters --- .../src/lro/backup/operation.ts | 48 +++++++------- .../keyvault-admin/src/lro/backup/poller.ts | 14 ++--- .../src/lro/restore/operation.ts | 63 ++++++++----------- .../keyvault-admin/src/lro/restore/poller.ts | 16 +++-- 4 files changed, 59 insertions(+), 82 deletions(-) diff --git a/sdk/keyvault/keyvault-admin/src/lro/backup/operation.ts b/sdk/keyvault/keyvault-admin/src/lro/backup/operation.ts index ee39c14d5af4..dd9f6a89ffe2 100644 --- a/sdk/keyvault/keyvault-admin/src/lro/backup/operation.ts +++ b/sdk/keyvault/keyvault-admin/src/lro/backup/operation.ts @@ -37,10 +37,6 @@ export interface BackupOperationState extends PollOperationState { * The end time of the backup operation in UTC */ endTime?: Date; - /** - * Internal request parameters - */ - requestParameters?: any; } /** @@ -48,28 +44,26 @@ export interface BackupOperationState extends PollOperationState { * @internal */ export interface BackupPollOperationState extends PollOperationState { - requestParameters?: { - /** - * Options for the core-http requests. - */ - requestOptions: RequestOptionsBase; - /** - * An interface representing the internal KeyVaultClient. - */ - client: KeyVaultClient; - /** - * The base URL to the vault. - */ - vaultUrl: string; - /** - * The URI of the blob storage account. - */ - blobStorageUri: string; - /** - * The SAS token. - */ - sasToken: string; - }; + /** + * Options for the core-http requests. + */ + requestOptions: RequestOptionsBase; + /** + * An interface representing the internal KeyVaultClient. + */ + client: KeyVaultClient; + /** + * The base URL to the vault. + */ + vaultUrl: string; + /** + * The URI of the blob storage account. + */ + blobStorageUri: string; + /** + * The SAS token. + */ + sasToken: string; /** * The id returned as part of the backup request */ @@ -150,7 +144,7 @@ async function update( } = {} ): Promise { const state = this.state; - const { requestOptions, vaultUrl, blobStorageUri, sasToken, client } = state.requestParameters!; + const { requestOptions, vaultUrl, blobStorageUri, sasToken, client } = state; if (options.abortSignal) { requestOptions.abortSignal = options.abortSignal; diff --git a/sdk/keyvault/keyvault-admin/src/lro/backup/poller.ts b/sdk/keyvault/keyvault-admin/src/lro/backup/poller.ts index 6dd95d4280cd..1fce9b8ed28b 100644 --- a/sdk/keyvault/keyvault-admin/src/lro/backup/poller.ts +++ b/sdk/keyvault/keyvault-admin/src/lro/backup/poller.ts @@ -24,7 +24,7 @@ export interface BackupPollerOptions { /** * Class that creates a poller that waits until the backup of a Key Vault ends up being generated. */ -export class BackupPoller extends Poller { +export class BackupPoller extends Poller { /** * Defines how much time the poller is going to wait before making a new request to the service. * @memberof BackupPoller @@ -50,13 +50,11 @@ export class BackupPoller extends Poller { const operation = makeBackupPollOperation({ ...state, - requestParameters: { - blobStorageUri, - sasToken, - requestOptions: requestOptions || {}, - client, - vaultUrl - } + blobStorageUri, + sasToken, + requestOptions: requestOptions || {}, + client, + vaultUrl }); super(operation); diff --git a/sdk/keyvault/keyvault-admin/src/lro/restore/operation.ts b/sdk/keyvault/keyvault-admin/src/lro/restore/operation.ts index e9e39fe44e81..c1ee80a5d689 100644 --- a/sdk/keyvault/keyvault-admin/src/lro/restore/operation.ts +++ b/sdk/keyvault/keyvault-admin/src/lro/restore/operation.ts @@ -36,10 +36,6 @@ export interface RestoreOperationState extends PollOperationState { * The end time of the restore operation in UTC */ endTime?: Date; - /** - * Internal request parameters - */ - requestParameters?: any; } /** @@ -47,32 +43,30 @@ export interface RestoreOperationState extends PollOperationState { * @internal */ export interface RestorePollOperationState extends PollOperationState { - requestParameters?: { - /** - * Options for the core-http requests. - */ - requestOptions: RequestOptionsBase; - /** - * An interface representing the internal KeyVaultClient. - */ - client: KeyVaultClient; - /** - * The base URL to the vault. - */ - vaultUrl: string; - /** - * The URI of the blob storage account. - */ - blobStorageUri: string; - /** - * The SAS token. - */ - sasToken: string; - /** - * The Folder name of the blob where the previous successful full backup was stored - */ - folderName: string; - }; + /** + * Options for the core-http requests. + */ + requestOptions: RequestOptionsBase; + /** + * An interface representing the internal KeyVaultClient. + */ + client: KeyVaultClient; + /** + * The base URL to the vault. + */ + vaultUrl: string; + /** + * The URI of the blob storage account. + */ + blobStorageUri: string; + /** + * The SAS token. + */ + sasToken: string; + /** + * The Folder name of the blob where the previous successful full backup was stored + */ + folderName: string; /** * The id returned as part of the restore request */ @@ -153,14 +147,7 @@ async function update( } = {} ): Promise { const state = this.state; - const { - client, - requestOptions, - vaultUrl, - blobStorageUri, - sasToken, - folderName - } = state.requestParameters!; + const { client, requestOptions, vaultUrl, blobStorageUri, sasToken, folderName } = state; if (options.abortSignal) { requestOptions.abortSignal = options.abortSignal; diff --git a/sdk/keyvault/keyvault-admin/src/lro/restore/poller.ts b/sdk/keyvault/keyvault-admin/src/lro/restore/poller.ts index f85ba7f51951..f7add6f11f04 100644 --- a/sdk/keyvault/keyvault-admin/src/lro/restore/poller.ts +++ b/sdk/keyvault/keyvault-admin/src/lro/restore/poller.ts @@ -24,7 +24,7 @@ export interface RestorePollerOptions { /** * Class that creates a poller that waits until a Key Vault ends up being restored. */ -export class RestorePoller extends Poller { +export class RestorePoller extends Poller { /** * Defines how much time the poller is going to wait before making a new request to the service. * @memberof RestorePoller @@ -50,14 +50,12 @@ export class RestorePoller extends Poller const operation = makeRestorePollOperation({ ...state, - requestParameters: { - blobStorageUri, - sasToken, - folderName, - requestOptions: requestOptions || {}, - client, - vaultUrl - } + blobStorageUri, + sasToken, + folderName, + requestOptions: requestOptions || {}, + client, + vaultUrl }); super(operation); From fd05a52ede9bf66a5e8fcc7675185bf7d1927c9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Rodr=C3=ADguez?= Date: Wed, 9 Sep 2020 17:12:03 -0400 Subject: [PATCH 11/12] no need for requestParameters, and some cleanup on the pollers --- .../review/keyvault-admin.api.md | 33 +++++++++++++++++-- .../keyvault-admin/src/backupClient.ts | 13 +++++--- .../src/lro/selectiveRestore/operation.ts | 24 ++------------ .../src/lro/selectiveRestore/poller.ts | 9 ++--- 4 files changed, 43 insertions(+), 36 deletions(-) diff --git a/sdk/keyvault/keyvault-admin/review/keyvault-admin.api.md b/sdk/keyvault/keyvault-admin/review/keyvault-admin.api.md index 46a93d0504a9..9c5b309d7985 100644 --- a/sdk/keyvault/keyvault-admin/review/keyvault-admin.api.md +++ b/sdk/keyvault/keyvault-admin/review/keyvault-admin.api.md @@ -20,6 +20,15 @@ export interface BackupClientOptions extends coreHttp.PipelineOptions { serviceVersion?: SUPPORTED_API_VERSIONS; } +// @public +export interface BackupOperationState extends PollOperationState { + endTime?: Date; + jobId?: string; + startTime?: Date; + status?: string; + statusDetails?: string; +} + // @public export interface BackupPollerOptions extends coreHttp.OperationOptions { intervalInMs?: number; @@ -64,9 +73,9 @@ export class KeyVaultAccessControlClient { // @public export class KeyVaultBackupClient { constructor(vaultUrl: string, credential: TokenCredential, pipelineOptions?: BackupClientOptions); - beginBackup(blobStorageUri: string, sasToken: string, options?: BeginBackupOptions): Promise, string>>; - beginRestore(blobStorageUri: string, sasToken: string, folderName: string, options?: BeginRestoreOptions): Promise, undefined>>; - beginSelectiveRestore(blobStorageUri: string, sasToken: string, folderName: string, keyName: string, options?: BeginBackupOptions): Promise, undefined>>; + beginBackup(blobStorageUri: string, sasToken: string, options?: BeginBackupOptions): Promise>; + beginRestore(blobStorageUri: string, sasToken: string, folderName: string, options?: BeginRestoreOptions): Promise>; + beginSelectiveRestore(blobStorageUri: string, sasToken: string, folderName: string, keyName: string, options?: BeginBackupOptions): Promise>; readonly vaultUrl: string; } @@ -132,12 +141,30 @@ export interface ListRoleDefinitionsPageSettings { continuationToken?: string; } +// @public +export interface RestoreOperationState extends PollOperationState { + endTime?: Date; + jobId?: string; + startTime?: Date; + status?: string; + statusDetails?: string; +} + // @public export type RoleAssignmentScope = "/" | "/keys" | string; // @public export const SDK_VERSION: string; +// @public +export interface SelectiveRestoreOperationState extends PollOperationState { + endTime?: Date; + jobId?: string; + startTime?: Date; + status?: string; + statusDetails?: string; +} + // @public export type SUPPORTED_API_VERSIONS = "7.2-preview"; diff --git a/sdk/keyvault/keyvault-admin/src/backupClient.ts b/sdk/keyvault/keyvault-admin/src/backupClient.ts index 8228b14e12d4..bacd3cd98b61 100644 --- a/sdk/keyvault/keyvault-admin/src/backupClient.ts +++ b/sdk/keyvault/keyvault-admin/src/backupClient.ts @@ -7,7 +7,7 @@ import { signingPolicy, TokenCredential } from "@azure/core-http"; -import { PollerLike, PollOperationState } from "@azure/core-lro"; +import { PollerLike } from "@azure/core-lro"; import { challengeBasedAuthenticationPolicy } from "../../keyvault-common"; import { KeyVaultClient } from "./generated/keyVaultClient"; @@ -17,6 +17,11 @@ import { logger } from "./log"; import { BackupPoller } from "./lro/backup/poller"; import { RestorePoller } from "./lro/restore/poller"; import { SelectiveRestorePoller } from "./lro/selectiveRestore/poller"; +import { BackupOperationState } from "./lro/backup/operation"; +import { RestoreOperationState } from "./lro/restore/operation"; +import { SelectiveRestoreOperationState } from "./lro/selectiveRestore/operation"; + +export { BackupOperationState, RestoreOperationState, SelectiveRestoreOperationState }; /** * The KeyVaultBackupClient provides methods to generate backups @@ -135,7 +140,7 @@ export class KeyVaultBackupClient { blobStorageUri: string, sasToken: string, options: BeginBackupOptions = {} - ): Promise, string>> { + ): Promise> { if (!(blobStorageUri && sasToken)) { throw new Error( "beginBackup requires non-empty strings for the parameters: blobStorageUri and sasToken." @@ -197,7 +202,7 @@ export class KeyVaultBackupClient { sasToken: string, folderName: string, options: BeginRestoreOptions = {} - ): Promise, undefined>> { + ): Promise> { if (!(blobStorageUri && sasToken && folderName)) { throw new Error( "beginRestore requires non-empty strings for the parameters: blobStorageUri, sasToken and folderName." @@ -262,7 +267,7 @@ export class KeyVaultBackupClient { folderName: string, keyName: string, options: BeginBackupOptions = {} - ): Promise, undefined>> { + ): Promise> { if (!(keyName && blobStorageUri && sasToken && folderName)) { throw new Error( "beginSelectiveRestore requires non-empty strings for the parameters: keyName, blobStorageUri, sasToken and folderName." diff --git a/sdk/keyvault/keyvault-admin/src/lro/selectiveRestore/operation.ts b/sdk/keyvault/keyvault-admin/src/lro/selectiveRestore/operation.ts index 476c211f3309..052218778e37 100644 --- a/sdk/keyvault/keyvault-admin/src/lro/selectiveRestore/operation.ts +++ b/sdk/keyvault/keyvault-admin/src/lro/selectiveRestore/operation.ts @@ -20,26 +20,6 @@ import { createSpan, setParentSpan } from "../../tracing"; * An interface representing the publicly available properties of the state of a restore Key Vault's poll operation. */ export interface SelectiveRestoreOperationState extends PollOperationState { - /** - * The base URL to the vault - */ - vaultUrl: string; - /** - * The name of a Key Vault Key. - */ - keyName: string; - /** - * The URI of the blob storage account. - */ - blobStorageUri: string; - /** - * The SAS token. - */ - sasToken: string; - /** - * The Folder name of the blob where the previous successful full backup was stored. - */ - folderName: string; /** * Identifier for the full restore operation. */ @@ -70,11 +50,11 @@ export interface SelectiveRestorePollOperationState extends PollOperationState { +export class SelectiveRestorePoller extends Poller { /** * Defines how much time the poller is going to wait before making a new request to the service. * @memberof SelectiveRestorePoller @@ -57,7 +57,7 @@ export class SelectiveRestorePoller extends Poller Date: Wed, 9 Sep 2020 17:42:56 -0400 Subject: [PATCH 12/12] Addressed https://github.com/Azure/azure-sdk-for-js/pull/11009#discussion_r485232118 --- .../keyvault-admin/src/lro/backup/operation.ts | 12 ++---------- .../keyvault-admin/src/lro/restore/operation.ts | 12 ++---------- .../src/lro/selectiveRestore/operation.ts | 12 ++---------- 3 files changed, 6 insertions(+), 30 deletions(-) diff --git a/sdk/keyvault/keyvault-admin/src/lro/backup/operation.ts b/sdk/keyvault/keyvault-admin/src/lro/backup/operation.ts index dd9f6a89ffe2..3c06ea0b6639 100644 --- a/sdk/keyvault/keyvault-admin/src/lro/backup/operation.ts +++ b/sdk/keyvault/keyvault-admin/src/lro/backup/operation.ts @@ -100,15 +100,11 @@ async function fullBackup( options: KeyVaultClientFullBackupOptionalParams ): Promise { const span = createSpan("generatedClient.fullBackup", options); - - let response: KeyVaultClientFullBackupResponse; try { - response = await client.fullBackup(vaultUrl, setParentSpan(span, options)); + return await client.fullBackup(vaultUrl, setParentSpan(span, options)); } finally { span.end(); } - - return response; } /** @@ -121,15 +117,11 @@ async function fullBackupStatus( options: BeginBackupOptions ): Promise { const span = createSpan("generatedClient.fullBackupStatus", options); - - let response: KeyVaultClientFullBackupStatusResponse; try { - response = await client.fullBackupStatus(vaultUrl, jobId, setParentSpan(span, options)); + return await client.fullBackupStatus(vaultUrl, jobId, setParentSpan(span, options)); } finally { span.end(); } - - return response; } /** diff --git a/sdk/keyvault/keyvault-admin/src/lro/restore/operation.ts b/sdk/keyvault/keyvault-admin/src/lro/restore/operation.ts index c1ee80a5d689..b8d5d8716a42 100644 --- a/sdk/keyvault/keyvault-admin/src/lro/restore/operation.ts +++ b/sdk/keyvault/keyvault-admin/src/lro/restore/operation.ts @@ -103,15 +103,11 @@ async function fullRestore( options: KeyVaultClientFullRestoreOperationOptionalParams ): Promise { const span = createSpan("generatedClient.fullRestore", options); - - let response: KeyVaultClientFullRestoreOperationResponse; try { - response = await client.fullRestoreOperation(vaultUrl, setParentSpan(span, options)); + return await client.fullRestoreOperation(vaultUrl, setParentSpan(span, options)); } finally { span.end(); } - - return response; } /** @@ -124,15 +120,11 @@ async function fullBackupStatus( options: OperationOptions ): Promise { const span = createSpan("generatedClient.fullBackupStatus", options); - - let response: KeyVaultClientFullBackupStatusResponse; try { - response = await client.fullBackupStatus(vaultUrl, jobId, setParentSpan(span, options)); + return await client.fullBackupStatus(vaultUrl, jobId, setParentSpan(span, options)); } finally { span.end(); } - - return response; } /** diff --git a/sdk/keyvault/keyvault-admin/src/lro/selectiveRestore/operation.ts b/sdk/keyvault/keyvault-admin/src/lro/selectiveRestore/operation.ts index 052218778e37..55de83fc770e 100644 --- a/sdk/keyvault/keyvault-admin/src/lro/selectiveRestore/operation.ts +++ b/sdk/keyvault/keyvault-admin/src/lro/selectiveRestore/operation.ts @@ -114,10 +114,8 @@ async function selectiveRestore( ): Promise { const requestOptions = operationOptionsToRequestOptionsBase(options); const span = createSpan("generatedClient.selectiveRestore", requestOptions); - - let response: KeyVaultClientSelectiveKeyRestoreOperationResponse; try { - response = await client.selectiveKeyRestoreOperation( + return await client.selectiveKeyRestoreOperation( vaultUrl, keyName, setParentSpan(span, requestOptions) @@ -125,8 +123,6 @@ async function selectiveRestore( } finally { span.end(); } - - return response; } /** @@ -140,15 +136,11 @@ async function fullRestoreStatus( ): Promise { const requestOptions = operationOptionsToRequestOptionsBase(options); const span = createSpan("generatedClient.fullRestoreStatus", requestOptions); - - let response: KeyVaultClientFullBackupStatusResponse; try { - response = await client.fullBackupStatus(vaultUrl, jobId, options); + return await client.fullBackupStatus(vaultUrl, jobId, options); } finally { span.end(); } - - return response; } /**