Samples & readmes (#2744)

* samples

* readme1

* rename misnamed type, readmes

* readmes, first pass, no links

* undo some uneeded changes

* PR comments
This commit is contained in:
George Arama 2021-08-16 19:41:56 -07:00 committed by GitHub
parent 68100a543c
commit 512ae655b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 1110 additions and 86 deletions

View File

@ -78,7 +78,7 @@ if(BUILD_TESTING)
endif()
add_subdirectory(test/ut)
add_subdirectory(test/sample)
add_subdirectory(test/test-app)
endif()
if (BUILD_PERFORMANCE_TESTS)
@ -86,7 +86,7 @@ if (BUILD_PERFORMANCE_TESTS)
endif()
if(BUILD_SAMPLES)
#add_subdirectory(test/samples)
add_subdirectory(test/samples)
endif()
az_vcpkg_export(

View File

@ -1,4 +1,3 @@
#to be edited to something more useful before first release
# Azure Security Keyvault Secrets Package client library for C++
Azure Security Keyvault Secrets Package client library for C++ (`azure-security-keyvault-secrets`) matches necessary patterns that the development team has established to create a unified SDK written in the C++ programming language. These libraries follow the Azure SDK Design Guidelines for C++.
@ -7,23 +6,176 @@ The library allows client libraries to expose common functionality in a consiste
## Getting started
For a rich example of a well formatted readme, please check [here.](https://github.com/Azure/azure-sdk/blob/main/docs/policies/README-TEMPLATE.md) In addition, this is an [example readme](https://github.com/Azure/azure-sdk/blob/main/docs/policies/README-EXAMPLE.md) that should be emulated. Note that the top-level sections in this template align with that of the [template.](https://github.com/Azure/azure-sdk/blob/main/docs/policies/README-TEMPLATE.md)
### Install the package
Install the Azure Key Vault secrets client library for C++ with vcpkg:
# Key concepts
```cmd
vcpkg install azure-security-keyvault-secrets-cpp
```
Bullet point list of your library's main concepts.
### Prerequisites
* An [Azure subscription][azure_sub].
* An existing Azure Key Vault. If you need to create an Azure Key Vault, you can use the Azure Portal or [Azure CLI][azure_cli].
# Examples
If you use the Azure CLI, replace `<your-resource-group-name>` and `<your-key-vault-name>` with your own, unique names:
Examples of some of the key concepts for your library.
```PowerShell
az keyvault create --resource-group <your-resource-group-name> --name <your-key-vault-name>
```
# Troubleshooting
## Key concepts
### SecretClient
`SecretClient` provides synchronous operations exists in the SDK. Once you've initialized a `SecretClient`, you can interact with the primary resource types in Azure Key Vault.
### Thread safety
We guarantee that all client instance methods are thread-safe and independent of each other ([guideline](https://azure.github.io/azure-sdk/cpp_introduction.html#thread-safety)). This ensures that the recommendation of reusing client instances is always safe, even across threads.
### Additional concepts
<!-- CLIENT COMMON BAR -->
[Replaceable HTTP transport adapter](https://github.com/Azure/azure-sdk-for-cpp/tree/main/sdk/core/azure-core#http-transport-adapter) |
[Long-running operations](https://github.com/Azure/azure-sdk-for-cpp/tree/main/sdk/core/azure-core#long-running-operations) |
<!-- CLIENT COMMON BAR -->
## Examples
For detailed samples please review the samples provided.
### Create a client
First step is to create a SecretClient.
```cpp Snippet:SecretSample1CreateCredential
auto tenantId = std::getenv("AZURE_TENANT_ID");
auto clientId = std::getenv("AZURE_CLIENT_ID");
auto clientSecret = std::getenv("AZURE_CLIENT_SECRET");
auto credential = std::make_shared<Azure::Identity::ClientSecretCredential>(tenantId, clientId, clientSecret);
// create client
SecretClient secretClient(std::getenv("AZURE_KEYVAULT_URL"), credential);
```
### Create a secret
We call the secret client to create a secret.
```cpp Snippet:SecretSample1SetSecret
std::string secretName("MySampleSecret");
std::string secretValue("my secret value");
secretClient.SetSecret(secretName, secretValue);
```
### Get a secret
We retrieve a secret by name.
```cpp Snippet:SecretSample1GetSecret
// get secret
Secret secret = secretClient.GetSecret(secretName).Value;
std::cout << "Secret is returned with name " << secret.Name << " and value " << secret.Value
<< std::endl;
```
### Update a secret
Updating an existing secret
```cpp Snippet:SecretSample1UpdateSecretProperties
// change one of the properties
secret.Properties.ContentType = "my content";
// update the secret
Secret updatedSecret = secretClient.UpdateSecretProperties(secret.Name, secret.Properties.Version, secret.Properties)
.Value;
std::cout << "Secret's content type is now " << updatedSecret.Properties.ContentType.Value()
<< std::endl;
```
### Delete a secret
Delete an existing secret.
```cpp Snippet:SecretSample1DeleteSecret
// start deleting the secret
DeleteSecretOperation operation = secretClient.StartDeleteSecret(secret.Name);
```
### Delete and purge a secret
Delete and Purge a secret.
```cpp Snippet:SecretSample1DeleteSecret
// start deleting the secret
DeleteSecretOperation operation = secretClient.StartDeleteSecret(secret.Name);
// You only need to wait for completion if you want to purge or recover the secret.
operation.PollUntilDone(std::chrono::milliseconds(2000));
// purge the deleted secret
secretClient.PurgeDeletedSecret(secret.Name);
```
### List Secrets
List all the secrets in keyvault.
```cpp Snippet:SecretSample4ListAllSecrets
// get properties of secrets
for (auto secrets = secretClient.GetPropertiesOfSecrets(); secrets.HasPage(); secrets.MoveToNextPage())
{ // go through every secret of each page returned
for (auto const& secret : secrets.Items)
{
std::cout << "Found Secret with name: " << secret.Name << std::endl;
}
}
```
## Troubleshooting
When you interact with the Azure Key Vault Secrets client library using the C++ SDK, errors returned by the service correspond to the same HTTP status codes returned for requests.
For example, if you try to retrieve a key that doesn't exist in your Azure Key Vault, a `404` error is returned, indicating "Not Found".
```cpp
try
{
Secret secret = client.GetSecret("some_secret").Value;
}
catch (const Azure::Core::RequestFailedException& ex)
{
std::cout << std::underlying_type<Azure::Core::Http::HttpStatusCode>::type(ex.StatusCode);
}
```
You will notice that additional information is logged, like the client request ID of the operation.
Running into issues? This section should contain details as to what to do there.
# Next steps
More sample code should go here, along with links out to the appropriate example tests.
Several Azure Key Vault secrets client library samples are available to you in this GitHub repository. These samples provide example code for additional scenarios commonly encountered while working with Azure Key Vault:
* Sample1-Basic-Operations:
* Create a secret
* Get a secret
* Update a secret
* Delete and Purge a secret
* Sample2-Backup-Restore
* Backup a secret
* Restore a deleted secret
* Sample3-Delete-Recover
* Delete a secret
* Recover a deleted Secret
* Sample4-Get-Secrets-Deleted
* List all secrets
* List all of a secrets versions
* List all deletes secrets
* Get properties of a deleted secret
## Contributing
For details on contributing to this repository, see the [contributing guide][azure_sdk_for_cpp_contributing].

View File

@ -20,7 +20,7 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Secrets {
/**
* @brief Represents a long running operation to restore a deleted secret.
*/
class RestoreDeletedSecretOperation final : public Azure::Core::Operation<Secret> {
class RecoverDeletedSecretOperation final : public Azure::Core::Operation<Secret> {
private:
friend class SecretClient;
@ -41,11 +41,11 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Secrets {
*
* Since C++ doesn't offer `internal` access, we use friends-only instead.
*/
RestoreDeletedSecretOperation(
RecoverDeletedSecretOperation(
std::shared_ptr<SecretClient> secretClient,
Azure::Response<Secret> response);
RestoreDeletedSecretOperation(
RecoverDeletedSecretOperation(
std::string resumeToken,
std::shared_ptr<SecretClient> secretClient);
@ -75,7 +75,7 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Secrets {
std::string GetResumeToken() const override { return m_continuationToken; }
/**
* @brief Create a #RestoreDeletedSecretOperation from the \p resumeToken fetched from
* @brief Create a #RecoverDeletedSecretOperation from the \p resumeToken fetched from
* another `Operation<T>`, updated to the the latest operation status.
*
* @remark After the operation is initialized, it is used to poll the last update from the
@ -85,9 +85,9 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Secrets {
* operation.
* @param client A #secretClient that is used for getting status updates.
* @param context A #Azure::Core::Context controlling the request lifetime.
* @return RestoreDeletedSecretOperation
* @return RecoverDeletedSecretOperation
*/
static RestoreDeletedSecretOperation CreateFromResumeToken(
static RecoverDeletedSecretOperation CreateFromResumeToken(
std::string const& resumeToken,
SecretClient const& client,
Azure::Core::Context const& context = Azure::Core::Context());

View File

@ -23,10 +23,11 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Secrets {
* @brief Define a single page to list the secrets from the Key Vault.
*
*/
class SecretPropertiesPagedResponse final : public Azure::Core::PagedResponse<SecretProperties> {
class SecretPropertiesPagedResponse final
: public Azure::Core::PagedResponse<SecretPropertiesPagedResponse> {
private:
friend class SecretClient;
friend class Azure::Core::PagedResponse<SecretProperties>;
friend class Azure::Core::PagedResponse<SecretPropertiesPagedResponse>;
std::string m_secretName;
std::shared_ptr<SecretClient> m_secretClient;

View File

@ -239,7 +239,7 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Secrets {
* @param name The name of the secret.
* @param context The context for the operation can be used for request cancellation.
*/
Azure::Security::KeyVault::Secrets::RestoreDeletedSecretOperation StartRecoverDeletedSecret(
Azure::Security::KeyVault::Secrets::RecoverDeletedSecretOperation StartRecoverDeletedSecret(
std::string const& name,
Azure::Core::Context const& context = Azure::Core::Context()) const;

View File

@ -9,9 +9,8 @@
#include "azure/keyvault/secrets/keyvault_operations.hpp"
#include "azure/keyvault/secrets/secret_client.hpp"
#include "private/secret_serializers.hpp"
// RestoreDeletedSecretOperation
Azure::Response<Secret> RestoreDeletedSecretOperation::PollUntilDoneInternal(
Azure::Response<Secret> RecoverDeletedSecretOperation::PollUntilDoneInternal(
std::chrono::milliseconds period,
Azure::Core::Context& context)
{
@ -30,46 +29,44 @@ Azure::Response<Secret> RestoreDeletedSecretOperation::PollUntilDoneInternal(
m_value, std::make_unique<Azure::Core::Http::RawResponse>(*m_rawResponse));
}
std::unique_ptr<Azure::Core::Http::RawResponse> RestoreDeletedSecretOperation::PollInternal(
std::unique_ptr<Azure::Core::Http::RawResponse> RecoverDeletedSecretOperation::PollInternal(
Azure::Core::Context const& context)
{
std::unique_ptr<Azure::Core::Http::RawResponse> rawResponse;
if (IsDone())
try
{
try
{
rawResponse
= m_secretClient->GetSecret(m_value.Name, GetSecretOptions(), context).RawResponse;
}
catch (Azure::Core::RequestFailedException& error)
{
rawResponse = std::move(error.RawResponse);
}
switch (rawResponse->GetStatusCode())
{
case Azure::Core::Http::HttpStatusCode::Ok:
case Azure::Core::Http::HttpStatusCode::Forbidden: {
m_status = Azure::Core::OperationStatus::Succeeded;
break;
}
case Azure::Core::Http::HttpStatusCode::NotFound: {
m_status = Azure::Core::OperationStatus::Running;
break;
}
default:
throw Azure::Core::RequestFailedException(rawResponse);
}
if (m_status == Azure::Core::OperationStatus::Succeeded)
{
m_value = _detail::SecretSerializer::Deserialize(m_value.Name, *rawResponse);
}
rawResponse = m_secretClient->GetSecret(m_value.Name, GetSecretOptions(), context).RawResponse;
}
catch (Azure::Core::RequestFailedException& error)
{
rawResponse = std::move(error.RawResponse);
}
switch (rawResponse->GetStatusCode())
{
case Azure::Core::Http::HttpStatusCode::Ok:
case Azure::Core::Http::HttpStatusCode::Forbidden: {
m_status = Azure::Core::OperationStatus::Succeeded;
break;
}
case Azure::Core::Http::HttpStatusCode::NotFound: {
m_status = Azure::Core::OperationStatus::Running;
break;
}
default:
throw Azure::Core::RequestFailedException(rawResponse);
}
if (m_status == Azure::Core::OperationStatus::Succeeded)
{
m_value = _detail::SecretSerializer::Deserialize(m_value.Name, *rawResponse);
}
return rawResponse;
}
RestoreDeletedSecretOperation::RestoreDeletedSecretOperation(
RecoverDeletedSecretOperation::RecoverDeletedSecretOperation(
std::shared_ptr<SecretClient> secretClient,
Azure::Response<Secret> response)
: m_secretClient(secretClient)
@ -86,7 +83,7 @@ RestoreDeletedSecretOperation::RestoreDeletedSecretOperation(
}
}
RestoreDeletedSecretOperation::RestoreDeletedSecretOperation(
RecoverDeletedSecretOperation::RecoverDeletedSecretOperation(
std::string resumeToken,
std::shared_ptr<SecretClient> secretClient)
: m_secretClient(secretClient), m_continuationToken(std::move(resumeToken))
@ -94,16 +91,16 @@ RestoreDeletedSecretOperation::RestoreDeletedSecretOperation(
m_value.Name = resumeToken;
}
RestoreDeletedSecretOperation RestoreDeletedSecretOperation::CreateFromResumeToken(
RecoverDeletedSecretOperation RecoverDeletedSecretOperation::CreateFromResumeToken(
std::string const& resumeToken,
SecretClient const& client,
Azure::Core::Context const& context)
{
RestoreDeletedSecretOperation operation(resumeToken, std::make_shared<SecretClient>(client));
RecoverDeletedSecretOperation operation(resumeToken, std::make_shared<SecretClient>(client));
operation.Poll(context);
return operation;
}
// DeleteSecretOperation
Azure::Response<DeletedSecret> DeleteSecretOperation::PollUntilDoneInternal(
std::chrono::milliseconds period,
Azure::Core::Context& context)
@ -126,36 +123,34 @@ std::unique_ptr<Azure::Core::Http::RawResponse> DeleteSecretOperation::PollInter
Azure::Core::Context const& context)
{
std::unique_ptr<Azure::Core::Http::RawResponse> rawResponse;
if (!IsDone())
try
{
try
{
rawResponse = m_secretClient->GetDeletedSecret(m_value.Name, context).RawResponse;
}
catch (Azure::Core::RequestFailedException& error)
{
rawResponse = std::move(error.RawResponse);
}
rawResponse = m_secretClient->GetDeletedSecret(m_value.Name, context).RawResponse;
}
catch (Azure::Core::RequestFailedException& error)
{
rawResponse = std::move(error.RawResponse);
}
switch (rawResponse->GetStatusCode())
{
case Azure::Core::Http::HttpStatusCode::Ok:
case Azure::Core::Http::HttpStatusCode::Forbidden: {
m_status = Azure::Core::OperationStatus::Succeeded;
break;
}
case Azure::Core::Http::HttpStatusCode::NotFound: {
m_status = Azure::Core::OperationStatus::Running;
break;
}
default:
throw Azure::Core::RequestFailedException(rawResponse);
switch (rawResponse->GetStatusCode())
{
case Azure::Core::Http::HttpStatusCode::Ok:
case Azure::Core::Http::HttpStatusCode::Forbidden: {
m_status = Azure::Core::OperationStatus::Succeeded;
break;
}
case Azure::Core::Http::HttpStatusCode::NotFound: {
m_status = Azure::Core::OperationStatus::Running;
break;
}
default:
throw Azure::Core::RequestFailedException(rawResponse);
}
if (m_status == Azure::Core::OperationStatus::Succeeded)
{
m_value = _detail::DeletedSecretSerializer::Deserialize(m_value.Name, *rawResponse);
}
if (m_status == Azure::Core::OperationStatus::Succeeded)
{
m_value = _detail::DeletedSecretSerializer::Deserialize(m_value.Name, *rawResponse);
}
return rawResponse;
}

View File

@ -209,10 +209,10 @@ Azure::Security::KeyVault::Secrets::DeleteSecretOperation SecretClient::StartDel
{_detail::SecretPath, name}));
}
Azure::Security::KeyVault::Secrets::RestoreDeletedSecretOperation SecretClient::
Azure::Security::KeyVault::Secrets::RecoverDeletedSecretOperation SecretClient::
StartRecoverDeletedSecret(std::string const& name, Azure::Core::Context const& context) const
{
return Azure::Security::KeyVault::Secrets::RestoreDeletedSecretOperation(
return Azure::Security::KeyVault::Secrets::RecoverDeletedSecretOperation(
std::make_shared<SecretClient>(*this),
m_protocolClient->SendRequest<Secret>(
context,

View File

@ -350,6 +350,7 @@ DeletedSecretPagedResponse DeletedSecretPagedResultSerializer::Deserialize(
DeletedSecret item;
item.Id = secretProperties[_detail::IdPropertyName].get<std::string>();
_detail::SecretSerializer::ParseIDUrl(item.Properties, item.Id);
item.Name = item.Properties.Name;
// Parse URL for the various attributes
if (secretProperties.contains(_detail::AttributesPropertyName))
{

View File

@ -0,0 +1,9 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# SPDX-License-Identifier: MIT
cmake_minimum_required (VERSION 3.13)
add_subdirectory(sample1-basic-operations)
add_subdirectory(sample2-backup-restore)
add_subdirectory(sample3-delete-recover)
add_subdirectory(sample4-get-secrets-deleted)

View File

@ -0,0 +1,15 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# SPDX-License-Identifier: MIT
cmake_minimum_required (VERSION 3.13)
project (sample1-basic-operations LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED True)
add_executable (
sample1-basic-operations
sample1-basic-operations.cpp
)
target_link_libraries(sample1-basic-operations PRIVATE azure-security-keyvault-secrets azure-identity)

View File

@ -0,0 +1,86 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @brief This sample provides the code implementation to use the Key Vault Secrets SDK client for
* C++ to create, get, update, delete and purge a secret.
*
* @remark The following environment variables must be set before running the sample.
* - AZURE_KEYVAULT_URL: To the Key Vault account URL.
* - AZURE_TENANT_ID: Tenant ID for the Azure account.
* - AZURE_CLIENT_ID: The Client ID to authenticate the request.
* - AZURE_CLIENT_SECRET: The client secret.
*
*/
#if defined(_MSC_VER)
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <azure/identity.hpp>
#include <azure/keyvault/keyvault_secrets.hpp>
#include <chrono>
#include <iostream>
using namespace Azure::Security::KeyVault::Secrets;
using namespace std::chrono_literals;
int main()
{
auto tenantId = std::getenv("AZURE_TENANT_ID");
auto clientId = std::getenv("AZURE_CLIENT_ID");
auto clientSecret = std::getenv("AZURE_CLIENT_SECRET");
auto credential
= std::make_shared<Azure::Identity::ClientSecretCredential>(tenantId, clientId, clientSecret);
// create client
SecretClient secretClient(std::getenv("AZURE_KEYVAULT_URL"), credential);
std::string secretName("MySampleSecret");
std::string secretValue("my secret value");
try
{
// create secret
secretClient.SetSecret(secretName, secretValue);
// get secret
Secret secret = secretClient.GetSecret(secretName).Value;
std::cout << "Secret is returned with name " << secret.Name << " and value " << secret.Value
<< std::endl;
// change one of the properties
secret.Properties.ContentType = "my content";
// update the secret
Secret updatedSecret
= secretClient
.UpdateSecretProperties(secret.Name, secret.Properties.Version, secret.Properties)
.Value;
std::cout << "Secret's content type is now " << updatedSecret.Properties.ContentType.Value()
<< std::endl;
// start deleting the secret
DeleteSecretOperation operation = secretClient.StartDeleteSecret(secret.Name);
// You only need to wait for completion if you want to purge or recover the secret.
operation.PollUntilDone(2s);
// purge the deleted secret
secretClient.PurgeDeletedSecret(secret.Name);
}
catch (Azure::Core::Credentials::AuthenticationException const& e)
{
std::cout << "Authentication Exception happened:" << std::endl << e.what() << std::endl;
return 1;
}
catch (Azure::Core::RequestFailedException const& e)
{
std::cout << "Key Vault Secret Client Exception happened:" << std::endl
<< e.Message << std::endl;
return 1;
}
return 0;
}

View File

@ -0,0 +1,87 @@
# Creating, getting, updating, and deleting secrets
This sample demonstrates how to create, get, update, and delete and purge a secret in Azure Key Vault.
To get started, you'll need a URI to an Azure Key Vault.
## Creating a SecretClient
To create a new `SecretClient` to create, get, update, or delete secrets, you need the endpoint to an Azure Key Vault and credentials.
Key Vault Secrets client for C++ currently supports the `ClientSecretCredential` for authenticating.
In the sample below, you can create a credential by setting the Tenant ID, Client ID and Client Secret as environment variables.
```cpp Snippet:SecretSample1CreateCredential
auto tenantId = std::getenv("AZURE_TENANT_ID");
auto clientId = std::getenv("AZURE_CLIENT_ID");
auto clientSecret = std::getenv("AZURE_CLIENT_SECRET");
auto credential = std::make_shared<Azure::Identity::ClientSecretCredential>(tenantId, clientId, clientSecret);
```
Then, in the sample below, you can set `keyVaultUrl` based on an environment variable, configuration setting, or any way that works for your application.
```cpp Snippet:SecretSample1SecretClient
SecretClient secretClient(std::getenv("AZURE_KEYVAULT_URL"), credential);
```
## Creating a Secret
To create a secret all you need to set id the name and secret value.
```cpp Snippet:SecretSample1SetSecret
std::string secretName("MySampleSecret");
std::string secretValue("my secret value");
secretClient.SetSecret(secretName, secretValue);
```
## Getting a Secret
To get a secret from the keyvault you will need to call GetSecret.
```cpp Snippet:SecretSample1GetSecret
// get secret
Secret secret = secretClient.GetSecret(secretName).Value;
std::cout << "Secret is returned with name " << secret.Name << " and value " << secret.Value
<< std::endl;
```
## Updating secret properties
We forgot to set the content type for the secret we created, we can do that using the UpdateSecretProperties method.
```cpp Snippet:SecretSample1UpdateSecretProperties
// change one of the properties
secret.Properties.ContentType = "my content";
// update the secret
Secret updatedSecret = secretClient.UpdateSecretProperties(secret.Name, secret.Properties.Version, secret.Properties)
.Value;
std::cout << "Secret's content type is now " << updatedSecret.Properties.ContentType.Value()
<< std::endl;
```
## Deleting a secret
The secret is no longer needed so we need to delete it.
```cpp Snippet:SecretSample1DeleteSecret
// start deleting the secret
DeleteSecretOperation operation = secretClient.StartDeleteSecret(secret.Name);
```
## Purging a deleted key
If the Azure Key Vault is soft delete-enabled and you want to permanently delete the secret before its `ScheduledPurgeDate`, the secret needs to be purged.
```cpp Snippet:SecretSample1PurgeSecret
// You only need to wait for completion if you want to purge or recover the secret.
operation.PollUntilDone(2s);
// purge the deleted secret
secretClient.PurgeDeletedSecret(secret.Name);
```
## Source
[defaultazurecredential]: https://github.com/Azure/azure-sdk-for-cpp/blob/main/sdk/identity/azure-identity/README.md

View File

@ -0,0 +1,15 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# SPDX-License-Identifier: MIT
cmake_minimum_required (VERSION 3.13)
project (sample2-backup-restore LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED True)
add_executable (
sample2-backup-restore
sample2-backup-restore.cpp
)
target_link_libraries(sample2-backup-restore PRIVATE azure-security-keyvault-secrets azure-identity)

View File

@ -0,0 +1,127 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @brief This sample provides the code implementation to use the Key Vault Secrets SDK client for
* C++ to backup, restore, delete and purge a secret.
*
* @remark The following environment variables must be set before running the sample.
* - AZURE_KEYVAULT_URL: To the Key Vault account URL.
* - AZURE_TENANT_ID: Tenant ID for the Azure account.
* - AZURE_CLIENT_ID: The Client ID to authenticate the request.
* - AZURE_CLIENT_SECRET: The client secret.
*
*/
#if defined(_MSC_VER)
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <azure/identity.hpp>
#include <azure/keyvault/keyvault_secrets.hpp>
#include <chrono>
#include <fstream>
#include <iostream>
using namespace Azure::Security::KeyVault::Secrets;
using namespace std::chrono_literals;
void AssertSecretsEqual(Secret const& expected, Secret const& actual);
int main()
{
auto tenantId = std::getenv("AZURE_TENANT_ID");
auto clientId = std::getenv("AZURE_CLIENT_ID");
auto clientSecret = std::getenv("AZURE_CLIENT_SECRET");
auto credential
= std::make_shared<Azure::Identity::ClientSecretCredential>(tenantId, clientId, clientSecret);
// create client
SecretClient secretClient(std::getenv("AZURE_KEYVAULT_URL"), credential);
std::string secretName("MySampleSecret2");
std::string secretValue("my secret value");
try
{
// create secret
secretClient.SetSecret(secretName, secretValue);
// get secret
Secret secret = secretClient.GetSecret(secretName).Value;
std::cout << "Secret is returned with name " << secret.Name << " and value " << secret.Value
<< std::endl;
size_t backUpSize = 0;
{
std::cout << "\t-Backup Key" << std::endl;
auto backupSecretResult = secretClient.BackupSecret(secret.Name).Value;
auto const& backedupSecret = backupSecretResult.Secret;
backUpSize = backedupSecret.size();
// save data to file
std::cout << "\t-Save to file" << std::endl;
std::ofstream savedFile;
savedFile.open("backup.dat");
for (auto const& data : backedupSecret)
{
savedFile << data;
}
savedFile.close();
}
// start deleting the secret
DeleteSecretOperation operation = secretClient.StartDeleteSecret(secret.Name);
// You only need to wait for completion if you want to purge or recover the secret.
operation.PollUntilDone(2s);
// purge the deleted secret
secretClient.PurgeDeletedSecret(secret.Name);
// let's wait for one minute so we know the key was purged.
std::this_thread::sleep_for(60s);
// Restore the key from the file backup
std::cout << "\t-Read from file." << std::endl;
std::ifstream inFile;
inFile.open("backup.dat");
std::vector<uint8_t> inMemoryBackup(backUpSize);
inFile >> inMemoryBackup.data();
inFile.close();
std::cout << "\t-Restore Key" << std::endl;
auto restoredSecret = secretClient.RestoreSecretBackup(inMemoryBackup).Value;
AssertSecretsEqual(secret, restoredSecret);
operation = secretClient.StartDeleteSecret(restoredSecret.Name);
// You only need to wait for completion if you want to purge or recover the key.
operation.PollUntilDone(2s);
secretClient.PurgeDeletedSecret(restoredSecret.Name);
}
catch (Azure::Core::Credentials::AuthenticationException const& e)
{
std::cout << "Authentication Exception happened:" << std::endl << e.what() << std::endl;
return 1;
}
catch (Azure::Core::RequestFailedException const& e)
{
std::cout << "Key Vault Secret Client Exception happened:" << std::endl
<< e.Message << std::endl;
return 1;
}
return 0;
}
void AssertSecretsEqual(Secret const& expected, Secret const& actual)
{
#if defined(NDEBUG)
// Use (void) to silence unused warnings.
(void)expected;
(void)actual;
#endif
assert(expected.Name == actual.Name);
assert(expected.Properties.Version == actual.Properties.Version);
assert(expected.Id == actual.Id);
}

View File

@ -0,0 +1,92 @@
# Backup and Restore secrets
This sample demonstrates how to backup and restore in Azure Key Vault.
To get started, you'll need a URI to an Azure Key Vault.
## Creating a SecretClient
To create a new `SecretClient` to create, get, update, or delete secrets, you need the endpoint to an Azure Key Vault and credentials.
Key Vault Secrets client for C++ currently supports the `ClientSecretCredential` for authenticating.
In the sample below, you can create a credential by setting the Tenant ID, Client ID and Client Secret as environment variables.
```cpp Snippet:SecretSample2CreateCredential
auto tenantId = std::getenv("AZURE_TENANT_ID");
auto clientId = std::getenv("AZURE_CLIENT_ID");
auto clientSecret = std::getenv("AZURE_CLIENT_SECRET");
auto credential = std::make_shared<Azure::Identity::ClientSecretCredential>(tenantId, clientId, clientSecret);
```
Then, in the sample below, you can set `keyVaultUrl` based on an environment variable, configuration setting, or any way that works for your application.
```cpp Snippet:SecretSample2SecretClient
SecretClient secretClient(std::getenv("AZURE_KEYVAULT_URL"), credential);
```
## Creating a Secret
To create a secret all you need to set id the name and secret value.
```cpp Snippet:SecretSample2SetSecret
std::string secretName("MySampleSecret");
std::string secretValue("my secret value");
secretClient.SetSecret(secretName, secretValue);
```
## Getting a Secret
To get a secret from the keyvault you will need to call GetSecret.
```cpp Snippet:SecretSample2GetSecret
// get secret
Secret secret = secretClient.GetSecret(secretName).Value;
std::cout << "Secret is returned with name " << secret.Name << " and value " << secret.Value
<< std::endl;
```
## Creating a Backup for the secret properties
In order to get the backup of the secret we need to call BackupSecret, which will return a vector of bytes representing the backed up content.
```cpp Snippet:SecretSample2BackupSecret
std::cout << "\t-Backup Key" << std::endl;
std::vector<uint8_t> backupKey(secretClient.BackupSecret(secret.Name).Value.Secret);
backUpSize = backupKey.size();
```
## Deleting the secret in order to later restore it
The secret is no longer needed so we need to delete it.
```cpp Snippet:SecretSample2DeleteSecret
// start deleting the secret
DeleteSecretOperation operation = secretClient.StartDeleteSecret(secret.Name);
```
## Purging a deleted key
If the Azure Key Vault is soft delete-enabled and you want to permanently delete the secret before its `ScheduledPurgeDate`, the secret needs to be purged.
```cpp Snippet:SecretSample2PurgeSecret
// You only need to wait for completion if you want to purge or recover the secret.
operation.PollUntilDone(2s);
// purge the deleted secret
secretClient.PurgeDeletedSecret(secret.Name);
```
## Restoring a secret
In order to restore a secret we need to call RestoreSecretBackup api passing in the byte vector obtained at the previous(backup) step.
```cpp Snippet:SecretSample2RestoreSecret
std::cout << "\t-Restore Key" << std::endl;
auto restoredSecret = secretClient.RestoreSecretBackup(inMemoryBackup).Value;
```
## Source
[defaultazurecredential]: https://github.com/Azure/azure-sdk-for-cpp/blob/main/sdk/identity/azure-identity/README.md

View File

@ -0,0 +1,15 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# SPDX-License-Identifier: MIT
cmake_minimum_required (VERSION 3.13)
project (sample3-delete-recover LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED True)
add_executable (
sample3-delete-recover
sample3-delete-recover.cpp
)
target_link_libraries(sample3-delete-recover PRIVATE azure-security-keyvault-secrets azure-identity)

View File

@ -0,0 +1,102 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @brief This sample provides the code implementation to use the Key Vault Secrets SDK client for
* C++ to delete and restore a secret.
*
* @remark The following environment variables must be set before running the sample.
* - AZURE_KEYVAULT_URL: To the Key Vault account URL.
* - AZURE_TENANT_ID: Tenant ID for the Azure account.
* - AZURE_CLIENT_ID: The Client ID to authenticate the request.
* - AZURE_CLIENT_SECRET: The client secret.
*
*/
#if defined(_MSC_VER)
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <azure/identity.hpp>
#include <azure/keyvault/keyvault_secrets.hpp>
#include <chrono>
#include <iostream>
using namespace Azure::Security::KeyVault::Secrets;
using namespace std::chrono_literals;
void AssertSecretsEqual(Secret const& expected, Secret const& actual);
int main()
{
auto tenantId = std::getenv("AZURE_TENANT_ID");
auto clientId = std::getenv("AZURE_CLIENT_ID");
auto clientSecret = std::getenv("AZURE_CLIENT_SECRET");
auto credential
= std::make_shared<Azure::Identity::ClientSecretCredential>(tenantId, clientId, clientSecret);
// create client
SecretClient secretClient(std::getenv("AZURE_KEYVAULT_URL"), credential);
std::string secretName("MySampleSecret");
std::string secretValue("my secret value");
try
{
// create secret
secretClient.SetSecret(secretName, secretValue);
// get secret
Secret secret = secretClient.GetSecret(secretName).Value;
std::cout << "Secret is returned with name " << secret.Name << " and value " << secret.Value
<< std::endl;
// start deleting the secret
DeleteSecretOperation operation = secretClient.StartDeleteSecret(secret.Name);
// You only need to wait for completion if you want to purge or recover the secret.
operation.PollUntilDone(2s);
// call recover secret
RecoverDeletedSecretOperation recoverOperation
= secretClient.StartRecoverDeletedSecret(secret.Name);
// poll until done
Secret restoredSecret = recoverOperation.PollUntilDone(2s).Value;
AssertSecretsEqual(secret, restoredSecret);
// cleanup
// start deleting the secret
DeleteSecretOperation cleanupOperation = secretClient.StartDeleteSecret(restoredSecret.Name);
cleanupOperation.PollUntilDone(2s);
secretClient.PurgeDeletedSecret(restoredSecret.Name);
}
catch (Azure::Core::Credentials::AuthenticationException const& e)
{
std::cout << "Authentication Exception happened:" << std::endl << e.what() << std::endl;
return 1;
}
catch (Azure::Core::RequestFailedException const& e)
{
std::cout << "Key Vault Secret Client Exception happened:" << std::endl
<< e.Message << std::endl;
return 1;
}
return 0;
}
void AssertSecretsEqual(Secret const& expected, Secret const& actual)
{
#if defined(NDEBUG)
// Use (void) to silence unused warnings.
(void)expected;
(void)actual;
#endif
assert(expected.Name == actual.Name);
assert(expected.Properties.Version == actual.Properties.Version);
assert(expected.Id == actual.Id);
}

View File

@ -0,0 +1,71 @@
# Delete and recover deleted secrets
This sample demonstrates how to delete and recover a deleted secret in Azure Key Vault.
## Creating a SecretClient
To create a new `SecretClient` to create, get, update, or delete secrets, you need the endpoint to an Azure Key Vault and credentials.
Key Vault Secrets client for C++ currently supports the `ClientSecretCredential` for authenticating.
In the sample below, you can create a credential by setting the Tenant ID, Client ID and Client Secret as environment variables.
```cpp Snippet:SecretSample3CreateCredential
auto tenantId = std::getenv("AZURE_TENANT_ID");
auto clientId = std::getenv("AZURE_CLIENT_ID");
auto clientSecret = std::getenv("AZURE_CLIENT_SECRET");
auto credential = std::make_shared<Azure::Identity::ClientSecretCredential>(tenantId, clientId, clientSecret);
```
Then, in the sample below, you can set `keyVaultUrl` based on an environment variable, configuration setting, or any way that works for your application.
```cpp Snippet:SecretSample3SecretClient
SecretClient secretClient(std::getenv("AZURE_KEYVAULT_URL"), credential);
```
## Creating a Secret
To create a secret all you need to set id the name and secret value.
```cpp Snippet:SecretSample3SetSecret
std::string secretName("MySampleSecret");
std::string secretValue("my secret value");
secretClient.SetSecret(secretName, secretValue);
```
## Getting a Secret
To get a secret from the keyvault you will need to call GetSecret.
```cpp Snippet:SecretSample3GetSecret
// get secret
Secret secret = secretClient.GetSecret(secretName).Value;
std::cout << "Secret is returned with name " << secret.Name << " and value " << secret.Value
<< std::endl;
```
## Deleting a secret
The secret is no longer needed so we need to delete it.
```cpp Snippet:SecretSample3DeleteSecret
// start deleting the secret
DeleteSecretOperation operation = secretClient.StartDeleteSecret(secret.Name);
```
## Recover a Deleted secret
To recover a deleted secret we need to call StartRecoverDeletedSecret and then poll untill the operation is done.
```cpp Snippet:SecretSample3RecoverSecret
// call restore secret
RecoverDeletedSecretOperation recoverOperation = secretClient.StartRecoverDeletedSecret(secret.Name);
// poll until done
Secret restoredSecret = recoverOperation.PollUntilDone(2s).Value;
```
## Source
[defaultazurecredential]: https://github.com/Azure/azure-sdk-for-cpp/blob/main/sdk/identity/azure-identity/README.md

View File

@ -0,0 +1,15 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# SPDX-License-Identifier: MIT
cmake_minimum_required (VERSION 3.13)
project (sample4-get-secrets-deleted LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED True)
add_executable (
sample4-get-secrets-deleted
sample4-get-secrets-deleted.cpp
)
target_link_libraries(sample4-get-secrets-deleted PRIVATE azure-security-keyvault-secrets azure-identity)

View File

@ -0,0 +1,115 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @brief This sample provides the code implementation to use the Key Vault Secrets SDK client for
* C++ to get secrets, get secret versions, get deleted secrets, get deleted secret.
*
* @remark The following environment variables must be set before running the sample.
* - AZURE_KEYVAULT_URL: To the Key Vault account URL.
* - AZURE_TENANT_ID: Tenant ID for the Azure account.
* - AZURE_CLIENT_ID: The Client ID to authenticate the request.
* - AZURE_CLIENT_SECRET: The client secret.
*
*/
#if defined(_MSC_VER)
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <azure/identity.hpp>
#include <azure/keyvault/keyvault_secrets.hpp>
#include <chrono>
#include <iostream>
using namespace Azure::Security::KeyVault::Secrets;
using namespace std::chrono_literals;
int main()
{
auto tenantId = std::getenv("AZURE_TENANT_ID");
auto clientId = std::getenv("AZURE_CLIENT_ID");
auto clientSecret = std::getenv("AZURE_CLIENT_SECRET");
auto credential
= std::make_shared<Azure::Identity::ClientSecretCredential>(tenantId, clientId, clientSecret);
// create client
SecretClient secretClient(std::getenv("AZURE_KEYVAULT_URL"), credential);
std::string secretName("MySampleSecret");
std::string secretName2("MySampleSecret2");
std::string secretValue("my secret value");
try
{
// create secret
Secret secret1 = secretClient.SetSecret(secretName, secretValue).Value;
Secret secret2 = secretClient.SetSecret(secretName2, secretValue).Value;
std::cout << "Secret1 Version : " << secret1.Properties.Version << std::endl;
// get properties of secrets
for (auto secrets = secretClient.GetPropertiesOfSecrets(); secrets.HasPage();
secrets.MoveToNextPage())
{ // go through every secret of each page returned
for (auto const& secret : secrets.Items)
{
std::cout << "Found Secret with name: " << secret.Name << std::endl;
}
}
// get all the versions of a secret
for (auto secretsVersion = secretClient.GetPropertiesOfSecretsVersions(secret1.Name);
secretsVersion.HasPage();
secretsVersion.MoveToNextPage())
{ // go through each version of the secret
for (auto const& secret : secretsVersion.Items)
{
std::cout << "Found Secret with name: " << secret.Name
<< " and with version: " << secret.Version << std::endl;
}
}
// start deleting the secret
DeleteSecretOperation operation = secretClient.StartDeleteSecret(secret1.Name);
// You only need to wait for completion if you want to purge or recover the secret.
operation.PollUntilDone(2s);
// start deleting the secret
operation = secretClient.StartDeleteSecret(secret2.Name);
// You only need to wait for completion if you want to purge or recover the secret.
operation.PollUntilDone(2s);
// get all the versions of a secret
for (auto deletedSecrets = secretClient.GetDeletedSecrets(); deletedSecrets.HasPage();
deletedSecrets.MoveToNextPage())
{ // go through each version of the secret
for (auto const& deletedSecret : deletedSecrets.Items)
{
std::cout << "Found Secret with name: " << deletedSecret.Name << std::endl;
}
}
// get one deleted secret
auto deletedSecret = secretClient.GetDeletedSecret(secret1.Name);
std::cout << "Deleted Secret with name: " << deletedSecret.Value.Name;
// cleanup
secretClient.PurgeDeletedSecret(secret1.Name);
secretClient.PurgeDeletedSecret(secret2.Name);
}
catch (Azure::Core::Credentials::AuthenticationException const& e)
{
std::cout << "Authentication Exception happened:" << std::endl << e.what() << std::endl;
return 1;
}
catch (Azure::Core::RequestFailedException const& e)
{
std::cout << "Key Vault Secret Client Exception happened:" << std::endl
<< e.Message << std::endl;
return 1;
}
return 0;
}

View File

@ -0,0 +1,126 @@
# Get Secrets, Get Secrets Versions, Get Deleted Secrets, Get Deleted Secret
This sample demonstrates how to list all the secrets , all the versions of a secret, list all deleted secrets, and get the properties of a deleted secret.
## Creating a SecretClient
To create a new `SecretClient` to create, get, update, or delete secrets, you need the endpoint to an Azure Key Vault and credentials.
Key Vault Secrets client for C++ currently supports the `ClientSecretCredential` for authenticating.
In the sample below, you can create a credential by setting the Tenant ID, Client ID and Client Secret as environment variables.
```cpp Snippet:SecretSample4CreateCredential
auto tenantId = std::getenv("AZURE_TENANT_ID");
auto clientId = std::getenv("AZURE_CLIENT_ID");
auto clientSecret = std::getenv("AZURE_CLIENT_SECRET");
auto credential = std::make_shared<Azure::Identity::ClientSecretCredential>(tenantId, clientId, clientSecret);
```
Then, in the sample below, you can set `keyVaultUrl` based on an environment variable, configuration setting, or any way that works for your application.
```cpp Snippet:SecretSample4SecretClient
SecretClient secretClient(std::getenv("AZURE_KEYVAULT_URL"), credential);
```
## Creating a couple of Secrets
To create a secret all you need to set id the name and secret value.
```cpp Snippet:SecretSample4SetSecret
std::string secretName("MySampleSecret");
std::string secretName2("MySampleSecret2");
std::string secretValue("my secret value");
Secret secret1 = secretClient.SetSecret(secretName, secretValue).Value;
Secret secret2 = secretClient.SetSecret(secretName2, secretValue).Value;
```
## Getting the properties of all the secrets in the keyvault
To get the properties of the secrets in the keyvault we will call GetPropertiesOfSecrets. The results of this call are paged to a maximum of 25 SecretProperties per page.
```cpp Snippet:SecretSample4ListAllSecrets
// get properties of secrets
for (auto secrets = secretClient.GetPropertiesOfSecrets(); secrets.HasPage(); secrets.MoveToNextPage())
{ // go through every secret of each page returned
for (auto const& secret : secrets.Items)
{
std::cout << "Found Secret with name: " << secret.Name << std::endl;
}
}
```
## Get the versions of a Secret
in order to list all the versions of a secret we need to call GetPropertiesOfSecretsVersions, which responds similarly with a paged response of up to 25 versions of the secret per page.
```cpp Snippet:SecretSample4GetVersions
// get all the versions of a secret
for (auto secretsVersion = secretClient.GetPropertiesOfSecretsVersions(secret1.Name);
secretsVersion.HasPage();
secretsVersion.MoveToNextPage())
{ // go through each version of the secret
for (auto const& secret : secretsVersion.Items)
{
std::cout << "Found Secret with name: " << secret.Name
<< " and with version: " << secret.Version << std::endl;
}
}
```
## Delete both secrets
The secrets is no longer needed so we need to delete them, in order to demonstrate the delete related operations. We shall not purge the secrets yet.
```cpp Snippet:SecretSample4DeleteSecrets
// start deleting the secret
DeleteSecretOperation operation = secretClient.StartDeleteSecret(secret1.Name);
// You only need to wait for completion if you want to purge or recover the secret.
operation.PollUntilDone(2s);
// start deleting the secret
operation = secretClient.StartDeleteSecret(secret2.Name);
// You only need to wait for completion if you want to purge or recover the secret.
operation.PollUntilDone(2s);
```
## Get Deleted Secrets
To get a list of preprties of all deleted secrets we will call GetDeletedSecrets, similarly to the previous calls this is a paged response with the same limit of 25 items per response.
```cpp Snippet:SecretSample4GetDeletedSecrets
// get all the versions of a secret
for (auto deletedSecrets = secretClient.GetDeletedSecrets(); deletedSecrets.HasPage();
deletedSecrets.MoveToNextPage())
{ // go through each version of the secret
for (auto const& deletedSecret : deletedSecrets.Items)
{
std::cout << "Found Secret with name: " << deletedSecret.Name << std::endl;
}
}
```
## Get Deleted Secret
To get information about a specific deleted secret we will call GetDeletedSecret passing the secret name as a parameter.
```cpp Snippet:SecretSample4GetDeletedSecret
// get one deleted secret
auto deletedSecret = secretClient.GetDeletedSecret(secret1.Name);
std::cout << "Deleted Secret with name: " << deletedSecret.Value.Name;
```
## Purge the secrets to cleanup
Since the secrets were deleted previously now we need to call purge to finish cleaning up.
```cpp Snippet:SecretSample4PurgeSecrets
// cleanup
secretClient.PurgeDeletedSecret(secret1.Name);
secretClient.PurgeDeletedSecret(secret2.Name);
```
## Source
[defaultazurecredential]: https://github.com/Azure/azure-sdk-for-cpp/blob/main/sdk/identity/azure-identity/README.md