Keyvault Secrets remake (#6463)

* first stab at a client tsp /tspconfig scripts

* space

* updates to clientTSP

* update for latest specs for KV

* gfd

* gfd

* hghf

* dfgdf

* jhg

* oopsie

* comments

* headers

* clang & param

* coverage

* more comments not gened

* spell

* more comments

* regen for testing

* gfd

* gdf

* tretre

* update to use tsp client

* vcxvx

* fdsfsd

* fds

* round 2

* api view

* dsa

* rte

* update to use code injection

* clang and comments

* gfd

* updates

* clang

* fsd

* spell

* comments

* some cleanup

* first test passing

* dsa

* second test

* startdeletesecret

* update secret ptoeprties

* recover secret

* cleanup clang

* docs

* update recordings and clean up tests

* ggfd

* ooops

* samples build

* gdf

* samples run

* perf tests

* CLANG

* fds

* CLAAAAAAAAANG

* update to latest version of the TSPs

* update to latest codegen

* gdfgdf

* replace method

* client and stuffs

* PR comments

* remove security from path

* clang

* qfe

* gdf

* update to models and to the lastest codegen

* forgot cmake file

* Update sdk/keyvault/azure-security-keyvault-secrets/samples/sample1-basic-operations/sample1_basic_operations.cpp

Co-authored-by: Anton Kolesnyk <41349689+antkmsft@users.noreply.github.com>

* test api view

* dfsfsd

* ccxcvx

* step1

* delete, and lor and paged

* all work

* works and serializers and test for them gone

* cleanup test files

* sample

* tests passing

* dfsfsd

* latest codegen

* after merge

* fsd

* gfd

* gfd

* ApiView

* move to _details namespace

* put back readme

* update readmes

* clang

* dfsd

* get rid of snippets, validation fails without explanation as to what the failure is

* update locations of methods tp cpp files

* format files

* cover

---------

Co-authored-by: Anton Kolesnyk <41349689+antkmsft@users.noreply.github.com>
This commit is contained in:
gearama 2025-03-14 13:46:49 -07:00 committed by GitHub
parent 250a80cbc8
commit 125c305961
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
53 changed files with 3510 additions and 1821 deletions

View File

@ -3,62 +3,52 @@
find_package(Git)
macro(GenerateCodeFromTypeSpec TSP_SHA TSP_REPO_PATH TSP_DESTINATION CODEGEN_SHA CODEGEN_DESTINATION )
macro(GenerateCodeFromTypeSpec TSP_DESTINATION TSP_SERVICE_PATH CODEGEN_SHA CODEGEN_DESTINATION GEN_FILES_DESTINATION COPY_CLIENT_TSP)
message("Generating code using the following params TSP_SHA=${TSP_SHA} TSP_REPO_PATH=${TSP_REPO_PATH} TSP_DESTINATION=${TSP_DESTINATION} CODEGEN_SHA=${CODEGEN_SHA} CODEGEN_DESTINATION=${CODEGEN_DESTINATION}")
message("\
GenerateCodeFromTypeSpec using the following params \n\
TSP_DESTINATION=${TSP_DESTINATION} \n\
TSP_SERVICE_PATH=${TSP_SERVICE_PATH} \n\
CODEGEN_SHA=${CODEGEN_SHA} \n\
CODEGEN_DESTINATION=${CODEGEN_DESTINATION} \n\
GEN_FILES_DESTINATION=${GEN_FILES_DESTINATION}")
set(CODEGEN_PATH packages/typespec-cpp)
DownloadTSPFiles(${TSP_SHA} ${TSP_REPO_PATH} ${TSP_DESTINATION})
DownloadTSPFiles(${TSP_DESTINATION})
DownloadCodeGenerator(${CODEGEN_SHA} ${CODEGEN_DESTINATION})
GenerateCodeFromTSP(${TSP_DESTINATION} ${TSP_REPO_PATH} ${CODEGEN_DESTINATION} ${CODEGEN_PATH})
GenerateCodeFromTSP(${TSP_DESTINATION} ${TSP_SERVICE_PATH} ${CODEGEN_DESTINATION} ${CODEGEN_PATH} ${GEN_FILES_DESTINATION} ${COPY_CLIENT_TSP})
endmacro()
macro(DownloadTSPFiles TSP_SHA TSP_REPO_PATH TSP_DESTINATION)
message ("Downloading TSP files using the following params TSP_REPO=${TSP_REPO} TSP_SHA=${TSP_SHA} TSP_REPO_PATH=${TSP_REPO_PATH} TSP_DESTINATION=${TSP_DESTINATION}")
if(Git_FOUND)
message("Git found: ${GIT_EXECUTABLE}")
else()
message(FATAL_ERROR "Git not found")
endif()
macro(DownloadTSPFiles TSP_DESTINATION)
set(TSP_REPO "https://github.com/Azure/azure-rest-api-specs.git")
set(DOWNLOAD_TSP_FOLDER ${CMAKE_SOURCE_DIR}/build/${TSP_DESTINATION})
# if we have the git folder, we don't need to download it again
# this also saves times on incremental builds
if(NOT EXISTS ${DOWNLOAD_TSP_FOLDER}/.git)
message("First time setting up the ${TSP_DESTINATION} repo.")
#make folder
make_directory(${DOWNLOAD_TSP_FOLDER})
message ("\
DownloadTSPFiles using the following params \n\
TSP_REPO = ${TSP_REPO} \n\
TSP_DESTINATION=${TSP_DESTINATION}")
set(DOWNLOAD_TSP_FOLDER ${CMAKE_SOURCE_DIR}/build/${TSP_DESTINATION})
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/tsp-location.yaml
DESTINATION ${DOWNLOAD_TSP_FOLDER})
set(SCRIPTS_FOLDER ${CMAKE_SOURCE_DIR}/eng/scripts/typespec/)
file(COPY ${SCRIPTS_FOLDER}/Run-Tsp-Update.ps1
DESTINATION ${DOWNLOAD_TSP_FOLDER})
execute_process(COMMAND pwsh Run-Tsp-Update.ps1
WORKING_DIRECTORY ${DOWNLOAD_TSP_FOLDER})
#init git in folder
execute_process(COMMAND ${GIT_EXECUTABLE} init
WORKING_DIRECTORY ${DOWNLOAD_TSP_FOLDER})
#add remote
execute_process(COMMAND ${GIT_EXECUTABLE} remote add origin ${TSP_REPO}
WORKING_DIRECTORY ${DOWNLOAD_TSP_FOLDER})
#set sparse-checkout
execute_process(COMMAND ${GIT_EXECUTABLE} sparse-checkout init --cone
WORKING_DIRECTORY ${DOWNLOAD_TSP_FOLDER})
#set sparse-checkout folder
execute_process(COMMAND ${GIT_EXECUTABLE} sparse-checkout set ${TSP_REPO_PATH}
WORKING_DIRECTORY ${DOWNLOAD_TSP_FOLDER})
else()
message("Repo detected at ${TSP_DESTINATION}. Jumping ahead to checkout.")
endif()
#fetch
execute_process(COMMAND ${GIT_EXECUTABLE} fetch
WORKING_DIRECTORY ${DOWNLOAD_TSP_FOLDER})
#switch branch
execute_process(COMMAND ${GIT_EXECUTABLE} checkout ${TSP_SHA}
WORKING_DIRECTORY ${DOWNLOAD_TSP_FOLDER})
if(NOT ${STATUS_CODE} EQUAL 0)
message(FATAL_ERROR "TSP download failed.")
endif()
endmacro()
macro (DownloadCodeGenerator CODEGEN_SHA CODEGEN_DESTINATION)
message("Downloading CODEGEN files using the following params CODEGEN_REPO=${CODEGEN_REPO} CODEGEN_SHA=${CODEGEN_SHA} CODEGEN_DESTINATION=${CODEGEN_DESTINATION}")
message("\
DownloadCodeGenerator using the following params \n\
CODEGEN_REPO=${CODEGEN_REPO} \n\
CODEGEN_SHA=${CODEGEN_SHA} \n\
CODEGEN_DESTINATION=${CODEGEN_DESTINATION}")
if(Git_FOUND)
message("Git found: ${GIT_EXECUTABLE}")
@ -90,47 +80,82 @@ macro (DownloadCodeGenerator CODEGEN_SHA CODEGEN_DESTINATION)
endif()
endmacro()
macro(GenerateCodeFromTSP TSP_DESTINATION TSP_REPO_PATH CODEGEN_DESTINATION CODEGEN_PATH)
message("Generating code using the following params TSP_DESTINATION=${TSP_DESTINATION} TSP_REPO_PATH=${TSP_REPO_PATH} CODEGEN_DESTINATION=${CODEGEN_DESTINATION}")
macro(GenerateCodeFromTSP TSP_DESTINATION TSP_SERVICE_PATH CODEGEN_DESTINATION CODEGEN_PATH GEN_FILES_DESTINATION COPY_CLIENT_TSP )
message("\
GenerateCodeFromTSP using the following params \n\
TSP_DESTINATION=${TSP_DESTINATION}\n\
TSP_SERVICE_PATH=${TSP_SERVICE_PATH}\n\
CODEGEN_DESTINATION=${CODEGEN_DESTINATION}\n\
CODEGEN_PATH=${CODEGEN_PATH}\n\
GEN_FILES_DESTINATION$=${GEN_FILES_DESTINATION}")
message("Remember to Download the typspec-cpp emitter from npmjs.org")
#TODO : https://github.com/Azure/azure-sdk-for-cpp/issues/6071
set(DOWNLOAD_CODEGEN_FOLDER ${CMAKE_SOURCE_DIR}/build/${CODEGEN_DESTINATION}/${CODEGEN_PATH}/specs/)
set(DOWNLOAD_TSP_FOLDER ${CMAKE_SOURCE_DIR}/build/${TSP_DESTINATION}/${TSP_REPO_PATH})
set(DOWNLOAD_CODEGEN_FOLDER ${CMAKE_SOURCE_DIR}/build/${CODEGEN_DESTINATION}/${CODEGEN_PATH}/specs/${TSP_SERVICE_PATH})
set(DOWNLOAD_TSP_FOLDER ${CMAKE_SOURCE_DIR}/build/${TSP_DESTINATION}/TempTypeSpecFiles)
set(TSP_FINAL_LOCATION ${DOWNLOAD_CODEGEN_FOLDER}/${TSP_SERVICE_PATH})
set(SCRIPTS_FOLDER ${CMAKE_SOURCE_DIR}/eng/scripts/typespec/)
message("Will copy tsp files from ${DOWNLOAD_TSP_FOLDER} to ${DOWNLOAD_CODEGEN_FOLDER}")
message("\
Will copy tsp files from \n\
${DOWNLOAD_TSP_FOLDER} to \n\
${DOWNLOAD_CODEGEN_FOLDER}")
#copy tsp files to the codegen folder
file(COPY ${DOWNLOAD_TSP_FOLDER}
file(COPY ${DOWNLOAD_TSP_FOLDER}/
DESTINATION ${DOWNLOAD_CODEGEN_FOLDER})
message("Will copy tsp generation scripts from ${SCRIPTS_FOLDER} to ${DOWNLOAD_CODEGEN_FOLDER}")
message("\
Will copy tsp generation scripts from \n\
${SCRIPTS_FOLDER} to \n\
${TSP_FINAL_LOCATION}")
file(COPY ${SCRIPTS_FOLDER}
DESTINATION ${DOWNLOAD_CODEGEN_FOLDER})
message("Will copy ${CMAKE_CURRENT_SOURCE_DIR}/client.tsp to ${DOWNLOAD_CODEGEN_FOLDER}")
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/client.tsp
DESTINATION ${DOWNLOAD_CODEGEN_FOLDER})
message("Will copy ${CMAKE_CURRENT_SOURCE_DIR}/tspconfig.yaml to ${DOWNLOAD_CODEGEN_FOLDER}")
DESTINATION ${TSP_FINAL_LOCATION})
if(${COPY_CLIENT_TSP})
message("\
Will copy \n\
${CMAKE_CURRENT_SOURCE_DIR}/client.tsp to \n\
${TSP_FINAL_LOCATION}")
# file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/client.tsp
# DESTINATION ${TSP_FINAL_LOCATION})
endif()
message("\
Will copy \n\
${CMAKE_CURRENT_SOURCE_DIR}/tspconfig.yaml to \n\
${TSP_FINAL_LOCATION}")
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/tspconfig.yaml
DESTINATION ${DOWNLOAD_CODEGEN_FOLDER})
DESTINATION ${TSP_FINAL_LOCATION})
#build codegen
message("Building codegen in folder ${DOWNLOAD_CODEGEN_FOLDER}")
message("Building codegen in folder \n\
${TSP_FINAL_LOCATION}")
execute_process(COMMAND pwsh Build-Codegen.ps1
WORKING_DIRECTORY ${DOWNLOAD_CODEGEN_FOLDER})
WORKING_DIRECTORY ${TSP_FINAL_LOCATION})
#generate code
message("Use codegen in folder ${DOWNLOAD_CODEGEN_FOLDER}")
execute_process(COMMAND pwsh Generate-Code.ps1
WORKING_DIRECTORY ${DOWNLOAD_CODEGEN_FOLDER})
message("\
Use codegen in folder \n\
${TSP_FINAL_LOCATION}")
execute_process(COMMAND pwsh Generate-Code.ps1 -outputPath ${GEN_FILES_DESTINATION}
WORKING_DIRECTORY ${TSP_FINAL_LOCATION})
endmacro()
macro(UpdateCodeFilesFromGenerated CODEGEN_DESTINATION INCLUDE_DESTINATION SOURCE_DESTINATION)
message("Updating code files using the following params CODEGEN_DESTINATION=${CODEGEN_DESTINATION} INCLUDE_DESTINATION=${INCLUDE_DESTINATION} SOURCE_DESTINATION=${SOURCE_DESTINATION}")
set(CODEGEN_PATH packages/typespec-cpp/specs)
macro(UpdateCodeFilesFromGenerated CODEGEN_DESTINATION TSP_SERVICE_PATH INCLUDE_DESTINATION SOURCE_DESTINATION)
message("\
Updating code files using the following params \n\
CODEGEN_DESTINATION=${CODEGEN_DESTINATION} \n\
TSP_SERVICE_PATH=${TSP_SERVICE_PATH} \n\
INCLUDE_DESTINATION=${INCLUDE_DESTINATION} \n\
SOURCE_DESTINATION=${SOURCE_DESTINATION}")
set(CODEGEN_PATH packages/typespec-cpp/specs/${TSP_SERVICE_PATH}/${TSP_SERVICE_PATH})
set(INCLUDE_SRC ${CMAKE_SOURCE_DIR}/build/${CODEGEN_DESTINATION}/${CODEGEN_PATH}/generated/inc/)
set(SOURCE_SRC ${CMAKE_SOURCE_DIR}/build/${CODEGEN_DESTINATION}/${CODEGEN_PATH}/generated/src/)
message("Copying files from ${INCLUDE_SRC} to ${INCLUDE_DESTINATION}")
message("\
Copying files from \n\
${INCLUDE_SRC} to \n\
${INCLUDE_DESTINATION}")
file(COPY ${INCLUDE_SRC} DESTINATION ${INCLUDE_DESTINATION})
message("Copying files from ${SOURCE_SRC} to ${SOURCE_DESTINATION}")
message("\
Copying files from \n\
${SOURCE_SRC} to \n\
${SOURCE_DESTINATION}")
file(COPY ${SOURCE_SRC} DESTINATION ${SOURCE_DESTINATION})
message("CMAKE_CURRENT_SOURCE_DIR = ${CMAKE_CURRENT_SOURCE_DIR}")
endmacro()

View File

@ -11,7 +11,7 @@ param(
npm install -g @microsoft/rush typescript autorest @typespec/compiler @azure-tools/typespec-client-generator-cli @azure-tools/typespec-azure-rulesets
pushd
cd ..\..\
cd ..\..\..\..\
cd codegen.cpp
if ($Reinstall) {

View File

@ -4,7 +4,10 @@
[CmdletBinding()]
param(
[Parameter(Mandatory=$false)]
[string] $ClangFormatPath = "clang-format"
[string] $ClangFormatPath = "clang-format",
[Parameter(Mandatory=$false)]
[string] $outputPath = ".\generated"
)
$ErrorActionPreference = "Stop"
@ -12,13 +15,13 @@ $PSNativeCommandUseErrorActionPreference = $true
pushd
cd $PSScriptRoot
cd ../
cd ../../../
$typespecCppDir = Get-Location
popd
pushd
Write-Host "Invoking: tsp compile ."
tsp compile --emit $typespecCppDir client.tsp
tsp compile --emit $typespecCppDir client.tsp --output-dir $outputPath
if (-not (Test-Path ".clang-format")) {
$oldProgressPreference = $ProgressPreference
@ -36,7 +39,7 @@ try {
}
Write-Host "Formatting generated code with clang-format"
Get-ChildItem generated -Include *.cpp, *.hpp -Recurse | ForEach-Object -Process{
Get-ChildItem $outputPath -Include *.cpp, *.hpp -Recurse | ForEach-Object -Process{
" Processing: $_"
& "$ClangFormatPath" -i $_
}

View File

@ -0,0 +1,3 @@
npm install -g @microsoft/rush typescript autorest @typespec/compiler @azure-tools/typespec-client-generator-cli @azure-tools/typespec-azure-rulesets
tsp-client update --save-inputs

View File

@ -2,5 +2,5 @@
"AssetsRepo": "Azure/azure-sdk-assets",
"AssetsRepoPrefixPath": "cpp",
"TagPrefix": "cpp/keyvault",
"Tag": "cpp/keyvault_ae1c1474ad"
"Tag": "cpp/keyvault_682056eb2b"
}

View File

@ -32,29 +32,23 @@ include(AzureBuildTargetForCI)
# Add create_map_file function
include(CreateMapFile)
option(AZURE_TSP_KV_SECRETS_GEN "Generate KeyVault Secrets from TypeSpec" OFF)
option(AZURE_TSP_KV_SECRETS_GEN3 "Generate KeyVault Secrets from TypeSpec" ON)
message("KeyVault Secrets TSP Generation ${AZURE_TSP_KV_SECRETS_GEN}")
if(AZURE_TSP_KV_SECRETS_GEN)
include(TSPCompile)
#typespec related repo information
set(TSP_REPO_PATH "specification/keyvault/data-plane/Security.KeyVault.Secrets/")
set(TSP_SHA "1da5a85c4dc4f4f1caa47fff691e85960ef4bf20")
set(TSP_SERVICE_PATH "Security.KeyVault.Secrets")
set(TSP_DESTINATION "keyvault_secrets")
#codegen related repo information
set(CODEGEN_SHA "1a9e3b7a337d5553603b8326dd3be5024d53b28a")
set(CODEGEN_SHA "deff0a603a9001da24b8751709075a4a3d40d39a")
set(CODEGEN_DESTINATION "typespec-cpp")
#destination folders
set(INCLUDE_DESTINATION "${CMAKE_CURRENT_SOURCE_DIR}/inc/azure/keyvault/secrets")
set(SOURCE_DESTINATION "${CMAKE_CURRENT_SOURCE_DIR}/src")
set(GEN_FILES_DESTINATION "${CMAKE_CURRENT_SOURCE_DIR}")
#generate code from typespec
GenerateCodeFromTypeSpec(${TSP_SHA} ${TSP_REPO_PATH} ${TSP_DESTINATION} ${CODEGEN_SHA} ${CODEGEN_DESTINATION})
#update code files left this as a separate step as generating and moving result around
#conceptually are two different steps
UpdateCodeFilesFromGenerated(${CODEGEN_DESTINATION} ${INCLUDE_DESTINATION} ${SOURCE_DESTINATION})
GenerateCodeFromTypeSpec(${TSP_DESTINATION} ${TSP_SERVICE_PATH} ${CODEGEN_SHA} ${CODEGEN_DESTINATION} ${GEN_FILES_DESTINATION} OFF)
endif()
if(FETCH_SOURCE_DEPS)
@ -83,17 +77,30 @@ set(
inc/azure/keyvault/secrets/keyvault_secret_properties.hpp
inc/azure/keyvault/secrets/rtti.hpp
inc/azure/keyvault/secrets/secret_client.hpp
inc/azure/keyvault/secrets/generated.hpp
inc/azure/keyvault/secrets/generated/dll_import_export.hpp
inc/azure/keyvault/secrets/generated/key_vault_client.hpp
inc/azure/keyvault/secrets/generated/key_vault_client_options.hpp
inc/azure/keyvault/secrets/generated/key_vault_client_paged_responses.hpp
inc/azure/keyvault/secrets/generated/models/generated_models.hpp
)
set(
AZURE_SECURITY_KEYVAULT_SECRETS_SOURCE
src/private/generated_package_version.hpp
src/private/package_version.hpp
src/generated.cpp
src/get_deleted_secrets_paged_response.cpp
src/get_secrets_paged_response.cpp
src/get_secret_versions_paged_response.cpp
src/keyvault_deleted_secret.cpp
src/key_vault_client.cpp
src/keyvault_operations.cpp
src/keyvault_protocol.cpp
src/keyvault_secret.cpp
src/keyvault_secret_paged_response.cpp
src/keyvault_secret_properties.cpp
src/keyvault_secrets_common_request.cpp
src/private/keyvault_protocol.hpp
src/private/keyvault_secrets_common_request.hpp
src/private/package_version.hpp
src/private/secret_constants.hpp
src/private/secret_serializers.hpp
@ -101,7 +108,7 @@ set(
src/secret_serializers.cpp
)
add_library(azure-security-keyvault-secrets ${AZURE_SECURITY_KEYVAULT_SECRETS_HEADER} ${AZURE_SECURITY_KEYVAULT_SECRETS_SOURCE})
add_library(azure-security-keyvault-secrets ${AZURE_SECURITY_KEYVAULT_SECRETS_HEADER} ${AZURE_SECURITY_KEYVAULT_SECRETS_SOURCE} "src/keyvault_secret.cpp")
add_library(Azure::azure-security-keyvault-secrets ALIAS azure-security-keyvault-secrets)
create_per_service_target_build(keyvault azure-security-keyvault-secrets)
@ -152,13 +159,13 @@ endif()
az_vcpkg_export(
azure-security-keyvault-secrets
SECURITY_KEYVAULT_SECRETS
"azure/keyvault/secrets/dll_import_export.hpp"
azure/keyvault/secrets/dll_import_export.hpp
)
az_rtti_setup(
azure-security-keyvault-secrets
SECURITY_KEYVAULT_SECRETS
"azure/keyvault/secrets/rtti.hpp"
azure/keyvault/secrets/rtti.hpp
)
unset(FETCH_SOURCE_DEPS CACHE)

View File

@ -80,7 +80,6 @@ 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>();
@ -93,7 +92,6 @@ 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");
@ -105,7 +103,6 @@ secretClient.SetSecret(secretName, secretValue);
We retrieve a secret by name.
<!-- @insert_snippet: SecretSample1GetSecret -->
```cpp
// get secret
KeyVaultSecret secret = secretClient.GetSecret(secretName).Value;
@ -119,14 +116,12 @@ std::cout << "Secret is returned with name " << secret.Name << " and value " <<
Updating an existing secret
<!-- @insert_snippet: SecretSample1UpdateSecretProperties -->
```cpp
```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::string updatedValueString = updatedSecret.Properties.ContentType.ValueOr("NONE RETURNED");
std::cout << "Secret's content type is now " << updatedValueString << std::endl;
```
@ -134,7 +129,6 @@ std::cout << "Secret's content type is now " << updatedValueString << std::endl;
Delete an existing secret.
<!-- @insert_snippet: SecretSample1DeleteSecret -->
```cpp
// start deleting the secret
DeleteSecretOperation operation = secretClient.StartDeleteSecret(secret.Name);
@ -152,7 +146,6 @@ secretClient.PurgeDeletedSecret(secret.Name);
Delete and Purge a secret.
<!-- @insert_snippet: SecretSample1DeleteSecret -->
```cpp
// start deleting the secret
DeleteSecretOperation operation = secretClient.StartDeleteSecret(secret.Name);
@ -170,7 +163,6 @@ 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);

View File

@ -1,7 +0,0 @@
// client.tsp
import "./main.tsp";
import "@azure-tools/typespec-client-generator-core";
using Azure.ClientGenerator.Core;
@@clientName(KeyVault, "SecretClient"); // This is the name of the client

View File

@ -0,0 +1,13 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// Code generated by Microsoft (R) TypeSpec Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
#pragma once
#include <azure/keyvault/secrets/generated/dll_import_export.hpp>
#include <azure/keyvault/secrets/generated/key_vault_client.hpp>
#include <azure/keyvault/secrets/generated/key_vault_client_options.hpp>
#include <azure/keyvault/secrets/generated/key_vault_client_paged_responses.hpp>
#include <azure/keyvault/secrets/generated/models/generated_models.hpp>
#include <azure/keyvault/secrets/generated/rtti.hpp>

View File

@ -0,0 +1,29 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// Code generated by Microsoft (R) TypeSpec Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
#pragma once
#if defined(AZ_SECURITY_KEYVAULT_SECRETS_DLL) \
|| (0 /*@AZ_SECURITY_KEYVAULT_SECRETS_DLL_INSTALLED_AS_PACKAGE@*/)
#define AZ_SECURITY_KEYVAULT_SECRETS_BUILT_AS_DLL 1
#else
#define AZ_SECURITY_KEYVAULT_SECRETS_BUILT_AS_DLL 0
#endif
#if AZ_SECURITY_KEYVAULT_SECRETS_BUILT_AS_DLL
#if defined(_MSC_VER)
#if defined(AZ_SECURITY_KEYVAULT_SECRETS_BEING_BUILT)
#define AZ_SECURITY_KEYVAULT_SECRETS_DLLEXPORT __declspec(dllexport)
#else // !defined(AZ_SECURITY_KEYVAULT_SECRETS_BEING_BUILT)
#define AZ_SECURITY_KEYVAULT_SECRETS_DLLEXPORT __declspec(dllimport)
#endif // AZ_SECURITY_KEYVAULT_SECRETS_BEING_BUILT
#else // !defined(_MSC_VER)
#define AZ_SECURITY_KEYVAULT_SECRETS_DLLEXPORT
#endif // _MSC_VER
#else // !AZ_SECURITY_KEYVAULT_SECRETS_BUILT_AS_DLL
#define AZ_SECURITY_KEYVAULT_SECRETS_DLLEXPORT
#endif // AZ_SECURITY_KEYVAULT_SECRETS_BUILT_AS_DLL
#undef AZ_SECURITY_KEYVAULT_SECRETS_BUILT_AS_DLL

View File

@ -0,0 +1,227 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// Code generated by Microsoft (R) TypeSpec Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
#pragma once
#include "azure/keyvault/secrets/generated/key_vault_client_options.hpp"
#include "azure/keyvault/secrets/generated/key_vault_client_paged_responses.hpp"
#include "azure/keyvault/secrets/generated/models/generated_models.hpp"
#include <azure/core/context.hpp>
#include <azure/core/credentials/credentials.hpp>
#include <azure/core/datetime.hpp>
#include <azure/core/internal/extendable_enumeration.hpp>
#include <azure/core/internal/http/pipeline.hpp>
#include <azure/core/nullable.hpp>
#include <azure/core/paged_response.hpp>
#include <azure/core/response.hpp>
#include <azure/core/url.hpp>
#include <cstdint>
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>
namespace Azure { namespace Security { namespace KeyVault { namespace Secrets { namespace _detail {
/**
* @brief The key vault client performs cryptographic key operations and vault operations against
* the Key Vault service.
*
*/
class KeyVaultClient final {
public:
/**
* @brief Constructs the KeyVaultClient.
* @param url The URL address where the client will send the requests to.
* @param credential Credential to authenticate with the service.
* @param options Optional parameters.
*
*/
explicit KeyVaultClient(
const std::string& url,
const std::shared_ptr<const Core::Credentials::TokenCredential>& credential,
const KeyVaultClientOptions& options = {});
/**
* @brief Gets the KeyVaultClient URL endpoint.
* @return The KeyVaultClient's URL endpoint.
*
*/
std::string GetUrl() const;
/**
* @brief The SET operation adds a secret to the Azure Key Vault. If the named secret already
* exists, Azure Key Vault creates a new version of that secret. This operation requires the
* secrets/set permission.
* @param secretName The name of the secret. The value you provide may be copied globally for
* the purpose of running the service. The value provided should not include personally
* identifiable or sensitive information.
* @param parameters The parameters for setting the secret.
* @param context The context for the operation can be used for request cancellation.
* @return A secret consisting of a value, id and its attributes.
*
*/
Response<Models::SecretBundle> SetSecret(
const std::string& secretName,
const Models::SecretSetParameters& parameters,
const Core::Context& context = {}) const;
/**
* @brief The DELETE operation applies to any secret stored in Azure Key Vault. DELETE cannot be
* applied to an individual version of a secret. This operation requires the secrets/delete
* permission.
* @param secretName The name of the secret.
* @param context The context for the operation can be used for request cancellation.
* @return A Deleted Secret consisting of its previous id, attributes and its tags, as well as
* information on when it will be purged.
*
*/
Response<Models::DeletedSecretBundle> DeleteSecret(
const std::string& secretName,
const Core::Context& context = {}) const;
/**
* @brief The UPDATE operation changes specified attributes of an existing stored secret.
* Attributes that are not specified in the request are left unchanged. The value of a secret
* itself cannot be changed. This operation requires the secrets/set permission.
* @param secretName The name of the secret.
* @param secretVersion The version of the secret.
* @param parameters The parameters for update secret operation.
* @param context The context for the operation can be used for request cancellation.
* @return A secret consisting of a value, id and its attributes.
*
*/
Response<Models::SecretBundle> UpdateSecret(
const std::string& secretName,
const std::string& secretVersion,
const Models::SecretUpdateParameters& parameters,
const Core::Context& context = {}) const;
/**
* @brief The GET operation is applicable to any secret stored in Azure Key Vault. This
* operation requires the secrets/get permission.
* @param secretName The name of the secret.
* @param secretVersion The version of the secret. This URI fragment is optional. If not
* specified, the latest version of the secret is returned.
* @param context The context for the operation can be used for request cancellation.
* @return A secret consisting of a value, id and its attributes.
*
*/
Response<Models::SecretBundle> GetSecret(
const std::string& secretName,
const std::string& secretVersion,
const Core::Context& context = {}) const;
/**
* @brief The Get Secrets operation is applicable to the entire vault. However, only the base
* secret identifier and its attributes are provided in the response. Individual secret versions
* are not listed in the response. This operation requires the secrets/list permission.
* @param options Optional parameters.
* @param context The context for the operation can be used for request cancellation.
* @return The secret list result.
*
*/
GetSecretsPagedResponse GetSecrets(
const KeyVaultClientGetSecretsOptions& options = {},
const Core::Context& context = {}) const;
/**
* @brief The full secret identifier and attributes are provided in the response. No values are
* returned for the secrets. This operations requires the secrets/list permission.
* @param secretName The name of the secret.
* @param options Optional parameters.
* @param context The context for the operation can be used for request cancellation.
* @return The secret list result.
*
*/
GetSecretVersionsPagedResponse GetSecretVersions(
const std::string& secretName,
const KeyVaultClientGetSecretVersionsOptions& options = {},
const Core::Context& context = {}) const;
/**
* @brief The Get Deleted Secrets operation returns the secrets that have been deleted for a
* vault enabled for soft-delete. This operation requires the secrets/list permission.
* @param options Optional parameters.
* @param context The context for the operation can be used for request cancellation.
* @return The deleted secret list result
*
*/
GetDeletedSecretsPagedResponse GetDeletedSecrets(
const KeyVaultClientGetDeletedSecretsOptions& options = {},
const Core::Context& context = {}) const;
/**
* @brief The Get Deleted Secret operation returns the specified deleted secret along with its
* attributes. This operation requires the secrets/get permission.
* @param secretName The name of the secret.
* @param context The context for the operation can be used for request cancellation.
* @return A Deleted Secret consisting of its previous id, attributes and its tags, as well as
* information on when it will be purged.
*
*/
Response<Models::DeletedSecretBundle> GetDeletedSecret(
const std::string& secretName,
const Core::Context& context = {}) const;
/**
* @brief The purge deleted secret operation removes the secret permanently, without the
* possibility of recovery. This operation can only be enabled on a soft-delete enabled vault.
* This operation requires the secrets/purge permission.
* @param secretName The name of the secret.
* @param context The context for the operation can be used for request cancellation.
* @return Operation result.
*
*/
Response<Models::PurgeDeletedSecretResult> PurgeDeletedSecret(
const std::string& secretName,
const Core::Context& context = {}) const;
/**
* @brief Recovers the deleted secret in the specified vault. This operation can only be
* performed on a soft-delete enabled vault. This operation requires the secrets/recover
* permission.
* @param secretName The name of the deleted secret.
* @param context The context for the operation can be used for request cancellation.
* @return A secret consisting of a value, id and its attributes.
*
*/
Response<Models::SecretBundle> RecoverDeletedSecret(
const std::string& secretName,
const Core::Context& context = {}) const;
/**
* @brief Requests that a backup of the specified secret be downloaded to the client. All
* versions of the secret will be downloaded. This operation requires the secrets/backup
* permission.
* @param secretName The name of the secret.
* @param context The context for the operation can be used for request cancellation.
* @return The backup secret result, containing the backup blob.
*
*/
Response<Models::BackupSecretResult> BackupSecret(
const std::string& secretName,
const Core::Context& context = {}) const;
/**
* @brief Restores a backed up secret, and all its versions, to a vault. This operation requires
* the secrets/restore permission.
* @param parameters The parameters to restore the secret.
* @param context The context for the operation can be used for request cancellation.
* @return A secret consisting of a value, id and its attributes.
*
*/
Response<Models::SecretBundle> RestoreSecret(
const Models::SecretRestoreParameters& parameters,
const Core::Context& context = {}) const;
private:
std::shared_ptr<Core::Http::_internal::HttpPipeline> m_pipeline;
Core::Url m_url;
std::string m_apiVersion;
};
}}}}} // namespace Azure::Security::KeyVault::Secrets::_detail

View File

@ -0,0 +1,68 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// Code generated by Microsoft (R) TypeSpec Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
#pragma once
#include "azure/keyvault/secrets/generated/models/generated_models.hpp"
#include <azure/core/internal/client_options.hpp>
#include <azure/core/nullable.hpp>
#include <cstdint>
#include <string>
namespace Azure { namespace Security { namespace KeyVault { namespace Secrets { namespace _detail {
/**
* @brief KeyVaultClient options.
*
*/
struct KeyVaultClientOptions final : public Core::_internal::ClientOptions
{
/// The API version to use for this operation.
std::string ApiVersion = "7.6-preview.2";
};
/**
* @brief GetSecrets operation options.
*
*/
struct KeyVaultClientGetSecretsOptions final
{
/// The URL to fetch the next page of results.
std::string NextPageToken;
/// Maximum number of results to return in a page. If not specified the service will return up
/// to 25 results.
Nullable<std::int32_t> Maxresults;
};
/**
* @brief GetSecretVersions operation options.
*
*/
struct KeyVaultClientGetSecretVersionsOptions final
{
/// The URL to fetch the next page of results.
std::string NextPageToken;
/// Maximum number of results to return in a page. If not specified the service will return up
/// to 25 results.
Nullable<std::int32_t> Maxresults;
};
/**
* @brief GetDeletedSecrets operation options.
*
*/
struct KeyVaultClientGetDeletedSecretsOptions final
{
/// The URL to fetch the next page of results.
std::string NextPageToken;
/// Maximum number of results to return in a page. If not specified the service will return up
/// to 25 results.
Nullable<std::int32_t> Maxresults;
};
}}}}} // namespace Azure::Security::KeyVault::Secrets::_detail

View File

@ -0,0 +1,88 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// Code generated by Microsoft (R) TypeSpec Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
#pragma once
#include "azure/keyvault/secrets/generated/key_vault_client_options.hpp"
#include "azure/keyvault/secrets/generated/models/generated_models.hpp"
#include <azure/core/datetime.hpp>
#include <azure/core/internal/extendable_enumeration.hpp>
#include <azure/core/nullable.hpp>
#include <azure/core/paged_response.hpp>
#include <cstdint>
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>
namespace Azure { namespace Security { namespace KeyVault { namespace Secrets { namespace _detail {
class KeyVaultClient;
/**
* @brief The secret list result.
*
*/
class GetSecretsPagedResponse final : public Core::PagedResponse<GetSecretsPagedResponse> {
friend class KeyVaultClient;
friend class Core::PagedResponse<GetSecretsPagedResponse>;
private:
std::shared_ptr<KeyVaultClient> m_client;
KeyVaultClientGetSecretsOptions m_options;
void OnNextPage(const Core::Context& context);
public:
/// A response message containing a list of secrets in the key vault along with a link to the
/// next page of secrets.
Nullable<std::vector<Models::SecretItem>> Value;
};
/**
* @brief The secret list result.
*
*/
class GetSecretVersionsPagedResponse final
: public Core::PagedResponse<GetSecretVersionsPagedResponse> {
friend class KeyVaultClient;
friend class Core::PagedResponse<GetSecretVersionsPagedResponse>;
private:
std::shared_ptr<KeyVaultClient> m_client;
std::string m_secretName;
KeyVaultClientGetSecretVersionsOptions m_options;
void OnNextPage(const Core::Context& context);
public:
/// A response message containing a list of secrets in the key vault along with a link to the
/// next page of secrets.
Nullable<std::vector<Models::SecretItem>> Value;
};
/**
* @brief The deleted secret list result
*
*/
class GetDeletedSecretsPagedResponse final
: public Core::PagedResponse<GetDeletedSecretsPagedResponse> {
friend class KeyVaultClient;
friend class Core::PagedResponse<GetDeletedSecretsPagedResponse>;
private:
std::shared_ptr<KeyVaultClient> m_client;
KeyVaultClientGetDeletedSecretsOptions m_options;
void OnNextPage(const Core::Context& context);
public:
/// A response message containing a list of deleted secrets in the key vault along with a link
/// to the next page of deleted secrets.
Nullable<std::vector<Models::DeletedSecretItem>> Value;
};
}}}}} // namespace Azure::Security::KeyVault::Secrets::_detail

View File

@ -0,0 +1,316 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// Code generated by Microsoft (R) TypeSpec Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
#pragma once
#include "azure/keyvault/secrets/generated/dll_import_export.hpp"
#include <azure/core/datetime.hpp>
#include <azure/core/internal/extendable_enumeration.hpp>
#include <azure/core/nullable.hpp>
#include <cstdint>
#include <map>
#include <string>
#include <utility>
#include <vector>
namespace Azure { namespace Security { namespace KeyVault { namespace Secrets { namespace _detail {
namespace Models {
/**
* @brief Reflects the deletion recovery level currently in effect for secrets in the current
* vault. If it contains 'Purgeable', the secret can be permanently deleted by a privileged
* user; otherwise, only the system can purge the secret, at the end of the retention interval.
*
*/
class DeletionRecoveryLevel final
: public Core::_internal::ExtendableEnumeration<DeletionRecoveryLevel> {
public:
/**
* @brief Constructs a new DeletionRecoveryLevel instance.
*
**/
DeletionRecoveryLevel() = default;
/**
* @brief Constructs a new DeletionRecoveryLevel instance from a string.
* @param deletionRecoveryLevel String value to construct the new instance from.
*
**/
explicit DeletionRecoveryLevel(std::string deletionRecoveryLevel)
: ExtendableEnumeration(std::move(deletionRecoveryLevel))
{
}
/// Denotes a vault state in which deletion is an irreversible operation, without the
/// possibility for recovery. This level corresponds to no protection being available against
/// a Delete operation; the data is irretrievably lost upon accepting a Delete operation at
/// the entity level or higher (vault, resource group, subscription etc.)
AZ_SECURITY_KEYVAULT_SECRETS_DLLEXPORT static const DeletionRecoveryLevel Purgeable;
/// Denotes a vault state in which deletion is recoverable, and which also permits immediate
/// and permanent deletion (i.e. purge). This level guarantees the recoverability of the
/// deleted entity during the retention interval (90 days), unless a Purge operation is
/// requested, or the subscription is cancelled. System wil permanently delete it after 90
/// days, if not recovered
AZ_SECURITY_KEYVAULT_SECRETS_DLLEXPORT static const DeletionRecoveryLevel
RecoverablePurgeable;
/// Denotes a vault state in which deletion is recoverable without the possibility for
/// immediate and permanent deletion (i.e. purge). This level guarantees the recoverability of
/// the deleted entity during the retention interval (90 days) and while the subscription is
/// still available. System wil permanently delete it after 90 days, if not recovered
AZ_SECURITY_KEYVAULT_SECRETS_DLLEXPORT static const DeletionRecoveryLevel Recoverable;
/// Denotes a vault and subscription state in which deletion is recoverable within retention
/// interval (90 days), immediate and permanent deletion (i.e. purge) is not permitted, and in
/// which the subscription itself cannot be permanently canceled. System wil permanently
/// delete it after 90 days, if not recovered
AZ_SECURITY_KEYVAULT_SECRETS_DLLEXPORT static const DeletionRecoveryLevel
RecoverableProtectedSubscription;
/// Denotes a vault state in which deletion is recoverable, and which also permits immediate
/// and permanent deletion (i.e. purge when 7 <= SoftDeleteRetentionInDays < 90). This level
/// guarantees the recoverability of the deleted entity during the retention interval, unless
/// a Purge operation is requested, or the subscription is cancelled.
AZ_SECURITY_KEYVAULT_SECRETS_DLLEXPORT static const DeletionRecoveryLevel
CustomizedRecoverablePurgeable;
/// Denotes a vault state in which deletion is recoverable without the possibility for
/// immediate and permanent deletion (i.e. purge when 7 <= SoftDeleteRetentionInDays <
/// 90).This level guarantees the recoverability of the deleted entity during the retention
/// interval and while the subscription is still available.
AZ_SECURITY_KEYVAULT_SECRETS_DLLEXPORT static const DeletionRecoveryLevel
CustomizedRecoverable;
/// Denotes a vault and subscription state in which deletion is recoverable, immediate and
/// permanent deletion (i.e. purge) is not permitted, and in which the subscription itself
/// cannot be permanently canceled when 7 <= SoftDeleteRetentionInDays < 90. This level
/// guarantees the recoverability of the deleted entity during the retention interval, and
/// also reflects the fact that the subscription itself cannot be cancelled.
AZ_SECURITY_KEYVAULT_SECRETS_DLLEXPORT static const DeletionRecoveryLevel
CustomizedRecoverableProtectedSubscription;
};
/**
* @brief The secret management attributes.
*
*/
struct SecretAttributes final
{
/// Determines whether the object is enabled.
Nullable<bool> Enabled;
/// Not before date in UTC.
Nullable<DateTime> NotBefore;
/// Expiry date in UTC.
Nullable<DateTime> Expires;
/// [out] Creation time in UTC.
Nullable<DateTime> Created;
/// [out] Last updated time in UTC.
Nullable<DateTime> Updated;
/// [out] softDelete data retention days. Value should be >=7 and <=90 when softDelete
/// enabled, otherwise 0.
Nullable<std::int32_t> RecoverableDays;
/// [out] Reflects the deletion recovery level currently in effect for secrets in the current
/// vault. If it contains 'Purgeable', the secret can be permanently deleted by a privileged
/// user; otherwise, only the system can purge the secret, at the end of the retention
/// interval.
Nullable<DeletionRecoveryLevel> RecoveryLevel;
};
/**
* @brief A secret consisting of a value, id and its attributes.
*
*/
struct SecretBundle final
{
/// The secret value.
Nullable<std::string> Value;
/// The secret id.
Nullable<std::string> Id;
/// The content type of the secret.
Nullable<std::string> ContentType;
/// The secret management attributes.
Nullable<SecretAttributes> Attributes;
/// Application specific metadata in the form of key-value pairs.
Nullable<std::map<std::string, std::string>> Tags;
/// [out] If this is a secret backing a KV certificate, then this field specifies the
/// corresponding key backing the KV certificate.
Nullable<std::string> Kid;
/// [out] True if the secret's lifetime is managed by key vault. If this is a secret backing a
/// certificate, then managed will be true.
Nullable<bool> Managed;
};
/**
* @brief The secret set parameters.
*
*/
struct SecretSetParameters final
{
/// The value of the secret.
std::string Value;
/// Application specific metadata in the form of key-value pairs.
Nullable<std::map<std::string, std::string>> Tags;
/// Type of the secret value such as a password.
Nullable<std::string> ContentType;
/// The secret management attributes.
Nullable<Models::SecretAttributes> SecretAttributes;
};
/**
* @brief A Deleted Secret consisting of its previous id, attributes and its tags, as well as
* information on when it will be purged.
*
*/
struct DeletedSecretBundle final
{
/// The secret value.
Nullable<std::string> Value;
/// The secret id.
Nullable<std::string> Id;
/// The content type of the secret.
Nullable<std::string> ContentType;
/// The secret management attributes.
Nullable<SecretAttributes> Attributes;
/// Application specific metadata in the form of key-value pairs.
Nullable<std::map<std::string, std::string>> Tags;
/// [out] If this is a secret backing a KV certificate, then this field specifies the
/// corresponding key backing the KV certificate.
Nullable<std::string> Kid;
/// [out] True if the secret's lifetime is managed by key vault. If this is a secret backing a
/// certificate, then managed will be true.
Nullable<bool> Managed;
/// The url of the recovery object, used to identify and recover the deleted secret.
Nullable<std::string> RecoveryId;
/// [out] The time when the secret is scheduled to be purged, in UTC
Nullable<DateTime> ScheduledPurgeDate;
/// [out] The time when the secret was deleted, in UTC
Nullable<DateTime> DeletedDate;
};
/**
* @brief The secret update parameters.
*
*/
struct SecretUpdateParameters final
{
/// Type of the secret value such as a password.
Nullable<std::string> ContentType;
/// The secret management attributes.
Nullable<Models::SecretAttributes> SecretAttributes;
/// Application specific metadata in the form of key-value pairs.
Nullable<std::map<std::string, std::string>> Tags;
};
/**
* @brief The secret item containing secret metadata.
*
*/
struct SecretItem final
{
/// Secret identifier.
Nullable<std::string> Id;
/// The secret management attributes.
Nullable<SecretAttributes> Attributes;
/// Application specific metadata in the form of key-value pairs.
Nullable<std::map<std::string, std::string>> Tags;
/// Type of the secret value such as a password.
Nullable<std::string> ContentType;
/// [out] True if the secret's lifetime is managed by key vault. If this is a key backing a
/// certificate, then managed will be true.
Nullable<bool> Managed;
};
/**
* @brief The deleted secret item containing metadata about the deleted secret.
*
*/
struct DeletedSecretItem final
{
/// Secret identifier.
Nullable<std::string> Id;
/// The secret management attributes.
Nullable<SecretAttributes> Attributes;
/// Application specific metadata in the form of key-value pairs.
Nullable<std::map<std::string, std::string>> Tags;
/// Type of the secret value such as a password.
Nullable<std::string> ContentType;
/// [out] True if the secret's lifetime is managed by key vault. If this is a key backing a
/// certificate, then managed will be true.
Nullable<bool> Managed;
/// The url of the recovery object, used to identify and recover the deleted secret.
Nullable<std::string> RecoveryId;
/// [out] The time when the secret is scheduled to be purged, in UTC
Nullable<DateTime> ScheduledPurgeDate;
/// [out] The time when the secret was deleted, in UTC
Nullable<DateTime> DeletedDate;
};
/**
* @brief PurgeDeletedSecret operation result.
*
*/
struct PurgeDeletedSecretResult final
{
};
/**
* @brief The backup secret result, containing the backup blob.
*
*/
struct BackupSecretResult final
{
/// [out] The backup blob containing the backed up secret.
Nullable<std::vector<std::uint8_t>> Value;
};
/**
* @brief The secret restore parameters.
*
*/
struct SecretRestoreParameters final
{
/// The backup blob associated with a secret bundle.
std::vector<std::uint8_t> SecretBundleBackup;
};
}}}}}} // namespace Azure::Security::KeyVault::Secrets::_detail::Models

View File

@ -0,0 +1,10 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// Code generated by Microsoft (R) TypeSpec Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
#pragma once
#if defined(AZURE_RTTI) || (0 /*@AZ_SECURITY_KEYVAULT_SECRETS_RTTI@*/)
#define AZ_SECURITY_KEYVAULT_SECRETS_RTTI
#endif

View File

@ -11,6 +11,12 @@
#include <azure/keyvault/secrets/keyvault_secret.hpp>
namespace Azure { namespace Security { namespace KeyVault { namespace Secrets {
class SecretClient;
class DeletedSecretPagedResponse;
namespace _detail { namespace Models {
struct DeletedSecretBundle;
struct DeletedSecretItem;
}} // namespace _detail::Models
/**
* @brief A Deleted Secret consisting of its previous id, attributes and its tags,
* as well as information on when it will be purged.
@ -44,5 +50,12 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Secrets {
* @param name Name of the deleted secret.
*/
DeletedSecret(std::string name) : KeyVaultSecret(std::move(name)) {}
private:
DeletedSecret(_detail::Models::DeletedSecretBundle const& deletedSecret);
DeletedSecret(_detail::Models::DeletedSecretItem const& deletedSecret);
friend class SecretClient;
friend class DeletedSecretOperation;
friend class DeletedSecretPagedResponse;
};
}}}} // namespace Azure::Security::KeyVault::Secrets

View File

@ -16,8 +16,8 @@
#include <azure/core/response.hpp>
#include <thread>
namespace Azure { namespace Security { namespace KeyVault { namespace Secrets {
class SecretClient;
/**
* @brief Represents a long running operation to restore a deleted secret.

View File

@ -6,10 +6,10 @@
* @brief Keyvault Secret actions options
*/
#pragma once
#include "azure/keyvault/secrets/generated/key_vault_client_options.hpp"
#include "dll_import_export.hpp"
#include <azure/core/internal/client_options.hpp>
namespace Azure { namespace Security { namespace KeyVault { namespace Secrets {
/**
@ -22,7 +22,7 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Secrets {
* @brief Service Version used.
*
*/
std::string ApiVersion{"7.5"};
std::string ApiVersion{_detail::KeyVaultClientOptions().ApiVersion};
};
/**

View File

@ -10,7 +10,13 @@
#include "azure/keyvault/secrets/keyvault_secret_properties.hpp"
namespace Azure { namespace Security { namespace KeyVault { namespace Secrets {
class SecretClient;
class SecretPropertiesPagedResponse;
namespace _detail { namespace Models {
struct SecretBundle;
struct SecretItem;
struct SecretSetParameters;
}} // namespace _detail::Models
/**
* @brief Secret is the resource consisting of name, value and its attributes specified in
* SecretProperties. It is managed by Secret Service.
@ -54,30 +60,17 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Secrets {
* @param name The name of the secret.
* @param value The name of the secret.
*/
KeyVaultSecret(std::string const& name, std::string const& value)
: Name(name), Value(value), Properties(name)
{
if (Name.empty())
{
throw std::invalid_argument("Name cannot be empty");
}
if (Value.HasValue() == false || Value.Value().empty())
{
throw std::invalid_argument("Value cannot be empty");
}
}
KeyVaultSecret(std::string const& name, std::string const& value);
private:
KeyVaultSecret(std::string name) : Name(std::move(name))
{
if (Name.empty())
{
throw std::invalid_argument("Name cannot be empty");
}
}
KeyVaultSecret(std::string name);
KeyVaultSecret(_detail::Models::SecretBundle const& secret);
KeyVaultSecret(_detail::Models::SecretItem const& secret);
_detail::Models::SecretSetParameters ToSetSecretParameters() const;
friend struct DeletedSecret;
friend class SecretClient;
friend class SecretPropertiesPagedResponse;
};
}}}} // namespace Azure::Security::KeyVault::Secrets

View File

@ -8,6 +8,7 @@
#pragma once
#include "azure/keyvault/secrets/generated/key_vault_client_paged_responses.hpp"
#include "azure/keyvault/secrets/keyvault_deleted_secret.hpp"
#include "azure/keyvault/secrets/keyvault_secret_properties.hpp"
@ -34,7 +35,8 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Secrets {
std::string m_secretName;
std::shared_ptr<SecretClient> m_secretClient;
_detail::GetSecretsPagedResponse m_generatedResponse;
_detail::GetSecretVersionsPagedResponse m_generatedVersionResponse;
void OnNextPage(const Azure::Core::Context& context);
SecretPropertiesPagedResponse(
@ -48,6 +50,36 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Secrets {
RawResponse = std::move(rawResponse);
}
SecretPropertiesPagedResponse(
_detail::GetSecretsPagedResponse& secretPagedResponse,
std::unique_ptr<Azure::Core::Http::RawResponse> rawResponse,
std::shared_ptr<SecretClient> secretClient,
std::string const& secretName = std::string())
: m_secretName(secretName), m_secretClient(std::move(secretClient)),
m_generatedResponse(std::move(secretPagedResponse))
{
for (auto& item : m_generatedResponse.Value.Value())
{
Items.push_back(KeyVaultSecret(item).Properties);
}
RawResponse = std::move(rawResponse);
}
SecretPropertiesPagedResponse(
_detail::GetSecretVersionsPagedResponse& secretPagedResponse,
std::unique_ptr<Azure::Core::Http::RawResponse> rawResponse,
std::shared_ptr<SecretClient> secretClient,
std::string const& secretName = std::string())
: m_secretName(secretName), m_secretClient(std::move(secretClient)),
m_generatedVersionResponse(std::move(secretPagedResponse))
{
for (auto& item : m_generatedVersionResponse.Value.Value())
{
Items.push_back(KeyVaultSecret(item).Properties);
}
RawResponse = std::move(rawResponse);
}
public:
/**
* @brief Construct a new SecretPropertiesPagedResponse object.
@ -74,6 +106,8 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Secrets {
friend class Azure::Core::PagedResponse<DeletedSecretPagedResponse>;
std::shared_ptr<SecretClient> m_secretClient;
_detail::GetDeletedSecretsPagedResponse m_generatedResponse;
void OnNextPage(const Azure::Core::Context& context);
DeletedSecretPagedResponse(
@ -86,6 +120,20 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Secrets {
RawResponse = std::move(rawResponse);
}
DeletedSecretPagedResponse(
_detail::GetDeletedSecretsPagedResponse& secretPagedResponse,
std::unique_ptr<Azure::Core::Http::RawResponse> rawResponse,
std::shared_ptr<SecretClient> secretClient)
: m_secretClient(std::move(secretClient)),
m_generatedResponse(std::move(secretPagedResponse))
{
for (auto& item : m_generatedResponse.Value.Value())
{
Items.push_back(DeletedSecret(item));
}
RawResponse = std::move(rawResponse);
}
public:
/**
* @brief Construct a new Deleted Key Single Page object

View File

@ -13,8 +13,11 @@
#include <azure/core/url.hpp>
#include <unordered_map>
namespace Azure { namespace Security { namespace KeyVault { namespace Secrets {
class SecretClient;
namespace _detail { namespace Models {
struct SecretUpdateParameters;
}} // namespace _detail::Models
/**
* @brief The Secret attributes managed by the KeyVault service.
@ -141,5 +144,9 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Secrets {
*
*/
static SecretProperties CreateFromURL(std::string const& url);
private:
_detail::Models::SecretUpdateParameters ToSecretUpdateParameters() const;
friend class SecretClient;
};
}}}} // namespace Azure::Security::KeyVault::Secrets

View File

@ -15,6 +15,7 @@
#include "azure/keyvault/secrets/keyvault_secret.hpp"
#include "azure/keyvault/secrets/keyvault_secret_paged_response.hpp"
#include "dll_import_export.hpp"
#include "generated.hpp"
#include <azure/core/http/http.hpp>
#include <azure/core/internal/http/pipeline.hpp>
@ -45,6 +46,7 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Secrets {
class SecretClient final {
private:
std::shared_ptr<_detail::KeyVaultClient> m_client = nullptr;
// Using a shared pipeline for a client to share it with LRO (like delete key)
Azure::Core::Url m_vaultUrl;
std::string m_apiVersion;
@ -68,12 +70,7 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Secrets {
*
* @param keyClient An existing key vault key client.
*/
explicit SecretClient(SecretClient const& keyClient)
: m_vaultUrl(keyClient.m_vaultUrl), m_apiVersion(keyClient.m_apiVersion),
m_pipeline(keyClient.m_pipeline)
{
}
explicit SecretClient(SecretClient const& keyClient) { m_client = keyClient.m_client; }
~SecretClient() = default;
@ -278,18 +275,6 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Secrets {
*
* @return The key secret's primary URL endpoint.
*/
std::string GetUrl() const;
private:
Azure::Core::Http::Request CreateRequest(
Azure::Core::Http::HttpMethod method,
std::vector<std::string> const& path = {},
Azure::Core::IO::BodyStream* content = nullptr) const;
Azure::Core::Http::Request ContinuationTokenRequest(
std::vector<std::string> const& path,
const Azure::Nullable<std::string>& NextPageToken) const;
std::unique_ptr<Azure::Core::Http::RawResponse> SendRequest(
Azure::Core::Http::Request& request,
Azure::Core::Context const& context) const;
std::string GetUrl() const { return m_client->GetUrl(); }
};
}}}} // namespace Azure::Security::KeyVault::Secrets

View File

@ -53,8 +53,7 @@ int main()
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::string updatedValueString = updatedSecret.Properties.ContentType.ValueOr("NONE RETURNED");
std::cout << "Secret's content type is now " << updatedValueString << std::endl;
// @end_snippet

View File

@ -57,10 +57,8 @@ Call UpdateSecretProperties to change on of the secret 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.Properties.ContentType.ValueOr("NONE RETURNED");
std::cout << "Secret's content type is now " << updatedValueString << std::endl;
```
## Deleting a secret

View File

@ -0,0 +1,19 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// Code generated by Microsoft (R) TypeSpec Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
#include "azure/keyvault/secrets/generated/models/generated_models.hpp"
using namespace Azure::Security::KeyVault::Secrets::_detail::Models;
const DeletionRecoveryLevel DeletionRecoveryLevel::Purgeable{"Purgeable"};
const DeletionRecoveryLevel DeletionRecoveryLevel::RecoverablePurgeable{"Recoverable+Purgeable"};
const DeletionRecoveryLevel DeletionRecoveryLevel::Recoverable{"Recoverable"};
const DeletionRecoveryLevel DeletionRecoveryLevel::RecoverableProtectedSubscription{
"Recoverable+ProtectedSubscription"};
const DeletionRecoveryLevel DeletionRecoveryLevel::CustomizedRecoverablePurgeable{
"CustomizedRecoverable+Purgeable"};
const DeletionRecoveryLevel DeletionRecoveryLevel::CustomizedRecoverable{"CustomizedRecoverable"};
const DeletionRecoveryLevel DeletionRecoveryLevel::CustomizedRecoverableProtectedSubscription{
"CustomizedRecoverable+ProtectedSubscription"};

View File

@ -0,0 +1,17 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// Code generated by Microsoft (R) TypeSpec Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
#include "azure/keyvault/secrets/generated/key_vault_client.hpp"
#include "azure/keyvault/secrets/generated/key_vault_client_paged_responses.hpp"
using namespace Azure::Security::KeyVault::Secrets::_detail;
void GetDeletedSecretsPagedResponse::OnNextPage(Core::Context const& context)
{
const auto pageToken = this->NextPageToken;
this->m_options.NextPageToken = pageToken.Value();
*this = this->m_client->GetDeletedSecrets(this->m_options, context);
this->CurrentPageToken = pageToken.Value();
}

View File

@ -0,0 +1,17 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// Code generated by Microsoft (R) TypeSpec Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
#include "azure/keyvault/secrets/generated/key_vault_client.hpp"
#include "azure/keyvault/secrets/generated/key_vault_client_paged_responses.hpp"
using namespace Azure::Security::KeyVault::Secrets::_detail;
void GetSecretVersionsPagedResponse::OnNextPage(Core::Context const& context)
{
const auto pageToken = this->NextPageToken;
this->m_options.NextPageToken = pageToken.Value();
*this = this->m_client->GetSecretVersions(this->m_secretName, this->m_options, context);
this->CurrentPageToken = pageToken.Value();
}

View File

@ -0,0 +1,17 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// Code generated by Microsoft (R) TypeSpec Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
#include "azure/keyvault/secrets/generated/key_vault_client.hpp"
#include "azure/keyvault/secrets/generated/key_vault_client_paged_responses.hpp"
using namespace Azure::Security::KeyVault::Secrets::_detail;
void GetSecretsPagedResponse::OnNextPage(Core::Context const& context)
{
const auto pageToken = this->NextPageToken;
this->m_options.NextPageToken = pageToken.Value();
*this = this->m_client->GetSecrets(this->m_options, context);
this->CurrentPageToken = pageToken.Value();
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,110 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// Code generated by Microsoft (R) TypeSpec Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
#include "azure/keyvault/secrets/keyvault_deleted_secret.hpp"
#include "azure/keyvault/secrets/generated/models/generated_models.hpp"
namespace Azure { namespace Security { namespace KeyVault { namespace Secrets {
DeletedSecret::DeletedSecret(_detail::Models::DeletedSecretBundle const& deletedSecret)
{
if (deletedSecret.RecoveryId.HasValue())
{
RecoveryId = deletedSecret.RecoveryId.Value();
}
if (deletedSecret.ScheduledPurgeDate.HasValue())
{
ScheduledPurgeDate = deletedSecret.ScheduledPurgeDate.Value();
}
if (deletedSecret.DeletedDate.HasValue())
{
DeletedOn = deletedSecret.DeletedDate.Value();
}
if (deletedSecret.Value.HasValue())
{
Value = deletedSecret.Value;
}
if (deletedSecret.Id.HasValue())
{
Properties = SecretProperties::CreateFromURL(deletedSecret.RecoveryId.Value());
Id = deletedSecret.Id.Value();
Properties.Id = deletedSecret.Id.Value();
Name = Properties.Name;
}
if (deletedSecret.ContentType.HasValue())
{
Properties.ContentType = deletedSecret.ContentType;
}
Properties.KeyId = deletedSecret.Kid;
if (deletedSecret.Managed.HasValue())
{
Properties.Managed = deletedSecret.Managed.Value();
}
if (deletedSecret.Attributes.HasValue())
{
Properties.ExpiresOn = deletedSecret.Attributes.Value().Expires;
Properties.NotBefore = deletedSecret.Attributes.Value().NotBefore;
Properties.Enabled = deletedSecret.Attributes.Value().Enabled;
Properties.CreatedOn = deletedSecret.Attributes.Value().Created;
Properties.UpdatedOn = deletedSecret.Attributes.Value().Updated;
if (deletedSecret.Attributes.Value().RecoverableDays.HasValue())
{
Properties.RecoverableDays = deletedSecret.Attributes.Value().RecoverableDays.Value();
}
}
if (deletedSecret.Tags.HasValue())
{
Properties.Tags = std::unordered_map<std::string, std::string>(
deletedSecret.Tags.Value().begin(), deletedSecret.Tags.Value().end());
}
}
DeletedSecret::DeletedSecret(_detail::Models::DeletedSecretItem const& deletedSecret)
{
if (deletedSecret.RecoveryId.HasValue())
{
RecoveryId = deletedSecret.RecoveryId.Value();
}
if (deletedSecret.ScheduledPurgeDate.HasValue())
{
ScheduledPurgeDate = deletedSecret.ScheduledPurgeDate.Value();
}
if (deletedSecret.DeletedDate.HasValue())
{
DeletedOn = deletedSecret.DeletedDate.Value();
}
if (deletedSecret.RecoveryId.HasValue())
{
Properties = SecretProperties::CreateFromURL(deletedSecret.Id.Value());
Id = deletedSecret.Id.Value();
Properties.Id = deletedSecret.Id.Value();
}
if (deletedSecret.ContentType.HasValue())
{
Properties.ContentType = deletedSecret.ContentType;
}
if (deletedSecret.Managed.HasValue())
{
Properties.Managed = deletedSecret.Managed.Value();
}
if (deletedSecret.Attributes.HasValue())
{
Properties.ExpiresOn = deletedSecret.Attributes.Value().Expires;
Properties.NotBefore = deletedSecret.Attributes.Value().NotBefore;
Properties.Enabled = deletedSecret.Attributes.Value().Enabled;
Properties.CreatedOn = deletedSecret.Attributes.Value().Created;
Properties.UpdatedOn = deletedSecret.Attributes.Value().Updated;
if (deletedSecret.Attributes.Value().RecoverableDays.HasValue())
{
Properties.RecoverableDays = deletedSecret.Attributes.Value().RecoverableDays.Value();
}
}
if (deletedSecret.Tags.HasValue())
{
Properties.Tags = std::unordered_map<std::string, std::string>(
deletedSecret.Tags.Value().begin(), deletedSecret.Tags.Value().end());
}
}
}}}} // namespace Azure::Security::KeyVault::Secrets

View File

@ -34,10 +34,12 @@ std::unique_ptr<Azure::Core::Http::RawResponse> RecoverDeletedSecretOperation::P
Azure::Core::Context const& context)
{
std::unique_ptr<Azure::Core::Http::RawResponse> rawResponse;
KeyVaultSecret secretResult;
try
{
rawResponse = m_secretClient->GetSecret(m_value.Name, GetSecretOptions(), context).RawResponse;
auto response = m_secretClient->GetSecret(m_continuationToken, GetSecretOptions(), context);
secretResult = response.Value;
rawResponse = std::move(response.RawResponse);
}
catch (Azure::Core::RequestFailedException& error)
{
@ -61,8 +63,7 @@ std::unique_ptr<Azure::Core::Http::RawResponse> RecoverDeletedSecretOperation::P
if (m_status == Azure::Core::OperationStatus::Succeeded)
{
auto receivedSecret = _detail::SecretSerializer::Deserialize(m_value.Name, *rawResponse);
m_value = receivedSecret.Properties;
m_value = secretResult.Properties;
}
return rawResponse;
@ -125,10 +126,12 @@ std::unique_ptr<Azure::Core::Http::RawResponse> DeleteSecretOperation::PollInter
Azure::Core::Context const& context)
{
std::unique_ptr<Azure::Core::Http::RawResponse> rawResponse;
Azure::Security::KeyVault::Secrets::DeletedSecret secretResult;
try
{
rawResponse = m_secretClient->GetDeletedSecret(m_value.Name, context).RawResponse;
auto response = m_secretClient->GetDeletedSecret(m_continuationToken, context);
secretResult = response.Value;
rawResponse = std::move(response.RawResponse);
}
catch (Azure::Core::RequestFailedException& error)
{
@ -152,7 +155,7 @@ std::unique_ptr<Azure::Core::Http::RawResponse> DeleteSecretOperation::PollInter
if (m_status == Azure::Core::OperationStatus::Succeeded)
{
m_value = _detail::DeletedSecretSerializer::Deserialize(m_value.Name, *rawResponse);
m_value = secretResult;
}
return rawResponse;
}

View File

@ -0,0 +1,155 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// Code generated by Microsoft (R) TypeSpec Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
#include "azure/keyvault/secrets/keyvault_secret.hpp"
#include "azure/keyvault/secrets/generated/models/generated_models.hpp"
namespace Azure { namespace Security { namespace KeyVault { namespace Secrets {
KeyVaultSecret::KeyVaultSecret(std::string const& name, std::string const& value)
: Name(name), Value(value), Properties(name)
{
if (Name.empty())
{
throw std::invalid_argument("Name cannot be empty");
}
if (Value.HasValue() == false || Value.Value().empty())
{
throw std::invalid_argument("Value cannot be empty");
}
}
KeyVaultSecret::KeyVaultSecret(std::string name) : Name(std::move(name))
{
if (Name.empty())
{
throw std::invalid_argument("Name cannot be empty");
}
}
KeyVaultSecret::KeyVaultSecret(_detail::Models::SecretBundle const& secret)
{
Value = secret.Value;
if (secret.Id.HasValue())
{
Id = secret.Id.Value();
Properties = SecretProperties::CreateFromURL(secret.Id.Value());
Name = Properties.Name;
}
Properties.ContentType = secret.ContentType;
Properties.KeyId = secret.Kid;
if (secret.Attributes.HasValue())
{
Properties.ExpiresOn = secret.Attributes.Value().Expires;
Properties.NotBefore = secret.Attributes.Value().NotBefore;
Properties.Enabled = secret.Attributes.Value().Enabled;
Properties.CreatedOn = secret.Attributes.Value().Created;
Properties.UpdatedOn = secret.Attributes.Value().Updated;
if (secret.Attributes.Value().RecoverableDays.HasValue())
{
Properties.RecoverableDays = secret.Attributes.Value().RecoverableDays.Value();
}
if (secret.Attributes.Value().RecoveryLevel.HasValue())
{
Properties.RecoveryLevel = secret.Attributes.Value().RecoveryLevel.Value().ToString();
}
}
if (secret.Managed.HasValue())
{
Properties.Managed = secret.Managed.Value();
}
if (secret.Tags.HasValue())
{
Properties.Tags = std::unordered_map<std::string, std::string>(
secret.Tags.Value().begin(), secret.Tags.Value().end());
}
}
KeyVaultSecret::KeyVaultSecret(_detail::Models::SecretItem const& secret)
{
if (secret.Id.HasValue())
{
Id = secret.Id.Value();
Properties = SecretProperties::CreateFromURL(secret.Id.Value());
Name = Properties.Name;
}
if (secret.Tags.HasValue())
{
Properties.Tags = std::unordered_map<std::string, std::string>(
secret.Tags.Value().begin(), secret.Tags.Value().end());
}
Properties.ContentType = secret.ContentType;
if (secret.Managed.HasValue())
{
Properties.Managed = secret.Managed.Value();
}
if (secret.Attributes.HasValue())
{
Properties.ExpiresOn = secret.Attributes.Value().Expires;
Properties.NotBefore = secret.Attributes.Value().NotBefore;
Properties.Enabled = secret.Attributes.Value().Enabled;
Properties.CreatedOn = secret.Attributes.Value().Created;
Properties.UpdatedOn = secret.Attributes.Value().Updated;
if (secret.Attributes.Value().RecoverableDays.HasValue())
{
Properties.RecoverableDays = secret.Attributes.Value().RecoverableDays.Value();
}
if (secret.Attributes.Value().RecoveryLevel.HasValue())
{
Properties.RecoveryLevel = secret.Attributes.Value().RecoveryLevel.Value().ToString();
}
}
}
_detail::Models::SecretSetParameters KeyVaultSecret::ToSetSecretParameters() const
{
_detail::Models::SecretSetParameters secretParameters;
if (Properties.ContentType.HasValue())
{
secretParameters.ContentType = Properties.ContentType;
}
if (Value.HasValue())
{
secretParameters.Value = Value.Value();
}
secretParameters.Tags
= std::map<std::string, std::string>(Properties.Tags.begin(), Properties.Tags.end());
secretParameters.SecretAttributes = _detail::Models::SecretAttributes();
if (Properties.Enabled.HasValue())
{
secretParameters.SecretAttributes.Value().Enabled = Properties.Enabled;
}
if (Properties.NotBefore.HasValue())
{
secretParameters.SecretAttributes.Value().NotBefore = Properties.NotBefore;
}
if (Properties.ExpiresOn.HasValue())
{
secretParameters.SecretAttributes.Value().Expires = Properties.ExpiresOn;
}
if (Properties.CreatedOn.HasValue())
{
secretParameters.SecretAttributes.Value().Created = Properties.CreatedOn;
}
if (Properties.UpdatedOn.HasValue())
{
secretParameters.SecretAttributes.Value().Updated = Properties.UpdatedOn;
}
if (Properties.RecoverableDays.HasValue())
{
secretParameters.SecretAttributes.Value().RecoverableDays
= static_cast<int32_t>(Properties.RecoverableDays.Value());
}
if (Properties.RecoveryLevel.HasValue())
{
secretParameters.SecretAttributes.Value().RecoveryLevel
= _detail::Models::DeletionRecoveryLevel(Properties.RecoveryLevel.Value());
}
return secretParameters;
}
}}}} // namespace Azure::Security::KeyVault::Secrets

View File

@ -9,6 +9,8 @@
#include "azure/keyvault/secrets/keyvault_secret.hpp"
#include "private/secret_serializers.hpp"
#include <azure/keyvault/secrets/generated/models/generated_models.hpp>
using namespace Azure::Security::KeyVault::Secrets;
SecretProperties SecretProperties::CreateFromURL(std::string const& url)
@ -20,3 +22,46 @@ SecretProperties SecretProperties::CreateFromURL(std::string const& url)
_detail::SecretSerializer::ParseIDUrl(result, urlInstance.GetAbsoluteUrl());
return result;
}
_detail::Models::SecretUpdateParameters SecretProperties::ToSecretUpdateParameters() const
{
_detail::Models::SecretUpdateParameters secretParameters;
if (ContentType.HasValue())
{
secretParameters.ContentType = ContentType.Value();
}
secretParameters.Tags = std::map<std::string, std::string>(Tags.begin(), Tags.end());
secretParameters.SecretAttributes = _detail::Models::SecretAttributes();
if (ExpiresOn.HasValue())
{
secretParameters.SecretAttributes.Value().Expires = ExpiresOn;
}
if (NotBefore.HasValue())
{
secretParameters.SecretAttributes.Value().NotBefore = NotBefore;
}
if (Enabled.HasValue())
{
secretParameters.SecretAttributes.Value().Enabled = Enabled;
}
if (RecoveryLevel.HasValue())
{
secretParameters.SecretAttributes.Value().RecoveryLevel
= _detail::Models::DeletionRecoveryLevel(RecoveryLevel.Value());
}
if (RecoverableDays.HasValue())
{
secretParameters.SecretAttributes.Value().RecoverableDays
= static_cast<int32_t>(RecoverableDays.Value());
}
if (CreatedOn.HasValue())
{
secretParameters.SecretAttributes.Value().Created = CreatedOn.Value();
}
if (UpdatedOn.HasValue())
{
secretParameters.SecretAttributes.Value().Updated = UpdatedOn.Value();
}
return secretParameters;
}

View File

@ -1,59 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#include "private/keyvault_secrets_common_request.hpp"
#include <azure/core/exception.hpp>
#include <azure/core/http/http.hpp>
#include <memory>
using namespace Azure::Security::KeyVault::Secrets;
using namespace Azure::Core::Http::_internal;
std::unique_ptr<Azure::Core::Http::RawResponse> _detail::KeyVaultSecretsCommonRequest::SendRequest(
Azure::Core::Http::_internal::HttpPipeline const& pipeline,
Azure::Core::Http::Request& request,
Azure::Core::Context const& context)
{
auto response = pipeline.Send(request, context);
auto responseCode = response->GetStatusCode();
switch (responseCode)
{
// 200, 201, 202, 204 are accepted responses
case Azure::Core::Http::HttpStatusCode::Ok:
case Azure::Core::Http::HttpStatusCode::Created:
case Azure::Core::Http::HttpStatusCode::Accepted:
case Azure::Core::Http::HttpStatusCode::NoContent:
break;
default:
throw Azure::Core::RequestFailedException(response);
}
return response;
}
Azure::Core::Http::Request _detail::KeyVaultSecretsCommonRequest::CreateRequest(
Azure::Core::Url url,
std::string const& apiVersion,
Azure::Core::Http::HttpMethod method,
std::vector<std::string> const& path,
Azure::Core::IO::BodyStream* content)
{
using namespace Azure::Core::Http;
Request request = content == nullptr ? Request(std::move(method), std::move(url))
: Request(std::move(method), std::move(url), content);
request.SetHeader(ContentHeaderName, ApplicationJsonValue);
request.GetUrl().AppendQueryParameter(ApiVersionQueryParamName, apiVersion);
for (std::string const& p : path)
{
if (!p.empty())
{
request.GetUrl().AppendPath(p);
}
}
return request;
}

View File

@ -0,0 +1,50 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// Code generated by Microsoft (R) TypeSpec Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
#pragma once
#include <cstdint>
#define AZURE_SECURITY_KEYVAULT_SECRETS_GENERATED_VERSION_MAJOR 1
#define AZURE_SECURITY_KEYVAULT_SECRETS_GENERATED_VERSION_MINOR 0
#define AZURE_SECURITY_KEYVAULT_SECRETS_GENERATED_VERSION_PATCH 0
#define AZURE_SECURITY_KEYVAULT_SECRETS_GENERATED_VERSION_PRERELEASE "beta.1"
#define AZURE_SECURITY_KEYVAULT_SECRETS_GENERATED_VERSION_ITOA_HELPER(i) #i
#define AZURE_SECURITY_KEYVAULT_SECRETS_GENERATED_VERSION_ITOA(i) \
AZURE_SECURITY_KEYVAULT_SECRETS_GENERATED_VERSION_ITOA_HELPER(i)
namespace Azure {
namespace Security {
namespace KeyVault {
namespace Secrets {
namespace Generated {
namespace _detail {
class PackageVersion final {
public:
static constexpr std::int32_t Major = AZURE_SECURITY_KEYVAULT_SECRETS_GENERATED_VERSION_MAJOR;
static constexpr std::int32_t Minor = AZURE_SECURITY_KEYVAULT_SECRETS_GENERATED_VERSION_MINOR;
static constexpr std::int32_t Patch = AZURE_SECURITY_KEYVAULT_SECRETS_GENERATED_VERSION_PATCH;
static constexpr bool IsPreRelease
= sizeof(AZURE_SECURITY_KEYVAULT_SECRETS_GENERATED_VERSION_PRERELEASE) != sizeof("");
static constexpr const char* ToString()
{
return IsPreRelease
? AZURE_SECURITY_KEYVAULT_SECRETS_GENERATED_VERSION_ITOA(AZURE_SECURITY_KEYVAULT_SECRETS_GENERATED_VERSION_MAJOR) "." AZURE_SECURITY_KEYVAULT_SECRETS_GENERATED_VERSION_ITOA(
AZURE_SECURITY_KEYVAULT_SECRETS_GENERATED_VERSION_MINOR) "." AZURE_SECURITY_KEYVAULT_SECRETS_GENERATED_VERSION_ITOA(AZURE_SECURITY_KEYVAULT_SECRETS_GENERATED_VERSION_PATCH) "-" AZURE_SECURITY_KEYVAULT_SECRETS_GENERATED_VERSION_PRERELEASE
: AZURE_SECURITY_KEYVAULT_SECRETS_GENERATED_VERSION_ITOA(AZURE_SECURITY_KEYVAULT_SECRETS_GENERATED_VERSION_MAJOR) "." AZURE_SECURITY_KEYVAULT_SECRETS_GENERATED_VERSION_ITOA(
AZURE_SECURITY_KEYVAULT_SECRETS_GENERATED_VERSION_MINOR) "." AZURE_SECURITY_KEYVAULT_SECRETS_GENERATED_VERSION_ITOA(AZURE_SECURITY_KEYVAULT_SECRETS_GENERATED_VERSION_PATCH);
}
};
}}}}}} // namespace Azure::Security::KeyVault::Secrets::Generated::_detail
#undef AZURE_SECURITY_KEYVAULT_SECRETS_GENERATED_VERSION_ITOA_HELPER
#undef AZURE_SECURITY_KEYVAULT_SECRETS_GENERATED_VERSION_ITOA
#undef AZURE_SECURITY_KEYVAULT_SECRETS_GENERATED_VERSION_MAJOR
#undef AZURE_SECURITY_KEYVAULT_SECRETS_GENERATED_VERSION_MINOR
#undef AZURE_SECURITY_KEYVAULT_SECRETS_GENERATED_VERSION_PATCH
#undef AZURE_SECURITY_KEYVAULT_SECRETS_GENERATED_VERSION_PRERELEASE

View File

@ -1,43 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
/**
* @brief Provides a wrapper class for the Azure Core Pipeline for Secrets service.
*
*/
#pragma once
#include <azure/core/context.hpp>
#include <azure/core/http/http.hpp>
#include <azure/core/internal/http/pipeline.hpp>
#include <azure/core/internal/json/json.hpp>
#include <azure/core/internal/json/json_serializable.hpp>
#include <azure/core/response.hpp>
#include <memory>
#include <string>
#include <vector>
namespace Azure { namespace Security { namespace KeyVault { namespace Secrets { namespace _detail {
constexpr static const char ContentHeaderName[] = "content-type";
constexpr static const char ApplicationJsonValue[] = "application/json";
constexpr static const char ApiVersionQueryParamName[] = "api-version";
struct KeyVaultSecretsCommonRequest final
{
static Azure::Core::Http::Request CreateRequest(
Azure::Core::Url url,
std::string const& apiVersion,
Azure::Core::Http::HttpMethod method,
std::vector<std::string> const& path,
Azure::Core::IO::BodyStream* content);
static std::unique_ptr<Azure::Core::Http::RawResponse> SendRequest(
Azure::Core::Http::_internal::HttpPipeline const& pipeline,
Azure::Core::Http::Request& request,
Azure::Core::Context const& context);
};
}}}}} // namespace Azure::Security::KeyVault::Secrets::_detail

View File

@ -1,55 +1,31 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
/**
* @file
* @brief Provides version information.
*/
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// Code generated by Microsoft (R) TypeSpec Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
#pragma once
#include <cstdint>
#define AZURE_SECURITY_KEYVAULT_SECRETS_VERSION_MAJOR 4
#define AZURE_SECURITY_KEYVAULT_SECRETS_VERSION_MINOR 3
#define AZURE_SECURITY_KEYVAULT_SECRETS_VERSION_MAJOR 1
#define AZURE_SECURITY_KEYVAULT_SECRETS_VERSION_MINOR 0
#define AZURE_SECURITY_KEYVAULT_SECRETS_VERSION_PATCH 0
#define AZURE_SECURITY_KEYVAULT_SECRETS_VERSION_PRERELEASE "beta.3"
#define AZURE_SECURITY_KEYVAULT_SECRETS_VERSION_PRERELEASE "beta.1"
#define AZURE_SECURITY_KEYVAULT_SECRETS_VERSION_ITOA_HELPER(i) #i
#define AZURE_SECURITY_KEYVAULT_SECRETS_VERSION_ITOA(i) \
AZURE_SECURITY_KEYVAULT_SECRETS_VERSION_ITOA_HELPER(i)
namespace Azure { namespace Security { namespace KeyVault { namespace Secrets { namespace _detail {
/**
* @brief Provides version information.
*/
class PackageVersion final {
public:
/**
* @brief Major numeric identifier.
*/
static constexpr int32_t Major = AZURE_SECURITY_KEYVAULT_SECRETS_VERSION_MAJOR;
static constexpr std::int32_t Major = AZURE_SECURITY_KEYVAULT_SECRETS_VERSION_MAJOR;
static constexpr std::int32_t Minor = AZURE_SECURITY_KEYVAULT_SECRETS_VERSION_MINOR;
static constexpr std::int32_t Patch = AZURE_SECURITY_KEYVAULT_SECRETS_VERSION_PATCH;
/**
* @brief Minor numeric identifier.
*/
static constexpr int32_t Minor = AZURE_SECURITY_KEYVAULT_SECRETS_VERSION_MINOR;
/**
* @brief Patch numeric identifier.
*/
static constexpr int32_t Patch = AZURE_SECURITY_KEYVAULT_SECRETS_VERSION_PATCH;
/**
* @brief Indicates whether the SDK is in a pre-release state.
*/
static constexpr bool IsPreRelease
= sizeof(AZURE_SECURITY_KEYVAULT_SECRETS_VERSION_PRERELEASE) != sizeof("");
/**
* @brief The version in string format used for telemetry following the `semver.org` standard
* (https://semver.org).
*/
static constexpr const char* ToString()
{
return IsPreRelease
@ -63,7 +39,6 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Secrets {
#undef AZURE_SECURITY_KEYVAULT_SECRETS_VERSION_ITOA_HELPER
#undef AZURE_SECURITY_KEYVAULT_SECRETS_VERSION_ITOA
#undef AZURE_SECURITY_KEYVAULT_SECRETS_VERSION_MAJOR
#undef AZURE_SECURITY_KEYVAULT_SECRETS_VERSION_MINOR
#undef AZURE_SECURITY_KEYVAULT_SECRETS_VERSION_PATCH

View File

@ -24,20 +24,6 @@ using namespace Azure::Security::KeyVault::Secrets;
namespace Azure { namespace Security { namespace KeyVault { namespace Secrets { namespace _detail {
struct SecretSerializer final
{
// Creates a new key based on a name and an HTTP raw response.
static KeyVaultSecret Deserialize(
std::string const& name,
Azure::Core::Http::RawResponse const& rawResponse);
// Create from HTTP raw response only.
static KeyVaultSecret Deserialize(Azure::Core::Http::RawResponse const& rawResponse);
// Updates a Key based on an HTTP raw response.
static void Deserialize(KeyVaultSecret& key, Azure::Core::Http::RawResponse const& rawResponse);
// Serializes a key vault secret for set action
static std::string Serialize(KeyVaultSecret const& parameters);
// Extract the host out of the URL (with port if available)
static std::string GetUrlAuthorityWithScheme(Azure::Core::Url const& url)
{
@ -84,47 +70,4 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Secrets {
}
}
};
struct DeletedSecretSerializer final
{
// Creates a new deleted secret based on a name and an HTTP raw response.
static DeletedSecret Deserialize(
std::string const& name,
Azure::Core::Http::RawResponse const& rawResponse);
// Create deleted secret from HTTP raw response only.
static DeletedSecret Deserialize(Azure::Core::Http::RawResponse const& rawResponse);
// Updates a deleted secret based on an HTTP raw response.
static void Deserialize(
DeletedSecret& secret,
Azure::Core::Http::RawResponse const& rawResponse);
};
struct SecretPropertiesSerializer final
{
static std::string Serialize(SecretProperties const& properties);
};
struct BackupSecretSerializer final
{
static BackupSecretResult Deserialize(Azure::Core::Http::RawResponse const& rawResponse);
};
struct RestoreSecretSerializer final
{
static std::string Serialize(std::vector<uint8_t> const& backup);
};
struct SecretPropertiesPagedResultSerializer final
{
static SecretPropertiesPagedResponse Deserialize(
Azure::Core::Http::RawResponse const& rawResponse);
};
struct DeletedSecretPagedResultSerializer final
{
static DeletedSecretPagedResponse Deserialize(
Azure::Core::Http::RawResponse const& rawResponse);
};
}}}}} // namespace Azure::Security::KeyVault::Secrets::_detail

View File

@ -8,9 +8,9 @@
#include "azure/keyvault/secrets/secret_client.hpp"
#include "azure/keyvault/secrets/generated.hpp"
#include "azure/keyvault/secrets/keyvault_operations.hpp"
#include "private/keyvault_protocol.hpp"
#include "private/keyvault_secrets_common_request.hpp"
#include "private/package_version.hpp"
#include "private/secret_constants.hpp"
#include "private/secret_serializers.hpp"
@ -29,63 +29,21 @@ using namespace Azure::Core::Http::Policies;
using namespace Azure::Core::Http::Policies::_internal;
using namespace Azure::Security::KeyVault::Secrets::_detail;
std::unique_ptr<RawResponse> SecretClient::SendRequest(
Azure::Core::Http::Request& request,
Azure::Core::Context const& context) const
{
return KeyVaultSecretsCommonRequest::SendRequest(*m_pipeline, request, context);
}
Request SecretClient::CreateRequest(
HttpMethod method,
std::vector<std::string> const& path,
Azure::Core::IO::BodyStream* content) const
{
return KeyVaultSecretsCommonRequest::CreateRequest(
m_vaultUrl, m_apiVersion, method, path, content);
}
Request SecretClient::ContinuationTokenRequest(
std::vector<std::string> const& path,
const Azure::Nullable<std::string>& NextPageToken) const
{
if (NextPageToken)
{
// Using a continuation token requires to send the request to the continuation token URL instead
// of the default URL which is used only for the first page.
Azure::Core::Url nextPageUrl(NextPageToken.Value());
return Request(HttpMethod::Get, nextPageUrl);
}
return CreateRequest(HttpMethod::Get, path);
}
SecretClient::SecretClient(
std::string const& vaultUrl,
std::shared_ptr<const Azure::Core::Credentials::TokenCredential> credential,
SecretClientOptions options)
: m_vaultUrl(vaultUrl), m_apiVersion(options.ApiVersion)
{
auto apiVersion = options.ApiVersion;
Azure::Core::Url url(vaultUrl);
std::vector<std::unique_ptr<HttpPolicy>> perRetryPolicies;
{
Azure::Core::Credentials::TokenRequestContext tokenContext;
tokenContext.Scopes = {_internal::UrlScope::GetScopeFromUrl(url)};
perRetryPolicies.emplace_back(
std::make_unique<_internal::KeyVaultChallengeBasedAuthenticationPolicy>(
credential, tokenContext));
}
std::vector<std::unique_ptr<HttpPolicy>> perCallPolicies;
m_pipeline = std::make_shared<Azure::Core::Http::_internal::HttpPipeline>(
options,
KeyVaultServicePackageName,
PackageVersion::ToString(),
std::move(perRetryPolicies),
std::move(perCallPolicies));
_detail::KeyVaultClientOptions generatedOptions;
generatedOptions.ApiVersion = options.ApiVersion;
generatedOptions.Log = options.Log;
generatedOptions.Retry = options.Retry;
generatedOptions.Transport = options.Transport;
generatedOptions.Telemetry = options.Telemetry;
generatedOptions.PerOperationPolicies = std::move(options.PerOperationPolicies);
generatedOptions.PerRetryPolicies = std::move(options.PerRetryPolicies);
m_client = std::make_shared<_detail::KeyVaultClient>(
_detail::KeyVaultClient(vaultUrl, credential, generatedOptions));
}
Azure::Response<KeyVaultSecret> SecretClient::GetSecret(
@ -93,24 +51,20 @@ Azure::Response<KeyVaultSecret> SecretClient::GetSecret(
GetSecretOptions const& options,
Azure::Core::Context const& context) const
{
auto request = CreateRequest(HttpMethod::Get, {_detail::SecretPath, name, options.Version});
// Send and parse response
auto rawResponse = SendRequest(request, context);
auto value = _detail::SecretSerializer::Deserialize(name, *rawResponse);
return Azure::Response<KeyVaultSecret>(std::move(value), std::move(rawResponse));
auto secret = m_client->GetSecret(name, options.Version.empty() ? "/" : options.Version, context);
KeyVaultSecret secretResult(secret.Value);
secretResult.Properties.VaultUrl = m_vaultUrl.GetAbsoluteUrl();
return Azure::Response<KeyVaultSecret>(std::move(secretResult), std::move(secret.RawResponse));
}
Azure::Response<DeletedSecret> SecretClient::GetDeletedSecret(
std::string const& name,
Azure::Core::Context const& context) const
{
auto request = CreateRequest(HttpMethod::Get, {_detail::DeletedSecretPath, name});
// Send and parse response
auto rawResponse = SendRequest(request, context);
auto value = _detail::DeletedSecretSerializer::Deserialize(name, *rawResponse);
return Azure::Response<DeletedSecret>(std::move(value), std::move(rawResponse));
auto response = m_client->GetDeletedSecret(name, context);
DeletedSecret secretResult(response.Value);
secretResult.Properties.VaultUrl = m_vaultUrl.GetAbsoluteUrl();
return Azure::Response<DeletedSecret>(std::move(secretResult), std::move(response.RawResponse));
}
Azure::Response<KeyVaultSecret> SecretClient::SetSecret(
@ -118,8 +72,11 @@ Azure::Response<KeyVaultSecret> SecretClient::SetSecret(
std::string const& value,
Azure::Core::Context const& context) const
{
KeyVaultSecret setParameters(name, value);
return SetSecret(name, setParameters, context);
_detail::Models::SecretSetParameters secretParameters;
secretParameters.Value = value;
auto response = m_client->SetSecret(name, secretParameters, context);
KeyVaultSecret secretResult(response.Value);
return Azure::Response<KeyVaultSecret>(std::move(secretResult), std::move(response.RawResponse));
}
Azure::Response<KeyVaultSecret> SecretClient::SetSecret(
@ -127,97 +84,75 @@ Azure::Response<KeyVaultSecret> SecretClient::SetSecret(
KeyVaultSecret const& secret,
Azure::Core::Context const& context) const
{
auto payload = _detail::SecretSerializer::Serialize(secret);
Azure::Core::IO::MemoryBodyStream payloadStream(
reinterpret_cast<const uint8_t*>(payload.data()), payload.size());
auto request = CreateRequest(HttpMethod::Put, {_detail::SecretPath, name}, &payloadStream);
// Send and parse response
auto rawResponse = SendRequest(request, context);
auto value = _detail::SecretSerializer::Deserialize(name, *rawResponse);
return Azure::Response<KeyVaultSecret>(std::move(value), std::move(rawResponse));
_detail::Models::SecretSetParameters secretParameters = secret.ToSetSecretParameters();
auto response = m_client->SetSecret(name, secretParameters, context);
KeyVaultSecret secretResult(response.Value);
return Azure::Response<KeyVaultSecret>(std::move(secretResult), std::move(response.RawResponse));
}
Azure::Response<KeyVaultSecret> SecretClient::UpdateSecretProperties(
SecretProperties const& properties,
Azure::Core::Context const& context) const
{
auto payload = _detail::SecretPropertiesSerializer::Serialize(properties);
Azure::Core::IO::MemoryBodyStream payloadStream(
reinterpret_cast<const uint8_t*>(payload.data()), payload.size());
auto request = CreateRequest(
HttpMethod::Patch,
{_detail::SecretPath, properties.Name, properties.Version},
&payloadStream);
// Send and parse response
auto rawResponse = SendRequest(request, context);
auto value = _detail::SecretSerializer::Deserialize(properties.Name, *rawResponse);
return Azure::Response<KeyVaultSecret>(std::move(value), std::move(rawResponse));
_detail::Models::SecretUpdateParameters secretParameters = properties.ToSecretUpdateParameters();
auto response
= m_client->UpdateSecret(properties.Name, properties.Version, secretParameters, context);
KeyVaultSecret secretResult(response.Value);
return Azure::Response<KeyVaultSecret>(std::move(secretResult), std::move(response.RawResponse));
}
Azure::Response<BackupSecretResult> SecretClient::BackupSecret(
std::string const& name,
Azure::Core::Context const& context) const
{
auto request
= CreateRequest(HttpMethod::Post, {_detail::SecretPath, name, _detail::BackupSecretPath});
// Send and parse response
auto rawResponse = SendRequest(request, context);
auto value = _detail::BackupSecretSerializer::Deserialize(*rawResponse);
return Azure::Response<BackupSecretResult>(std::move(value), std::move(rawResponse));
auto response = m_client->BackupSecret(name, context);
BackupSecretResult backupResult;
backupResult.Secret = std::move(response.Value.Value.Value());
return Azure::Response<BackupSecretResult>(
std::move(backupResult), std::move(response.RawResponse));
}
Azure::Response<KeyVaultSecret> SecretClient::RestoreSecretBackup(
BackupSecretResult const& backup,
Azure::Core::Context const& context) const
{
auto payload = _detail::RestoreSecretSerializer::Serialize(backup.Secret);
Azure::Core::IO::MemoryBodyStream payloadStream(
reinterpret_cast<const uint8_t*>(payload.data()), payload.size());
auto request = CreateRequest(
HttpMethod::Post, {_detail::SecretPath, _detail::RestoreSecretPath}, &payloadStream);
// Send and parse response
auto rawResponse = SendRequest(request, context);
auto value = _detail::SecretSerializer::Deserialize(*rawResponse);
return Azure::Response<KeyVaultSecret>(std::move(value), std::move(rawResponse));
_detail::Models::SecretRestoreParameters restoreParameters;
restoreParameters.SecretBundleBackup = backup.Secret;
auto response = m_client->RestoreSecret(restoreParameters, context);
KeyVaultSecret secretResult(response.Value);
return Azure::Response<KeyVaultSecret>(std::move(secretResult), std::move(response.RawResponse));
}
Azure::Response<PurgedSecret> SecretClient::PurgeDeletedSecret(
std::string const& name,
Azure::Core::Context const& context) const
{
auto request = CreateRequest(HttpMethod::Delete, {_detail::DeletedSecretPath, name});
// Send and parse response
auto rawResponse = SendRequest(request, context);
PurgedSecret value;
return Azure::Response<PurgedSecret>(std::move(value), std::move(rawResponse));
auto response = m_client->PurgeDeletedSecret(name, context);
PurgedSecret purgedResult;
return Azure::Response<PurgedSecret>(std::move(purgedResult), std::move(response.RawResponse));
}
Azure::Security::KeyVault::Secrets::DeleteSecretOperation SecretClient::StartDeleteSecret(
std::string const& name,
Azure::Core::Context const& context) const
{
auto request = CreateRequest(HttpMethod::Delete, {_detail::SecretPath, name});
// Send and parse response
auto rawResponse = SendRequest(request, context);
auto value = _detail::DeletedSecretSerializer::Deserialize(name, *rawResponse);
auto responseT = Azure::Response<DeletedSecret>(std::move(value), std::move(rawResponse));
auto response = m_client->DeleteSecret(name, context);
DeletedSecret value(response.Value);
auto responseT
= Azure::Response<DeletedSecret>(std::move(value), std::move(response.RawResponse));
return DeleteSecretOperation(std::make_shared<SecretClient>(*this), std::move(responseT));
}
Azure::Security::KeyVault::Secrets::RecoverDeletedSecretOperation SecretClient::
StartRecoverDeletedSecret(std::string const& name, Azure::Core::Context const& context) const
{
auto request = CreateRequest(
HttpMethod::Post, {_detail::DeletedSecretPath, name, _detail::RecoverDeletedSecretPath});
// Send and parse response
auto rawResponse = SendRequest(request, context);
auto parsedResponse = _detail::SecretSerializer::Deserialize(name, *rawResponse);
auto value = parsedResponse.Properties;
auto responseT = Azure::Response<SecretProperties>(std::move(value), std::move(rawResponse));
auto response = m_client->RecoverDeletedSecret(name, context);
KeyVaultSecret value(response.Value);
value.Name = name;
value.Properties.Name = name;
auto responseT = Azure::Response<SecretProperties>(
std::move(value.Properties), std::move(response.RawResponse));
return RecoverDeletedSecretOperation(std::make_shared<SecretClient>(*this), std::move(responseT));
}
@ -225,14 +160,16 @@ SecretPropertiesPagedResponse SecretClient::GetPropertiesOfSecrets(
GetPropertiesOfSecretsOptions const& options,
Azure::Core::Context const& context) const
{
// Request and settings
auto request = ContinuationTokenRequest({SecretPath}, options.NextPageToken);
_detail::KeyVaultClientGetSecretsOptions generatedOptions;
if (options.NextPageToken.HasValue())
{
generatedOptions.NextPageToken = options.NextPageToken.Value();
}
auto response = m_client->GetSecrets(generatedOptions, context);
SecretPropertiesPagedResponse secretPropertiesPagedResponse(
response, std::move(response.RawResponse), std::make_unique<SecretClient>(*this));
// Send and parse response
auto rawResponse = SendRequest(request, context);
auto value = _detail::SecretPropertiesPagedResultSerializer::Deserialize(*rawResponse);
return SecretPropertiesPagedResponse(
std::move(value), std::move(rawResponse), std::make_unique<SecretClient>(*this));
return secretPropertiesPagedResponse;
}
SecretPropertiesPagedResponse SecretClient::GetPropertiesOfSecretsVersions(
@ -240,29 +177,31 @@ SecretPropertiesPagedResponse SecretClient::GetPropertiesOfSecretsVersions(
GetPropertiesOfSecretVersionsOptions const& options,
Azure::Core::Context const& context) const
{
// Request and settings
auto request = ContinuationTokenRequest(
{_detail::SecretPath, name, _detail::VersionsName}, options.NextPageToken);
_detail::KeyVaultClientGetSecretVersionsOptions generatedOptions;
if (options.NextPageToken.HasValue())
{
generatedOptions.NextPageToken = options.NextPageToken.Value();
}
auto response = m_client->GetSecretVersions(name, generatedOptions, context);
SecretPropertiesPagedResponse secretPropertiesPagedResponse(
response, std::move(response.RawResponse), std::make_unique<SecretClient>(*this), name);
// Send and parse response
auto rawResponse = SendRequest(request, context);
auto value = _detail::SecretPropertiesPagedResultSerializer::Deserialize(*rawResponse);
return SecretPropertiesPagedResponse(
std::move(value), std::move(rawResponse), std::make_unique<SecretClient>(*this), name);
return secretPropertiesPagedResponse;
}
DeletedSecretPagedResponse SecretClient::GetDeletedSecrets(
GetDeletedSecretsOptions const& options,
Azure::Core::Context const& context) const
{
// Request and settings
auto request = ContinuationTokenRequest({_detail::DeletedSecretPath}, options.NextPageToken);
_detail::KeyVaultClientGetDeletedSecretsOptions generatedOptions;
if (options.NextPageToken.HasValue())
{
generatedOptions.NextPageToken = options.NextPageToken.Value();
}
_detail::GetDeletedSecretsPagedResponse response
= m_client->GetDeletedSecrets(generatedOptions, context);
DeletedSecretPagedResponse deletedSecretPagedResponse(
response, std::move(response.RawResponse), std::make_unique<SecretClient>(*this));
// Send and parse response
auto rawResponse = SendRequest(request, context);
auto value = _detail::DeletedSecretPagedResultSerializer::Deserialize(*rawResponse);
return DeletedSecretPagedResponse(
std::move(value), std::move(rawResponse), std::make_unique<SecretClient>(*this));
return deletedSecretPagedResponse;
}
std::string SecretClient::GetUrl() const { return m_vaultUrl.GetAbsoluteUrl(); }

View File

@ -20,406 +20,3 @@ using namespace Azure::Core::Json::_internal;
using Azure::Core::_internal::PosixTimeConverter;
using namespace Azure::Security::KeyVault::Secrets;
using namespace Azure::Security::KeyVault::Secrets::_detail;
// Creates a new key based on a name and an HTTP raw response.
KeyVaultSecret SecretSerializer::Deserialize(
std::string const& name,
Azure::Core::Http::RawResponse const& rawResponse)
{
KeyVaultSecret secret;
secret.Name = name;
_detail::SecretSerializer::Deserialize(secret, rawResponse);
return secret;
}
// Create from HTTP raw response only.
KeyVaultSecret SecretSerializer::Deserialize(Azure::Core::Http::RawResponse const& rawResponse)
{
KeyVaultSecret secret;
_detail::SecretSerializer::Deserialize(secret, rawResponse);
return secret;
}
// Updates a Key based on an HTTP raw response.
void SecretSerializer::Deserialize(
KeyVaultSecret& secret,
Azure::Core::Http::RawResponse const& rawResponse)
{
auto const& body = rawResponse.GetBody();
auto jsonParser = json::parse(body);
secret.Id = jsonParser[_detail::IdPropertyName];
secret.Properties.Id = secret.Id;
ParseIDUrl(secret.Properties, secret.Id);
if (!secret.Properties.Name.empty())
{
secret.Name = secret.Properties.Name;
}
else
{
secret.Properties.Name = secret.Name;
}
// Parse URL for the various attributes
if (jsonParser.contains(_detail::AttributesPropertyName))
{
auto attributes = jsonParser[_detail::AttributesPropertyName];
JsonOptional::SetIfExists(secret.Properties.Enabled, attributes, _detail::EnabledPropertyName);
JsonOptional::SetIfExists<int64_t, Azure::DateTime>(
secret.Properties.NotBefore,
attributes,
_detail::NbfPropertyName,
PosixTimeConverter::PosixTimeToDateTime);
JsonOptional::SetIfExists<int64_t, Azure::DateTime>(
secret.Properties.ExpiresOn,
attributes,
_detail::ExpPropertyName,
PosixTimeConverter::PosixTimeToDateTime);
JsonOptional::SetIfExists<int64_t, Azure::DateTime>(
secret.Properties.CreatedOn,
attributes,
_detail::CreatedPropertyName,
PosixTimeConverter::PosixTimeToDateTime);
JsonOptional::SetIfExists<int64_t, Azure::DateTime>(
secret.Properties.UpdatedOn,
attributes,
_detail::UpdatedPropertyName,
PosixTimeConverter::PosixTimeToDateTime);
JsonOptional::SetIfExists<std::string>(
secret.Properties.RecoveryLevel, attributes, _detail::RecoveryLevelPropertyName);
JsonOptional::SetIfExists<int64_t>(
secret.Properties.RecoverableDays, attributes, _detail::RecoverableDaysPropertyName);
}
// "Tags"
if (jsonParser.contains(_detail::TagsPropertyName))
{
auto const& tags = jsonParser[_detail::TagsPropertyName];
{
for (auto tag = tags.begin(); tag != tags.end(); ++tag)
{
secret.Properties.Tags.emplace(tag.key(), tag.value().get<std::string>());
}
}
}
// managed
if (jsonParser.contains(_detail::ManagedPropertyName))
{
secret.Properties.Managed = jsonParser[_detail::ManagedPropertyName].get<bool>();
}
// value
if (jsonParser.contains(_detail::ValuePropertyName))
{
secret.Value = jsonParser[_detail::ValuePropertyName];
}
// key id
JsonOptional::SetIfExists<std::string>(
secret.Properties.KeyId, jsonParser, _detail::KeyIdPropertyName);
// content type
JsonOptional::SetIfExists<std::string>(
secret.Properties.ContentType, jsonParser, _detail::ContentTypePropertyName);
}
DeletedSecret DeletedSecretSerializer::Deserialize(
std::string const& name,
Azure::Core::Http::RawResponse const& rawResponse)
{
DeletedSecret deletedSecret(name);
Deserialize(deletedSecret, rawResponse);
return deletedSecret;
}
// Create deleted secret from HTTP raw response only.
DeletedSecret DeletedSecretSerializer::Deserialize(
Azure::Core::Http::RawResponse const& rawResponse)
{
DeletedSecret deletedSecret;
Deserialize(deletedSecret, rawResponse);
return deletedSecret;
}
// Updates a deleted secret based on an HTTP raw response.
void DeletedSecretSerializer::Deserialize(
DeletedSecret& secret,
Azure::Core::Http::RawResponse const& rawResponse)
{
SecretSerializer::Deserialize(secret, rawResponse);
auto const& body = rawResponse.GetBody();
auto jsonParser = json::parse(body);
secret.RecoveryId = jsonParser[_detail::RecoveryIdPropertyName];
secret.ScheduledPurgeDate = PosixTimeConverter::PosixTimeToDateTime(
jsonParser[_detail::ScheduledPurgeDatePropertyName]);
secret.DeletedOn
= PosixTimeConverter::PosixTimeToDateTime(jsonParser[_detail::DeletedDatePropertyName]);
}
// serializes a set secret parameters object
std::string SecretSerializer::Serialize(KeyVaultSecret const& parameters)
{
json payload;
JsonOptional::SetFromNullable(parameters.Value, payload, _detail::ValuePropertyName);
JsonOptional::SetFromNullable(
parameters.Properties.ContentType, payload, _detail::ContentTypePropertyName);
json attributes;
JsonOptional::SetFromNullable<Azure::DateTime, int64_t>(
parameters.Properties.CreatedOn,
attributes,
_detail::CreatedPropertyName,
PosixTimeConverter::DateTimeToPosixTime);
JsonOptional::SetFromNullable(
parameters.Properties.Enabled, attributes, _detail::EnabledPropertyName);
JsonOptional::SetFromNullable<Azure::DateTime, int64_t>(
parameters.Properties.ExpiresOn,
attributes,
_detail::ExpPropertyName,
PosixTimeConverter::DateTimeToPosixTime);
JsonOptional::SetFromNullable<Azure::DateTime, int64_t>(
parameters.Properties.NotBefore,
attributes,
_detail::NbfPropertyName,
PosixTimeConverter::DateTimeToPosixTime);
JsonOptional::SetFromNullable(
parameters.Properties.RecoverableDays, attributes, _detail::RecoverableDaysPropertyName);
JsonOptional::SetFromNullable(
parameters.Properties.RecoveryLevel, attributes, _detail::RecoveryLevelPropertyName);
JsonOptional::SetFromNullable<Azure::DateTime, int64_t>(
parameters.Properties.UpdatedOn,
attributes,
_detail::UpdatedPropertyName,
PosixTimeConverter::DateTimeToPosixTime);
// optional tags
attributes[TagsPropertyName] = json(parameters.Properties.Tags);
payload[AttributesPropertyName] = attributes;
return payload.dump();
}
std::string SecretPropertiesSerializer::Serialize(SecretProperties const& properties)
{
json payload;
// content type
JsonOptional::SetFromNullable(properties.ContentType, payload, _detail::ContentTypePropertyName);
// optional tags
payload[TagsPropertyName] = json(properties.Tags);
// attributes
json attributes;
JsonOptional::SetFromNullable(
properties.RecoverableDays, attributes, _detail::RecoverableDaysPropertyName);
JsonOptional::SetFromNullable(
properties.RecoveryLevel, attributes, _detail::RecoveryLevelPropertyName);
JsonOptional::SetFromNullable(properties.Enabled, attributes, _detail::EnabledPropertyName);
JsonOptional::SetFromNullable<Azure::DateTime, int64_t>(
properties.NotBefore,
attributes,
_detail::NbfPropertyName,
PosixTimeConverter::DateTimeToPosixTime);
JsonOptional::SetFromNullable<Azure::DateTime, int64_t>(
properties.ExpiresOn,
attributes,
_detail::ExpPropertyName,
PosixTimeConverter::DateTimeToPosixTime);
payload[AttributesPropertyName] = attributes;
return payload.dump();
}
BackupSecretResult BackupSecretSerializer::Deserialize(
Azure::Core::Http::RawResponse const& rawResponse)
{
auto const& body = rawResponse.GetBody();
auto jsonParser = json::parse(body);
auto encodedResult = jsonParser[_detail::ValuePropertyName].get<std::string>();
BackupSecretResult data;
data.Secret = Base64Url::Base64UrlDecode(encodedResult);
return data;
}
std::string RestoreSecretSerializer::Serialize(std::vector<uint8_t> const& backup)
{
json payload;
payload[_detail::ValuePropertyName] = Base64Url::Base64UrlEncode(backup);
return payload.dump();
}
SecretPropertiesPagedResponse SecretPropertiesPagedResultSerializer::Deserialize(
Azure::Core::Http::RawResponse const& rawResponse)
{
SecretPropertiesPagedResponse result;
auto const& body = rawResponse.GetBody();
auto jsonParser = json::parse(body);
JsonOptional::SetIfExists(result.NextPageToken, jsonParser, "nextLink");
// Key properties
auto secretsPropertiesJson = jsonParser["value"];
for (auto const& secretProperties : secretsPropertiesJson)
{
SecretProperties item;
item.Id = secretProperties[_detail::IdPropertyName].get<std::string>();
_detail::SecretSerializer::ParseIDUrl(item, item.Id);
// Parse URL for the various attributes
if (secretProperties.contains(_detail::AttributesPropertyName))
{
auto attributes = secretProperties[_detail::AttributesPropertyName];
JsonOptional::SetIfExists(item.Enabled, attributes, _detail::EnabledPropertyName);
JsonOptional::SetIfExists<int64_t, Azure::DateTime>(
item.NotBefore,
attributes,
_detail::NbfPropertyName,
PosixTimeConverter::PosixTimeToDateTime);
JsonOptional::SetIfExists<int64_t, Azure::DateTime>(
item.ExpiresOn,
attributes,
_detail::ExpPropertyName,
PosixTimeConverter::PosixTimeToDateTime);
JsonOptional::SetIfExists<int64_t, Azure::DateTime>(
item.CreatedOn,
attributes,
_detail::CreatedPropertyName,
PosixTimeConverter::PosixTimeToDateTime);
JsonOptional::SetIfExists<int64_t, Azure::DateTime>(
item.UpdatedOn,
attributes,
_detail::UpdatedPropertyName,
PosixTimeConverter::PosixTimeToDateTime);
JsonOptional::SetIfExists<std::string>(
item.RecoveryLevel, attributes, _detail::RecoveryLevelPropertyName);
JsonOptional::SetIfExists<int64_t>(
item.RecoverableDays, attributes, _detail::RecoverableDaysPropertyName);
}
// "Tags"
if (secretProperties.contains(_detail::TagsPropertyName))
{
auto const& tags = secretProperties[_detail::TagsPropertyName];
{
for (auto tag = tags.begin(); tag != tags.end(); ++tag)
{
item.Tags.emplace(tag.key(), tag.value().get<std::string>());
}
}
}
// managed
if (secretProperties.contains(_detail::ManagedPropertyName))
{
item.Managed = secretProperties[_detail::ManagedPropertyName].get<bool>();
}
// content type
JsonOptional::SetIfExists<std::string>(
item.ContentType, secretProperties, _detail::ContentTypePropertyName);
result.Items.emplace_back(item);
}
return result;
}
DeletedSecretPagedResponse DeletedSecretPagedResultSerializer::Deserialize(
Azure::Core::Http::RawResponse const& rawResponse)
{
DeletedSecretPagedResponse result;
auto const& body = rawResponse.GetBody();
auto jsonParser = json::parse(body);
auto string = jsonParser.dump();
JsonOptional::SetIfExists(result.NextPageToken, jsonParser, "nextLink");
// Key properties
auto secretsPropertiesJson = jsonParser["value"];
for (auto const& secretProperties : secretsPropertiesJson)
{
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))
{
auto attributes = secretProperties[_detail::AttributesPropertyName];
JsonOptional::SetIfExists(item.Properties.Enabled, attributes, _detail::EnabledPropertyName);
JsonOptional::SetIfExists<int64_t, Azure::DateTime>(
item.Properties.NotBefore,
attributes,
_detail::NbfPropertyName,
PosixTimeConverter::PosixTimeToDateTime);
JsonOptional::SetIfExists<int64_t, Azure::DateTime>(
item.Properties.ExpiresOn,
attributes,
_detail::ExpPropertyName,
PosixTimeConverter::PosixTimeToDateTime);
JsonOptional::SetIfExists<int64_t, Azure::DateTime>(
item.Properties.CreatedOn,
attributes,
_detail::CreatedPropertyName,
PosixTimeConverter::PosixTimeToDateTime);
JsonOptional::SetIfExists<int64_t, Azure::DateTime>(
item.Properties.UpdatedOn,
attributes,
_detail::UpdatedPropertyName,
PosixTimeConverter::PosixTimeToDateTime);
JsonOptional::SetIfExists<std::string>(
item.Properties.RecoveryLevel, attributes, _detail::RecoveryLevelPropertyName);
JsonOptional::SetIfExists<int64_t>(
item.Properties.RecoverableDays, attributes, _detail::RecoverableDaysPropertyName);
}
// "Tags"
if (secretProperties.contains(_detail::TagsPropertyName))
{
auto const& tags = secretProperties[_detail::TagsPropertyName];
{
for (auto tag = tags.begin(); tag != tags.end(); ++tag)
{
item.Properties.Tags.emplace(tag.key(), tag.value().get<std::string>());
}
}
}
// managed
if (secretProperties.contains(_detail::ManagedPropertyName))
{
item.Properties.Managed = secretProperties[_detail::ManagedPropertyName].get<bool>();
}
// content type
JsonOptional::SetIfExists<std::string>(
item.Properties.ContentType, secretProperties, _detail::ContentTypePropertyName);
item.RecoveryId = secretProperties[_detail::RecoveryIdPropertyName];
item.ScheduledPurgeDate = PosixTimeConverter::PosixTimeToDateTime(
secretProperties[_detail::ScheduledPurgeDatePropertyName]);
item.DeletedOn = PosixTimeConverter::PosixTimeToDateTime(
secretProperties[_detail::DeletedDatePropertyName]);
result.Items.emplace_back(item);
}
return result;
}

View File

@ -18,16 +18,8 @@ add_executable (
azure-security-keyvault-secrets-test
challenge_based_authentication_policy_test.cpp
macro_guard.cpp
secret_backup_deserialize_test.cpp
secret_backup_deserialize_test.hpp
secret_client_base_test.hpp
secret_client_test.cpp
secret_get_client_deserialize_test.cpp
secret_get_client_deserialize_test.hpp
secret_paged_deserialize_test.cpp
secret_paged_deserialize_test.hpp
secret_set_parameters_serializer_test.cpp
secret_update_properties_test.cpp
)
target_compile_definitions(azure-security-keyvault-secrets-test PRIVATE _azure_BUILDING_TESTS)

View File

@ -1,55 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#include "secret_backup_deserialize_test.hpp"
#include "../src/private/secret_serializers.hpp"
#include "azure/keyvault/secrets/secret_client.hpp"
using namespace Azure::Security::KeyVault::Secrets;
using namespace Azure::Security::KeyVault::Secrets::_test;
using namespace Azure::Security::KeyVault::Secrets::_detail;
using namespace Azure::Core::Json::_internal;
TEST(BackupSecretSerializer, EmptyValue)
{
auto response = BackupHelpers::GetEmptyResponse();
auto secret = _detail::BackupSecretSerializer::Deserialize(response);
EXPECT_EQ(secret.Secret.size(), size_t(0));
}
TEST(BackupSecretSerializer, FullValue)
{
auto response = BackupHelpers::GetFullResponse();
auto secret = _detail::BackupSecretSerializer::Deserialize(response);
EXPECT_EQ(secret.Secret.size(), size_t(10));
std::string str(secret.Secret.begin(), secret.Secret.end());
EXPECT_EQ(str, "my name is");
}
TEST(RestoreSecretSerializer, EmptyValue)
{
std::string str = "";
auto data = std::vector<uint8_t>(str.begin(), str.end());
auto secret = _detail::RestoreSecretSerializer::Serialize(data);
auto jsonParser = json::parse(secret);
EXPECT_EQ(secret.size(), size_t(12));
EXPECT_EQ(jsonParser["value"].get<std::string>().empty(), true);
}
TEST(RestoreSecretSerializer, SomeValue)
{
std::string str = "my name is";
auto data = std::vector<uint8_t>(str.begin(), str.end());
auto secret = _detail::RestoreSecretSerializer::Serialize(data);
auto jsonParser = json::parse(secret);
EXPECT_EQ(secret.size(), size_t(26));
// cspell: disable-next-line
EXPECT_EQ(jsonParser["value"], "bXkgbmFtZSBpcw");
}

View File

@ -1,78 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#include "azure/keyvault/secrets/keyvault_deleted_secret.hpp"
#include "azure/keyvault/secrets/keyvault_secret.hpp"
#include <azure/core/http/http.hpp>
#include <azure/core/http/policies/policy.hpp>
#include <string>
#include <gtest/gtest.h>
using namespace Azure::Security::KeyVault::Secrets;
using namespace Azure::Core::Http::_internal;
namespace Azure { namespace Security { namespace KeyVault { namespace Secrets { namespace _test {
struct BackupHelpers
{
static Azure::Core::Http::RawResponse GetEmptyResponse()
{
auto response
= Azure::Core::Http::RawResponse(1, 1, Azure::Core::Http::HttpStatusCode::Ok, "OK");
constexpr static const uint8_t responseBody[] = R"json({
"value": ""
}
)json";
response.SetHeader(HttpShared::ContentType, "application/json");
response.SetHeader(HttpShared::MsRequestId, "1");
response.SetHeader(HttpShared::MsClientRequestId, "2");
response.SetBody(std::vector<uint8_t>(responseBody, responseBody + sizeof(responseBody)));
response.SetBodyStream(std::make_unique<Azure::Core::IO::MemoryBodyStream>(
responseBody, sizeof(responseBody) - 1));
return response;
}
static Azure::Core::Http::RawResponse GetFullResponse()
{
auto response
= Azure::Core::Http::RawResponse(1, 1, Azure::Core::Http::HttpStatusCode::Ok, "OK");
// cspell: disable-next-line
constexpr static const uint8_t responseBody[] = R"json({"value": "bXkgbmFtZSBpcw=="})json";
response.SetHeader(HttpShared::ContentType, "application/json");
response.SetHeader(HttpShared::MsRequestId, "1");
response.SetHeader(HttpShared::MsClientRequestId, "2");
response.SetBody(std::vector<uint8_t>(responseBody, responseBody + sizeof(responseBody)));
response.SetBodyStream(std::make_unique<Azure::Core::IO::MemoryBodyStream>(
responseBody, sizeof(responseBody) - 1));
return response;
}
static Azure::Core::Http::RawResponse GetIncorrectResponse()
{
auto response
= Azure::Core::Http::RawResponse(1, 1, Azure::Core::Http::HttpStatusCode::Ok, "OK");
constexpr static const uint8_t responseBody[] = R"json({
"value": "my name is"
}
)json";
response.SetHeader(HttpShared::ContentType, "application/json");
response.SetHeader(HttpShared::MsRequestId, "1");
response.SetHeader(HttpShared::MsClientRequestId, "2");
response.SetBody(std::vector<uint8_t>(responseBody, responseBody + sizeof(responseBody)));
response.SetBodyStream(std::make_unique<Azure::Core::IO::MemoryBodyStream>(
responseBody, sizeof(responseBody) - 1));
return response;
}
};
}}}}} // namespace Azure::Security::KeyVault::Secrets::_test

View File

@ -33,7 +33,7 @@ TEST(SecretClient, ServiceVersion)
// Default - 7.5
EXPECT_NO_THROW(auto options = SecretClientOptions();
SecretClient SecretClient("http://account.vault.azure.net", credential, options);
EXPECT_EQ(options.ApiVersion, "7.5"););
EXPECT_EQ(options.ApiVersion, "7.6-preview.2"););
// 7.4
EXPECT_NO_THROW(auto options = SecretClientOptions(); options.ApiVersion = "7.4";
@ -115,7 +115,7 @@ TEST_F(KeyVaultSecretClientTest, SecondCreateTest)
}
}
TEST_F(KeyVaultSecretClientTest, DISABLED_UpdateTest)
TEST_F(KeyVaultSecretClientTest, UpdateTest)
{
auto secretName = "UpdateTest";
SecretProperties properties;
@ -135,17 +135,15 @@ TEST_F(KeyVaultSecretClientTest, DISABLED_UpdateTest)
auto secret = secretResponse.Value;
properties = secret.Properties;
EXPECT_EQ(secret.Value.Value(), secretValue);
EXPECT_EQ(properties.Name, secretName);
}
{
properties.ContentType = "xyz";
UpdateSecretPropertiesOptions options;
auto props = properties;
properties.RecoverableDays = 90;
properties.Name = secretName;
properties.Version = "/";
auto secretResponse = client.UpdateSecretProperties(properties);
CheckValidResponse(secretResponse);
auto secret = secretResponse.Value;
EXPECT_EQ(secret.Properties.Name, secretName);
EXPECT_EQ(secret.Properties.ContentType.Value(), properties.ContentType.Value());
EXPECT_EQ(secret.Properties.RecoverableDays.Value(), 90);
}
{
auto operation = client.StartDeleteSecret(secretName);
@ -184,7 +182,7 @@ TEST_F(KeyVaultSecretClientTest, BackupRestore)
auto deletedSecretResponse = client.GetDeletedSecret(secretName);
CheckValidResponse(deletedSecretResponse);
auto secret = deletedSecretResponse.Value;
EXPECT_EQ(secret.Name, secretName);
EXPECT_EQ(secret.Properties.RecoverableDays.Value(), 90);
}
{
auto purgedResponse = client.PurgeDeletedSecret(secretName);
@ -221,7 +219,7 @@ TEST_F(KeyVaultSecretClientTest, BackupRestore)
auto restore = client.RestoreSecretBackup(backupData);
CheckValidResponse(restore);
auto restored = restore.Value;
EXPECT_TRUE(restored.Id.length() > 0);
EXPECT_EQ(restored.Properties.RecoverableDays.Value(), 90);
}
}
@ -262,8 +260,7 @@ TEST_F(KeyVaultSecretClientTest, RecoverSecret)
auto operationResult = operation.Value();
auto restoredSecret = client.GetSecret(secretName);
auto secret = restoredSecret.Value;
EXPECT_EQ(secret.Name, secretName);
EXPECT_EQ(operationResult.Name, secretName);
EXPECT_EQ(operationResult.RecoverableDays.Value(), secret.Properties.RecoverableDays.Value());
EXPECT_EQ(operation.GetRawResponse().GetStatusCode(), Azure::Core::Http::HttpStatusCode::Ok);
}
}
@ -281,7 +278,6 @@ TEST_F(KeyVaultSecretClientTest, TestGetPropertiesOfSecret)
auto secretResponse = client.SetSecret(name, "secretValue");
CheckValidResponse(secretResponse);
auto secret = secretResponse.Value;
EXPECT_EQ(secret.Name, name);
// Avoid server Throttled while creating keys
TestSleep();
}
@ -299,3 +295,14 @@ TEST_F(KeyVaultSecretClientTest, TestGetPropertiesOfSecret)
EXPECT_TRUE(secretProps.size() >= static_cast<size_t>(capacity));
}
TEST(SecretProperties, FactoryValid)
{
std::string url(
"https://myvault.vault.azure.net/secrets/my_secret_name/4387e9f3d6e14c459867679a90fd0f79");
SecretProperties props = SecretProperties::CreateFromURL(url);
EXPECT_EQ(props.Name, "my_secret_name");
EXPECT_EQ(props.Version, "4387e9f3d6e14c459867679a90fd0f79");
EXPECT_EQ(props.Id, url);
EXPECT_EQ(props.VaultUrl, "https://myvault.vault.azure.net");
}

View File

@ -1,107 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#include "secret_get_client_deserialize_test.hpp"
#include "../src/private/secret_serializers.hpp"
#include "azure/keyvault/secrets/secret_client.hpp"
using namespace Azure::Security::KeyVault::Secrets;
using namespace Azure::Security::KeyVault::Secrets::_test;
using namespace Azure::Security::KeyVault::Secrets::_detail;
TEST(KeyVaultSecretSerializer, GetClientDeserializePartial1)
{
auto response = Helpers::GetPartialResponse();
KeyVaultSecret secret = _detail::SecretSerializer::Deserialize(response);
Helpers::RunPartialExpect(secret);
}
TEST(KeyVaultSecretSerializer, GetClientDeserializePartial2)
{
auto response = Helpers::GetPartialResponse();
KeyVaultSecret secret = _detail::SecretSerializer::Deserialize("name1", response);
Helpers::RunPartialExpect(secret);
}
TEST(KeyVaultSecretSerializer, GetClientDeserializePartial3)
{
auto response = Helpers::GetPartialResponse();
KeyVaultSecret secret = KeyVaultSecret("name2", "a");
_detail::SecretSerializer::Deserialize(secret, response);
Helpers::RunPartialExpect(secret);
}
TEST(KeyVaultSecretSerializer, GetClientdeserializeFull1)
{
auto response = Helpers::GetFullResponse();
KeyVaultSecret secret = _detail::SecretSerializer::Deserialize(response);
Helpers::RunFullExpect(secret);
}
TEST(KeyVaultSecretSerializer, GetClientdeserializeFull2)
{
auto response = Helpers::GetFullResponse();
KeyVaultSecret secret = _detail::SecretSerializer::Deserialize("name1", response);
Helpers::RunFullExpect(secret);
}
TEST(KeyVaultSecretSerializer, GetClientdeserializeFull3)
{
auto response = Helpers::GetFullResponse();
KeyVaultSecret secret = KeyVaultSecret("name2", "a");
_detail::SecretSerializer::Deserialize(secret, response);
Helpers::RunFullExpect(secret);
}
TEST(DeletedSecretSerializer, GetDeletedClientDeserializeFull1)
{
auto response = Helpers::GetDeletedFullResponse();
DeletedSecret secret = _detail::DeletedSecretSerializer::Deserialize(response);
Helpers::RunFullExpect(secret, false);
Helpers::RunDeletedExtras(secret);
}
TEST(DeletedSecretSerializer, GetDeletedClientDeserializeFull2)
{
auto response = Helpers::GetDeletedFullResponse();
DeletedSecret secret = _detail::DeletedSecretSerializer::Deserialize("name1", response);
Helpers::RunFullExpect(secret, false);
Helpers::RunDeletedExtras(secret);
}
TEST(DeletedSecretSerializer, GetDeletedClientDeserializeFull3)
{
auto response = Helpers::GetDeletedFullResponse();
DeletedSecret secret = DeletedSecret("name2");
_detail::DeletedSecretSerializer::Deserialize(secret, response);
Helpers::RunFullExpect(secret, false);
Helpers::RunDeletedExtras(secret);
}
TEST(SecretProperties, FactoryValid)
{
std::string url(
"https://myvault.vault.azure.net/secrets/my_secret_name/4387e9f3d6e14c459867679a90fd0f79");
SecretProperties props = SecretProperties::CreateFromURL(url);
EXPECT_EQ(props.Name, "my_secret_name");
EXPECT_EQ(props.Version, "4387e9f3d6e14c459867679a90fd0f79");
EXPECT_EQ(props.Id, url);
EXPECT_EQ(props.VaultUrl, "https://myvault.vault.azure.net");
}

View File

@ -1,161 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#include "azure/keyvault/secrets/keyvault_deleted_secret.hpp"
#include "azure/keyvault/secrets/keyvault_secret.hpp"
#include <azure/core/http/http.hpp>
#include <azure/core/http/policies/policy.hpp>
#include <string>
#include <gtest/gtest.h>
using namespace Azure::Security::KeyVault::Secrets;
using namespace Azure::Core::Http::_internal;
namespace Azure { namespace Security { namespace KeyVault { namespace Secrets { namespace _test {
struct Helpers
{
static Azure::Core::Http::RawResponse GetPartialResponse()
{
auto response
= Azure::Core::Http::RawResponse(1, 1, Azure::Core::Http::HttpStatusCode::Ok, "OK");
constexpr static const uint8_t responseBody[] = R"json({
"value": "my_secret_value",
"id": "https://myvault.vault.azure.net/secrets/my_secret_name/4387e9f3d6e14c459867679a90fd0f79",
"managed":true,
"attributes": {
"enabled": true,
"created": 1493938410,
"updated": 1493938410,
"recoveryLevel": "Recoverable+Purgeable"
}
}
)json";
response.SetHeader(HttpShared::ContentType, "application/json");
response.SetHeader(HttpShared::MsRequestId, "1");
response.SetHeader(HttpShared::MsClientRequestId, "2");
response.SetBody(std::vector<uint8_t>(responseBody, responseBody + sizeof(responseBody)));
response.SetBodyStream(std::make_unique<Azure::Core::IO::MemoryBodyStream>(
responseBody, sizeof(responseBody) - 1));
return response;
}
static Azure::Core::Http::RawResponse GetFullResponse()
{
auto response
= Azure::Core::Http::RawResponse(1, 1, Azure::Core::Http::HttpStatusCode::Ok, "OK");
constexpr static const uint8_t responseBody[] = R"json({
"value": "my_secret_value",
"id": "https://myvault.vault.azure.net/secrets/my_secret_name/4387e9f3d6e14c459867679a90fd0f79",
"contentType" : "ct",
"kid": "kid",
"managed": true,
"attributes": {
"enabled": true,
"created": 1493938410,
"updated": 1493938410,
"recoveryLevel": "Recoverable+Purgeable"
}
}
)json";
response.SetHeader(HttpShared::ContentType, "application/json");
response.SetHeader(HttpShared::MsRequestId, "1");
response.SetHeader(HttpShared::MsClientRequestId, "2");
response.SetBody(std::vector<uint8_t>(responseBody, responseBody + sizeof(responseBody)));
response.SetBodyStream(std::make_unique<Azure::Core::IO::MemoryBodyStream>(
responseBody, sizeof(responseBody) - 1));
return response;
}
static Azure::Core::Http::RawResponse GetDeletedFullResponse()
{
auto response
= Azure::Core::Http::RawResponse(1, 1, Azure::Core::Http::HttpStatusCode::Ok, "OK");
constexpr static const uint8_t responseBody[] = R"json({
"recoveryId": "https://myvault.vault.azure.net/deletedsecrets/GetDeletedSecretTest",
"deletedDate": 1493938433,
"scheduledPurgeDate": 1501714433,
"managed": true,
"id": "https://myvault.vault.azure.net/secrets/my_secret_name/4387e9f3d6e14c459867679a90fd0f79",
"attributes": {
"enabled": true,
"created": 1493938433,
"updated": 1493938433,
"recoveryLevel": "Recoverable+Purgeable"
}
})json";
response.SetHeader(HttpShared::ContentType, "application/json");
response.SetHeader(HttpShared::MsRequestId, "1");
response.SetHeader(HttpShared::MsClientRequestId, "2");
response.SetBody(std::vector<uint8_t>(responseBody, responseBody + sizeof(responseBody)));
response.SetBodyStream(std::make_unique<Azure::Core::IO::MemoryBodyStream>(
responseBody, sizeof(responseBody) - 1));
return response;
}
static void RunPartialExpect(KeyVaultSecret& secret, bool expectValue = true)
{
if (expectValue)
{
EXPECT_EQ(secret.Value.Value(), "my_secret_value");
}
EXPECT_EQ(secret.Name, "my_secret_name");
EXPECT_EQ(secret.Properties.VaultUrl, "https://myvault.vault.azure.net");
EXPECT_EQ(secret.Properties.Version, "4387e9f3d6e14c459867679a90fd0f79");
EXPECT_EQ(secret.Properties.Id, secret.Id);
EXPECT_EQ(
secret.Id,
"https://myvault.vault.azure.net/secrets/my_secret_name/"
"4387e9f3d6e14c459867679a90fd0f79");
EXPECT_EQ(secret.Properties.Managed, true);
EXPECT_EQ(secret.Properties.KeyId.HasValue(), false);
EXPECT_EQ(secret.Properties.UpdatedOn.HasValue(), true);
EXPECT_EQ(secret.Properties.CreatedOn.HasValue(), true);
}
static void RunFullExpect(KeyVaultSecret& secret, bool expectValue = true)
{
if (expectValue)
{
EXPECT_EQ(secret.Value.Value(), "my_secret_value");
EXPECT_EQ(secret.Properties.ContentType.Value(), "ct");
EXPECT_EQ(secret.Properties.KeyId.Value(), "kid");
}
EXPECT_EQ(secret.Name, "my_secret_name");
EXPECT_EQ(secret.Properties.VaultUrl, "https://myvault.vault.azure.net");
EXPECT_EQ(secret.Properties.Version, "4387e9f3d6e14c459867679a90fd0f79");
EXPECT_EQ(secret.Properties.Id, secret.Id);
EXPECT_EQ(
secret.Id,
"https://myvault.vault.azure.net/secrets/my_secret_name/"
"4387e9f3d6e14c459867679a90fd0f79");
EXPECT_EQ(secret.Properties.Enabled.Value(), true);
EXPECT_EQ(secret.Properties.Managed, true);
EXPECT_EQ(secret.Properties.UpdatedOn.HasValue(), true);
EXPECT_EQ(secret.Properties.CreatedOn.HasValue(), true);
}
static void RunDeletedExtras(DeletedSecret& secret)
{
EXPECT_EQ(
secret.RecoveryId, "https://myvault.vault.azure.net/deletedsecrets/GetDeletedSecretTest");
EXPECT_EQ(secret.ScheduledPurgeDate.Value().ToString(), "2017-08-02T22:53:53Z");
EXPECT_EQ(secret.DeletedOn.Value().ToString(), "2017-05-04T22:53:53Z");
}
};
}}}}} // namespace Azure::Security::KeyVault::Secrets::_test

View File

@ -1,138 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#include "secret_paged_deserialize_test.hpp"
using namespace Azure::Security::KeyVault::Secrets;
using namespace Azure::Security::KeyVault::Secrets::_test;
using namespace Azure::Security::KeyVault::Secrets::_detail;
using namespace Azure::Core::Json::_internal;
TEST(SecretPropertiesPagedResponse, SingleWithNext)
{
auto response = _test::PagedHelpers::GetFirstResponse();
auto result = _detail::SecretPropertiesPagedResultSerializer::Deserialize(response);
EXPECT_EQ(result.Items.size(), size_t(1));
EXPECT_EQ(
result.NextPageToken.Value(),
"https://gearama-test2.vault.azure.net:443/"
"secrets?api-version=7.2&$skiptoken="
"eyJOZXh0TWFya2VyIjoiMiE4NCFNREF3TURFM0lYTmxZM0psZEM5VFQwMUZVMFZEVWtWVUlUQXdNREF5T0NFNU9UazVM"
"VEV5TFRNeFZESXpPalU1T2pVNUxqazVPVGs1T1RsYUlRLS0iLCJUYXJnZXRMb2NhdGlvbiI6MH0&maxresults=1");
auto item = result.Items[0];
EXPECT_EQ(item.Enabled.Value(), true);
EXPECT_EQ(item.RecoverableDays.Value(), 90);
EXPECT_EQ(item.RecoveryLevel.Value(), "Recoverable+Purgeable");
EXPECT_EQ(item.Id, "https://gearama-test2.vault.azure.net/secrets/magic");
}
TEST(SecretPropertiesPagedResponse, MultipleNoNext)
{
auto response = _test::PagedHelpers::GetMultipleResponse();
auto result = _detail::SecretPropertiesPagedResultSerializer::Deserialize(response);
EXPECT_EQ(result.Items.size(), size_t(3));
EXPECT_EQ(result.NextPageToken.HasValue(), false);
auto item = result.Items[0];
EXPECT_EQ(item.Enabled.Value(), true);
EXPECT_EQ(item.RecoverableDays.Value(), 90);
EXPECT_EQ(item.RecoveryLevel.Value(), "Recoverable+Purgeable");
EXPECT_EQ(
item.Id,
"https://gearama-test2.vault.azure.net/secrets/magic/5a0fdd819481420eac6f3282ce722461");
EXPECT_EQ(item.Name, "magic");
EXPECT_EQ(item.Version, "5a0fdd819481420eac6f3282ce722461");
item = result.Items[1];
EXPECT_EQ(item.Enabled.Value(), true);
EXPECT_EQ(item.RecoverableDays.Value(), 90);
EXPECT_EQ(item.RecoveryLevel.Value(), "Recoverable+Purgeable");
EXPECT_EQ(
item.Id,
"https://gearama-test2.vault.azure.net/secrets/magic/8faafbb99216484dbbd75f9dd6bcaadf");
EXPECT_EQ(item.Name, "magic");
EXPECT_EQ(item.Version, "8faafbb99216484dbbd75f9dd6bcaadf");
item = result.Items[2];
EXPECT_EQ(item.Enabled.Value(), true);
EXPECT_EQ(item.RecoverableDays.Value(), 90);
EXPECT_EQ(item.RecoveryLevel.Value(), "Recoverable+Purgeable");
EXPECT_EQ(
item.Id,
"https://gearama-test2.vault.azure.net/secrets/magic/d75080822f03400ab4d658bd0e988ac5");
EXPECT_EQ(item.Name, "magic");
EXPECT_EQ(item.Version, "d75080822f03400ab4d658bd0e988ac5");
}
TEST(SecretPropertiesPagedResponse, NoneNoNext)
{
auto response = _test::PagedHelpers::GetEmptyResponse();
auto result = _detail::SecretPropertiesPagedResultSerializer::Deserialize(response);
EXPECT_EQ(result.Items.size(), size_t(0));
EXPECT_EQ(result.NextPageToken.HasValue(), false);
}
TEST(DeletedSecretPagedResultSerializer, SingleWithNext)
{
auto response = _test::PagedHelpers::GetDeletedFirstResponse();
auto result = _detail::DeletedSecretPagedResultSerializer::Deserialize(response);
EXPECT_EQ(result.Items.size(), size_t(1));
EXPECT_EQ(result.NextPageToken.Value(), "nextLink");
auto item = result.Items[0];
EXPECT_EQ(item.Properties.Enabled.Value(), true);
EXPECT_EQ(item.Properties.RecoverableDays.Value(), 90);
EXPECT_EQ(item.Properties.RecoveryLevel.Value(), "Recoverable+Purgeable");
EXPECT_EQ(item.Id, "https://gearama-test2.vault.azure.net/secrets/eqwewq");
EXPECT_EQ(item.RecoveryId, "https://gearama-test2.vault.azure.net/deletedsecrets/eqwewq");
}
TEST(DeletedSecretPagedResultSerializer, MultipleNoNext)
{
auto response = _test::PagedHelpers::GetDeletedMultipleResponse();
auto result = _detail::DeletedSecretPagedResultSerializer::Deserialize(response);
EXPECT_EQ(result.Items.size(), size_t(3));
EXPECT_FALSE(result.NextPageToken.HasValue());
auto item = result.Items[0];
EXPECT_EQ(item.Properties.Enabled.Value(), true);
EXPECT_EQ(item.Properties.RecoverableDays.Value(), 90);
EXPECT_EQ(item.Properties.RecoveryLevel.Value(), "Recoverable+Purgeable");
EXPECT_EQ(item.Id, "https://gearama-test2.vault.azure.net/secrets/eqwewq");
EXPECT_EQ(item.RecoveryId, "https://gearama-test2.vault.azure.net/deletedsecrets/eqwewq");
item = result.Items[1];
EXPECT_EQ(item.Properties.Enabled.Value(), true);
EXPECT_EQ(item.Properties.RecoverableDays.Value(), 90);
EXPECT_EQ(item.Properties.RecoveryLevel.Value(), "Recoverable+Purgeable");
EXPECT_EQ(item.Id, "https://gearama-test2.vault.azure.net/secrets/someSecret");
EXPECT_EQ(item.RecoveryId, "https://gearama-test2.vault.azure.net/secrets/someSecret");
item = result.Items[2];
EXPECT_EQ(item.Properties.Enabled.Value(), true);
EXPECT_EQ(item.Properties.RecoverableDays.Value(), 90);
EXPECT_EQ(item.Properties.RecoveryLevel.Value(), "Recoverable+Purgeable");
EXPECT_EQ(item.Id, "https://gearama-test2.vault.azure.net/secrets/someSecret2");
EXPECT_EQ(item.RecoveryId, "https://gearama-test2.vault.azure.net/deletedsecrets/someSecret2");
}
TEST(DeletedSecretPagedResultSerializer, NoneNoNext)
{
auto response = _test::PagedHelpers::GetEmptyResponse();
auto result = _detail::DeletedSecretPagedResultSerializer::Deserialize(response);
EXPECT_EQ(result.Items.size(), size_t(0));
EXPECT_EQ(result.NextPageToken.HasValue(), false);
}

View File

@ -1,222 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#include "../src/private/secret_serializers.hpp"
#include "azure/keyvault/secrets/keyvault_secret_paged_response.hpp"
#include "azure/keyvault/secrets/secret_client.hpp"
#include "private/secret_constants.hpp"
#include "private/secret_serializers.hpp"
#include <azure/core/http/http.hpp>
#include <azure/core/http/policies/policy.hpp>
#include <azure/core/internal/json/json.hpp>
#include <azure/core/internal/json/json_optional.hpp>
#include <azure/core/internal/json/json_serializable.hpp>
#include <cstddef>
#include <string>
#include <gtest/gtest.h>
using namespace Azure::Security::KeyVault::Secrets;
using namespace Azure::Core::Http::_internal;
namespace Azure { namespace Security { namespace KeyVault { namespace Secrets { namespace _test {
struct PagedHelpers
{
static Azure::Core::Http::RawResponse GetFirstResponse()
{
auto response
= Azure::Core::Http::RawResponse(1, 1, Azure::Core::Http::HttpStatusCode::Ok, "OK");
constexpr static const uint8_t responseBody[] = R"json({
"nextLink": "https://gearama-test2.vault.azure.net:443/secrets?api-version=7.2&$skiptoken=eyJOZXh0TWFya2VyIjoiMiE4NCFNREF3TURFM0lYTmxZM0psZEM5VFQwMUZVMFZEVWtWVUlUQXdNREF5T0NFNU9UazVMVEV5TFRNeFZESXpPalU1T2pVNUxqazVPVGs1T1RsYUlRLS0iLCJUYXJnZXRMb2NhdGlvbiI6MH0&maxresults=1",
"value": [{
"attributes": {
"created": 1627404049,
"enabled": true,
"recoverableDays": 90,
"recoveryLevel": "Recoverable+Purgeable",
"updated": 1627404049
},
"id": "https://gearama-test2.vault.azure.net/secrets/magic"
}]
}
)json";
response.SetHeader(HttpShared::ContentType, "application/json");
response.SetHeader(HttpShared::MsRequestId, "1");
response.SetHeader(HttpShared::MsClientRequestId, "2");
response.SetBody(std::vector<uint8_t>(responseBody, responseBody + sizeof(responseBody)));
response.SetBodyStream(std::make_unique<Azure::Core::IO::MemoryBodyStream>(
responseBody, sizeof(responseBody) - 1));
return response;
}
static Azure::Core::Http::RawResponse GetMultipleResponse()
{
auto response
= Azure::Core::Http::RawResponse(1, 1, Azure::Core::Http::HttpStatusCode::Ok, "OK");
constexpr static const uint8_t responseBody[] = R"json({
"nextLink": null,
"value": [{
"attributes": {
"created": 1628101925,
"enabled": true,
"recoverableDays": 90,
"recoveryLevel": "Recoverable+Purgeable",
"updated": 1628101925
},
"contentType": "content",
"id": "https://gearama-test2.vault.azure.net/secrets/magic/5a0fdd819481420eac6f3282ce722461",
"tags": {}
}, {
"attributes": {
"created": 1627404049,
"enabled": true,
"recoverableDays": 90,
"recoveryLevel": "Recoverable+Purgeable",
"updated": 1627404049
},
"id": "https://gearama-test2.vault.azure.net/secrets/magic/8faafbb99216484dbbd75f9dd6bcaadf"
}, {
"attributes": {
"created": 1628101911,
"enabled": true,
"recoverableDays": 90,
"recoveryLevel": "Recoverable+Purgeable",
"updated": 1628101911
},
"id": "https://gearama-test2.vault.azure.net/secrets/magic/d75080822f03400ab4d658bd0e988ac5",
"tags": {}
}]
}
)json";
response.SetHeader(HttpShared::ContentType, "application/json");
response.SetHeader(HttpShared::MsRequestId, "1");
response.SetHeader(HttpShared::MsClientRequestId, "2");
response.SetBody(std::vector<uint8_t>(responseBody, responseBody + sizeof(responseBody)));
response.SetBodyStream(std::make_unique<Azure::Core::IO::MemoryBodyStream>(
responseBody, sizeof(responseBody) - 1));
return response;
}
static Azure::Core::Http::RawResponse GetEmptyResponse()
{
auto response
= Azure::Core::Http::RawResponse(1, 1, Azure::Core::Http::HttpStatusCode::Ok, "OK");
constexpr static const uint8_t responseBody[] = R"json({
"nextLink": null,
"value": []
}
)json";
response.SetHeader(HttpShared::ContentType, "application/json");
response.SetHeader(HttpShared::MsRequestId, "1");
response.SetHeader(HttpShared::MsClientRequestId, "2");
response.SetBody(std::vector<uint8_t>(responseBody, responseBody + sizeof(responseBody)));
response.SetBodyStream(std::make_unique<Azure::Core::IO::MemoryBodyStream>(
responseBody, sizeof(responseBody) - 1));
return response;
}
static Azure::Core::Http::RawResponse GetDeletedFirstResponse()
{
auto response
= Azure::Core::Http::RawResponse(1, 1, Azure::Core::Http::HttpStatusCode::Ok, "OK");
constexpr static const uint8_t responseBody[] = R"json({
"nextLink": "nextLink",
"value": [{
"attributes": {
"created": 1628110306,
"enabled": true,
"recoverableDays": 90,
"recoveryLevel": "Recoverable+Purgeable",
"updated": 1628110306
},
"deletedDate": 1628110318,
"id": "https://gearama-test2.vault.azure.net/secrets/eqwewq",
"recoveryId": "https://gearama-test2.vault.azure.net/deletedsecrets/eqwewq",
"scheduledPurgeDate": 1635886318,
"tags": {}
}]
}
)json";
response.SetHeader(HttpShared::ContentType, "application/json");
response.SetHeader(HttpShared::MsRequestId, "1");
response.SetHeader(HttpShared::MsClientRequestId, "2");
response.SetBody(std::vector<uint8_t>(responseBody, responseBody + sizeof(responseBody)));
response.SetBodyStream(std::make_unique<Azure::Core::IO::MemoryBodyStream>(
responseBody, sizeof(responseBody) - 1));
return response;
}
static Azure::Core::Http::RawResponse GetDeletedMultipleResponse()
{
auto response
= Azure::Core::Http::RawResponse(1, 1, Azure::Core::Http::HttpStatusCode::Ok, "OK");
constexpr static const uint8_t responseBody[] = R"json({
"nextLink": null,
"value": [{
"attributes": {
"created": 1628110306,
"enabled": true,
"recoverableDays": 90,
"recoveryLevel": "Recoverable+Purgeable",
"updated": 1628110306
},
"deletedDate": 1628110318,
"id": "https://gearama-test2.vault.azure.net/secrets/eqwewq",
"recoveryId": "https://gearama-test2.vault.azure.net/deletedsecrets/eqwewq",
"scheduledPurgeDate": 1635886318,
"tags": {}
}, {
"attributes": {
"created": 1626967532,
"enabled": true,
"recoverableDays": 90,
"recoveryLevel": "Recoverable+Purgeable",
"updated": 1626967532
},
"deletedDate": 1628110252,
"id": "https://gearama-test2.vault.azure.net/secrets/someSecret",
"recoveryId": "https://gearama-test2.vault.azure.net/secrets/someSecret",
"scheduledPurgeDate": 1635886252
}, {
"attributes": {
"created": 1627101774,
"enabled": true,
"recoverableDays": 90,
"recoveryLevel": "Recoverable+Purgeable",
"updated": 1627101774
},
"deletedDate": 1628110259,
"id": "https://gearama-test2.vault.azure.net/secrets/someSecret2",
"recoveryId": "https://gearama-test2.vault.azure.net/deletedsecrets/someSecret2",
"scheduledPurgeDate": 1635886259
}]
}
)json";
response.SetHeader(HttpShared::ContentType, "application/json");
response.SetHeader(HttpShared::MsRequestId, "1");
response.SetHeader(HttpShared::MsClientRequestId, "2");
response.SetBody(std::vector<uint8_t>(responseBody, responseBody + sizeof(responseBody)));
response.SetBodyStream(std::make_unique<Azure::Core::IO::MemoryBodyStream>(
responseBody, sizeof(responseBody) - 1));
return response;
}
};
}}}}} // namespace Azure::Security::KeyVault::Secrets::_test

View File

@ -1,60 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#include "../src/private/secret_serializers.hpp"
#include "azure/core/internal/json/json.hpp"
#include "azure/core/internal/json/json_optional.hpp"
#include "azure/core/internal/json/json_serializable.hpp"
#include "azure/keyvault/secrets/secret_client.hpp"
#include "private/secret_constants.hpp"
#include "private/secret_serializers.hpp"
#include "secret_get_client_deserialize_test.hpp"
using namespace Azure::Security::KeyVault::Secrets;
using namespace Azure::Security::KeyVault::Secrets::_detail;
using namespace Azure::Core::Json::_internal;
TEST(KeyvaultSecretSetParametersSerializer, SetValue)
{
KeyVaultSecret params("name", "value");
std::string result = SecretSerializer::Serialize(params);
auto jsonParser = json::parse(result);
EXPECT_EQ(jsonParser[ValuePropertyName], params.Value.Value());
EXPECT_EQ(jsonParser[IdPropertyName], nullptr);
EXPECT_EQ(jsonParser[ContentTypePropertyName], nullptr);
}
TEST(KeyvaultSecretSetParametersSerializer, SetValueCT)
{
KeyVaultSecret params("name", "value");
params.Properties.ContentType = "ct";
std::string result = SecretSerializer::Serialize(params);
auto jsonParser = json::parse(result);
EXPECT_EQ(jsonParser[ValuePropertyName], params.Value.Value());
EXPECT_EQ(jsonParser[ContentTypePropertyName], params.Properties.ContentType.Value());
}
TEST(KeyvaultSecretSetParametersSerializer, SetValueCTAttrTag)
{
KeyVaultSecret params("name", "value");
params.Properties.ContentType = "ct";
params.Properties.Enabled = true;
params.Properties.Tags = std::unordered_map<std::string, std::string>{{"a", "b"}};
std::string result = SecretSerializer::Serialize(params);
auto jsonParser = json::parse(result);
EXPECT_EQ(jsonParser[ValuePropertyName], params.Value.Value());
EXPECT_EQ(jsonParser[AttributesPropertyName][TagsPropertyName]["a"], "b");
EXPECT_EQ(jsonParser[AttributesPropertyName][EnabledPropertyName], true);
EXPECT_EQ(jsonParser[ContentTypePropertyName], params.Properties.ContentType.Value());
}

View File

@ -1,70 +0,0 @@
#include "../src/private/secret_serializers.hpp"
#include "azure/core/internal/json/json.hpp"
#include "azure/core/internal/json/json_optional.hpp"
#include "azure/core/internal/json/json_serializable.hpp"
#include "azure/keyvault/secrets/secret_client.hpp"
#include "private/secret_constants.hpp"
#include "secret_get_client_deserialize_test.hpp"
using namespace Azure::Security::KeyVault::Secrets;
using namespace Azure::Security::KeyVault::Secrets::_detail;
using namespace Azure::Core::Json::_internal;
TEST(SecretPropertiesSerializer, Serialize1)
{
SecretProperties properties;
properties.ContentType = "contentType";
properties.Enabled = true;
auto serialized = _detail::SecretPropertiesSerializer::Serialize(properties);
auto jsonParser = json::parse(serialized);
EXPECT_EQ(properties.ContentType.Value(), jsonParser[_detail::ContentTypePropertyName]);
EXPECT_EQ(
properties.Enabled.Value(),
jsonParser[_detail::AttributesPropertyName][_detail::EnabledPropertyName]);
}
TEST(SecretPropertiesSerializer, Serialize2)
{
SecretProperties properties;
properties.ContentType = "contentType";
properties.Enabled = true;
properties.Tags.emplace("a", "b");
auto serialized = _detail::SecretPropertiesSerializer::Serialize(properties);
auto jsonParser = json::parse(serialized);
EXPECT_EQ(properties.ContentType.Value(), jsonParser[_detail::ContentTypePropertyName]);
EXPECT_EQ(
properties.Enabled.Value(),
jsonParser[_detail::AttributesPropertyName][_detail::EnabledPropertyName]);
EXPECT_EQ(properties.Tags["a"], jsonParser[_detail::TagsPropertyName]["a"]);
}
TEST(SecretPropertiesSerializer, Serialize3)
{
SecretProperties properties;
properties.ContentType = "contentType";
properties.Enabled = true;
properties.Tags.emplace("a", "b");
properties.Tags.emplace("c", "d");
auto serialized = _detail::SecretPropertiesSerializer::Serialize(properties);
auto jsonParser = json::parse(serialized);
EXPECT_EQ(properties.ContentType.Value(), jsonParser[_detail::ContentTypePropertyName]);
EXPECT_EQ(
properties.Enabled.Value(),
jsonParser[_detail::AttributesPropertyName][_detail::EnabledPropertyName]);
for (auto kvp : properties.Tags)
{
EXPECT_EQ(properties.Tags[kvp.first], jsonParser[_detail::TagsPropertyName][kvp.first]);
}
}

View File

@ -0,0 +1,5 @@
directory: specification/keyvault/Security.KeyVault.Secrets
commit: bc18a6a035dbab575177a5548c936621e47d1124
repo: Azure/azure-rest-api-specs
additionalDirectories:
- specification/keyvault/Security.KeyVault.Common/

View File

@ -18,4 +18,5 @@ options:
"@azure-tools/typespec-cpp":
flavor: azure
package-dir: "azure-security-keyvault-secrets"
namespace: "Azure::Security::KeyVault::Secrets"
namespace: "Azure::Security::KeyVault::Secrets::_detail"
headersOutputPath: "azure/keyvault/secrets/generated"

View File

@ -30,8 +30,8 @@ extends:
CtestRegex: "azure-security-keyvault.*"
LiveTestCtestRegex: "azure-security-keyvault.*"
LiveTestTimeoutInMinutes: 120
LineCoverageTarget: 81
BranchCoverageTarget: 42
LineCoverageTarget: 77
BranchCoverageTarget: 48
Artifacts:
- Name: azure-security-keyvault-keys
Path: azure-security-keyvault-keys