Use code snippets from managed identity credential samples in identity readme doc and fix minor generation issues (#6020)

* Use code snippets from managed identity credential samples in identity readme doc.

* Generate readme from snippets.

* Update snippet generation script to remove unnecessary indentation and extra new line at eof.

* Update Snippet Generation doc to show a concrete example on how to run it.

* Update other repo READMEs with the generation fixes.

* Fix KeyVault Secrets sample and use the snippets in its README

* Use the added sample snippet.
This commit is contained in:
Ahson Khan 2024-09-25 16:56:57 -07:00 коммит произвёл GitHub
Родитель f3119bd899
Коммит aa728eed6d
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
9 изменённых файлов: 143 добавлений и 49 удалений

Просмотреть файл

@ -110,9 +110,14 @@ The snippet generation tool, located in `eng\scripts\Generate-Snippets.ps1`, is
```bash
pwsh -f eng\scripts\Generate-Snippets.ps1 -source_dir <path to source code containing snippets> -output_dir <path to directory containing output files>
```
For example, you can run the snippet generation tool for all the packages in the repo, as follows:
```bash
pwsh -f .\eng\scripts\Generate-Snippets.ps1 -source_dir sdk -output_dir sdk
```
The tool will recursively search the source directory for snippet sources and parse the snippet sources in each
source file.

Просмотреть файл

@ -82,7 +82,28 @@ function ProcessSnippetsInFile {
# Insert the snippet text.
$snippet_text = $snippet_map[$snippet_name]
$output_file_contents = $output_file_contents -replace "<!--\s+@insert_snippet:\s+$snippet_name\s*-->\s+", "<!-- @insert_snippet: $snippet_name -->`r`n``````cpp`r`n$snippet_text`r`n```````r`n`r`n"
# Remove leading spaces from each line, by first splitting the text into lines.
$lines = $snippet_text -split [Environment]::NewLine
# Then, find the minimum leading whitespace across all lines.
# This is done to trim the minimum amount of leading whitespace from each line while preserving the relative indentation for lines that are already indented.
# When calculating the min whitespace, we only consider lines that are not empty.
$minWhitespace = ($lines | Where-Object { $_.Trim() -ne '' } | ForEach-Object { $_.IndexOf($_.TrimStart()) }) | Measure-Object -Minimum | Select-Object -ExpandProperty Minimum
# Trim the minimum whitespace from each line
$trimmedLines = $lines | ForEach-Object {
if ($_.Length -gt $minWhitespace) {
$_.Substring($minWhitespace)
} else {
$_
}
}
# Join the lines back into a single string
$snippet_text_clean = $trimmedLines -join [Environment]::NewLine
$output_file_contents = $output_file_contents -replace "<!--\s+@insert_snippet:\s+$snippet_name\s*-->\s+", "<!-- @insert_snippet: $snippet_name -->`r`n``````cpp`r`n$snippet_text_clean`r`n```````r`n`r`n"
}
elseif ($output_file.Extension -eq '.hpp') {
@ -98,8 +119,8 @@ function ProcessSnippetsInFile {
}
# The Regex::Replace above inserts an extra newline at the end of the file. Remove it.
$output_file_contents = $output_file_contents -replace "`r`n\s*\Z", "`r`n"
$original_contents = $original_file_contents -replace "`r`n\s*\Z", "`r`n"
$output_file_contents = $output_file_contents -replace "`r`n\s*\Z", ""
$original_contents = $original_file_contents -replace "`r`n\s*\Z", ""
if ($verify) {
if ($output_file_contents -ne $original_contents) {

Просмотреть файл

@ -45,31 +45,31 @@ An AMQP Message Sender is responsible for sending messages to an AMQP server ove
<!-- @insert_snippet: CreateSender -->
```cpp
Azure::Core::Amqp::_internal::MessageSenderOptions senderOptions;
senderOptions.Name = "sender-link";
senderOptions.MessageSource = "source";
senderOptions.SettleMode = Azure::Core::Amqp::_internal::SenderSettleMode::Unsettled;
senderOptions.MaxMessageSize = (std::numeric_limits<uint16_t>::max)();
Azure::Core::Amqp::_internal::MessageSenderOptions senderOptions;
senderOptions.Name = "sender-link";
senderOptions.MessageSource = "source";
senderOptions.SettleMode = Azure::Core::Amqp::_internal::SenderSettleMode::Unsettled;
senderOptions.MaxMessageSize = (std::numeric_limits<uint16_t>::max)();
Azure::Core::Amqp::_internal::MessageSender sender(
session, credentials->GetEntityPath(), senderOptions, nullptr);
Azure::Core::Amqp::_internal::MessageSender sender(
session, credentials->GetEntityPath(), senderOptions, nullptr);
```
Once the message sender has been created, it can be used to send messages to the remote server.
<!-- @insert_snippet: SendMessages -->
```cpp
Azure::Core::Amqp::Models::AmqpMessage message;
message.SetBody(Azure::Core::Amqp::Models::AmqpBinaryData{'H', 'e', 'l', 'l', 'o'});
Azure::Core::Amqp::Models::AmqpMessage message;
message.SetBody(Azure::Core::Amqp::Models::AmqpBinaryData{'H', 'e', 'l', 'l', 'o'});
constexpr int maxMessageSendCount = 5;
constexpr int maxMessageSendCount = 5;
int messageSendCount = 0;
while (messageSendCount < maxMessageSendCount)
{
auto result = sender.Send(message);
messageSendCount += 1;
}
int messageSendCount = 0;
while (messageSendCount < maxMessageSendCount)
{
auto result = sender.Send(message);
messageSendCount += 1;
}
```
## Next steps
@ -106,4 +106,3 @@ Azure SDK for C++ is licensed under the [MIT](https://github.com/Azure/azure-sdk
[cloud_shell_bash]: https://shell.azure.com/bash
![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-cpp%2Fsdk%2Fcore%2Fcore-opentelemetry%2FREADME.png)

Просмотреть файл

@ -75,24 +75,24 @@ Demonstrates writing messages to the Azure Event Hubs service using the AMQP pro
<!-- @insert_snippet: CreateSender -->
```cpp
Azure::Core::Amqp::_internal::MessageSenderOptions senderOptions;
senderOptions.Name = "sender-link";
senderOptions.MessageSource = "source";
senderOptions.SettleMode = Azure::Core::Amqp::_internal::SenderSettleMode::Unsettled;
senderOptions.MaxMessageSize = (std::numeric_limits<uint16_t>::max)();
Azure::Core::Amqp::_internal::MessageSenderOptions senderOptions;
senderOptions.Name = "sender-link";
senderOptions.MessageSource = "source";
senderOptions.SettleMode = Azure::Core::Amqp::_internal::SenderSettleMode::Unsettled;
senderOptions.MaxMessageSize = (std::numeric_limits<uint16_t>::max)();
Azure::Core::Amqp::_internal::MessageSender sender(
session, credentials->GetEntityPath(), senderOptions, nullptr);
Azure::Core::Amqp::_internal::MessageSender sender(
session, credentials->GetEntityPath(), senderOptions, nullptr);
```
<!-- @insert_snippet: create_connection -->
```cpp
Azure::Core::Amqp::_internal::ConnectionOptions connectionOptions;
connectionOptions.ContainerId = "whatever";
connectionOptions.EnableTrace = true;
connectionOptions.Port = credential->GetPort();
Azure::Core::Amqp::_internal::Connection connection(
credential->GetHostName(), credential, connectionOptions);
Azure::Core::Amqp::_internal::ConnectionOptions connectionOptions;
connectionOptions.ContainerId = "whatever";
connectionOptions.EnableTrace = true;
connectionOptions.Port = credential->GetPort();
Azure::Core::Amqp::_internal::Connection connection(
credential->GetHostName(), credential, connectionOptions);
```
### eventhub_token_reader_sample
@ -112,4 +112,3 @@ Demonstrates receiving messages from a local AMQP server using the AMQP protocol
### eventhub_get_eventhub_properties_sample
Demonstrates receiving messages from the Azure Event Hubs service using an AMQP Management API.

Просмотреть файл

@ -104,16 +104,16 @@ Many Azure hosts allow the assignment of a user-assigned managed identity. The f
To use a client ID, create a `ManagedIdentityId` with `ManagedIdentityIdKind::ClientId`, set that as the `IdentityId` in the `ManagedIdentityCredentialOptions`, and pass that to the `ManagedIdentityCredential` constructor. For example:
<!-- @insert_snippet: UserAssignedManagedIdentityViaClientId -->
```cpp
// When deployed to an Azure host, ManagedIdentityCredential will authenticate the specified user-assigned managed identity.
// When deployed to an Azure host, ManagedIdentityCredential will authenticate the specified
// user-assigned managed identity.
std::string userAssignedClientId = "<your managed identity client ID>";
ManagedIdentityCredentialOptions options;
options.IdentityId = ManagedIdentityId(ManagedIdentityIdKind::ClientId, userAssignedClientId);
auto credential = std::make_shared<ManagedIdentityCredential>(options);
std::string blobUrl = "https://myaccount.blob.core.windows.net/mycontainer/myblob";
auto blobClient = BlobClient(blobUrl, credential);
```
@ -121,13 +121,14 @@ auto blobClient = BlobClient(blobUrl, credential);
Similarly, to use a resource ID, create a `ManagedIdentityId` with `ManagedIdentityIdKind::ResourceId`, set that as the `IdentityId` in the `ManagedIdentityCredentialOptions`, and pass that to the `ManagedIdentityCredential` constructor. The resource ID takes the form `/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{identityName}`. Because resource IDs can be built by convention, they can be more convenient when there are a large number of user-assigned managed identities in your environment. For example:
<!-- @insert_snippet: UserAssignedManagedIdentityViaResourceId -->
```cpp
std::string userAssignedResourceId = "<your managed identity resource ID>";
ManagedIdentityCredentialOptions options;
options.IdentityId = ManagedIdentityId(ManagedIdentityIdKind::ResourceId, userAssignedResourceId);
options.IdentityId
= ManagedIdentityId(ManagedIdentityIdKind::ResourceId, userAssignedResourceId);
auto credential = std::make_shared<ManagedIdentityCredential>(options);
auto blobClient = BlobClient(blobUrl, credential);
```
@ -135,13 +136,13 @@ auto blobClient = BlobClient(blobUrl, credential);
Similarly, to use an object ID, create a `ManagedIdentityId` with `ManagedIdentityIdKind::ObjectId`, set that as the `IdentityId` in the `ManagedIdentityCredentialOptions`, and pass that to the `ManagedIdentityCredential` constructor. For example:
<!-- @insert_snippet: UserAssignedManagedIdentityViaObjectId -->
```cpp
std::string userAssignedObjectId = "<your managed identity object ID>";
ManagedIdentityCredentialOptions options;
options.IdentityId = ManagedIdentityId(ManagedIdentityIdKind::ObjectId, userAssignedObjectId);
auto credential = std::make_shared<ManagedIdentityCredential>(options);
auto blobClient = BlobClient(blobUrl, credential);
```
@ -149,6 +150,7 @@ auto blobClient = BlobClient(blobUrl, credential);
You can express your intent to use a system-assigned managed identity, explicitly, by creating a `ManagedIdentityId` with `ManagedIdentityIdKind::SystemAssigned` and an empty ID value, set that as the `IdentityId` in the `ManagedIdentityCredentialOptions`, and pass that to the `ManagedIdentityCredential` constructor. For example:
<!-- @insert_snippet: SystemAssignedManagedIdentity -->
```cpp
ManagedIdentityCredentialOptions options;
options.IdentityId = ManagedIdentityId(ManagedIdentityIdKind::SystemAssigned, {});
@ -159,6 +161,7 @@ auto blobClient = BlobClient(blobUrl, credential);
An alternative way to specify a system-assigned managed identity, implicitly, is by calling the default `ManagedIdentityCredential` constructor. For example:
<!-- @insert_snippet: SystemAssignedManagedIdentityBrief -->
```cpp
auto credential = std::make_shared<ManagedIdentityCredential>();
auto blobClient = BlobClient(blobUrl, credential);

Просмотреть файл

@ -54,7 +54,7 @@ target_compile_definitions(environment_credential_sample PRIVATE _azure_BUILDING
create_per_service_target_build_for_sample(identity environment_credential_sample)
add_executable(managed_identity_credential_sample managed_identity_credential.cpp)
target_link_libraries(managed_identity_credential_sample PRIVATE azure-identity service)
target_link_libraries(managed_identity_credential_sample PRIVATE azure-identity service azure-storage-blobs)
target_include_directories(managed_identity_credential_sample PRIVATE .)
target_compile_definitions(managed_identity_credential_sample PRIVATE _azure_BUILDING_SAMPLES)
create_per_service_target_build_for_sample(identity managed_identity_credential_sample)

Просмотреть файл

@ -3,9 +3,67 @@
#include <azure/identity/managed_identity_credential.hpp>
#include <azure/service/client.hpp>
#include <azure/storage/blobs.hpp>
#include <iostream>
static void ShowDifferentManagedIdentityApproaches()
{
using namespace Azure::Identity;
using namespace Azure::Storage::Blobs;
std::string blobUrl = "https://myaccount.blob.core.windows.net/mycontainer/myblob";
{
// @begin_snippet: UserAssignedManagedIdentityViaClientId
// When deployed to an Azure host, ManagedIdentityCredential will authenticate the specified
// user-assigned managed identity.
std::string userAssignedClientId = "<your managed identity client ID>";
ManagedIdentityCredentialOptions options;
options.IdentityId = ManagedIdentityId(ManagedIdentityIdKind::ClientId, userAssignedClientId);
auto credential = std::make_shared<ManagedIdentityCredential>(options);
auto blobClient = BlobClient(blobUrl, credential);
// @end_snippet
}
{
// @begin_snippet: UserAssignedManagedIdentityViaResourceId
std::string userAssignedResourceId = "<your managed identity resource ID>";
ManagedIdentityCredentialOptions options;
options.IdentityId
= ManagedIdentityId(ManagedIdentityIdKind::ResourceId, userAssignedResourceId);
auto credential = std::make_shared<ManagedIdentityCredential>(options);
auto blobClient = BlobClient(blobUrl, credential);
// @end_snippet
}
{
// @begin_snippet: UserAssignedManagedIdentityViaObjectId
std::string userAssignedObjectId = "<your managed identity object ID>";
ManagedIdentityCredentialOptions options;
options.IdentityId = ManagedIdentityId(ManagedIdentityIdKind::ObjectId, userAssignedObjectId);
auto credential = std::make_shared<ManagedIdentityCredential>(options);
auto blobClient = BlobClient(blobUrl, credential);
// @end_snippet
}
{
// @begin_snippet: SystemAssignedManagedIdentity
ManagedIdentityCredentialOptions options;
options.IdentityId = ManagedIdentityId(ManagedIdentityIdKind::SystemAssigned, {});
auto credential = std::make_shared<ManagedIdentityCredential>(options);
auto blobClient = BlobClient(blobUrl, credential);
// @end_snippet
}
{
// @begin_snippet: SystemAssignedManagedIdentityBrief
auto credential = std::make_shared<ManagedIdentityCredential>();
auto blobClient = BlobClient(blobUrl, credential);
// @end_snippet
}
}
int main()
{
try
@ -31,5 +89,7 @@ int main()
return 1;
}
ShowDifferentManagedIdentityApproaches();
return 0;
}

Просмотреть файл

@ -80,9 +80,11 @@ For detailed samples please review the samples provided.
First step is to create a SecretClient.
<!-- @insert_snippet: SecretSample1CreateCredential -->
```cpp
auto const keyVaultUrl = std::getenv("AZURE_KEYVAULT_URL");
auto credential = std::make_shared<Azure::Identity::DefaultAzureCredential>();
// create client
SecretClient secretClient(keyVaultUrl, credential);
```
@ -91,6 +93,7 @@ SecretClient secretClient(keyVaultUrl, credential);
We call the secret client to create a secret.
<!-- @insert_snippet: SecretSample1CreateSecret -->
```cpp
std::string secretName("MySampleSecret");
std::string secretValue("my secret value");
@ -102,34 +105,36 @@ secretClient.SetSecret(secretName, secretValue);
We retrieve a secret by name.
<!-- @insert_snippet: SecretSample1GetSecret -->
```cpp
// get secret
KeyVaultSecret secret = secretClient.GetSecret(secretName).Value;
std::string valueString = secret.Value.HasValue() ? secret.Value.Value() : "NONE RETURNED";
std::cout << "Secret is returned with name " << secret.Name << " and value "
<< valueString << std::endl;
std::cout << "Secret is returned with name " << secret.Name << " and value " << valueString
<< std::endl;
```
### Update a secret
Updating an existing secret
<!-- @insert_snippet: SecretSample1UpdateSecretProperties -->
```cpp
// change one of the properties
secret.Properties.ContentType = "my content";
// update the secret
KeyVaultSecret updatedSecret = secretClient.UpdateSecretProperties(secret.Properties).Value;
std::string updatedValueString = updatedSecret.Value.HasValue() ? updatedSecret.Value.Value()
: "NONE RETURNED";
std::cout << "Secret's content type is now " << updatedValueString
<< std::endl;
std::string updatedValueString
= updatedSecret.Value.HasValue() ? updatedSecret.Value.Value() : "NONE RETURNED";
std::cout << "Secret's content type is now " << updatedValueString << std::endl;
```
### Delete a secret
Delete an existing secret.
<!-- @insert_snippet: SecretSample1DeleteSecret -->
```cpp
// start deleting the secret
DeleteSecretOperation operation = secretClient.StartDeleteSecret(secret.Name);
@ -147,6 +152,7 @@ secretClient.PurgeDeletedSecret(secret.Name);
Delete and Purge a secret.
<!-- @insert_snippet: SecretSample1DeleteSecret -->
```cpp
// start deleting the secret
DeleteSecretOperation operation = secretClient.StartDeleteSecret(secret.Name);
@ -164,6 +170,7 @@ secretClient.PurgeDeletedSecret(secret.Name);
List all the secrets in keyvault.
<!-- @insert_snippet: SecretSample4ListAllSecrets -->
```cpp
// get all the versions of a secret
for (auto secretsVersion = secretClient.GetPropertiesOfSecretsVersions(secret1.Name);

Просмотреть файл

@ -21,8 +21,8 @@ using namespace std::chrono_literals;
int main()
{
auto const keyVaultUrl = std::getenv("AZURE_KEYVAULT_URL");
// @begin_snippet: SecretSample1CreateCredential
auto const keyVaultUrl = std::getenv("AZURE_KEYVAULT_URL");
auto credential = std::make_shared<Azure::Identity::DefaultAzureCredential>();
// create client