diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
deleted file mode 100644
index 222779e5afa..00000000000
--- a/.devcontainer/Dockerfile
+++ /dev/null
@@ -1,78 +0,0 @@
-FROM debian:10
-
-# This Dockerfile adds a non-root 'vscode' user with sudo access. However, for Linux,
-# this user's GID/UID must match your local user UID/GID to avoid permission issues
-# with bind mounts. Update USER_UID / USER_GID if yours is not 1000. See
-# https://aka.ms/vscode-remote/containers/non-root-user for details.
-ARG USERNAME=azure-sdk-for-cpp
-ARG USER_UID=1000
-ARG USER_GID=$USER_UID
-ARG PORT=4000
-
-# Install packages as root
-USER root
-
-# Install needed packages and setup non-root user. Use a separate RUN statement to add your own dependencies.
-RUN apt-get update \
- && export DEBIAN_FRONTEND=noninteractive \
- && LANG=C LC_ALL=C apt-get -y install --no-install-recommends \
- apt-utils \
- dialog \
- sudo \
- #
- # Install vim, git, process tools, lsb-release
- git \
- openssh-client \
- less \
- #
- # Azure SDK for C++ dev env
- make \
- cmake \
- ninja-build \
- build-essential \
- zlib1g-dev \
- libcurl4-openssl-dev \
- libssl-dev \
- libxml2-dev \
- gdb \
- # clang format 10 req
- gnupg2 \
- wget \
- ca-certificates \
- # vcpkg reqs
- curl \
- zip \
- unzip \
- tar \
- pkg-config \
-
- #
- # Add en_US.UTF-8 locale
- && echo 'en_US.UTF-8 UTF-8' >> /etc/locale.gen \
- && wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - \
- && echo 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-10 main' | tee -a /etc/apt/sources.list \
- && echo 'deb-src http://apt.llvm.org/bionic/ llvm-toolchain-bionic-10 main' | tee -a /etc/apt/sources.list \
- && apt-get update \
- && apt-get -y install --no-install-recommends clang-format-10 \
- #
- # Create a non-root user to use if preferred - see https://aka.ms/vscode-remote/containers/non-root-user.
- && groupadd --gid $USER_GID $USERNAME \
- && useradd -s /bin/bash --uid $USER_UID --gid $USER_GID -m $USERNAME \
- #
- # Add sudo support for the non-root user
- && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME\
- && chmod 0440 /etc/sudoers.d/$USERNAME \
- #
- # Clean up
- && apt-get autoremove -y \
- && apt-get clean -y \
- && rm -rf /var/lib/apt/lists/*
-
-RUN cd / \
- && git clone https://github.com/microsoft/vcpkg.git \
- && cd vcpkg \
- && ./bootstrap-vcpkg.sh \
- && ./vcpkg install curl
-
-# Switch back to the non-root user
-USER ${USERNAME}
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
deleted file mode 100644
index dbfa1099a5e..00000000000
--- a/.devcontainer/devcontainer.json
+++ /dev/null
@@ -1,32 +0,0 @@
-{
- "name": "Ubuntu-20.04.VCPKG",
- "dockerFile": "Dockerfile",
- "settings": {
- "terminal.integrated.shell.linux": "/bin/bash"
- },
- "extensions": [
- "ms-vscode.cpptools-themes",
- "bbenoist.doxygen",
- "streetsidesoftware.code-spell-checker",
- "ms-vscode.cpptools",
- "xaver.clang-format",
- "twxs.cmake",
- "ms-vscode.cmake-tools",
- "eamodio.gitlens",
- "davidschuldenfrei.gtest-adapter"
- ],
- // Do not run as root. See https://aka.ms/vscode-remote/containers/non-root.
- "remoteUser": "azure-sdk-for-cpp",
- "containerEnv": {
- "AZURE_CLIENT_ID": "",
- "AZURE_CLIENT_SECRET": "",
- "AZURE_KEYVAULT_HSM_URL": "",
- "AZURE_KEYVAULT_URL": "",
- "AZURE_LOG_LEVEL": "1",
- "AZURE_TENANT_ID": "",
- "AZURE_TEST_MODE": "PLAYBACK",
- "CLIENT_OBJECTID": "",
- // set or unset to run using vcpkg or not
- "VCPKG_ROOT": "/vcpkg"
- }
-}
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index a31ee36f7cd..aedc472e01d 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -6,7 +6,7 @@
################
# Git Hub integration and bot rules
-/.github/ @jsquire @rickwinter
+/.github/ @jsquire @rickwinter @ronniegeraghty
###########
# SDK
@@ -23,14 +23,14 @@
/sdk/core/ @rickwinter @ahsonkhan @antkmsft @vhvb1989 @gearama @LarryOsterman
# PRLabel: %Azure.Identity
-/sdk/identity/ @antkmsft @schaabs @ahsonkhan @rickwinter @vhvb1989 @gearama
+/sdk/identity/ @antkmsft @schaabs @ahsonkhan @rickwinter @vhvb1989 @gearama @LarryOsterman
###########
# Client SDKs
###########
# PRLabel: %Attestation
-/sdk/attestation/ @LarryOsterman @gkostal @anilba06 @kroshkina-ms
+/sdk/attestation/ @LarryOsterman @gkostal @anilba06 @kroshkina-ms @ahmadmsft @rickwinter @ahsonkhan @antkmsft @vhvb1989 @gearama
# PRLabel: %KeyVault
/sdk/keyvault/ @vhvb1989 @gearama @antkmsft @rickwinter
diff --git a/.gitignore b/.gitignore
index 2b3a003e551..f426b11b3da 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,7 +19,7 @@
[Rr]eleases/
x64/
x86/
-bld/
+bld*/
[Bb]in/
[Oo]bj/
[Ll]og/
diff --git a/.vscode/cspell.json b/.vscode/cspell.json
index 5b01ec946c9..77305e988df 100644
--- a/.vscode/cspell.json
+++ b/.vscode/cspell.json
@@ -11,6 +11,8 @@
"*.exe",
"*.a",
"*.lib",
+ "*.yaml",
+ "**/libcurl-stress-test/README.md",
".github/CODEOWNERS",
".gitignore",
".vscode/cspell.json",
@@ -110,6 +112,7 @@
"sasia",
"scus",
"SDDL",
+ "sdpath",
"serializers",
"Seriot",
"southcentralus",
@@ -123,9 +126,11 @@
"unscoped",
"unskipped",
"UPNs",
+ "uaenorth",
"usgov",
"usgoviowa",
"usgovvirginia",
+ "westcentralus",
"vcpkg",
"Viet",
"Viktor",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 391c771aa90..8b8ff1fa3ec 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -113,6 +113,5 @@ add_subdirectory(sdk/storage)
add_subdirectory(sdk/template)
if(BUILD_SAMPLES)
- add_subdirectory(samples/integration/vcpkg-keyvault)
add_subdirectory(samples/integration/vcpkg-all-smoke)
endif()
diff --git a/CMakeSettings.json b/CMakeSettings.json
index 445a2b69521..c10c6410f73 100644
--- a/CMakeSettings.json
+++ b/CMakeSettings.json
@@ -21,7 +21,6 @@
"value": "True",
"type": "BOOL"
}
-
]
},
{
@@ -231,6 +230,28 @@
"type": "BOOL"
}
]
+ },
+ {
+ "name": "x64-DebugWithPerfTest",
+ "generator": "Ninja",
+ "configurationType": "Debug",
+ "buildRoot": "${projectDir}\\out\\build\\${name}",
+ "installRoot": "${projectDir}\\out\\install\\${name}",
+ "cmakeCommandArgs": "-DINSTALL_GTEST=OFF -DBUILD_TESTING=ON -DBUILD_TRANSPORT_CURL=ON -DBUILD_SAMPLES=ON -DBUILD_PERFORMANCE_TESTS=ON",
+ "buildCommandArgs": "-v",
+ "inheritEnvironments": [ "msvc_x64_x64" ],
+ "variables": [
+ {
+ "name": "VCPKG_TARGET_TRIPLET",
+ "value": "x64-windows-static",
+ "type": "STRING"
+ },
+ {
+ "name": "MSVC_USE_STATIC_CRT",
+ "value": "True",
+ "type": "BOOL"
+ }
+ ]
}
]
}
\ No newline at end of file
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 39d54cffcd3..6eab9f5cab5 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,4 +1,4 @@
-## Azure SDK for C++ Contributing Guide
+# Azure SDK for C++ Contributing Guide
Thank you for your interest in contributing to Azure SDK for C++.
@@ -39,9 +39,9 @@ Thank you for your interest in contributing to Azure SDK for C++.
- Contributor is using an e-mail address other than the primary GitHub address and wants that preserved in the history. Contributor must be willing to squash
the commits manually before acceptance.
-## Developer Guide
+# Developer Guide
-### Codespaces
+## Codespaces
Codespaces is new technology that allows you to use a container as your development environment. This repo provides a Codespaces container which is supported by both GitHub Codespaces and VS Code Codespaces.
@@ -50,54 +50,54 @@ Codespaces is new technology that allows you to use a container as your developm
1. From the Azure SDK GitHub repo, click on the "Code -> Open with Codespaces" button.
1. Open a Terminal. The development environment will be ready for you. Continue to [Building and Testing](https://github.com/Azure/azure-sdk-for-cpp/blob/main/CONTRIBUTING.md#building-and-testing).
-#### VS Code Codespaces
+### VS Code Codespaces
1. Install the [VS Code Remote Extension Pack](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack)
1. When you open the Azure SDK for C++ repo in VS Code, it will prompt you to open the project in the Dev Container. If it does not prompt you, then hit CTRL+P, and select "Remote-Containers: Open Folder in Container..."
1. Open a Terminal. The development environment will be ready for you. Continue to [Building and Testing](https://github.com/Azure/azure-sdk-for-cpp/blob/main/CONTRIBUTING.md#building-and-testing).
-### Full Local Setup
+## Full Local Setup
-#### Pre-requisites
+### Pre-requisites
-##### CMake
+#### CMake
CMake version 3.13 or higher is required to build these libraries. Download and install CMake from the project's
[website](https://cmake.org/download/).
-##### Third Party Dependencies
+### Third Party Dependencies
-- curl
-- libxml2
-- clang-format (min version 10)
+Azure SDK uses Vcpkg manifest mode to declare the [list of required 3rd party dependencies](https://github.com/Azure/azure-sdk-for-cpp/blob/main/vcpkg.json) for building the SDK service libraries. It will also get and set up Vcpkg automatically. **You can move on to [Building the project](#building-the-project)** and skip the next part if you are not interested in learning about alternatives for setting up dependencies.
-Vcpkg can be used to install the Azure SDK for CPP dependencies into a specific folder on the system instead of globally installing them.
-Follow [vcpkg install guide](https://github.com/microsoft/vcpkg#getting-started) to get vcpkg and install the following dependencies:
+#### Customize the Vcpkg dependency integration
-```sh
-./vcpkg install curl libxml2
-```
-
-When using vcpkg, you can set the `VCPKG_ROOT` environment variable to the vcpkg Git repository folder. This would automatically set the CMake variable `CMAKE_TOOLCHAIN_FILE` for you, enabling the project to use any library installed with vcpkg.
+If the CMake option _-DCMAKE_TOOLCHAIN_FILE=..._ is not defined to generate the project, the Azure SDK project will automatically get Vcpkg and link it to get its dependencies. You can use the next environment variables to change this behavior:
-The Azure SDK for C++ uses [this vcpkg release version](https://github.com/Azure/azure-sdk-for-cpp/blob/main/eng/vcpkg-commit.txt) for continuous integration (CI) building and testing. Make sure to checkout this version when following the next steps for building and running the Azure SDK for C++. Using a newer vcpkg version might still work, however, if it is tested.
-
-```sh
-# Checking out vcpkg release version before installing dependencies
+
-git clone https://github.com/Microsoft/vcpkg.git
-cd vcpkg
-# Checkout the vcpkg commit from the vcpkg-commit.txt file (link above)
-git checkout
+
+
+Environment Variable |
+Description |
+
+
+AZURE_SDK_DISABLE_AUTO_VCPKG |
+When defined, Vcpkg won't be automatically cloned and linked. Use this setting, for example, if your dependencies are installed on the system and you don't need to get them. |
+
+
+AZURE_SDK_VCPKG_COMMIT |
+This variable can set the git commit id to be used when automatically cloning Vcpkg. |
+
+
+VCPKG_ROOT |
+Use this variable to set an existing Vcpkg folder from your system to be linked for building. Use this, for example, when working with Vcpkg classic mode, to switch between different Vcpkg folders. |
+
+
-# build vcpkg (showing Linux command, see vcpkg getting started for Windows)
-./bootstrap-vcpkg.sh
-./vcpkg install curl libxml2
-```
+
-### Building and Testing
-#### Building the project
+## Building the project
Generate the CMake files and build as you would with any standard CMake project. From the
repo root, run:
diff --git a/Dockerfile b/Dockerfile
deleted file mode 100644
index 21521125512..00000000000
--- a/Dockerfile
+++ /dev/null
@@ -1,79 +0,0 @@
-FROM debian:10
-
-# This Dockerfile adds a non-root 'vscode' user with sudo access. However, for Linux,
-# this user's GID/UID must match your local user UID/GID to avoid permission issues
-# with bind mounts. Update USER_UID / USER_GID if yours is not 1000. See
-# https://aka.ms/vscode-remote/containers/non-root-user for details.
-ARG USERNAME=azure-sdk-for-cpp
-ARG USER_UID=1000
-ARG USER_GID=$USER_UID
-ARG PORT=4000
-
-# Install packages as root
-USER root
-
-# Install needed packages and setup non-root user. Use a separate RUN statement to add your own dependencies.
-RUN apt-get update \
- && export DEBIAN_FRONTEND=noninteractive \
- && LANG=C LC_ALL=C apt-get -y install --no-install-recommends \
- apt-utils \
- dialog \
- sudo \
- #
- # Install vim, git, process tools, lsb-release
- git \
- openssh-client \
- less \
- #
- # Azure SDK for C++ dev env
- make \
- #cmake \
- ninja-build \
- build-essential \
- zlib1g-dev \
- libcurl4-openssl-dev \
- libssl-dev \
- libxml2-dev \
- gdb \
- # clang format 10 req
- gnupg2 \
- wget \
- ca-certificates \
- # vcpkg reqs
- curl \
- zip \
- unzip \
- tar \
- pkg-config \
-
- #
- # Add en_US.UTF-8 locale
- && echo 'en_US.UTF-8 UTF-8' >> /etc/locale.gen \
- && wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - \
- && echo 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-10 main' | tee -a /etc/apt/sources.list \
- && echo 'deb-src http://apt.llvm.org/bionic/ llvm-toolchain-bionic-10 main' | tee -a /etc/apt/sources.list \
- && apt-get update \
- && apt-get -y install --no-install-recommends clang-format-10 \
- #
- # Create a non-root user to use if preferred - see https://aka.ms/vscode-remote/containers/non-root-user.
- && groupadd --gid $USER_GID $USERNAME \
- && useradd -s /bin/bash --uid $USER_UID --gid $USER_GID -m $USERNAME \
- #
- # Add sudo support for the non-root user
- && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME\
- && chmod 0440 /etc/sudoers.d/$USERNAME \
- #
- # Clean up
- && apt-get autoremove -y \
- && apt-get clean -y \
- && rm -rf /var/lib/apt/lists/*
-
-RUN wget https://github.com/Kitware/CMake/releases/download/v3.20.2/cmake-3.20.2.tar.gz \
- && tar -zxvf cmake-3.20.2.tar.gz \
- && cd cmake-3.20.2 \
- && ./bootstrap \
- && make \
- && make install
-
-# Switch back to the non-root user
-USER ${USERNAME}
diff --git a/Dockerfile.src b/Dockerfile.src
deleted file mode 100644
index 7db38f2cdda..00000000000
--- a/Dockerfile.src
+++ /dev/null
@@ -1,15 +0,0 @@
-FROM base:latest
-ARG USERNAME=azure-sdk-for-cpp
-# Install packages as root
-USER root
-
-WORKDIR /home/azure-sdk-for-cpp/src
-
-COPY ./sdk/keyvault/azure-security-keyvault-certificates ./sdk/keyvault/azure-security-keyvault-certificates
-COPY ./sdk/keyvault/azure-security-keyvault-shared ./sdk/keyvault/azure-security-keyvault-shared
-COPY ./cmake-modules ./cmake-modules
-
-WORKDIR /home/azure-sdk-for-cpp/src/sdk/keyvault/azure-security-keyvault-certificates
-
-USER ${USERNAME}
-
diff --git a/README.md b/README.md
index 23a00e568fd..d15cca613cf 100644
--- a/README.md
+++ b/README.md
@@ -14,63 +14,146 @@ For API reference docs, tutorials, samples, quick starts, and other documentatio
### Download & Install the SDK
-The easiest way to acquire the C++ SDK is leveraging vcpkg package manager. You will need to install [Git](https://git-scm.com/downloads) before getting started.
+Here are some alternatives, from easiest to advanced, how you can get, build and integrate Azure SDK clients to your application.
-First clone and bootstrap vcpkg itself. You can install it anywhere on your machine, but **make note** of the directory where you clone the vcpkg repo.
+#### CMake Project + Vcpkg - manifest mode
-```cmd
-> git clone https://github.com/microsoft/vcpkg
+The easiest way to acquire the C++ SDK is leveraging [vcpkg](https://github.com/microsoft/vcpkg#getting-started) package manager. You will need to install [Git](https://git-scm.com/downloads) before getting started.
+
+##### 1. Create a [CMake](https://cmake.org/cmake/help/latest/) project
+
+CMake will take care of cross-operating system support.
+
+> Visual Studio installs CMake without adding it to the path. You need to [install CMake](https://cmake.org/download/) if you are not using Visual Studio or if you want to use a command line outside Visual Studio.
+
+Visual Studio:
+
+If you are using Visual Studio and you installed [support for CMake](https://docs.microsoft.com/cpp/build/cmake-projects-in-visual-studio?view=vs-2019), you can create a new CMake Project from Visual Studio, new project menu.
+
+-IMAGE HERE Visual Studio-
+
+Visual Studio Code:
+
+Install the VSCode extensions: [CMake](https://marketplace.visualstudio.com/items?itemName=twxs.cmake) and [CMake Tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools). Then, create folder for your project and open it with VSCode. Press `F1` and type _CMake: Quick Start_, follow the steps to give a name to your project, to select a compiler and any other initial configuration.
+
+-IMAGE HERE VSCode-
+
+> You can also manually create the root `CMakeLists.txt` with your own initial configuration and source.
+
+##### 2. Link the Vcpkg toolchain file to your CMake project
+
+Azure SDK provides a CMake module that you can use for your application. You only need to create a folder called _cmake-modules_ on the top level of your CMake project and copy [AzureVcpkg.cmake](https://github.com/Azure/azure-sdk-for-cpp/blob/main/cmake-modules/AzureVcpkg.cmake) to this folder.
+
+The AzureVcpkg module supports three scenarios:
+
+1. Getting and setting up Vcpkg automatically (default case). You can set the env var `AZURE_SDK_DISABLE_AUTO_VCPKG` to disable this bahavior.
+2. Automatically linking your application to an existing Vcpkg folder. Set the environment variable `VCPKG_ROOT` to the Vcpkg folder you want to link.
+3. Manually setting a toolchain file with cmake command option. `AzureVcpkg.cmake` module will respect the option.
+
+Add the next lines to your root `CMakeLists.txt` to use `AzureVcpkg.cmake` module:
+
+```cmake
+# Add this lines on the top, before the call to `project(name VERSION 0.0.0)
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules")
+include(AzureVcpkg)
+az_vcpkg_integrate()
```
-On Windows:
+##### 3. Add Vcpkg manifest
+
+Add a new file called `vcpkg.json` on the root of your CMake project and add the Azure SDK clients you want to use in your application. For example, the next manifest defines Azure Identity and Blobs.
-```cmd
-> .\vcpkg\bootstrap-vcpkg.bat
+```json
+{
+ "name": "your-app-name",
+ "version-string": "",
+ "dependencies": [
+ "azure-identity-cpp",
+ "azure-storage-blobs-cpp"
+ ]
+}
```
-On Linux:
+##### 4. Link Azure SDK libraries to your application
-```sh
-> ./vcpkg/bootstrap-vcpkg.sh
+Add the next lines to your `CMakeLists.txt` file. It must be added after the cmake target name is defined.
+
+```cmake
+find_package(azure-identity-cpp CONFIG REQUIRED)
+find_package(azure-storage-blobs-cpp CONFIG REQUIRED)
+target_link_libraries(quick-sample PRIVATE Azure::azure-identity Azure::azure-storage-blobs)
```
-To install the libraries for your project, run the following, optionally specifying the triplet. For example, the following will install packages for the `x64-windows` triplet. On Windows, not specifying a triplet will default to `x86-windows`:
+> See the list of available SDK clients for C++ [here](https://azure.github.io/azure-sdk/releases/latest/cpp.html)
-```cmd
-> .\vcpkg\vcpkg install azure-storage-blobs-cpp:x64-windows
+
+##### 5. Generate project and compile
+
+At this point, you can press F7 on Visual Studio or VSCode to generate and build the project. Or you can also run the following commands from a command line:
+
+```bash
+# Create a build folder (if there's not one already there)
+mkdir build
+cd build
+cmake ..
+cmake --build .
```
-See the [list of packages](https://github.com/Azure/azure-sdk-for-cpp#vcpkg) available via vcpkg below. All Azure C++ SDK package names start with `azure-`. You can also search for the libraries you need with the `search` command. For example:
+> Using Vcpkg manifest makes easy to define multiple dependencies and delegate building them to Vcpkg.
+
+#### CMake Project + fetch content
+
+For this scenario, CMake will fetch the Azure SDK source code and make it part of your project. THe SDK client libraries will be compiled at the same time as your application.
+
+Follow the step 1 from above to create a CMake project first.
-```cmd
-> .\vcpkg\vcpkg search azure-
+###### 2. Define CMake fetch content
+
+Add the following code to your root `CMakeLists.txt` file:
+
+```cmake
+# Add this code before creating and linking your application
+
+include(FetchContent)
+FetchContent_Declare(
+ azuresdk
+ GIT_REPOSITORY https://github.com/Azure/azure-sdk-for-cpp.git
+ GIT_TAG
+)
+FetchContent_GetProperties(azuresdk)
+if(NOT azuresdk_POPULATED)
+ FetchContent_Populate(azuresdk)
+ # Adding all Azure SDK libraries
+ add_subdirectory(${azuresdk_SOURCE_DIR} ${azuresdk_BINARY_DIR} EXCLUDE_FROM_ALL)
+ # Adding one Azure SDK Library only (Storage blobs)
+ # add_subdirectory(${azuresdk_SOURCE_DIR}/sdk/storage/azure-storage-blobs ${azuresdk_BINARY_DIR} EXCLUDE_FROM_ALL)
+endif()
```
-Once the library is installed, follow the instructions from the console output to include the library in your `CMake` application. For example, to include `azure-storage-blobs-cpp`, add the following to your `CMakeLists.txt` file:
+##### 3. Link Azure SDK libraries to your application
-```CMake
-find_package(azure-storage-blobs-cpp CONFIG REQUIRED)
-target_link_libraries( PRIVATE Azure::azure-storage-blobs)
+The only difference from the previous scenario is that you don't need to call `find_package()`, since the cmake targets are integrated to your project. So you only need:
+
+```cmake
+# After creating the cmake target
+target_link_libraries(quick-sample PRIVATE Azure::azure-identity Azure::azure-storage-blobs)
```
-> NOTE: All the Azure client libraries take a dependency on `azure-core-cpp` which provides functionality commonly needed by all Azure clients. When you install any client library via vcpkg, it will bring in all the necessary dependencies as well. You don't need to install those individually to get started.
+> Note: You need to take care of getting the Azure SDK dependencies on your own. Either manually installing them or by integrating the source code to your project as well.
-You can reference this [vcpkg Quick Start](https://github.com/microsoft/vcpkg#quick-start-windows) for more details.
+Use step 5 from previous scenario to generate and build your project.
-#### Getting Beta Releases in Vcpkg
+> This scenario requires extra manual configuration to get dependencies, but it is useful as an alternative when Vcpkg is not available
-Official vcpkg registry may have beta versions of Azure SDK client libraries, up until a given library gets released as stable. After that, we don't publish post-first-stable beta releases of that library in the official registry.
+#### Other combinations
-If you are interested in both stable releases and post-first-stable beta releases, see [Azure SDK Beta Vcpkg Registry](https://github.com/Azure/azure-sdk-vcpkg-betas/).
+It should be possible to create your application without a CMake project. For example, manually cloning Azure SDK, building libraries and finally linking them to your application. However, this is considered an advanced scenario and it is not either described or maintained (The other scenarios described below are validated with CI pipelines).
-### Building your Application
+#### Getting Beta Releases in Vcpkg
-In order to use the SDK installed via vcpkg with CMake, you can use the toolchain file from vcpkg:
+Official vcpkg registry may have beta versions of Azure SDK client libraries, up until a given library gets released as stable. After that, we don't publish post-first-stable beta releases of that library in the official registry.
-```cmd
-> cmake -B [build directory] -S . -DCMAKE_TOOLCHAIN_FILE=[path to vcpkg repo]/scripts/buildsystems/vcpkg.cmake
-> cmake --build [build directory]
-```
+If you are interested in both stable releases and post-first-stable beta releases, see [Azure SDK Beta Vcpkg Registry](https://github.com/Azure/azure-sdk-vcpkg-betas/). You can update the `AzureVcpkg.cmake` module to use the beta registry.
#### Using the SDK within your Application
@@ -230,12 +313,14 @@ The following SDK library releases are available on [vcpkg](https://github.com/m
* `azure-core-cpp`
* `azure-identity-cpp`
+* `azure-security-attestation-cpp`
+* `azure-security-keyvault-certificates-cpp`
+* `azure-security-keyvault-keys-cpp`
+* `azure-security-keyvault-secrets-cpp`
* `azure-storage-blobs-cpp`
* `azure-storage-files-datalake-cpp`
* `azure-storage-files-shares-cpp`
-* `azure-security-keyvault-keys-cpp`
-* `azure-security-keyvault-secrets-cpp`
-* `azure-security-keyvault-certificates-cpp`
+* `azure-storage-queues-cpp`
> NOTE: In case of getting linker errors when consuming the SDK on Windows, make sure that [vcpkg triplet](https://vcpkg.readthedocs.io/en/latest/users/triplets/) being consumed matches the [CRT link flags](https://docs.microsoft.com/cpp/build/reference/md-mt-ld-use-run-time-library?view=msvc-160) being set for your app or library build. See also `MSVC_USE_STATIC_CRT` build flag.
diff --git a/cmake-modules/AzureVcpkg.cmake b/cmake-modules/AzureVcpkg.cmake
index 85d02890180..2789241fb5f 100644
--- a/cmake-modules/AzureVcpkg.cmake
+++ b/cmake-modules/AzureVcpkg.cmake
@@ -5,14 +5,45 @@
set(AZ_ROOT_DIR "${CMAKE_CURRENT_LIST_DIR}/..")
macro(az_vcpkg_integrate)
- # vcpkg Integration
- if(DEFINED ENV{VCPKG_ROOT} AND NOT DEFINED CMAKE_TOOLCHAIN_FILE)
- set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"
- CACHE STRING "")
- elseif(DEFINED ENV{VCPKG_INSTALLATION_ROOT} AND NOT DEFINED CMAKE_TOOLCHAIN_FILE)
- set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_INSTALLATION_ROOT}/scripts/buildsystems/vcpkg.cmake"
- CACHE STRING "")
+ # AUTO CMAKE_TOOLCHAIN_FILE:
+ # User can call `cmake -DCMAKE_TOOLCHAIN_FILE="path_to_the_toolchain"` as the most specific scenario.
+ # An env var VCPKG_ROOT or VCPKG_INSTALLATION_ROOT can be set to let Azure SDK to set the VCPKG toolchain automatically.
+ # As the last alternative (default case), Azure SDK will automatically clone VCPKG folder and set toolchain from there.
+ if(NOT DEFINED CMAKE_TOOLCHAIN_FILE)
+ if(DEFINED ENV{VCPKG_ROOT})
+ set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"
+ CACHE STRING "")
+ elseif(DEFINED ENV{VCPKG_INSTALLATION_ROOT})
+ set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_INSTALLATION_ROOT}/scripts/buildsystems/vcpkg.cmake"
+ CACHE STRING "")
+ else()
+ # Set AZURE_SDK_DISABLE_AUTO_VCPKG env var to avoid Azure SDK from cloning and setting VCPKG automatically
+ # This option delegate package's dependencies installation to user.
+ if(NOT DEFINED ENV{AZURE_SDK_DISABLE_AUTO_VCPKG})
+ # GET VCPKG FROM SOURCE
+ # User can set env var AZURE_SDK_VCPKG_COMMIT to pick the VCPKG commit to fetch
+ set(VCPKG_COMMIT_STRING f0aa678b7471497f1adedcc99f40e1599ad22f69) # default SDK tested commit
+ if(DEFINED ENV{AZURE_SDK_VCPKG_COMMIT})
+ set(VCPKG_COMMIT_STRING "$ENV{AZURE_SDK_VCPKG_COMMIT}") # default SDK tested commit
+ endif()
+ include(FetchContent)
+ FetchContent_Declare(
+ vcpkg
+ GIT_REPOSITORY https://github.com/microsoft/vcpkg.git
+ GIT_TAG ${VCPKG_COMMIT_STRING}
+ )
+ FetchContent_GetProperties(vcpkg)
+ # make sure to pull vcpkg only once.
+ if(NOT vcpkg_POPULATED)
+ FetchContent_Populate(vcpkg)
+ endif()
+ # use the vcpkg source path
+ set(CMAKE_TOOLCHAIN_FILE "${vcpkg_SOURCE_DIR}/scripts/buildsystems/vcpkg.cmake" CACHE STRING "")
+ endif()
+ endif()
endif()
+
+ # enable triplet customization
if(DEFINED ENV{VCPKG_DEFAULT_TRIPLET} AND NOT DEFINED VCPKG_TARGET_TRIPLET)
set(VCPKG_TARGET_TRIPLET "$ENV{VCPKG_DEFAULT_TRIPLET}" CACHE STRING "")
endif()
diff --git a/cmake-modules/FolderList.cmake b/cmake-modules/FolderList.cmake
index 8c3685b4324..eb1946395a8 100644
--- a/cmake-modules/FolderList.cmake
+++ b/cmake-modules/FolderList.cmake
@@ -2,21 +2,21 @@ macro(GetFolderList project)
message ("project found ${project}")
message ("FLAG VALUE : ${FETCH_SOURCE_DEPS}")
if(${project} STREQUAL CERTIFICATES)
- DownloadDepVersion(sdk/core azure-core 1.2.0)
+ DownloadDepVersion(sdk/core azure-core 1.5.0)
DownloadDepVersion(sdk/identity azure-identity 1.1.0)
elseif(${project} STREQUAL IDENTITY)
DownloadDepVersion(sdk/core azure-core 1.2.0)
elseif(${project} STREQUAL SECRETS)
- DownloadDepVersion(sdk/core azure-core 1.2.0)
+ DownloadDepVersion(sdk/core azure-core 1.5.0)
DownloadDepVersion(sdk/identity azure-identity 1.1.0)
elseif(${project} STREQUAL KEYS)
- DownloadDepVersion(sdk/core azure-core 1.2.0)
+ DownloadDepVersion(sdk/core azure-core 1.5.0)
DownloadDepVersion(sdk/identity azure-identity 1.1.0)
elseif(${project} STREQUAL STORAGE_COMMON)
DownloadDepVersion(sdk/core azure-core 1.5.0)
elseif(${project} STREQUAL STORAGE_BLOBS)
DownloadDepVersion(sdk/core azure-core 1.5.0)
- DownloadDepVersion(sdk/storage/azure-storage-common azure-storage-common 12.2.3)
+ DownloadDepVersion(sdk/storage/azure-storage-common azure-storage-common 12.2.4)
elseif(${project} STREQUAL STORAGE_FILES_DATALAKE)
DownloadDepVersion(sdk/core azure-core 1.3.1)
DownloadDepVersion(sdk/storage/azure-storage-common azure-storage-common 12.2.2)
diff --git a/doc/DistributedTracing.md b/doc/DistributedTracing.md
index ecf6e3be3f8..b9dfe7bc6bd 100644
--- a/doc/DistributedTracing.md
+++ b/doc/DistributedTracing.md
@@ -85,7 +85,7 @@ functions as an abstract class integration between OpenTelemetry and Azure Core:
```c++
std::shared_ptr traceProvider
- = std::make_shared(CreateOpenTelemetryProvider());
+ = Azure::Core::Tracing::OpenTelemetry::OpenTelemetryProvider::Create(CreateOpenTelemetryProvider());
```
To finish the integration with Azure clients, there are two mechanisms to integrate OpenTelemetry into a client application:
@@ -110,7 +110,7 @@ the service client.
```c++
auto tracerProvider(CreateOpenTelemetryProvider());
-auto provider(std::make_shared(tracerProvider));
+auto provider(Azure::Core::Tracing::OpenTelemetry::OpenTelemetryProvider::Create(tracerProvider));
ServiceClientOptions clientOptions;
clientOptions.Telemetry.TracingProvider = provider;
@@ -133,7 +133,7 @@ There are two steps needed to integrate Distributed Tracing with a Service Clien
To add a new `DiagnosticTracingFactory` to the client, simply add the class as a member:
```c++
- Azure::Core::Tracing::_internal::DiagnosticTracingFactory m_tracingFactory;
+ Azure::Core::Tracing::_internal::TracingContextFactory m_tracingFactory;
```
@@ -158,11 +158,10 @@ And construct the new tracing factory in the service constructor:
Azure::Core::Context const& context = Azure::Core::Context{})
{
// Create a new context and span for this request.
- auto contextAndSpan = m_tracingFactory.CreateSpan(
- "ServiceMethod", Azure::Core::Tracing::_internal::SpanKind::Internal, context);
+ auto contextAndSpan = m_tracingFactory.CreateSpan("ServiceMethod", context);
- // contextAndSpan.first is the new context for the operation.
- // contextAndSpan.second is the new span for the operation.
+ // contextAndSpan.Context is the new context for the operation.
+ // contextAndSpan.Span is the new span for the operation.
try
{
@@ -171,15 +170,14 @@ And construct the new tracing factory in the service constructor:
HttpMethod::Get, Azure::Core::Url(""));
std::unique_ptr response
- = m_pipeline->Send(requestToSend, contextAndSpan.first);
- contextAndSpan.second.SetStatus(Azure::Core::Tracing::_internal::SpanStatus::Ok);
+ = m_pipeline->Send(requestToSend, contextAndSpan.Context);
+ contextAndSpan.Span.SetStatus(Azure::Core::Tracing::_internal::SpanStatus::Ok);
return Azure::Response("", std::move(response));
}
catch (std::exception const& ex)
{
// Register that the exception has happened and that the span is now in error.
- contextAndSpan.second.AddEvent(ex);
- contextAndSpan.second.SetStatus(Azure::Core::Tracing::_internal::SpanStatus::Error);
+ contextAndSpan.Span.AddEvent(ex);
throw;
}
@@ -247,4 +245,4 @@ Generated traces have the following attributes:
| `http.status_code` | HTTP status code returned by the service | HTTP Spans.
| `http.user_agent` | The value of the `User-Agent` HTTP header sent to the service | HTTP Spans.
| `requestId` | The value of the `x-ms-client-request-id` header sent by the client | HTTP Spans.
-| `serviceRequestId` | The value -f the `x-ms-request-id` sent by the server | HTTP Spans.
+| `serviceRequestId` | The value of the `x-ms-request-id` sent by the server | HTTP Spans.
diff --git a/doc/LibcurlTransportAdapter.md b/doc/LibcurlTransportAdapter.md
index 9b414ebe609..6aeec041999 100644
--- a/doc/LibcurlTransportAdapter.md
+++ b/doc/LibcurlTransportAdapter.md
@@ -19,7 +19,7 @@ One of the more interesting features of the Azure SDK for C++ is that a customer
## Libcurl Transport Adapter
-The azure-core-cpp library provides a transport adapter implemented with libcurl. The next paragraphs mentions some of the limitations of libcurl and the code that is part of the LibcurlTransportAdatper (LTA) that satisfy the expectations for an SDK client.
+The azure-core-cpp library provides a transport adapter implemented with libcurl. The next paragraphs mentions some of the limitations of libcurl and the code that is part of the LibcurlTransportAdapter (LTA) that satisfy the expectations for an SDK client.
### Easy handle
diff --git a/eng/common/TestResources/New-TestResources.ps1 b/eng/common/TestResources/New-TestResources.ps1
index b7785df9ddf..25d8060cc11 100644
--- a/eng/common/TestResources/New-TestResources.ps1
+++ b/eng/common/TestResources/New-TestResources.ps1
@@ -63,6 +63,10 @@ param (
[ValidateSet('AzureCloud', 'AzureUSGovernment', 'AzureChinaCloud', 'Dogfood')]
[string] $Environment = 'AzureCloud',
+ [Parameter()]
+ [ValidateSet('test', 'perf')]
+ [string] $ResourceType = 'test',
+
[Parameter()]
[hashtable] $ArmTemplateParameters,
@@ -223,7 +227,7 @@ function BuildBicepFile([System.IO.FileSystemInfo] $file)
}
$tmp = $env:TEMP ? $env:TEMP : [System.IO.Path]::GetTempPath()
- $templateFilePath = Join-Path $tmp "test-resources.$(New-Guid).compiled.json"
+ $templateFilePath = Join-Path $tmp "$ResourceType-resources.$(New-Guid).compiled.json"
# Az can deploy bicep files natively, but by compiling here it becomes easier to parse the
# outputted json for mismatched parameter declarations.
@@ -349,7 +353,7 @@ try {
$root = [System.IO.Path]::Combine($repositoryRoot, "sdk", $ServiceDirectory) | Resolve-Path
$templateFiles = @()
- 'test-resources.json', 'test-resources.bicep' | ForEach-Object {
+ "$ResourceType-resources.json", "$ResourceType-resources.bicep" | ForEach-Object {
Write-Verbose "Checking for '$_' files under '$root'"
Get-ChildItem -Path $root -Filter "$_" -Recurse | ForEach-Object {
Write-Verbose "Found template '$($_.FullName)'"
@@ -397,7 +401,7 @@ try {
# string.
if (!$Location) {
$Location = @{
- 'AzureCloud' = 'westus2';
+ 'AzureCloud' = 'westus';
'AzureUSGovernment' = 'usgovvirginia';
'AzureChinaCloud' = 'chinaeast2';
'Dogfood' = 'westus'
@@ -586,9 +590,9 @@ try {
# Service principals in the Microsoft AAD tenant must end with an @microsoft.com domain; those in other tenants
# are not permitted to do so. Format the non-MS name so there's an assocation with the Azure SDK.
if ($TenantId -eq '72f988bf-86f1-41af-91ab-2d7cd011db47') {
- $displayName = "test-resources-$($baseName)$suffix.microsoft.com"
+ $displayName = "$ResourceType-resources-$($baseName)$suffix.microsoft.com"
} else {
- $displayName = "$($baseName)$suffix.test-resources.azure.sdk"
+ $displayName = "$($baseName)$suffix.$ResourceType-resources.azure.sdk"
}
$servicePrincipalWrapper = NewServicePrincipalWrapper -subscription $SubscriptionId -resourceGroup $ResourceGroupName -displayName $DisplayName
@@ -705,7 +709,7 @@ try {
}
}
- $preDeploymentScript = $templateFile.originalFilePath | Split-Path | Join-Path -ChildPath 'test-resources-pre.ps1'
+ $preDeploymentScript = $templateFile.originalFilePath | Split-Path | Join-Path -ChildPath "$ResourceType-resources-pre.ps1"
if (Test-Path $preDeploymentScript) {
Log "Invoking pre-deployment script '$preDeploymentScript'"
&$preDeploymentScript -ResourceGroupName $ResourceGroupName @PSBoundParameters
@@ -745,7 +749,7 @@ try {
$deploymentOutputs = SetDeploymentOutputs $serviceName $context $deployment $templateFile
- $postDeploymentScript = $templateFile.originalFilePath | Split-Path | Join-Path -ChildPath 'test-resources-post.ps1'
+ $postDeploymentScript = $templateFile.originalFilePath | Split-Path | Join-Path -ChildPath "$ResourceType-resources-post.ps1"
if (Test-Path $postDeploymentScript) {
Log "Invoking post-deployment script '$postDeploymentScript'"
&$postDeploymentScript -ResourceGroupName $ResourceGroupName -DeploymentOutputs $deploymentOutputs @PSBoundParameters
@@ -903,7 +907,7 @@ This is used for CI automation.
Optional location where resources should be created. If left empty, the default
is based on the cloud to which the template is being deployed:
-* AzureCloud -> 'westus2'
+* AzureCloud -> 'westus'
* AzureUSGovernment -> 'usgovvirginia'
* AzureChinaCloud -> 'chinaeast2'
* Dogfood -> 'westus'
diff --git a/eng/common/TestResources/New-TestResources.ps1.md b/eng/common/TestResources/New-TestResources.ps1.md
index 2ccf6ca4af6..a18e2e5b8d6 100644
--- a/eng/common/TestResources/New-TestResources.ps1.md
+++ b/eng/common/TestResources/New-TestResources.ps1.md
@@ -422,7 +422,7 @@ Optional location where resources should be created.
If left empty, the default
is based on the cloud to which the template is being deployed:
-* AzureCloud -\> 'westus2'
+* AzureCloud -\> 'westus'
* AzureUSGovernment -\> 'usgovvirginia'
* AzureChinaCloud -\> 'chinaeast2'
* Dogfood -\> 'westus'
diff --git a/eng/common/TestResources/README.md b/eng/common/TestResources/README.md
index 957a1f9c357..757c7c337ac 100644
--- a/eng/common/TestResources/README.md
+++ b/eng/common/TestResources/README.md
@@ -49,7 +49,7 @@ ${env:KEYVAULT_CLIENT_ID} = '<>'
${env:KEYVAULT_CLIENT_SECRET} = '<>'
${env:KEYVAULT_SUBSCRIPTION_ID} = 'YOUR SUBSCRIPTION ID'
${env:KEYVAULT_RESOURCE_GROUP} = 'rg-myusername'
-${env:KEYVAULT_LOCATION} = 'westus2'
+${env:KEYVAULT_LOCATION} = 'westus'
${env:KEYVAULT_SKU} = 'premium'
${env:AZURE_KEYVAULT_URL} = '<>'
```
diff --git a/eng/common/TestResources/Remove-TestResources.ps1 b/eng/common/TestResources/Remove-TestResources.ps1
index 788dae63e6e..069f2bf8a63 100644
--- a/eng/common/TestResources/Remove-TestResources.ps1
+++ b/eng/common/TestResources/Remove-TestResources.ps1
@@ -52,6 +52,10 @@ param (
[Parameter(ParameterSetName = 'ResourceGroup+Provisioner')]
[switch] $CI,
+ [Parameter()]
+ [ValidateSet('test', 'perf')]
+ [string] $ResourceType = 'test',
+
[Parameter()]
[switch] $Force,
@@ -198,7 +202,7 @@ Log "Selected subscription '$subscriptionName'"
if ($ServiceDirectory) {
$root = [System.IO.Path]::Combine("$PSScriptRoot/../../../sdk", $ServiceDirectory) | Resolve-Path
- $preRemovalScript = Join-Path -Path $root -ChildPath 'remove-test-resources-pre.ps1'
+ $preRemovalScript = Join-Path -Path $root -ChildPath "remove-$ResourceType-resources-pre.ps1"
if (Test-Path $preRemovalScript) {
Log "Invoking pre resource removal script '$preRemovalScript'"
@@ -210,7 +214,7 @@ if ($ServiceDirectory) {
}
# Make sure environment files from New-TestResources -OutFile are removed.
- Get-ChildItem -Path $root -Filter test-resources.json.env -Recurse | Remove-Item -Force:$Force
+ Get-ChildItem -Path $root -Filter "$ResourceType-resources.json.env" -Recurse | Remove-Item -Force:$Force
}
$verifyDeleteScript = {
diff --git a/eng/common/TestResources/deploy-test-resources.yml b/eng/common/TestResources/deploy-test-resources.yml
index 25c0823ac55..a0c68f33a3c 100644
--- a/eng/common/TestResources/deploy-test-resources.yml
+++ b/eng/common/TestResources/deploy-test-resources.yml
@@ -4,6 +4,7 @@ parameters:
DeleteAfterHours: 8
Location: ''
SubscriptionConfiguration: $(sub-config-azure-cloud-test-resources)
+ ResourceType: test
# SubscriptionConfiguration will be splatted into the parameters of the test
# resources script. It should be JSON in the form:
@@ -48,6 +49,7 @@ steps:
# pass those in via the ArmTemplateParameters flag, and handle any
# additional parameters from the pipelines via AdditionalParameters
eng/common/TestResources/New-TestResources.ps1 `
+ -ResourceType '${{ parameters.ResourceType }}' `
-ServiceDirectory '${{ parameters.ServiceDirectory }}' `
-Location '${{ parameters.Location }}' `
-DeleteAfterHours '${{ parameters.DeleteAfterHours }}' `
diff --git a/eng/common/TestResources/remove-test-resources.yml b/eng/common/TestResources/remove-test-resources.yml
index cf5c0c5ac45..9675f58e06e 100644
--- a/eng/common/TestResources/remove-test-resources.yml
+++ b/eng/common/TestResources/remove-test-resources.yml
@@ -4,6 +4,7 @@
parameters:
ServiceDirectory: ''
SubscriptionConfiguration: $(sub-config-azure-cloud-test-resources)
+ ResourceType: test
# SubscriptionConfiguration will be splat into the parameters of the test
# resources script. It should be JSON in the form:
@@ -29,6 +30,7 @@ steps:
eng/common/TestResources/Remove-TestResources.ps1 `
@subscriptionConfiguration `
+ -ResourceType '${{ parameters.ResourceType }}' `
-ServiceDirectory "${{ parameters.ServiceDirectory }}" `
-CI `
-Force `
diff --git a/eng/common/docgeneration/templates/matthews/partials/class.header.tmpl.partial b/eng/common/docgeneration/templates/matthews/partials/class.header.tmpl.partial
index 49a27d82732..db73a4bddb2 100644
--- a/eng/common/docgeneration/templates/matthews/partials/class.header.tmpl.partial
+++ b/eng/common/docgeneration/templates/matthews/partials/class.header.tmpl.partial
@@ -87,14 +87,14 @@
{{/syntax.typeParameters.0}}
-{{#remarks}}
-
-
-{{/remarks}}
-
{{#example.0}}
-{{__global.examples}}
+{{__global.examples}}
{{/example.0}}
{{#example}}
{{{.}}}
{{/example}}
+
+{{#remarks}}
+
+
+{{/remarks}}
\ No newline at end of file
diff --git a/eng/common/docgeneration/templates/matthews/partials/class.tmpl.partial b/eng/common/docgeneration/templates/matthews/partials/class.tmpl.partial
index 5f00b822cc7..37a69fa1c4e 100644
--- a/eng/common/docgeneration/templates/matthews/partials/class.tmpl.partial
+++ b/eng/common/docgeneration/templates/matthews/partials/class.tmpl.partial
@@ -132,11 +132,6 @@
{{/definition}}
{{/implements}}
-{{#remarks}}
-
-
-{{/remarks}}
-
{{#example.0}}
{{__global.examples}}
{{/example.0}}
@@ -144,6 +139,11 @@
{{{.}}}
{{/example}}
+{{#remarks}}
+
+
+{{/remarks}}
+
{{#exceptions.0}}
{{__global.exceptions}}
diff --git a/eng/common/pipelines/templates/jobs/docindex.yml b/eng/common/pipelines/templates/jobs/docindex.yml
index 488c835a828..ea7b2997dbd 100644
--- a/eng/common/pipelines/templates/jobs/docindex.yml
+++ b/eng/common/pipelines/templates/jobs/docindex.yml
@@ -4,9 +4,9 @@ jobs:
vmImage: windows-2019
steps:
- task: UsePythonVersion@0
- displayName: 'Use Python 3.6'
+ displayName: 'Use Python 3.9'
inputs:
- versionSpec: '3.6'
+ versionSpec: '3.9'
- pwsh: |
Invoke-WebRequest -Uri "https://github.com/dotnet/docfx/releases/download/v2.43.2/docfx.zip" `
@@ -27,10 +27,6 @@ jobs:
-DocOutDir "$(Build.ArtifactStagingDirectory)/docfx_project"
-verbose
- - task: UsePythonVersion@0
- displayName: 'Use Python 3.6'
- inputs:
- versionSpec: '3.6'
- template: /eng/common/pipelines/templates/steps/mashup-doc-index.yml
parameters:
SourceDirectory: $(Build.ArtifactStagingDirectory)
diff --git a/eng/common/pipelines/templates/jobs/perf.yml b/eng/common/pipelines/templates/jobs/perf.yml
new file mode 100644
index 00000000000..3d3a3f6e310
--- /dev/null
+++ b/eng/common/pipelines/templates/jobs/perf.yml
@@ -0,0 +1,142 @@
+parameters:
+- name: Variables
+ type: object
+ default: []
+- name: OperatingSystems
+ type: string
+ default: 'Linux'
+- name: Language
+ type: string
+ default: ''
+- name: InstallLanguageSteps
+ type: stepList
+ default: []
+- name: ServiceDirectory
+ type: string
+ default: ''
+- name: Services
+ type: string
+ default: ''
+- name: PackageVersions
+ type: string
+ default: '.*'
+- name: Tests
+ type: string
+ default: '.*'
+- name: Arguments
+ type: string
+ default: '.*'
+- name: Iterations
+ type: number
+ default: '5'
+- name: AdditionalArguments
+ type: string
+ default: ''
+- name: EnvVars
+ type: object
+ default: {}
+
+resources:
+ repositories:
+ - repository: azure-sdk-tools
+ type: github
+ endpoint: Azure
+ name: Azure/azure-sdk-tools
+ ref: main
+
+variables:
+- ${{ parameters.Variables }}
+
+jobs:
+- job: Perf
+ timeoutInMinutes: 360
+ strategy:
+ matrix:
+ ${{ if contains(parameters.OperatingSystems, 'Linux') }}:
+ Linux:
+ Pool: 'azsdk-pool-mms-ubuntu-2004-perf'
+ OsVmImage: 'MMSUbuntu20.04'
+ MatrixName: 'Linux'
+ ${{ if contains(parameters.OperatingSystems, 'Windows') }}:
+ Windows:
+ Pool: 'azsdk-pool-mms-win-2019-perf'
+ OsVmImage: 'MMS2019'
+ MatrixName: 'Windows'
+ pool:
+ name: $(Pool)
+ vmImage: $(OSVmImage)
+ steps:
+ - checkout: self
+ path: s
+
+ - checkout: azure-sdk-tools
+ path: s/azure-sdk-tools
+
+ - template: /eng/common/pipelines/templates/steps/verify-agent-os.yml
+ parameters:
+ AgentImage: $(OSVmImage)
+
+ - ${{ parameters.InstallLanguageSteps }}
+
+ - template: /eng/common/TestResources/deploy-test-resources.yml
+ parameters:
+ ServiceDirectory: ${{ parameters.ServiceDirectory }}
+ Location: westus
+ ResourceType: perf
+
+ - pwsh: |
+ set-content -path config.yml -value "WorkingDirectories:"
+ add-content -path config.yml -value " ${{ parameters.Language }}: $(Agent.BuildDirectory)/s"
+ workingDirectory: azure-sdk-tools/tools/perf-automation/Azure.Sdk.Tools.PerfAutomation
+ displayName: Create config.yml
+
+ - script: >-
+ dotnet run -- run
+ --no-sync
+ --languages ${{ parameters.Language }}
+ --services "${{ parameters.Services }}"
+ --package-versions "${{ parameters.PackageVersions }}"
+ --tests "${{ parameters.Tests }}"
+ --arguments "${{ parameters.Arguments }}"
+ --iterations ${{ parameters.Iterations }}
+ ${{ parameters.AdditionalArguments }}
+ workingDirectory: azure-sdk-tools/tools/perf-automation/Azure.Sdk.Tools.PerfAutomation
+ env:
+ ${{ each var in parameters.EnvVars }}:
+ ${{ var.key }}: ${{ var.value }}
+ displayName: Run perf tests
+
+ - pwsh: |
+ get-content results.txt
+ workingDirectory: azure-sdk-tools/tools/perf-automation/Azure.Sdk.Tools.PerfAutomation/results
+ displayName: Print results.txt
+ condition: always()
+
+ - pwsh: |
+ get-content results.csv
+ workingDirectory: azure-sdk-tools/tools/perf-automation/Azure.Sdk.Tools.PerfAutomation/results
+ displayName: Print results.csv
+ condition: always()
+
+ - pwsh: |
+ get-content results.md
+ workingDirectory: azure-sdk-tools/tools/perf-automation/Azure.Sdk.Tools.PerfAutomation/results
+ displayName: Print results.md
+ condition: always()
+
+ - pwsh: |
+ get-content results.json
+ workingDirectory: azure-sdk-tools/tools/perf-automation/Azure.Sdk.Tools.PerfAutomation/results
+ displayName: Print results.json
+ condition: always()
+
+ - task: PublishPipelineArtifact@1
+ inputs:
+ targetPath: azure-sdk-tools/tools/perf-automation/Azure.Sdk.Tools.PerfAutomation/results
+ artifactName: results-$(MatrixName)
+ condition: always()
+
+ - template: /eng/common/TestResources/remove-test-resources.yml
+ parameters:
+ ServiceDirectory: ${{ parameters.ServiceDirectory }}
+ ResourceType: perf
diff --git a/eng/common/pipelines/templates/steps/cosmos-emulator.yml b/eng/common/pipelines/templates/steps/cosmos-emulator.yml
index cda0e8ac10e..f1faae362f4 100644
--- a/eng/common/pipelines/templates/steps/cosmos-emulator.yml
+++ b/eng/common/pipelines/templates/steps/cosmos-emulator.yml
@@ -22,15 +22,3 @@ steps:
-Stage "Launch"
pwsh: true
displayName: Launch Public Cosmos DB Emulator
- continueOnError: true
-
- - task: Powershell@2
- inputs:
- filePath: $(Build.SourcesDirectory)/eng/common/scripts/Cosmos-Emulator.ps1
- arguments: >
- -EmulatorMsiUrl "${{ parameters.EmulatorMsiUrl }}"
- -StartParameters "${{ parameters.StartParameters }}"
- -Stage "Launch"
- pwsh: true
- displayName: Retry Launch of Public Cosmos DB Emulator
- condition: failed()
\ No newline at end of file
diff --git a/eng/common/pipelines/templates/steps/create-apireview.yml b/eng/common/pipelines/templates/steps/create-apireview.yml
index cd658132dec..e8500694377 100644
--- a/eng/common/pipelines/templates/steps/create-apireview.yml
+++ b/eng/common/pipelines/templates/steps/create-apireview.yml
@@ -24,4 +24,11 @@ steps:
pwsh: true
workingDirectory: $(Pipeline.Workspace)
displayName: Create API Review for ${{ artifact.name}}
- condition: and(succeededOrFailed(), ne(variables['Skip.CreateApiReview'], 'true') , ne(variables['Build.Reason'],'PullRequest'), eq(variables['System.TeamProject'], 'internal'))
+ condition: >-
+ and(
+ succeededOrFailed(),
+ ne(variables['Skip.CreateApiReview'], 'true'),
+ ne(variables['Build.Reason'],'PullRequest'),
+ eq(variables['System.TeamProject'], 'internal'),
+ not(endsWith(variables['Build.Repository.Name'], '-pr'))
+ )
diff --git a/eng/common/pipelines/templates/steps/credscan.yml b/eng/common/pipelines/templates/steps/credscan.yml
index 0171c79d0d2..8a2e53748ab 100644
--- a/eng/common/pipelines/templates/steps/credscan.yml
+++ b/eng/common/pipelines/templates/steps/credscan.yml
@@ -28,6 +28,8 @@ steps:
Write-Host "##vso[task.setvariable variable=SKIP_CREDSCAN]true"
}
displayName: CredScan setup
+ condition: succeededOrFailed()
+
- task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@3
displayName: CredScan running
condition: and(succeededOrFailed(), ne(variables['SKIP_CREDSCAN'], true))
diff --git a/eng/common/pipelines/templates/steps/set-test-pipeline-version.yml b/eng/common/pipelines/templates/steps/set-test-pipeline-version.yml
index 091ef62766e..dee4e38349d 100644
--- a/eng/common/pipelines/templates/steps/set-test-pipeline-version.yml
+++ b/eng/common/pipelines/templates/steps/set-test-pipeline-version.yml
@@ -1,5 +1,6 @@
parameters:
PackageName: ''
+ PackageNames: ''
ServiceDirectory: ''
TestPipeline: false
@@ -7,9 +8,12 @@ steps:
- ${{ if eq(parameters.TestPipeline, 'true') }}:
- task: PowerShell@2
displayName: Prep template pipeline for release
- condition: and(succeeded(), ne(variables['Skip.SetTestPipelineVersion'], 'true'))
+ condition: and(succeeded(), ne(variables['Skip.SetTestPipelineVersion'], 'true'))
inputs:
- pwsh: true
workingDirectory: $(Build.SourcesDirectory)
filePath: $(Build.SourcesDirectory)/eng/common/scripts/SetTestPipelineVersion.ps1
- arguments: '-BuildID $(Build.BuildId) -PackageName ${{ parameters.PackageName }} -ServiceDirectory ${{ parameters.ServiceDirectory }}'
\ No newline at end of file
+ arguments: >
+ -BuildID $(Build.BuildId)
+ -PackageNames '${{ coalesce(parameters.PackageName, parameters.PackageNames) }}'
+ -ServiceDirectory '${{ parameters.ServiceDirectory }}'
+ pwsh: true
diff --git a/eng/common/pipelines/templates/steps/sparse-checkout.yml b/eng/common/pipelines/templates/steps/sparse-checkout.yml
index 69db80fc82d..a3b553b3a7a 100644
--- a/eng/common/pipelines/templates/steps/sparse-checkout.yml
+++ b/eng/common/pipelines/templates/steps/sparse-checkout.yml
@@ -44,8 +44,10 @@ steps:
Write-Host "git sparse-checkout init"
git sparse-checkout init
- Write-Host "git sparse-checkout set '/*' '!/*/' '/eng'"
- git sparse-checkout set '/*' '!/*/' '/eng'
+ # Set non-cone mode otherwise path filters will not work in git >= 2.37.0
+ # See https://github.blog/2022-06-27-highlights-from-git-2-37/#tidbits
+ Write-Host "git sparse-checkout set --no-cone '/*' '!/*/' '/eng'"
+ git sparse-checkout set --no-cone '/*' '!/*/' '/eng'
}
# Prevent wildcard expansion in Invoke-Expression (e.g. for checkout path '/*')
@@ -59,8 +61,9 @@ steps:
# sparse-checkout commands after initial checkout will auto-checkout again
if (!$hasInitialized) {
- Write-Host "git checkout $($repository.Commitish)"
- git checkout $($repository.Commitish) # this will use the default branch if repo.Commitish is empty
+ Write-Host "git -c advice.detachedHead=false checkout $($repository.Commitish)"
+ # This will use the default branch if repo.Commitish is empty
+ git -c advice.detachedHead=false checkout $($repository.Commitish)
} else {
Write-Host "Skipping checkout as repo has already been initialized"
}
diff --git a/eng/common/pipelines/templates/steps/validate-filename.yml b/eng/common/pipelines/templates/steps/validate-filename.yml
new file mode 100644
index 00000000000..0f63e8977fe
--- /dev/null
+++ b/eng/common/pipelines/templates/steps/validate-filename.yml
@@ -0,0 +1,18 @@
+parameters:
+ WorkingDirectory: '$(System.DefaultWorkingDirectory)'
+steps:
+ - pwsh: |
+ $differByCaseFiles = git ls-files | Group-Object | Where-Object { $_.Count -gt 1 }
+
+ if ($differByCaseFiles)
+ {
+ foreach ($fileGroup in $differByCaseFiles) {
+ Write-Host "Duplicated Files: "
+ Write-Host "[ $($fileGroup.Group) ]"
+ }
+ Write-Host "Do NOT name the files which only differ in case. Please check above files."
+ exit 1
+ }
+ Write-Host "There are no file names that only differ in case."
+ displayName: Check file case duplicates
+ workingDirectory: ${{ parameters.WorkingDirectory }}
\ No newline at end of file
diff --git a/eng/common/pipelines/templates/steps/verify-readme.yml b/eng/common/pipelines/templates/steps/verify-readme.yml
index 9d8d92fb7cb..7b9217ade3e 100644
--- a/eng/common/pipelines/templates/steps/verify-readme.yml
+++ b/eng/common/pipelines/templates/steps/verify-readme.yml
@@ -1,8 +1,20 @@
parameters:
- ScanPath: $(Build.SourcesDirectory)
- RepoRoot: $(Build.SourcesDirectory)
- SettingsPath: '$(Build.SourcesDirectory)/eng/.docsettings.yml'
- DocWardenVersion : '0.7.2'
+- name: ScanPath
+ type: string
+ default: ''
+ # Where ScanPath takes a single path, ScanPaths takes a comma separated list of paths to scan
+- name: ScanPaths
+ type: string
+ default: ''
+- name: RepoRoot
+ type: string
+ default: $(Build.SourcesDirectory)
+- name: SettingsPath
+ type: string
+ default: '$(Build.SourcesDirectory)/eng/.docsettings.yml'
+- name: DocWardenVersion
+ type: string
+ default: ''
steps:
- task: PowerShell@2
@@ -10,8 +22,8 @@ steps:
inputs:
filePath: "eng/common/scripts/Verify-Readme.ps1"
arguments: >
- -DocWardenVersion ${{ parameters.DocWardenVersion }}
- -ScanPath ${{ parameters.ScanPath }}
+ -DocWardenVersion '${{ parameters.DocWardenVersion }}'
+ -ScanPaths '${{ coalesce(parameters.ScanPath, parameters.ScanPaths) }}'
-RepoRoot ${{ parameters.RepoRoot }}
-SettingsPath ${{ parameters.SettingsPath }}
pwsh: true
\ No newline at end of file
diff --git a/eng/common/pipelines/templates/steps/verify-samples.yml b/eng/common/pipelines/templates/steps/verify-samples.yml
index fef0f4ddd8c..d722cdcfd0b 100644
--- a/eng/common/pipelines/templates/steps/verify-samples.yml
+++ b/eng/common/pipelines/templates/steps/verify-samples.yml
@@ -1,15 +1,25 @@
parameters:
- name: ServiceDirectory
type: string
- default: not-specified
+ default: ''
+ - name: ServiceDirectories
+ type: string
+ default: ''
- name: ScriptDirectory
type: string
default: eng/common/scripts
steps:
- pwsh: |
- # If the last path segment is an absolute path it will be used entirely.
- $root = [System.IO.Path]::Combine('$(Build.SourcesDirectory)', 'sdk', '${{ parameters.ServiceDirectory }}')
- Get-ChildItem $root -Filter *.md -Recurse | ${{ parameters.ScriptDirectory }}/Test-SampleMetadata.ps1 -AllowParentProducts
+ # Take whichever parameter has been set. If set, ServiceDirectory will be a single path or
+ # ServiceDirectories will be a comma separated list.
+ $ServiceDirectories = '${{ coalesce(parameters.ServiceDirectory, parameters.ServiceDirectories) }}'
+ $ScanPaths = @()
+ foreach ($ServiceDirectory in $ServiceDirectories.Split(',')) {
+ $ScanPath = [System.IO.Path]::Combine('$(Build.SourcesDirectory)', 'sdk', $ServiceDirectory)
+ Write-Host "Adding $ScanPath to the scanned paths"
+ $ScanPaths += $ScanPath
+ }
+ Get-ChildItem $ScanPaths -Filter *.md -Recurse | ${{ parameters.ScriptDirectory }}/Test-SampleMetadata.ps1 -AllowParentProducts
displayName: Verify sample metadata
workingDirectory: $(Build.SourcesDirectory)
diff --git a/eng/common/scripts/Detect-Api-Changes.ps1 b/eng/common/scripts/Detect-Api-Changes.ps1
index 1c9cdf696bf..572ef43e1cf 100644
--- a/eng/common/scripts/Detect-Api-Changes.ps1
+++ b/eng/common/scripts/Detect-Api-Changes.ps1
@@ -27,6 +27,7 @@ function Submit-Request($filePath, $packageName)
if (!$repoName) {
$repoName = "azure/azure-sdk-for-$LanguageShort"
}
+ $reviewFileName = "$($packageName)_$($LanguageShort).json"
$query = [System.Web.HttpUtility]::ParseQueryString('')
$query.Add('artifactName', $ArtifactName)
$query.Add('buildId', $BuildId)
@@ -35,6 +36,12 @@ function Submit-Request($filePath, $packageName)
$query.Add('repoName', $repoName)
$query.Add('pullRequestNumber', $PullRequestNumber)
$query.Add('packageName', $packageName)
+ $query.Add('language', $LanguageShort)
+ $reviewFileFullName = Join-Path -Path $ArtifactPath $packageName $reviewFileName
+ if (Test-Path $reviewFileFullName)
+ {
+ $query.Add('codeFile', $reviewFileName)
+ }
$uri = [System.UriBuilder]$APIViewUri
$uri.query = $query.toString()
Write-Host "Request URI: $($uri.Uri.OriginalString)"
@@ -65,7 +72,7 @@ function Should-Process-Package($pkgPath, $packageName)
# Get package info from json file created before updating version to daily dev
$pkgInfo = Get-Content $pkgPropPath | ConvertFrom-Json
$packagePath = $pkgInfo.DirectoryPath
- $modifiedFiles = Get-ChangedFiles -DiffPath "$packagePath/*" -DiffFilterType ''
+ $modifiedFiles = @(Get-ChangedFiles -DiffPath "$packagePath/*" -DiffFilterType '')
$filteredFileCount = $modifiedFiles.Count
Write-Host "Number of modified files for package: $filteredFileCount"
return ($filteredFileCount -gt 0 -and $pkgInfo.IsNewSdk)
@@ -80,7 +87,6 @@ function Log-Input-Params()
Write-Host "Language: $($Language)"
Write-Host "Commit SHA: $($CommitSha)"
Write-Host "Repo Name: $($RepoFullName)"
- Write-Host "Package Name: $($PackageName)"
}
Log-Input-Params
diff --git a/eng/common/scripts/Helpers/Metadata-Helpers.ps1 b/eng/common/scripts/Helpers/Metadata-Helpers.ps1
index a8daf0d8374..ba6f32b7d72 100644
--- a/eng/common/scripts/Helpers/Metadata-Helpers.ps1
+++ b/eng/common/scripts/Helpers/Metadata-Helpers.ps1
@@ -80,3 +80,70 @@ function GetPrimaryCodeOwner ([string]$TargetDirectory)
Write-Warning "No code owner found in $TargetDirectory."
return $null
}
+
+function GetDocsMsService($packageInfo, $serviceName)
+{
+ $service = $serviceName.ToLower().Replace(' ', '').Replace('/', '-')
+ if ($packageInfo.MSDocService) {
+ # Use MSDocService in csv metadata to override the service directory
+ # TODO: Use taxonomy for service name -- https://github.com/Azure/azure-sdk-tools/issues/1442
+ $service = $packageInfo.MSDocService
+ }
+ Write-Host "The service of package: $service"
+ return $service
+}
+
+function compare-and-merge-metadata ($original, $updated) {
+ $updateMetdata = ($updated.GetEnumerator() | ForEach-Object { "$($_.Key): $($_.Value)" }) -join "`r`n"
+ $updateMetdata += "`r`n"
+ if (!$original) {
+ return $updateMetdata
+ }
+ $originalTable = ConvertFrom-StringData -StringData $original -Delimiter ":"
+ foreach ($key in $originalTable.Keys) {
+ if (!($updated.ContainsKey($key))) {
+ Write-Warning "New metadata missed the entry: $key. Adding back."
+ $updateMetdata += "$key`: $($originalTable[$key])`r`n"
+ }
+ }
+ return $updateMetdata
+}
+
+function GenerateDocsMsMetadata($originalMetadata, $language, $languageDisplayName, $serviceName, $tenantId, $clientId, $clientSecret, $msService)
+{
+ $langTitle = "Azure $serviceName SDK for $languageDisplayName"
+ $langDescription = "Reference for Azure $serviceName SDK for $languageDisplayName"
+ # Github url for source code: e.g. https://github.com/Azure/azure-sdk-for-js
+ $serviceBaseName = $serviceName.ToLower().Replace(' ', '').Replace('/', '-')
+ $author = GetPrimaryCodeOwner -TargetDirectory "/sdk/$serviceBaseName/"
+ $msauthor = ""
+ if (!$author) {
+ LogError "Cannot fetch the author from CODEOWNER file."
+ }
+ elseif ($TenantId -and $ClientId -and $ClientSecret) {
+ $msauthor = GetMsAliasFromGithub -TenantId $tenantId -ClientId $clientId -ClientSecret $clientSecret -GithubUser $author
+ }
+ # Default value
+ if (!$msauthor) {
+ LogError "No ms.author found for $author. "
+ $msauthor = $author
+ }
+ $date = Get-Date -Format "MM/dd/yyyy"
+
+ $metadataTable = @{
+ "title"= $langTitle
+ "description"= $langDescription
+ "author"= $author
+ "ms.author"= $msauthor
+ "ms.data"= $date
+ "ms.topic"= "reference"
+ "ms.devlang"= $language
+ "ms.service"= $msService
+ }
+ $updatedMetadata = compare-and-merge-metadata -original $originalMetadata -updated $metadataTable
+ return "---`r`n$updatedMetadata---`r`n"
+}
+
+function ServiceLevelReadmeNameStyle($serviceName) {
+ return $serviceName.ToLower().Replace(' ', '-').Replace('/', '-')
+}
diff --git a/eng/common/scripts/Helpers/PSModule-Helpers.ps1 b/eng/common/scripts/Helpers/PSModule-Helpers.ps1
index 96f34ff71f4..1a2a0a90083 100644
--- a/eng/common/scripts/Helpers/PSModule-Helpers.ps1
+++ b/eng/common/scripts/Helpers/PSModule-Helpers.ps1
@@ -1,7 +1,7 @@
$DefaultPSRepositoryUrl = "https://www.powershellgallery.com/api/v2"
$global:CurrentUserModulePath = ""
-function Update-PSModulePath()
+function Update-PSModulePathForCI()
{
# Information on PSModulePath taken from docs
# https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_psmodulepath
@@ -48,8 +48,15 @@ function Update-PSModulePath()
}
# If we want to use another default repository other then PSGallery we can update the default parameters
-function Install-ModuleIfNotInstalled($moduleName, $version, $repositoryUrl = $DefaultPSRepositoryUrl)
+function Install-ModuleIfNotInstalled()
{
+ [CmdletBinding(SupportsShouldProcess = $true)]
+ param(
+ [string]$moduleName,
+ [string]$version,
+ [string]$repositoryUrl = $DefaultPSRepositoryUrl
+ )
+
# Check installed modules
$modules = (Get-Module -ListAvailable $moduleName)
if ($version -as [Version]) {
@@ -94,4 +101,6 @@ function Install-ModuleIfNotInstalled($moduleName, $version, $repositoryUrl = $D
return $modules[0]
}
-Update-PSModulePath
\ No newline at end of file
+if ($null -ne $env:SYSTEM_TEAMPROJECTID) {
+ Update-PSModulePathForCI
+}
diff --git a/eng/common/scripts/Helpers/Package-Helpers.ps1 b/eng/common/scripts/Helpers/Package-Helpers.ps1
new file mode 100644
index 00000000000..15a1f2ea8d4
--- /dev/null
+++ b/eng/common/scripts/Helpers/Package-Helpers.ps1
@@ -0,0 +1,37 @@
+function GetPackageKey($pkg) {
+ $pkgKey = $pkg.Package
+ $groupId = $null
+
+ if ($pkg.PSObject.Members.Name -contains "GroupId") {
+ $groupId = $pkg.GroupId
+ }
+
+ if ($groupId) {
+ $pkgKey = "${groupId}:${pkgKey}"
+ }
+
+ return $pkgKey
+ }
+
+ # Different language needs a different way to index the package. Build a map in convienice to lookup the package.
+ # E.g. : is the package key in java.
+ function GetPackageLookup($packageList) {
+ $packageLookup = @{}
+
+ foreach ($pkg in $packageList) {
+ $pkgKey = GetPackageKey $pkg
+
+ # We want to prefer updating non-hidden packages but if there is only
+ # a hidden entry then we will return that
+ if (!$packageLookup.ContainsKey($pkgKey) -or $packageLookup[$pkgKey].Hide -eq "true") {
+ $packageLookup[$pkgKey] = $pkg
+ }
+ else {
+ # Warn if there are more then one non-hidden package
+ if ($pkg.Hide -ne "true") {
+ Write-Host "Found more than one package entry for $($pkg.Package) selecting the first non-hidden one."
+ }
+ }
+ }
+ return $packageLookup
+ }
diff --git a/eng/common/scripts/Service-Level-Readme-Automation.ps1 b/eng/common/scripts/Service-Level-Readme-Automation.ps1
new file mode 100644
index 00000000000..1bef0122935
--- /dev/null
+++ b/eng/common/scripts/Service-Level-Readme-Automation.ps1
@@ -0,0 +1,224 @@
+<#
+.SYNOPSIS
+The script is to generate service level readme if it is missing.
+For exist ones, we do 2 things here:
+1. Generate the client but not import to the existing service level readme.
+2. Update the metadata of service level readme
+
+.DESCRIPTION
+Given a doc repo location, and the credential for fetching the ms.author.
+Generate missing service level readme and updating metadata of the existing ones.
+
+.PARAMETER DocRepoLocation
+Location of the documentation repo. This repo may be sparsely checked out
+depending on the requirements for the domain
+
+.PARAMETER TenantId
+The aad tenant id/object id for ms.author.
+
+.PARAMETER ClientId
+The add client id/application id for ms.author.
+
+.PARAMETER ClientSecret
+The client secret of add app for ms.author.
+#>
+
+param(
+ [Parameter(Mandatory = $true)]
+ [string] $DocRepoLocation,
+
+ [Parameter(Mandatory = $false)]
+ [string]$TenantId,
+
+ [Parameter(Mandatory = $false)]
+ [string]$ClientId,
+
+ [Parameter(Mandatory = $false)]
+ [string]$ClientSecret
+)
+. $PSScriptRoot/common.ps1
+. $PSScriptRoot/Helpers/Metadata-Helpers.ps1
+. $PSScriptRoot/Helpers/Package-Helpers.ps1
+
+Set-StrictMode -Version 3
+
+function create-metadata-table($readmeFolder, $readmeName, $moniker, $msService, $clientTableLink, $mgmtTableLink, $serviceName)
+{
+ $readmePath = Join-Path $readmeFolder -ChildPath $readmeName
+ $content = ""
+ if (Test-Path (Join-Path $readmeFolder -ChildPath $clientTableLink)) {
+ $content = "## Client packages - $moniker`r`n"
+ $content += "[!INCLUDE [client-packages]($clientTableLink)]`r`n"
+ }
+ if (Test-Path (Join-Path $readmeFolder -ChildPath $mgmtTableLink)) {
+ $content += "## Management packages - $moniker`r`n"
+ $content += "[!INCLUDE [mgmt-packages]($mgmtTableLink)]`r`n"
+ }
+ if (!$content) {
+ return
+ }
+ # Generate the front-matter for docs needs
+ # $Language, $LanguageDisplayName are the variables globally defined in Language-Settings.ps1
+ $metadataString = GenerateDocsMsMetadata -language $Language -languageDisplayName $LanguageDisplayName -serviceName $serviceName `
+ -tenantId $TenantId -clientId $ClientId -clientSecret $ClientSecret `
+ -msService $msService
+ Add-Content -Path $readmePath -Value $metadataString -NoNewline
+
+ # Add tables, seperate client and mgmt.
+ $readmeHeader = "# Azure $serviceName SDK for $languageDisplayName - $moniker`r`n"
+ Add-Content -Path $readmePath -Value $readmeHeader
+ Add-Content -Path $readmePath -Value $content -NoNewline
+}
+
+# Update the metadata table.
+function update-metadata-table($readmeFolder, $readmeName, $serviceName, $msService)
+{
+ $readmePath = Join-Path $readmeFolder -ChildPath $readmeName
+ $readmeContent = Get-Content -Path $readmePath -Raw
+ $match = $readmeContent -match "^---\n*(?(.*\n?)*?)---\n*(?(.*\n?)*)"
+ $restContent = $readmeContent
+ $metadata = ""
+ if ($match) {
+ $restContent = $Matches["content"].trim()
+ $metadata = $Matches["metadata"].trim()
+ }
+ # $Language, $LanguageDisplayName are the variables globally defined in Language-Settings.ps1
+ $metadataString = GenerateDocsMsMetadata -originalMetadata $metadata -language $Language -languageDisplayName $LanguageDisplayName -serviceName $serviceName `
+ -tenantId $TenantId -clientId $ClientId -clientSecret $ClientSecret `
+ -msService $msService
+ Set-Content -Path $readmePath -Value "$metadataString$restContent" -NoNewline
+}
+
+function generate-markdown-table($readmeFolder, $readmeName, $packageInfo, $moniker) {
+ $tableHeader = "| Reference | Package | Source |`r`n|---|---|---|`r`n"
+ $tableContent = ""
+ # Here is the table, the versioned value will
+ foreach ($pkg in $packageInfo) {
+ $repositoryLink = "$PackageRepositoryUri/$($pkg.Package)"
+ if (Test-Path "Function:$GetRepositoryLinkFn") {
+ $repositoryLink = &$GetRepositoryLinkFn -packageInfo $pkg
+ }
+ $packageLevelReadme = ""
+ if (Test-Path "Function:$GetPackageLevelReadmeFn") {
+ $packageLevelReadme = &$GetPackageLevelReadmeFn -packageMetadata $pkg
+ }
+
+ $referenceLink = "[$($pkg.DisplayName)]($packageLevelReadme-readme.md)"
+ if (!(Test-Path (Join-Path $readmeFolder -ChildPath "$packageLevelReadme-readme.md"))) {
+ $referenceLink = $pkg.DisplayName
+ }
+ $githubLink = $GithubUri
+ if ($pkg.PSObject.Members.Name -contains "DirectoryPath") {
+ $githubLink = "$GithubUri/blob/main/$($pkg.DirectoryPath)"
+ }
+ $line = "|$referenceLink|[$($pkg.Package)]($repositoryLink)|[Github]($githubLink)|`r`n"
+ $tableContent += $line
+ }
+ $readmePath = Join-Path $readmeFolder -ChildPath $readmeName
+ if($tableContent) {
+ $null = New-Item -Path $readmePath -ItemType File -Force
+ Add-Content -Path $readmePath -Value $tableHeader -NoNewline
+ Add-Content -Path $readmePath -Value $tableContent -NoNewline
+ }
+}
+
+function generate-service-level-readme($readmeBaseName, $pathPrefix, $packageInfos, $serviceName, $moniker) {
+ # Add ability to override
+ # Fetch the service readme name
+ $msService = GetDocsMsService -packageInfo $packageInfos[0] -serviceName $serviceName
+
+ $readmeFolder = "$DocRepoLocation/$pathPrefix/$moniker/"
+ $serviceReadme = "$readmeBaseName.md"
+ $clientIndexReadme = "$readmeBaseName-client-index.md"
+ $mgmtIndexReadme = "$readmeBaseName-mgmt-index.md"
+ $clientPackageInfo = $packageInfos.Where({ 'client' -eq $_.Type }) | Sort-Object -Property Package
+ if ($clientPackageInfo) {
+ generate-markdown-table -readmeFolder $readmeFolder -readmeName $clientIndexReadme -packageInfo $clientPackageInfo -moniker $moniker
+ }
+
+ $mgmtPackageInfo = $packageInfos.Where({ 'mgmt' -eq $_.Type }) | Sort-Object -Property Package
+ if ($mgmtPackageInfo) {
+ generate-markdown-table -readmeFolder $readmeFolder -readmeName $mgmtIndexReadme -packageInfo $mgmtPackageInfo -moniker $moniker
+ }
+ if (!(Test-Path (Join-Path $readmeFolder -ChildPath $serviceReadme))) {
+ create-metadata-table -readmeFolder $readmeFolder -readmeName $serviceReadme -moniker $moniker -msService $msService `
+ -clientTableLink $clientIndexReadme -mgmtTableLink $mgmtIndexReadme `
+ -serviceName $serviceName
+ }
+ else {
+ update-metadata-table -readmeFolder $readmeFolder -readmeName $serviceReadme -serviceName $serviceName -msService $msService
+ }
+}
+
+$fullMetadata = Get-CSVMetadata
+$monikers = @("latest", "preview")
+foreach($moniker in $monikers) {
+ # The onboarded packages return is key-value pair, which key is the package index, and value is the package info from {metadata}.json
+ # E.g.
+ # Key as: @azure/storage-blob
+ # Value as:
+ # {
+ # "Name": "@azure/storage-blob",
+ # "Version": "12.10.0-beta.1",
+ # "DevVersion": null,
+ # "DirectoryPath": "sdk/storage/storage-blob",
+ # "ServiceDirectory": "storage",
+ # "ReadMePath": "sdk/storage/storage-blob/README.md",
+ # "ChangeLogPath": "sdk/storage/storage-blob/CHANGELOG.md",
+ # "Group": null,
+ # "SdkType": "client",
+ # "IsNewSdk": true,
+ # "ArtifactName": "azure-storage-blob",
+ # "ReleaseStatus": "2022-04-19"
+ # }
+ $onboardedPackages = &$GetOnboardedDocsMsPackagesForMonikerFn `
+ -DocRepoLocation $DocRepoLocation -moniker $moniker
+ $csvMetadata = @()
+ foreach($metadataEntry in $fullMetadata) {
+ if ($metadataEntry.Package -and $metadataEntry.Hide -ne 'true') {
+ $pkgKey = GetPackageKey $metadataEntry
+ if($onboardedPackages.ContainsKey($pkgKey)) {
+ if ($onboardedPackages[$pkgKey] -and $onboardedPackages[$pkgKey].DirectoryPath) {
+ if (!($metadataEntry.PSObject.Members.Name -contains "DirectoryPath")) {
+ Add-Member -InputObject $metadataEntry `
+ -MemberType NoteProperty `
+ -Name DirectoryPath `
+ -Value $onboardedPackages[$pkgKey].DirectoryPath
+ }
+ }
+ $csvMetadata += $metadataEntry
+ }
+ }
+ }
+ $packagesForService = @{}
+ $allPackages = GetPackageLookup $csvMetadata
+ foreach ($metadataKey in $allPackages.Keys) {
+ $metadataEntry = $allPackages[$metadataKey]
+ if (!$metadataEntry.ServiceName) {
+ LogWarning "Empty ServiceName for package `"$metadataKey`". Skipping."
+ continue
+ }
+ $packagesForService[$metadataKey] = $metadataEntry
+ }
+ $services = @{}
+ foreach ($package in $packagesForService.Values) {
+ if ($package.ServiceName -eq 'Other') {
+ # Skip packages under the service category "Other". Those will be handled
+ # later
+ continue
+ }
+ if (!$services.ContainsKey($package.ServiceName)) {
+ $services[$package.ServiceName] = $true
+ }
+ }
+ foreach ($service in $services.Keys) {
+ Write-Host "Building service: $service"
+
+ $servicePackages = $packagesForService.Values.Where({ $_.ServiceName -eq $service })
+ $serviceReadmeBaseName = ServiceLevelReadmeNameStyle -serviceName $service
+ $hrefPrefix = "docs-ref-services"
+
+ generate-service-level-readme -readmeBaseName $serviceReadmeBaseName -pathPrefix $hrefPrefix `
+ -packageInfos $servicePackages -serviceName $service -moniker $moniker
+ }
+}
diff --git a/eng/common/scripts/SetTestPipelineVersion.ps1 b/eng/common/scripts/SetTestPipelineVersion.ps1
index 6bc333cd630..a24c011f85e 100644
--- a/eng/common/scripts/SetTestPipelineVersion.ps1
+++ b/eng/common/scripts/SetTestPipelineVersion.ps1
@@ -2,32 +2,55 @@
param (
[Parameter(mandatory = $true)]
- $BuildID,
+ [string]$BuildID,
[Parameter(mandatory = $true)]
- $PackageName,
+ [string]$PackageNames,
[Parameter(mandatory = $true)]
- $ServiceDirectory
+ [string]$ServiceDirectory
)
. (Join-Path $PSScriptRoot common.ps1)
-$latestTags = git tag -l "${PackageName}_*"
-$semVars = @()
+Write-Host "PackageNames: $PackageNames"
+Write-Host "ServiceDirectory: $ServiceDirectory"
+Write-Host "BuildID: $BuildID"
-Foreach ($tags in $latestTags)
-{
- $semVars += $tags.Replace("${PackageName}_", "")
+$packageNamesArray = @()
+
+if ([String]::IsNullOrWhiteSpace($PackageNames)) {
+ LogError "PackageNames cannot be empty."
+ exit 1
+} else {
+ $packageNamesArray = $PackageNames.Split(',')
}
-$semVarsSorted = [AzureEngSemanticVersion]::SortVersionStrings($semVars)
-LogDebug "Last Published Version $($semVarsSorted[0])"
+foreach ($packageName in $packageNamesArray) {
+ Write-Host "Processing $packageName"
+ $newVersion = [AzureEngSemanticVersion]::new("1.0.0")
+ $latestTags = git tag -l "${packageName}_*"
+
+ Write-Host "Get Latest Tag : git tag -l ${packageName}_*"
+ $semVars = @()
+
+ if ($latestTags -and ($latestTags.Length -gt 0))
+ {
+ foreach ($tags in $latestTags)
+ {
+ $semVars += $tags.Replace("${packageName}_", "")
+ }
-$newVersion = [AzureEngSemanticVersion]::new($semVarsSorted[0])
-$newVersion.PrereleaseLabel = $newVersion.DefaultPrereleaseLabel
-$newVersion.PrereleaseNumber = $BuildID
+ $semVarsSorted = [AzureEngSemanticVersion]::SortVersionStrings($semVars)
+ Write-Host "Last Published Version $($semVarsSorted[0])"
+ $newVersion = [AzureEngSemanticVersion]::new($semVarsSorted[0])
+ }
-LogDebug "Version to publish [ $($newVersion.ToString()) ]"
+ $newVersion.PrereleaseLabel = $newVersion.DefaultPrereleaseLabel
+ $newVersion.PrereleaseNumber = $BuildID
+ $newVersion.IsPrerelease = $True
-SetPackageVersion -PackageName $PackageName `
- -Version $newVersion `
- -ServiceDirectory $ServiceDirectory
\ No newline at end of file
+ Write-Host "Version to publish [ $($newVersion.ToString()) ]"
+
+ SetPackageVersion -PackageName $packageName `
+ -Version $newVersion.ToString() `
+ -ServiceDirectory $ServiceDirectory
+}
diff --git a/eng/common/scripts/Test-SampleMetadata.ps1 b/eng/common/scripts/Test-SampleMetadata.ps1
index d5681e85d3c..6ce31c2095c 100644
--- a/eng/common/scripts/Test-SampleMetadata.ps1
+++ b/eng/common/scripts/Test-SampleMetadata.ps1
@@ -73,7 +73,7 @@ process {
Write-Error "File '$($file.FullName)' contains invalid product slug: $product" -TargetObject $file `
-Category InvalidData -CategoryTargetName $product -CategoryTargetType string `
- -RecommendedAction 'Use only product slugs listed at https://review.docs.microsoft.com/help/contribute/metadata-taxonomies?branch=master#product'
+ -RecommendedAction 'Use only product slugs listed at https://review.docs.microsoft.com/help/contribute/metadata-taxonomies?branch=main#product'
}
}
@@ -95,7 +95,7 @@ end {
}
begin {
- # https://review.docs.microsoft.com/help/contribute/metadata-taxonomies?branch=master#product
+ # https://review.docs.microsoft.com/help/contribute/metadata-taxonomies?branch=main#product
$productSlugs = @(
"ai-builder",
"aspnet",
@@ -358,6 +358,7 @@ begin {
"ef-core",
"ef6",
"expression-studio",
+ "language-service",
"m365-ems",
"m365-ems-cloud-app-security",
"m365-ems-configuration-manager",
@@ -498,7 +499,7 @@ Checks sample markdown files' frontmatter for invalid information.
.DESCRIPTION
Given a collection of markdown files, their frontmatter - if present - is checked for invalid information, including:
-Invalid product slugs, i.e. those not listed in https://review.docs.microsoft.com/help/contribute/metadata-taxonomies?branch=master#product.
+Invalid product slugs, i.e. those not listed in https://review.docs.microsoft.com/help/contribute/metadata-taxonomies?branch=main#product.
.PARAMETER Path
Specifies the path to an item to search. Wildcards are permitted.
diff --git a/eng/common/scripts/Update-DocsMsMetadata.ps1 b/eng/common/scripts/Update-DocsMsMetadata.ps1
index c0b7d555639..b6b696758ac 100644
--- a/eng/common/scripts/Update-DocsMsMetadata.ps1
+++ b/eng/common/scripts/Update-DocsMsMetadata.ps1
@@ -95,7 +95,7 @@ function GetAdjustedReadmeContent($ReadmeContent, $PackageInfo, $PackageMetadata
$foundTitle = ""
if ($ReadmeContent -match $TITLE_REGEX) {
- $ReadmeContent = $ReadmeContent -replace $TITLE_REGEX, "`${0} - Version $($PackageInfo.Version) `n"
+ $ReadmeContent = $ReadmeContent -replace $TITLE_REGEX, "`${0} - version $($PackageInfo.Version) `n"
$foundTitle = $matches["filetitle"]
}
diff --git a/eng/common/scripts/Update-DocsMsToc.ps1 b/eng/common/scripts/Update-DocsMsToc.ps1
index d1a6139d419..5287d315756 100644
--- a/eng/common/scripts/Update-DocsMsToc.ps1
+++ b/eng/common/scripts/Update-DocsMsToc.ps1
@@ -18,8 +18,8 @@ ToC node layout:
* Client Package 2 (package level overview page)
...
* Management
- * Management Package 1
- * Management Package 2
+ * Management Package 1 (package level overview page)
+ * Management Package 2 (package level overview page)
...
.PARAMETER DocRepoLocation
@@ -45,9 +45,9 @@ Install-ModuleIfNotInstalled "powershell-yaml" "0.4.1" | Import-Module
Set-StrictMode -Version 3
-function GetClientPackageNode($clientPackage) {
+function GetPackageNode($package) {
$packageInfo = &$GetDocsMsTocDataFn `
- -packageMetadata $clientPackage `
+ -packageMetadata $package `
-docRepoLocation $DocRepoLocation
return [PSCustomObject]@{
@@ -181,22 +181,20 @@ foreach ($service in $serviceNameList) {
$clientPackages = $packagesForToc.Values.Where({ $_.ServiceName -eq $service -and ('client' -eq $_.Type) })
$clientPackages = $clientPackages | Sort-Object -Property Package
foreach ($clientPackage in $clientPackages) {
- $packageItems += GetClientPackageNode -clientPackage $clientPackage
+ $packageItems += GetPackageNode -package $clientPackage
}
# All management packages go under a single `Management` header in the ToC
$mgmtPackages = $packagesForToc.Values.Where({ $_.ServiceName -eq $service -and ('mgmt' -eq $_.Type) })
$mgmtPackages = $mgmtPackages | Sort-Object -Property Package
- if ($mgmtPackages) {
- $children = &$GetDocsMsTocChildrenForManagementPackagesFn `
- -packageMetadata $mgmtPackages `
- -docRepoLocation $DocRepoLocation
-
+ $mgmtItems = @()
+ foreach ($pkg in $mgmtPackages) {
+ $mgmtItems += GetPackageNode -package $pkg
+ }
+ if ($mgmtItems) {
$packageItems += [PSCustomObject]@{
name = 'Management'
- # There could be multiple packages, ensure this is treated as an array
- # even if it is a single package
- children = @($children)
+ items = $mgmtItems
}
}
@@ -266,12 +264,12 @@ if ($otherPackages) {
if ($null -ne $currentNode) {
$otherPackage.DisplayName = $segments[$segments.Count - 1]
- $currentNode.Add((GetClientPackageNode $otherPackage))
+ $currentNode.Add((GetPackageNode $otherPackage))
}
}
else {
- $otherPackageItems.Add((GetClientPackageNode $otherPackage))
+ $otherPackageItems.Add((GetPackageNode $otherPackage))
}
}
}
diff --git a/eng/common/scripts/Verify-Readme.ps1 b/eng/common/scripts/Verify-Readme.ps1
index c0259934048..4e2cd652249 100644
--- a/eng/common/scripts/Verify-Readme.ps1
+++ b/eng/common/scripts/Verify-Readme.ps1
@@ -1,24 +1,105 @@
# Wrapper Script for Readme Verification
[CmdletBinding()]
param (
- [Parameter(Mandatory = $true)]
+ [Parameter(Mandatory = $false)]
[string]$DocWardenVersion,
- [Parameter(Mandatory = $true)]
- [string]$ScanPath,
[string]$RepoRoot,
+ [string]$ScanPaths,
[Parameter(Mandatory = $true)]
[string]$SettingsPath
)
+. (Join-Path $PSScriptRoot common.ps1)
+$DefaultDocWardenVersion = "0.7.2"
+$script:FoundError = $false
+
+function Test-Readme-Files {
+ param(
+ [string]$SettingsPath,
+ [string]$ScanPath,
+ [string]$RepoRoot)
+
+ Write-Host "Scanning..."
+
+ if ($RepoRoot)
+ {
+ Write-Host "ward scan -d $ScanPath -u $RepoRoot -c $SettingsPath"
+ ward scan -d $ScanPath -u $RepoRoot -c $SettingsPath
+ }
+ else
+ {
+ Write-Host "ward scan -d $ScanPath -c $SettingsPath"
+ ward scan -d $ScanPath -c $SettingsPath
+ }
+ # ward scan is what returns the non-zero exit code on failure.
+ # Since it's being called from a function, that error needs to
+ # be propagated back so the script can exit appropriately
+ if ($LASTEXITCODE -ne 0) {
+ $script:FoundError = $true
+ }
+}
+
+# Verify all of the inputs before running anything
+if ([String]::IsNullOrWhiteSpace($DocWardenVersion)) {
+ $DocWardenVersion = $DefaultDocWardenVersion
+}
+
+# verify the doc settings file exists
+if (!(Test-Path -Path $SettingsPath -PathType leaf)) {
+ LogError "Setting file, $SettingsPath, does not exist"
+ $script:FoundError = $true
+}
+
+$scanPathsArray = @()
+# Verify that either ScanPath or ScanPaths were set but not both or neither
+if ([String]::IsNullOrWhiteSpace($ScanPaths)) {
+ LogError "ScanPaths cannot be empty."
+} else {
+ $scanPathsArray = $ScanPaths.Split(',')
+ foreach ($path in $scanPathsArray) {
+ if (!(Test-Path -Path $path -PathType Container)) {
+ LogError "path, $path, doesn't exist or isn't a directory"
+ $script:FoundError = $true
+ }
+ }
+}
+
+# Exit out now if there were any argument issues
+if ($script:FoundError) {
+ LogError "There were argument failures, please see above for specifics"
+ exit 1
+}
+
+# Echo back the settings
+Write-Host "DocWardenVersion=$DocWardenVersion"
+Write-Host "SettingsPath=$SettingsPath"
+
+if ($RepoRoot) {
+ Write-Host "RepoRoot=$RepoRoot"
+}
+
+Write-Host "ScanPath=$ScanPaths"
+
+Write-Host "Installing setup tools and DocWarden"
+Write-Host "pip install setuptools wheel --quiet"
pip install setuptools wheel --quiet
+if ($LASTEXITCODE -ne 0) {
+ LogError "pip install setuptools wheel --quiet failed with exit code $LASTEXITCODE"
+ exit 1
+}
+Write-Host "pip install doc-warden==$DocWardenVersion --quiet"
pip install doc-warden==$DocWardenVersion --quiet
-
-if ($RepoRoot)
-{
- ward scan -d $ScanPath -u $RepoRoot -c $SettingsPath
+if ($LASTEXITCODE -ne 0) {
+ LogError "pip install doc-warden==$DocWardenVersion --quiet failed with exit code $LASTEXITCODE"
+ exit 1
}
-else
-{
- ward scan -d $ScanPath -c $SettingsPath
+
+# Finally, do the scanning
+foreach ($path in $scanPathsArray) {
+ Test-Readme-Files $SettingsPath $path $RepoRoot
}
+if ($script:FoundError) {
+ LogError "There were README verification failures, scroll up to see the issue(s)"
+ exit 1
+}
\ No newline at end of file
diff --git a/eng/common/scripts/Verify-Resource-Ref.ps1 b/eng/common/scripts/Verify-Resource-Ref.ps1
index 048f91c3afe..f806290e981 100644
--- a/eng/common/scripts/Verify-Resource-Ref.ps1
+++ b/eng/common/scripts/Verify-Resource-Ref.ps1
@@ -7,9 +7,18 @@ foreach ($file in $ymlfiles)
{
Write-Host "Verifying '${file}'"
$ymlContent = Get-Content $file.FullName -Raw
- $ymlObject = ConvertFrom-Yaml $ymlContent -Ordered
- if ($ymlObject.Contains("resources"))
+ try
+ {
+ $ymlObject = ConvertFrom-Yaml $ymlContent -Ordered
+ }
+ catch
+ {
+ Write-Host "Skipping $($file.FullName) because the file does not contain valid yml."
+ continue
+ }
+
+ if ($ymlObject -and ($ymlObject.Contains("resources")))
{
if ($ymlObject["resources"]["repositories"])
{
diff --git a/eng/common/scripts/common.ps1 b/eng/common/scripts/common.ps1
index 6951c5a9a9b..1b77491fd37 100644
--- a/eng/common/scripts/common.ps1
+++ b/eng/common/scripts/common.ps1
@@ -50,6 +50,9 @@ $FindArtifactForApiReviewFn = "Find-${Language}-Artifacts-For-Apireview"
$TestProxyTrustCertFn = "Import-Dev-Cert-${Language}"
$ValidateDocsMsPackagesFn = "Validate-${Language}-DocMsPackages"
$GetOnboardedDocsMsPackagesFn = "Get-${Language}-OnboardedDocsMsPackages"
+$GetOnboardedDocsMsPackagesForMonikerFn = "Get-${Language}-OnboardedDocsMsPackagesForMoniker"
$GetDocsMsTocDataFn = "Get-${Language}-DocsMsTocData"
$GetDocsMsTocChildrenForManagementPackagesFn = "Get-${Language}-DocsMsTocChildrenForManagementPackages"
$UpdateDocsMsTocFn = "Get-${Language}-UpdatedDocsMsToc"
+$GetPackageLevelReadmeFn = "Get-${Language}-PackageLevelReadme"
+$GetRepositoryLinkFn = "Get-${Language}-RepositoryLink"
diff --git a/eng/common/scripts/job-matrix/README.md b/eng/common/scripts/job-matrix/README.md
index d46efdd42e1..51c57506f9c 100644
--- a/eng/common/scripts/job-matrix/README.md
+++ b/eng/common/scripts/job-matrix/README.md
@@ -102,7 +102,7 @@ Example:
"operatingSystem": [
"windows-2019",
"ubuntu-18.04",
- "macOS-10.15"
+ "macos-11"
],
"framework": [
"net461",
@@ -120,26 +120,49 @@ Example:
The `include` field defines any number of matrices to be appended to the base matrix after processing exclusions.
+```
+# matrix entry format:
+{
+ "a": 1,
+ "b": 2,
+ "c": 3,
+}
+
+# Include field in a matrix config
+{
+ "include": [
+ {
+ "a": 1,
+ "b": 2
+ }
+ ]
+}
+```
+
+
#### exclude
-The `include` field defines any number of matrices to be removed from the base matrix. Exclude parameters can be a partial
+The `exclude` field defines any number of matrices to be removed from the base matrix. Exclude parameters can be a partial
set, meaning as long as all exclude parameters match against a matrix entry (even if the matrix entry has additional parameters),
then it will be excluded from the matrix. For example, the below entry will match the exclusion and be removed:
```
-matrix entry:
+# matrix entry format:
{
"a": 1,
"b": 2,
"c": 3,
}
-"exclude": [
- {
- "a": 1,
- "b": 2
- }
-]
+# Exclude field in a matrix config
+{
+ "exclude": [
+ {
+ "a": 1,
+ "b": 2
+ }
+ ]
+}
```
#### displayNames
@@ -357,7 +380,7 @@ In the matrix job output that azure pipelines consumes, the format is a dictiona
{
"net461_macOS1015": {
"framework": "net461",
- "operatingSystem": "macOS-10.15"
+ "operatingSystem": "macos-11"
},
"net50_ubuntu1804": {
"framework": "net50",
@@ -489,7 +512,7 @@ Given a matrix like below with `JavaTestVersion` marked as a non-sparse paramete
"Agent": {
"windows-2019": { "OSVmImage": "MMS2019", "Pool": "azsdk-pool-mms-win-2019-general" },
"ubuntu-1804": { "OSVmImage": "MMSUbuntu18.04", "Pool": "azsdk-pool-mms-ubuntu-1804-general" },
- "macOS-10.15": { "OSVmImage": "macOS-10.15", "Pool": "Azure Pipelines" }
+ "macos-11": { "OSVmImage": "macos-11", "Pool": "Azure Pipelines" }
},
"JavaTestVersion": [ "1.8", "1.11" ],
"AZURE_TEST_HTTP_CLIENTS": "netty",
diff --git a/eng/common/scripts/job-matrix/job-matrix-functions.ps1 b/eng/common/scripts/job-matrix/job-matrix-functions.ps1
index 7d367521350..8822d7ce723 100644
--- a/eng/common/scripts/job-matrix/job-matrix-functions.ps1
+++ b/eng/common/scripts/job-matrix/job-matrix-functions.ps1
@@ -117,7 +117,7 @@ function GenerateMatrix(
}
$matrix = FilterMatrix $matrix $filters
- $matrix = ProcessReplace $matrix $replace $config.displayNamesLookup
+ $matrix = ProcessReplace $matrix $replace $combinedDisplayNameLookup
$matrix = FilterMatrixDisplayName $matrix $displayNameFilter
return $matrix
}
@@ -352,7 +352,7 @@ function ProcessImport([MatrixParameter[]]$matrix, [String]$selection, [Array]$n
}
}
if ((!$matrix -and !$importPath) -or !$importPath) {
- return $matrix, @()
+ return $matrix, @(), @{}
}
if (!(Test-Path $importPath)) {
@@ -370,7 +370,7 @@ function ProcessImport([MatrixParameter[]]$matrix, [String]$selection, [Array]$n
$combinedDisplayNameLookup[$lookup.Name] = $lookup.Value
}
- return $matrix, $importedMatrix, $importedMatrixConfig.displayNamesLookup
+ return $matrix, $importedMatrix, $combinedDisplayNameLookup
}
function CombineMatrices([Array]$matrix1, [Array]$matrix2, [Hashtable]$displayNamesLookup = @{})
diff --git a/eng/common/scripts/job-matrix/samples/matrix.json b/eng/common/scripts/job-matrix/samples/matrix.json
index a9e291604d0..98e1dd757f3 100644
--- a/eng/common/scripts/job-matrix/samples/matrix.json
+++ b/eng/common/scripts/job-matrix/samples/matrix.json
@@ -6,7 +6,7 @@
"Agent": {
"ubuntu": { "OSVmImage": "ubuntu-18.04", "Pool": "Azure Pipelines" },
"windows": { "OSVmImage": "windows-2019", "Pool": "Azure Pipelines" },
- "macOS": { "OSVmImage": "macOS-10.15", "Pool": "Azure Pipelines" }
+ "macOS": { "OSVmImage": "macos-11", "Pool": "Azure Pipelines" }
},
"TestTargetFramework": [ "netcoreapp2.1", "net461", "net5.0" ]
},
diff --git a/eng/common/scripts/job-matrix/tests/job-matrix-functions.filter.tests.ps1 b/eng/common/scripts/job-matrix/tests/job-matrix-functions.filter.tests.ps1
index a25367bebff..7c327eb27dd 100644
--- a/eng/common/scripts/job-matrix/tests/job-matrix-functions.filter.tests.ps1
+++ b/eng/common/scripts/job-matrix/tests/job-matrix-functions.filter.tests.ps1
@@ -6,7 +6,7 @@ BeforeAll {
$matrixConfig = @"
{
"matrix": {
- "operatingSystem": [ "windows-2019", "ubuntu-18.04", "macOS-10.15" ],
+ "operatingSystem": [ "windows-2019", "ubuntu-18.04", "macos-11" ],
"framework": [ "net461", "netcoreapp2.1" ],
"additionalArguments": [ "", "mode=test" ]
}
diff --git a/eng/common/scripts/job-matrix/tests/job-matrix-functions.modification.tests.ps1 b/eng/common/scripts/job-matrix/tests/job-matrix-functions.modification.tests.ps1
index 08979caaaf5..9dca8eba099 100644
--- a/eng/common/scripts/job-matrix/tests/job-matrix-functions.modification.tests.ps1
+++ b/eng/common/scripts/job-matrix/tests/job-matrix-functions.modification.tests.ps1
@@ -403,7 +403,7 @@ Describe "Platform Matrix Replace" -Tag "replace" {
{ $parsed = ParseReplacement $query } | Should -Throw
{ $parsed = ParseReplacement $query } | Should -Throw
}
-
+
It "Should replace values in a matrix" {
$matrixJson = @'
{
@@ -542,4 +542,31 @@ Describe "Platform Matrix Replace" -Tag "replace" {
$matrix[1].parameters.Foo | Should -Be "foo2"
$matrix[1].parameters.Bar | Should -Be "bar1"
}
+
+ It "Should parse replacement syntax and source imported display name lookups" {
+ $matrixJson = @'
+{
+ "displayNames": {
+ "replaceme": ""
+ },
+ "matrix": {
+ "$IMPORT": "./test-import-matrix.json",
+ "replaceme": "replaceme"
+ }
+}
+'@
+ $importConfig = GetMatrixConfigFromJson $matrixJson
+ $replace = 'Foo=(foo)1/$1ReplacedFoo1', 'B.*=(.*)2/$1ReplacedBar2'
+ $matrix = GenerateMatrix $importConfig "sparse" -replace $replace
+
+ $matrix.Length | Should -Be 3
+ $matrix[0].name | Should -Be "fooReplacedFoo1_bar1"
+ $matrix[0].parameters.Foo | Should -Be "fooReplacedFoo1"
+ $matrix[1].name | Should -Be "foo2_barReplacedBar2"
+ $matrix[1].parameters.Bar | Should -Be "barReplacedBar2"
+ $matrix[2].name | Should -Be "importedBazName"
+ $matrix[2].parameters.Baz | Should -Be "importedBaz"
+ $matrix[2].parameters.replaceme | Should -Be "replaceme"
+ }
+
}
diff --git a/eng/common/scripts/job-matrix/tests/job-matrix-functions.tests.ps1 b/eng/common/scripts/job-matrix/tests/job-matrix-functions.tests.ps1
index 38b7e44429c..689ed910837 100644
--- a/eng/common/scripts/job-matrix/tests/job-matrix-functions.tests.ps1
+++ b/eng/common/scripts/job-matrix/tests/job-matrix-functions.tests.ps1
@@ -12,7 +12,7 @@ BeforeAll {
"operatingSystem": [
"windows-2019",
"ubuntu-18.04",
- "macOS-10.15"
+ "macos-11"
],
"framework": [
"net461",
@@ -36,11 +36,11 @@ BeforeAll {
"framework": "net461"
},
{
- "operatingSystem": "macOS-10.15",
+ "operatingSystem": "macos-11",
"framework": "netcoreapp2.1"
},
{
- "operatingSystem": ["macOS-10.15", "ubuntu-18.04"],
+ "operatingSystem": ["macos-11", "ubuntu-18.04"],
"additionalArguments": "--enableFoo"
}
]
@@ -275,7 +275,7 @@ Describe "Platform Matrix Generation" -Tag "generate" {
"operatingSystem": [
"windows-2019",
"ubuntu-18.04",
- "macOS-10.15"
+ "macos-11"
],
"framework": [
"net461",
@@ -340,7 +340,7 @@ Describe "Platform Matrix Generation" -Tag "generate" {
$element.parameters.additionalArguments | Should -Be "--enableFoo"
$element = GetNdMatrixElement @(2, 1, 1) $matrix $dimensions
- $element.parameters.operatingSystem | Should -Be "macOS-10.15"
+ $element.parameters.operatingSystem | Should -Be "macos-11"
$element.parameters.framework | Should -Be "netcoreapp2.1"
$element.parameters.additionalArguments | Should -Be "--enableFoo"
}
@@ -348,7 +348,7 @@ Describe "Platform Matrix Generation" -Tag "generate" {
It "Should initialize a sparse matrix from an N-dimensional matrix" -TestCases @(
@{ i = 0; name = "windows2019_net461"; operatingSystem = "windows-2019"; framework = "net461"; additionalArguments = ""; }
@{ i = 1; name = "ubuntu1804_netcoreapp21_withfoo"; operatingSystem = "ubuntu-18.04"; framework = "netcoreapp2.1"; additionalArguments = "--enableFoo"; }
- @{ i = 2; name = "macOS1015_net461"; operatingSystem = "macOS-10.15"; framework = "net461"; additionalArguments = ""; }
+ @{ i = 2; name = "macOS11_net461"; operatingSystem = "macos-11"; framework = "net461"; additionalArguments = ""; }
) {
$sparseMatrix = GenerateSparseMatrix $generateConfig.matrixParameters $generateConfig.displayNamesLookup
$dimensions = GetMatrixDimensions $generateConfig.matrixParameters
@@ -440,9 +440,9 @@ Describe "Platform Matrix Post Transformation" -Tag "transform" {
$matrix[2].parameters.operatingSystem | Should -Be "ubuntu-18.04"
$matrix[2].parameters.additionalArguments | Should -Be ""
- $matrix[4].name | Should -Be "macOS1015_net461"
+ $matrix[4].name | Should -Be "macOS11_net461"
$matrix[4].parameters.framework | Should -Be "net461"
- $matrix[4].parameters.operatingSystem | Should -Be "macOS-10.15"
+ $matrix[4].parameters.operatingSystem | Should -Be "macos-11"
$matrix[4].parameters.additionalArguments | Should -Be ""
$matrix[7].name | Should -Be "windows2019_net50_enableWindowsFoo"
diff --git a/eng/common/scripts/stress-testing/deploy-stress-tests.ps1 b/eng/common/scripts/stress-testing/deploy-stress-tests.ps1
index f4da78bd522..01920bdcbfe 100644
--- a/eng/common/scripts/stress-testing/deploy-stress-tests.ps1
+++ b/eng/common/scripts/stress-testing/deploy-stress-tests.ps1
@@ -21,7 +21,10 @@ param(
[switch] $CI = ($null -ne $env:SYSTEM_TEAMPROJECTID),
# Optional namespace override, otherwise the shell user or chart annotation will be used
- [string]$Namespace
+ [string]$Namespace,
+
+ # Override remote stress-test-addons with local on-disk addons for development
+ [System.IO.FileInfo]$LocalAddonsPath
)
. $PSScriptRoot/stress-test-deployment-lib.ps1
diff --git a/eng/common/scripts/stress-testing/find-all-stress-packages.ps1 b/eng/common/scripts/stress-testing/find-all-stress-packages.ps1
index 3456cee6895..24c27da485f 100644
--- a/eng/common/scripts/stress-testing/find-all-stress-packages.ps1
+++ b/eng/common/scripts/stress-testing/find-all-stress-packages.ps1
@@ -9,6 +9,7 @@ class StressTestPackageInfo {
[string]$ReleaseName
[string]$Dockerfile
[string]$DockerBuildDir
+ [string]$Deployer
}
function FindStressPackages(
@@ -50,6 +51,17 @@ function MatchesAnnotations([hashtable]$chart, [hashtable]$filters) {
return $true
}
+function GetUsername() {
+ # Check GITHUB_USER for users in codespaces environments, since the default user is `codespaces` and
+ # we would like to avoid namespace overlaps for different codespaces users.
+ $stressUser = $env:GITHUB_USER ?? $env:USER ?? $env:USERNAME
+ # Remove spaces, underscores, etc. that may be in $namespace.
+ # Value must be a valid RFC 1123 DNS label: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-label-names
+ $stressUser = $stressUser -replace '_|\W', '-'
+
+ return $stressUser.ToLower()
+}
+
function NewStressTestPackageInfo(
[hashtable]$chart,
[System.IO.FileInfo]$chartFile,
@@ -61,18 +73,7 @@ function NewStressTestPackageInfo(
} elseif ($CI) {
$chart.annotations.namespace
} else {
- # Check GITHUB_USER for users in codespaces environments, since the default user is `codespaces` and
- # we would like to avoid namespace overlaps for different codespaces users.
- $namespace = if ($env:GITHUB_USER) {
- $env:GITHUB_USER
- } elseif ($env:USER) {
- $env:USER
- } else {
- $env:USERNAME
- }
- # Remove spaces, underscores, etc. that may be in $namespace. Value must be a valid RFC 1123 DNS label:
- # https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-label-names
- $namespace -replace '_|\W', '-'
+ GetUsername
}
return [StressTestPackageInfo]@{
diff --git a/eng/common/scripts/stress-testing/stress-test-deployment-lib.ps1 b/eng/common/scripts/stress-testing/stress-test-deployment-lib.ps1
index da91279fd63..97c4d925fe2 100644
--- a/eng/common/scripts/stress-testing/stress-test-deployment-lib.ps1
+++ b/eng/common/scripts/stress-testing/stress-test-deployment-lib.ps1
@@ -63,21 +63,29 @@ function Login([string]$subscription, [string]$clusterGroup, [switch]$pushImages
function DeployStressTests(
[string]$searchDirectory = '.',
[hashtable]$filters = @{},
- [string]$environment = 'test',
+ # Default to playground environment
+ [string]$environment = 'pg',
[string]$repository = '',
[switch]$pushImages,
[string]$clusterGroup = '',
- [string]$deployId = 'local',
+ [string]$deployId = '',
[switch]$login,
[string]$subscription = '',
[switch]$CI,
- [string]$Namespace
+ [string]$Namespace,
+ [ValidateScript({
+ if (!(Test-Path $_)) {
+ throw "LocalAddonsPath $LocalAddonsPath does not exist"
+ }
+ return $true
+ })]
+ [System.IO.FileInfo]$LocalAddonsPath
) {
- if ($environment -eq 'test') {
+ if ($environment -eq 'pg') {
if ($clusterGroup -or $subscription) {
- Write-Warning "Overriding cluster group and subscription with defaults for 'test' environment."
+ Write-Warning "Overriding cluster group and subscription with defaults for 'pg' environment."
}
- $clusterGroup = 'rg-stress-cluster-test'
+ $clusterGroup = 'rg-stress-cluster-pg'
$subscription = 'Azure SDK Developer Playground'
} elseif ($environment -eq 'prod') {
if ($clusterGroup -or $subscription) {
@@ -89,15 +97,26 @@ function DeployStressTests(
if ($login) {
if (!$clusterGroup -or !$subscription) {
- throw "clusterGroup and subscription parameters must be specified when logging into an environment that is not test or prod."
+ throw "clusterGroup and subscription parameters must be specified when logging into an environment that is not pg or prod."
}
Login -subscription $subscription -clusterGroup $clusterGroup -pushImages:$pushImages
}
- RunOrExitOnFailure helm repo add stress-test-charts https://stresstestcharts.blob.core.windows.net/helm/
+ $chartRepoName = 'stress-test-charts'
+ if ($LocalAddonsPath) {
+ $absAddonsPath = Resolve-Path $LocalAddonsPath
+ if (!(helm plugin list | Select-String 'file')) {
+ RunOrExitOnFailure helm plugin add (Join-Path $absAddonsPath file-plugin)
+ }
+ RunOrExitOnFailure helm repo add --force-update $chartRepoName file://$absAddonsPath
+ } else {
+ RunOrExitOnFailure helm repo add --force-update $chartRepoName https://stresstestcharts.blob.core.windows.net/helm/
+ }
+
Run helm repo update
if ($LASTEXITCODE) { return $LASTEXITCODE }
+ $deployer = if ($deployId) { $deployId } else { GetUsername }
$pkgs = FindStressPackages -directory $searchDirectory -filters $filters -CI:$CI -namespaceOverride $Namespace
Write-Host "" "Found $($pkgs.Length) stress test packages:"
Write-Host $pkgs.Directory ""
@@ -105,15 +124,15 @@ function DeployStressTests(
Write-Host "Deploying stress test at '$($pkg.Directory)'"
DeployStressPackage `
-pkg $pkg `
- -deployId $deployId `
+ -deployId $deployer `
-environment $environment `
-repositoryBase $repository `
-pushImages:$pushImages `
-login:$login
}
- Write-Host "Releases deployed by $deployId"
- Run helm list --all-namespaces -l deployId=$deployId
+ Write-Host "Releases deployed by $deployer"
+ Run helm list --all-namespaces -l deployId=$deployer
if ($FailedCommands) {
Write-Warning "The following commands failed:"
diff --git a/eng/common/testproxy/target_version.txt b/eng/common/testproxy/target_version.txt
index 86b34733bfc..640f3e5d1dc 100644
--- a/eng/common/testproxy/target_version.txt
+++ b/eng/common/testproxy/target_version.txt
@@ -1 +1 @@
-1.0.0-dev.20220427.1
+1.0.0-dev.20220630.4
diff --git a/eng/common/testproxy/test-proxy-docker.yml b/eng/common/testproxy/test-proxy-docker.yml
index df2548ab776..52a7c807a3d 100644
--- a/eng/common/testproxy/test-proxy-docker.yml
+++ b/eng/common/testproxy/test-proxy-docker.yml
@@ -1,10 +1,11 @@
parameters:
rootFolder: '$(Build.SourcesDirectory)'
targetVersion: ''
+ templateRoot: '$(Build.SourcesDirectory)'
steps:
- pwsh: |
- $(Build.SourcesDirectory)/eng/common/scripts/trust-proxy-certificate.ps1
+ ${{ parameters.templateRoot }}/eng/common/scripts/trust-proxy-certificate.ps1
displayName: 'Language Specific Certificate Trust'
- pwsh: |
@@ -12,7 +13,7 @@ steps:
displayName: 'Dump active docker information'
- pwsh: |
- $(Build.SourcesDirectory)/eng/common/testproxy/docker-start-proxy.ps1 -Mode start -TargetFolder "${{ parameters.rootFolder }}" -VersionOverride="${{ parameters.targetVersion }}"
+ ${{ parameters.templateRoot }}/eng/common/testproxy/docker-start-proxy.ps1 -Mode start -TargetFolder "${{ parameters.rootFolder }}" -VersionOverride="${{ parameters.targetVersion }}"
displayName: 'Run the docker container'
- pwsh: |
diff --git a/eng/common/testproxy/test-proxy-tool.yml b/eng/common/testproxy/test-proxy-tool.yml
index 7b5fedaaeb3..679ad2108d7 100644
--- a/eng/common/testproxy/test-proxy-tool.yml
+++ b/eng/common/testproxy/test-proxy-tool.yml
@@ -2,14 +2,15 @@ parameters:
rootFolder: '$(Build.SourcesDirectory)'
runProxy: true
targetVersion: ''
+ templateRoot: '$(Build.SourcesDirectory)'
steps:
- pwsh: |
- $(Build.SourcesDirectory)/eng/common/scripts/trust-proxy-certificate.ps1
+ ${{ parameters.templateRoot }}/eng/common/scripts/trust-proxy-certificate.ps1
displayName: 'Language Specific Certificate Trust'
- pwsh: |
- $version = $(Get-Content "$(Build.SourcesDirectory)/eng/common/testproxy/target_version.txt" -Raw).Trim()
+ $version = $(Get-Content "${{ parameters.templateRoot }}/eng/common/testproxy/target_version.txt" -Raw).Trim()
$overrideVersion = "${{ parameters.targetVersion }}"
if($overrideVersion) {
@@ -29,7 +30,7 @@ steps:
- ${{ if eq(parameters.runProxy, 'true') }}:
- pwsh: |
- Write-Host "##vso[task.setvariable variable=ASPNETCORE_Kestrel__Certificates__Default__Path]$(Build.SourcesDirectory)/eng/common/testproxy/dotnet-devcert.pfx"
+ Write-Host "##vso[task.setvariable variable=ASPNETCORE_Kestrel__Certificates__Default__Path]${{ parameters.templateRoot }}/eng/common/testproxy/dotnet-devcert.pfx"
Write-Host "##vso[task.setvariable variable=ASPNETCORE_Kestrel__Certificates__Default__Password]password"
Write-Host "##vso[task.setvariable variable=PROXY_MANUAL_START]true"
displayName: 'Configure Kestrel and PROXY_MANUAL_START Variables'
@@ -37,13 +38,13 @@ steps:
- pwsh: |
Start-Process $(Build.BinariesDirectory)/test-proxy/test-proxy.exe `
-ArgumentList "--storage-location ${{ parameters.rootFolder }}" `
- -NoNewWindow -PassThru -RedirectStandardOutput $(Build.SourcesDirectory)/test-proxy.log
+ -NoNewWindow -PassThru -RedirectStandardOutput ${{ parameters.templateRoot }}/test-proxy.log
displayName: 'Run the testproxy - windows'
condition: and(succeeded(), eq(variables['Agent.OS'],'Windows_NT'))
# nohup does NOT continue beyond the current session if you use it within powershell
- bash: |
- nohup $(Build.BinariesDirectory)/test-proxy/test-proxy > $(Build.SourcesDirectory)/test-proxy.log &
+ nohup $(Build.BinariesDirectory)/test-proxy/test-proxy > ${{ parameters.templateRoot }}/test-proxy.log &
displayName: "Run the testproxy - linux/mac"
condition: and(succeeded(), ne(variables['Agent.OS'],'Windows_NT'))
workingDirectory: "${{ parameters.rootFolder }}"
diff --git a/eng/pipelines/templates/jobs/archetype-sdk-client.yml b/eng/pipelines/templates/jobs/archetype-sdk-client.yml
index d24656dc3dd..14883215a99 100644
--- a/eng/pipelines/templates/jobs/archetype-sdk-client.yml
+++ b/eng/pipelines/templates/jobs/archetype-sdk-client.yml
@@ -56,6 +56,50 @@ jobs:
# Disable build for cpp - client
- ${{ if ne(parameters.ServiceDirectory, 'not-specified' )}}:
+ - ${{ each artifact in parameters.Artifacts }}:
+ - job:
+ displayName: Create API Review for ${{ artifact.name }}
+ pool:
+ name: azsdk-pool-mms-win-2019-general
+ vmImage: MMS2019
+ steps:
+ - task: Powershell@2
+ inputs:
+ filePath: $(Build.SourcesDirectory)/eng/common/scripts/Save-Package-Properties.ps1
+ arguments: >
+ -ServiceDirectory ${{ parameters.ServiceDirectory }}
+ -OutDirectory $(Build.ArtifactStagingDirectory)/PackageInfo
+ pwsh: true
+ workingDirectory: $(Pipeline.Workspace)
+ displayName: Dump Package properties
+ condition: succeeded()
+
+ - template: /eng/common/pipelines/templates/steps/set-default-branch.yml
+
+ - task: Powershell@2
+ inputs:
+ filePath: $(System.DefaultWorkingDirectory)/eng/scripts/Create-APIReview.ps1
+ arguments: >
+ -ArtifactName ${{ artifact.name }}
+ -OutPath $(Build.ArtifactStagingDirectory)
+ -ApiviewUri "$(azuresdk-apiview-uri)"
+ -ApiKey "$(azuresdk-apiview-apikey)"
+ -ApiLabel "Auto Review - $(Build.SourceVersion)"
+ -SourceBranch $(Build.SourceBranchName)
+ -DefaultBranch $(DefaultBranch)
+ -ConfigFileDir $(Build.ArtifactStagingDirectory)/PackageInfo
+ pwsh: true
+ workingDirectory: $(Pipeline.Workspace)
+ displayName: Create API Review for ${{ artifact.name }}
+ continueOnError: true
+ condition: >-
+ and(
+ succeeded(),
+ ne(variables['Skip.CreateApiReview'], 'true'),
+ ne(variables['Build.Reason'],'PullRequest'),
+ eq(variables['System.TeamProject'], 'internal')
+ )
+
- job: GenerateReleaseArtifacts
pool:
name: azsdk-pool-mms-win-2019-general
@@ -73,7 +117,7 @@ jobs:
Directory: ''
CheckLinkGuidance: $true
- - ${{ each artifact in parameters.Artifacts }}:
+ - ${{ each artifact in parameters.Artifacts }}:
- template: /eng/common/pipelines/templates/steps/set-test-pipeline-version.yml
parameters:
PackageName: ${{ artifact.Name }}
@@ -93,9 +137,6 @@ jobs:
workingDirectory: $(Agent.TempDirectory)
displayName: Download and Install Doxygen
- # Install dependencies required for build from vcpkg
- # TODO: We should be able to generate docs without having to install these
- # prerequisites:
- template: /eng/pipelines/templates/steps/vcpkg.yml
- template: /eng/pipelines/templates/steps/cmake-build.yml
@@ -148,7 +189,7 @@ jobs:
Copy-Item -Recurse `
build/vcpkg/ports/${{ artifact.VcpkgPortName }}/. `
- $(Build.ArtifactStagingDirectory)/packages/${{ artifact.Name }}/vcpkg/port
+ $(Build.ArtifactStagingDirectory)/packages/${{ artifact.Name }}/vcpkg/port
pwsh: true
displayName: Copy vcpkg port files from build
@@ -195,7 +236,7 @@ jobs:
sourceFolder: build/sdk/${{ parameters.ServiceDirectory }}/${{ artifact.Path }}/docs/html
targetFolder: $(Build.ArtifactStagingDirectory)/docs/${{ artifact.Name }}
displayName: Copy documentation to artifact staging directory
-
+
- task: Powershell@2
inputs:
filePath: $(Build.SourcesDirectory)/eng/common/scripts/Verify-ChangeLog.ps1
diff --git a/eng/pipelines/templates/stages/archetype-cpp-release.yml b/eng/pipelines/templates/stages/archetype-cpp-release.yml
index 21f35c8ad60..e4070400a6b 100644
--- a/eng/pipelines/templates/stages/archetype-cpp-release.yml
+++ b/eng/pipelines/templates/stages/archetype-cpp-release.yml
@@ -108,7 +108,7 @@ stages:
- pwsh: |
$branchName = "azure-sdk-for-cpp-${{ artifact.Name }}-$(Build.BuildId)"
if ('$(VcpkgForkBranchName)') {
- Write-Host "Using queue time branch name"
+ Write-Host "Using queue time branch name"
$branchName = '$(VcpkgForkBranchName)'
}
Write-Host "##vso[task.setvariable variable=PrBranchName]$branchName"
@@ -164,14 +164,12 @@ stages:
CommitMsg: Update vcpkg-configuration.json
BaseRepoBranch: $(DefaultBranch)
- # Set $(HasChanges) to $true so that
- # create-pull-request.yml completes the push and PR
- # submission steps. This is contegnent upon
- # `$(PublishToVcpkg)` being `true`. `$(PublishToVcpkg)` is
- # set in `vcpkg-publish.yml`
- - pwsh: Write-Host "##vso[task.setvariable variable=HasChanges]$true"
- condition: and(succeeded(), eq(variables['PublishToVcpkg'], 'true'))
- displayName: Set $(HasChanges) to $true for create-pull-request.yml
+ # Set $(HasChanges) to $(PublishToVcpkg) so that
+ # create-pull-request.yml creates or does not create a PR
+ # based on the deicision of the step that determines
+ # whether to publish to vcpkg.
+ - pwsh: Write-Host "##vso[task.setvariable variable=HasChanges]$(PublishToVcpkg)"
+ displayName: Set $(HasChanges) to $(PublishToVcpkg) for create-pull-request.yml
- template: /eng/common/pipelines/templates/steps/set-default-branch.yml
parameters:
diff --git a/eng/pipelines/templates/stages/platform-matrix-live.json b/eng/pipelines/templates/stages/platform-matrix-live.json
index f5932952d69..7e9f0181071 100644
--- a/eng/pipelines/templates/stages/platform-matrix-live.json
+++ b/eng/pipelines/templates/stages/platform-matrix-live.json
@@ -128,12 +128,14 @@
"RunSamples": 1,
"WindowsCtestConfig": "-C Release"
},
- "Win_x64_with_unit_test_libcurl": {
+ "HSM_Win_x64_with_unit_test_libcurl": {
"VCPKG_DEFAULT_TRIPLET": "x64-windows-static",
"CMAKE_GENERATOR_PLATFORM": "x64",
"CmakeArgs": " -DBUILD_TRANSPORT_CURL=ON -DBUILD_TESTING=ON -DRUN_LONG_UNIT_TESTS=ON -DBUILD_PERFORMANCE_TESTS=ON -DMSVC_USE_STATIC_CRT=ON ",
"BuildArgs": "-v --parallel 8 --config Release",
- "WindowsCtestConfig": "-C Release"
+ "WindowsCtestConfig": "-C Release",
+ "KVLocation": "eastus2",
+ "EnableHSM": 1
},
"Win_x64_with_unit_samples_libcurl": {
"VcpkgInstall": "curl[winssl] openssl",
diff --git a/eng/pipelines/templates/steps/vcpkg-publish.yml b/eng/pipelines/templates/steps/vcpkg-publish.yml
index dbf9f7ccad6..e732f5adedb 100644
--- a/eng/pipelines/templates/steps/vcpkg-publish.yml
+++ b/eng/pipelines/templates/steps/vcpkg-publish.yml
@@ -46,7 +46,7 @@ steps:
-GitCommitParameters '-c user.name="azure-sdk" -c user.email="azuresdk@microsoft.com"'
-DailyRelease:$${{ parameters.DailyRelease }}
workingDirectory: ${{ parameters.Workspace }}/vcpkg
- condition: and(succeeded(), eq(variables['PublishToVcpkg'], 'true'))
+ condition: and(succeeded(), eq(variables['PublishToVcpkg'], 'true'))
displayName: Update vcpkg port ${{ parameters.DisplayNameExtension }}
# On package release vcpkg beta should always be updated
diff --git a/eng/pipelines/templates/steps/vcpkg.yml b/eng/pipelines/templates/steps/vcpkg.yml
index b442b765819..54ad698c4b1 100644
--- a/eng/pipelines/templates/steps/vcpkg.yml
+++ b/eng/pipelines/templates/steps/vcpkg.yml
@@ -1,16 +1,5 @@
steps:
- pwsh: |
- $TargetPath = "$(Agent.TempDirectory)/vcpkg"
- Remove-Item -Path $TargetPath -Recurse -Force -ErrorAction Ignore
- New-Item -ItemType Directory -Path $TargetPath -Force
-
- $VcpkgCommit = $(Get-Content eng/vcpkg-commit.txt)
- Write-Host "Target Path for vcpkg: $TargetPath"
- Write-Host "Vcpkg SHA: $VcpkgCommit"
-
- Write-Host "##vso[task.prependpath]$TargetPath"
- Write-Host "##vso[task.setvariable variable=VCPKG_INSTALLATION_ROOT]$TargetPath"
- Write-Host "##vso[task.setvariable variable=VcpkgCommit]$VcpkgCommit"
Write-Host "##vso[task.setvariable variable=VCPKG_BINARY_SOURCES_SECRET;issecret=true;]clear;x-azblob,https://cppvcpkgcache.blob.core.windows.net/public-vcpkg-container,,read"
displayName: Set Vcpkg Variables
@@ -22,13 +11,3 @@ steps:
arguments: -StorageAccountKey '$(cpp-vcpkg-cache-storage-key)'
displayName: Set Vcpkg Write-mode Cache
condition: and(succeeded(), eq(variables['System.TeamProject'], 'internal'))
-
- - task: PowerShell@2
- inputs:
- targetType: filePath
- filePath: eng/scripts/vcpkg.ps1
- arguments: >-
- -Ref $(VcpkgCommit)
- -VcpkgPath $(VCPKG_INSTALLATION_ROOT)
- pwsh: true
- displayName: Clone Vcpkg.
diff --git a/eng/scripts/Create-APIReview.ps1 b/eng/scripts/Create-APIReview.ps1
new file mode 100644
index 00000000000..0a0d7cd1afa
--- /dev/null
+++ b/eng/scripts/Create-APIReview.ps1
@@ -0,0 +1,43 @@
+Param(
+ [Parameter(Mandatory=$True)]
+ [string] $ArtifactName,
+ [Parameter(Mandatory=$True)]
+ [string] $OutPath,
+ [Parameter(Mandatory=$True)]
+ [string] $ApiviewUri,
+ [Parameter(Mandatory=$True)]
+ [string] $ApiKey,
+ [Parameter(Mandatory=$True)]
+ [string] $ApiLabel,
+ [Parameter(Mandatory=$True)]
+ [string] $SourceBranch,
+ [Parameter(Mandatory=$True)]
+ [string] $DefaultBranch,
+ [Parameter(Mandatory=$True)]
+ [string] $ConfigFileDir
+)
+
+Write-Host "$PSScriptRoot"
+. (Join-Path $PSScriptRoot .. common scripts common.ps1)
+$createReviewScript = (Join-Path $PSScriptRoot .. common scripts Create-APIReview.ps1)
+Set-Location $PSScriptRoot
+
+Write-Host "Creating API review artifact for $ArtifactName"
+New-Item -ItemType Directory -Path $OutPath/$ArtifactName -force
+
+$gitroot = Join-Path $PSScriptRoot .. ..
+Write-Host "Get-ApiViewCommandLine.ps1 $gitroot $ArtifactName"
+$cmdLine = & $PSScriptRoot/Get-ApiViewCommandLine.ps1 $gitroot $ArtifactName
+Write-Host "Executing clang++ command:"
+Write-Host $cmdLine
+$cmd, $cmdArgs = $cmdLine -split ' '
+# Get-ApiViewCommandLine.ps1 returns a string representing a clang++ command that needs to be run, e.g.
+# clang++ -Xclang -ast-dump -I
+# ApiView expects a zip of this ast as the format for a C++ language artifact.
+& $cmd $cmdArgs > clangAstOutput
+
+Compress-Archive -Path clangAstOutput -DestinationPath $OutPath/$ArtifactName/$ArtifactName
+Rename-Item $OutPath/$ArtifactName/$ArtifactName.zip -NewName "$ArtifactName.cppast"
+
+Write-Host "Send request to APIView to create review for $ArtifactName"
+&($createReviewScript) -ArtifactPath $OutPath -APIViewUri $ApiviewUri -APIKey $ApiKey -APILabel $ApiLabel -PackageName $ArtifactName -SourceBranch $SourceBranch -DefaultBranch $DefaultBranch -ConfigFileDir $ConfigFileDir
diff --git a/eng/scripts/Get-ApiViewCommandLine.ps1 b/eng/scripts/Get-ApiViewCommandLine.ps1
new file mode 100644
index 00000000000..5eeb9aa257a
--- /dev/null
+++ b/eng/scripts/Get-ApiViewCommandLine.ps1
@@ -0,0 +1,58 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# SPDX-License-Identifier: MIT
+
+# Usage: Get-ApiViewCommandLine.ps1 .\azure-sdk-for-cpp azure-identity
+# Or: ..\Get-ApiViewCommandLine.ps1 . azure-core
+# Or: Get-ApiViewCommandLine.ps1 ..\.. azure-security-attestation
+# Or: c:\src\azure-sdk-for-cpp\eng\scripts\Get-ApiViewCommandLine.ps1 c:\src\azure-sdk-for-cpp azure-identity
+
+param([String]$RepoPath, [String]$LibName)
+
+[String]$SdkRoot = Resolve-Path ($RepoPath + "\sdk")
+
+[String[]]$AllIncDirs = Get-ChildItem -Directory -Filter "inc" -Recurse $SdkRoot | Select-Object -ExpandProperty FullName
+
+[String[]]$AllIncDirsWithoutInc = $AllIncDirs | Select-Object @{ Label="Substr"; Expression = { $_.Substring(0, $_.Length - "inc".Length) } } | Select-Object -ExpandProperty Substr
+
+[String[]]$AllLibIncDirs = @()
+for($i = 0; $i -lt $AllIncDirsWithoutInc.Length; $i++) {
+ $isLibDir = $true
+ $libDir = $AllIncDirsWithoutInc[$i]
+ for($j = 0; $j -lt $AllIncDirsWithoutInc.Length; $j++) {
+ if ($i -eq $j) {
+ continue
+ }
+
+ $StartsWith = $AllIncDirsWithoutInc[$j] + "*"
+ if ($libDir -Like $StartsWith) {
+ $isLibDir = $false
+ break
+ }
+ }
+
+ if ($isLibDir){
+ $AllLibIncDirs += $libDir + "inc"
+ }
+}
+
+[String]$LibIncDir = $AllLibIncDirs | Where-Object {$_ -Match ("\\" + $LibName + "\\inc") } | Select-Object -First 1
+
+[String[]]$LibHeaders = Get-ChildItem -File -Recurse $LibIncDir | Select-Object -ExpandProperty FullName
+
+$CmdLine = "clang++"
+foreach ($header in $LibHeaders) {
+ $CmdLine += " " + $header
+}
+
+$CmdLine += " -Xclang -ast-dump"
+
+foreach ($incDir in $AllLibIncDirs) {
+ $CmdLine += " -I " + $incDir
+}
+
+# Define an _azure_APIVIEW macro so that the public headers that depend on 3rd party headers apply a work around
+# for declaring 3rd party dependencies in a minimalistic way that is sufficient for the ApiView generation.
+# Otherwise, ApiView would've been including 3rd party types for review, which is not what we want.
+$CmdLine += " -D_azure_APIVIEW"
+
+$CmdLine
diff --git a/eng/scripts/Language-Settings.ps1 b/eng/scripts/Language-Settings.ps1
index 4ceca708d50..7dc88bcf89c 100644
--- a/eng/scripts/Language-Settings.ps1
+++ b/eng/scripts/Language-Settings.ps1
@@ -98,3 +98,16 @@ function SetPackageVersion ($PackageName, $Version, $ServiceDirectory, $ReleaseD
-ReleaseDate $ReleaseDate `
-ReplaceLatestEntryTitle $ReplaceLatestEntryTitle
}
+
+function Find-cpp-Artifacts-For-Apireview($ArtifactPath, $PackageName)
+{
+ $artifact = Get-ChildItem -Path (Join-Path $ArtifactPath $PackageName) -Filter "*.cppast"
+ if ($artifact)
+ {
+ $packages = @{
+ $artifact.FullName = $artifact.FullName
+ }
+ return $packages
+ }
+ return $null
+}
diff --git a/eng/scripts/vcpkg.ps1 b/eng/scripts/vcpkg.ps1
deleted file mode 100644
index 41b1885edc6..00000000000
--- a/eng/scripts/vcpkg.ps1
+++ /dev/null
@@ -1,27 +0,0 @@
-[CmdletBinding()]
-Param (
- [Parameter()]
- [ValidateNotNullOrEmpty()]
- [string] $Ref = (Get-Content "$PSScriptRoot/../vcpkg-commit.txt"),
-
- [Parameter()]
- [ValidateNotNullOrEmpty()]
- [string] $VcpkgPath = "$PSScriptRoot/../../vcpkg"
-)
-
-$initialDirectory = Get-Location
-
-try {
- git clone https://github.com/Microsoft/vcpkg $VcpkgPath
- Set-Location $VcpkgPath
- git fetch --tags
- git checkout $Ref
-
- if ($IsWindows) {
- .\bootstrap-vcpkg.bat
- } else {
- ./bootstrap-vcpkg.sh
- }
-} finally {
- Set-Location $initialDirectory
-}
diff --git a/eng/vcpkg-commit.txt b/eng/vcpkg-commit.txt
deleted file mode 100644
index 428f461f182..00000000000
--- a/eng/vcpkg-commit.txt
+++ /dev/null
@@ -1 +0,0 @@
-f0aa678b7471497f1adedcc99f40e1599ad22f69
diff --git a/samples/helpers/service/CMakeLists.txt b/samples/helpers/service/CMakeLists.txt
index 8f25a20ca3a..af8944052b6 100644
--- a/samples/helpers/service/CMakeLists.txt
+++ b/samples/helpers/service/CMakeLists.txt
@@ -10,8 +10,11 @@ set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
add_library(
service
- INTERFACE
+ OBJECT
inc/azure/service/client.hpp
-)
+ src/client.cpp
+ )
-target_include_directories(service INTERFACE inc)
+ target_link_libraries(service PUBLIC azure-core)
+
+target_include_directories(service PUBLIC inc)
diff --git a/samples/helpers/service/inc/azure/service/client.hpp b/samples/helpers/service/inc/azure/service/client.hpp
index b489445ce3b..e28b0f687b3 100644
--- a/samples/helpers/service/inc/azure/service/client.hpp
+++ b/samples/helpers/service/inc/azure/service/client.hpp
@@ -3,9 +3,11 @@
#pragma once
+#include
#include
#include
+#include
#include
namespace Azure { namespace Service {
@@ -26,32 +28,13 @@ namespace Azure { namespace Service {
static_cast(serviceUrl); // to suppress the "unused variable" warning.
}
- void DoSomething(const Core::Context& context) const
- {
- static_cast(context); // to suppress the "unused variable" warning.
-
- // This method does nothing, because the purpose of this class is to demonstrate
- // how Azure::Identity classes can be used with a generic Azure SDK service client.
- // If we have code here that gets the token, it would be up to the user to set it up to be
- // valid enough to get a token, which is not critical for the intended demonstration purposes.
- // And if user runs this, and authentication is unsuccessful, it may draw an unnecessary
- // attention to an irrelevant (to the demo) point.
-
- // But an oversimplified logic of what a typical Azure SDK client does is below:
-#if (0)
- // Every client has its own scope. We use management.azure.com here as an example.
- Core::Credentials::TokenRequestContext azureServiceClientContext;
- azureServiceClientContext.Scopes = {"https://management.azure.com/"};
-
- auto authenticationToken = m_credential->GetToken(azureServiceClientContext, context);
-
- // Now that it has a token, Client can authorize and DoSomething().
- // ...
- // ...
-
- static_cast(authenticationToken); // to suppress the "unused variable" warning.
-#endif
- }
+ // This method does nothing, because the purpose of this class is to demonstrate how
+ // Azure::Identity classes can be used with a generic Azure SDK service client. If we have code
+ // here that gets the token, it would be up to the user to set it up to be valid enough to get a
+ // token, which is not critical for the intended demonstration purposes. And if user runs this,
+ // and authentication is unsuccessful, it may draw an unnecessary attention to an irrelevant (to
+ // the demo) point.
+ void DoSomething(const Core::Context& context) const;
};
}} // namespace Azure::Service
diff --git a/samples/helpers/service/src/client.cpp b/samples/helpers/service/src/client.cpp
new file mode 100644
index 00000000000..6d86975216d
--- /dev/null
+++ b/samples/helpers/service/src/client.cpp
@@ -0,0 +1,24 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+#include "azure/service/client.hpp"
+
+void Azure::Service::Client::DoSomething(const Azure::Core::Context& context) const
+{
+ static_cast(context); // to suppress the "unused variable" warning.
+
+ // An oversimplified logic of what a typical Azure SDK client does is below:
+#if (0)
+ // Every client has its own scope. We use management.azure.com here as an example.
+ Core::Credentials::TokenRequestContext azureServiceClientContext;
+ azureServiceClientContext.Scopes = {"https://management.azure.com/"};
+
+ auto authenticationToken = m_credential->GetToken(azureServiceClientContext, context);
+
+ // Now that it has a token, Client can authorize and DoSomething().
+ // ...
+ // ...
+
+ static_cast(authenticationToken); // to suppress the "unused variable" warning.
+#endif
+}
diff --git a/samples/integration/vcpkg-all-smoke/src/main.cpp b/samples/integration/vcpkg-all-smoke/src/main.cpp
index 2823894836e..678fe231263 100644
--- a/samples/integration/vcpkg-all-smoke/src/main.cpp
+++ b/samples/integration/vcpkg-all-smoke/src/main.cpp
@@ -36,8 +36,9 @@ int main()
auto clientSecret = std::getenv("AZURE_CLIENT_SECRET");
const std::string leaseID = "leaseID";
const std::string smokeUrl = "https://blob.com";
- // Creating an attestation service instance requires contacting the attestation service (to retrieve validation collateral).
- // Use the West US Shared client (which should always be available) as an anonymous service instance.
+ // Creating an attestation service instance requires contacting the attestation service (to
+ // retrieve validation collateral). Use the West US Shared client (which should always be
+ // available) as an anonymous service instance.
const std::string attestationUrl = "https://sharedwus.wus.attest.azure.net";
auto credential
@@ -75,11 +76,10 @@ int main()
// Attestation
std::cout << "Creating Attestation Clients" << std::endl;
- std::unique_ptr attestationAdminClient(
- AttestationAdministrationClientFactory::Create(attestationUrl, credential));
+ AttestationAdministrationClient attestationAdminClient(
+ AttestationAdministrationClient::Create(attestationUrl, credential));
- std::unique_ptr attestationClient(
- AttestationClientFactory::Create(attestationUrl));
+ AttestationClient attestationClient(AttestationClient::Create(attestationUrl));
std::cout << "Successfully Created the Clients" << std::endl;
}
diff --git a/samples/integration/vcpkg-keyvault/.devcontainer/Dockerfile b/samples/integration/vcpkg-keyvault/.devcontainer/Dockerfile
deleted file mode 100644
index e5f5ca09abe..00000000000
--- a/samples/integration/vcpkg-keyvault/.devcontainer/Dockerfile
+++ /dev/null
@@ -1,7 +0,0 @@
-# base image installs keyvault beta1 from vcpkg only
-FROM vhvb1989/keyvault:beta1
-
-RUN cd vcpkg \
- && sudo ./vcpkg install azure-identity-cpp
-
-ENV VCPKG_DEFAULT_TRIPLET=x64-linux
diff --git a/samples/integration/vcpkg-keyvault/.devcontainer/devcontainer.json b/samples/integration/vcpkg-keyvault/.devcontainer/devcontainer.json
deleted file mode 100644
index 0dd126a6d89..00000000000
--- a/samples/integration/vcpkg-keyvault/.devcontainer/devcontainer.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "name": "Ubuntu-21.04",
- "dockerFile": "Dockerfile",
- "settings": {
- "terminal.integrated.shell.linux": "/bin/bash"
- },
- "extensions": [
- "ms-vscode.cpptools-themes",
- "bbenoist.doxygen",
- "streetsidesoftware.code-spell-checker",
- "ms-vscode.cpptools",
- "xaver.clang-format",
- "twxs.cmake",
- "ms-vscode.cmake-tools",
- "eamodio.gitlens",
- "davidschuldenfrei.gtest-adapter"
- ],
- // Do not run as root. See https://aka.ms/vscode-remote/containers/non-root.
- "remoteUser": "azure-sdk-for-cpp"
-}
diff --git a/samples/integration/vcpkg-keyvault/CMakeLists.txt b/samples/integration/vcpkg-keyvault/CMakeLists.txt
deleted file mode 100644
index 1707c6a2c79..00000000000
--- a/samples/integration/vcpkg-keyvault/CMakeLists.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# SPDX-License-Identifier: MIT
-
-# vcpkg integration.
-if(DEFINED ENV{VCPKG_ROOT} AND NOT DEFINED CMAKE_TOOLCHAIN_FILE)
- set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"
- CACHE STRING "")
-endif()
-if(DEFINED ENV{VCPKG_DEFAULT_TRIPLET} AND NOT DEFINED VCPKG_TARGET_TRIPLET)
- set(VCPKG_TARGET_TRIPLET "$ENV{VCPKG_DEFAULT_TRIPLET}" CACHE STRING "")
-endif()
-
-# Project set up
-cmake_minimum_required(VERSION 3.13)
-project(Application-using-keyvault-from-vcpkg LANGUAGES CXX)
-set(CMAKE_CXX_STANDARD 14)
-set(CMAKE_CXX_STANDARD_REQUIRED True)
-
-add_executable (
- application
- src/main
-)
-
-# Link to Azure SDK
-target_link_libraries(application
- PRIVATE
- Azure::azure-security-keyvault-keys
- Azure::azure-identity
- get-env-helper
-)
diff --git a/samples/integration/vcpkg-keyvault/LICENSE b/samples/integration/vcpkg-keyvault/LICENSE
deleted file mode 100644
index 51b6a76e544..00000000000
--- a/samples/integration/vcpkg-keyvault/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
- MIT License
-
- Copyright (c) Microsoft Corporation. All rights reserved.
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
diff --git a/samples/integration/vcpkg-keyvault/README.md b/samples/integration/vcpkg-keyvault/README.md
deleted file mode 100644
index dd7e4b7054d..00000000000
--- a/samples/integration/vcpkg-keyvault/README.md
+++ /dev/null
@@ -1,67 +0,0 @@
-# Integrating the Azure SDK for C++ into your application using vcpkg
-
-This application shows how to integrate the Azure SDK for C++ in your application. It uses vcpkg to acquire and build the Azure SDK for C++ client libraries. Your CMake project needs to link the libraries from vcpkg by setting the toolchain file to vcpkg (shown below).
-
-## Pre-requisites
-
-There are two options to set up the development environment:
-
-### Manual installation
-
-Install the [Azure SDK for C++ dependencies](https://github.com/Azure/azure-sdk-for-cpp/blob/main/CONTRIBUTING.md#third-party-dependencies).
-
-- CMake project (min version 3.13).
-- C++ version 14 or greater.
-
-### Container
-
-The sample provides a .devcontainer folder which can be used by VS Code to build and run a docker container with the required C++ build tools and with vcpkg installed.
-
-This method requires VS Code + [Remote Container](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) to be installed in the system. Also make sure to have Docker installed and running. This method works for any operating system where Docker and VSCode is supported like Windows, Linux and macOS. The development environment will be Debian 10.
-
-- Open vcpkg folder in VS Code.
-- VS Code will detect the `devcontainer` configuration and ask you if you would like to re-open the folder in a container. Click Yes.
-- If VS Code did not ask, you can press F1 and type `Reopen in container` option.
-
-Once VS Code builds and run the container, open the terminal and continue to build step.
-
-> Note: The container is set up to automatically link vcpkg to CMake projects by setting env variables that the CMake sample project will use to set the toolchain.
-
-## Build
-
-### Linux terminal
-
-```bash
-#
-# Building the application.
-# Instructions from application root directory.
-#
-
-# Create build directory just the first time.
-mkdir build
-cd build
-
-# Generate and build
-# This code assumes that the SDK dependencies were installed with vcpkg
-# When using docker provided container, the TOOLCHAIN option is not required (cmake ..).
-cmake -DCMAKE_TOOLCHAIN_FILE=path/to/vcpkg/scripts/buildsystems/vcpkg.cmake ..
-cmake -build .
-```
-
-### Windows VS
-
-If you are using Visual Studio, the toolchain to link vcpkg is set with `CMakeSettings.json`. Update this file and set the vcpkg toolchain file for vcpkg (VCPKG_ROOT\scripts\buildsystems\vcpkg.cmake). After setting the toolchain, VS can generate and build the sample. Use VS to open the sample folder only.
-
-## Run application
-
-Review source code header for `environment variables` that must be set up before running the app.
-
-```bash
-#
-# Running the Application
-# Instructions from inside the build directory.
-#
-
-# Run binary (.exe on Windows)
-./application
-```
diff --git a/samples/integration/vcpkg-keyvault/src/main.cpp b/samples/integration/vcpkg-keyvault/src/main.cpp
deleted file mode 100644
index 541a95160c0..00000000000
--- a/samples/integration/vcpkg-keyvault/src/main.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-/**
- * @brief This sample provides the code implementation to use the Key Vault SDK client for C++
- * to create, get, update, delete and purge a key.
- *
- * @remark The following environment variables must be set before running the sample.
- * - AZURE_KEYVAULT_URL: To the Key Vault account URL.
- * - AZURE_TENANT_ID: Tenant ID for the Azure account.
- * - AZURE_CLIENT_ID: The Client ID to authenticate the request.
- * - AZURE_CLIENT_SECRET: The client secret.
- *
- */
-
-#include "get_env.hpp"
-
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-
-using namespace Azure::Security::KeyVault::Keys;
-
-int main()
-{
- auto tenantId = std::getenv("AZURE_TENANT_ID");
- auto clientId = std::getenv("AZURE_CLIENT_ID");
- auto clientSecret = std::getenv("AZURE_CLIENT_SECRET");
- auto credential
- = std::make_shared(tenantId, clientId, clientSecret);
-
- KeyClient keyClient(std::getenv("AZURE_KEYVAULT_URL"), credential);
-
- std::string rsaKeyName("CloudRsaKey" + Azure::Core::Uuid::CreateUuid().ToString());
- try
- {
- auto rsaKey = CreateRsaKeyOptions(rsaKeyName);
- rsaKey.KeySize = 2048;
- rsaKey.ExpiresOn = std::chrono::system_clock::now() + std::chrono::hours(24 * 365);
-
- keyClient.CreateRsaKey(rsaKey);
-
- KeyVaultKey cloudRsaKey = keyClient.GetKey(rsaKeyName).Value;
- std::cout << "Key is returned with name " << cloudRsaKey.Name() << " and type "
- << cloudRsaKey.GetKeyType().ToString() << std::endl;
-
- cloudRsaKey.Properties.ExpiresOn
- = cloudRsaKey.Properties.ExpiresOn.Value() + std::chrono::hours(24 * 365);
- KeyVaultKey updatedKey = keyClient.UpdateKeyProperties(cloudRsaKey.Properties).Value;
- std::cout << "Key's updated expiry time is " << updatedKey.Properties.ExpiresOn->ToString()
- << std::endl;
-
- CreateRsaKeyOptions newRsaKey(rsaKeyName);
- newRsaKey.KeySize = 4096;
- newRsaKey.ExpiresOn = std::chrono::system_clock::now() + std::chrono::hours(24 * 365);
-
- keyClient.CreateRsaKey(newRsaKey);
-
- DeleteKeyOperation operation = keyClient.StartDeleteKey(rsaKeyName);
-
- // You only need to wait for completion if you want to purge or recover the key.
- operation.PollUntilDone(std::chrono::milliseconds(2000));
-
- keyClient.PurgeDeletedKey(rsaKeyName);
- }
- catch (Azure::Core::Credentials::AuthenticationException const& e)
- {
- std::cout << "Authentication Exception happened:" << std::endl << e.what() << std::endl;
- return 1;
- }
- catch (Azure::Core::RequestFailedException const& e)
- {
- std::cout << "KeyVault Client Exception happened:" << std::endl << e.Message << std::endl;
- return 1;
- }
-
- return 0;
-}
diff --git a/samples/integration/vcpkg-storage/.devcontainer/Dockerfile b/samples/integration/vcpkg-storage/.devcontainer/Dockerfile
deleted file mode 100644
index 2bac8b85070..00000000000
--- a/samples/integration/vcpkg-storage/.devcontainer/Dockerfile
+++ /dev/null
@@ -1,14 +0,0 @@
-# base image installs dev env for storage v12 beta10
-FROM vhvb1989/storage12:preview10
-
-# Get vcpkg and install storage blobs
-RUN sudo git clone https://github.com/microsoft/vcpkg.git \
- && cd vcpkg \
- # VCPKG commit version for key vault keys 1.0.0-beta.1 - Storage beta 10 - Identity beta 5 - Core beta 8
- && sudo git checkout 414bec05f2a97cfc0ddb8e22fd4635dfe2a20ab8 \
- && sudo ./bootstrap-vcpkg.sh
-
-ENV VCPKG_ROOT=/vcpkg
-
-RUN cd vcpkg \
- && sudo ./vcpkg install azure-storage-blobs-cpp
diff --git a/samples/integration/vcpkg-storage/.devcontainer/devcontainer.json b/samples/integration/vcpkg-storage/.devcontainer/devcontainer.json
deleted file mode 100644
index a1a73de699b..00000000000
--- a/samples/integration/vcpkg-storage/.devcontainer/devcontainer.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "name": "AzureSDK-Storage-v12-beta10",
- "dockerFile": "Dockerfile",
- "settings": {
- "terminal.integrated.shell.linux": "/bin/bash"
- },
- "extensions": [
- "ms-vscode.cpptools-themes",
- "bbenoist.doxygen",
- "streetsidesoftware.code-spell-checker",
- "ms-vscode.cpptools",
- "xaver.clang-format",
- "twxs.cmake",
- "ms-vscode.cmake-tools",
- "eamodio.gitlens",
- "davidschuldenfrei.gtest-adapter"
- ],
- // Do not run as root. See https://aka.ms/vscode-remote/containers/non-root.
- "remoteUser": "azure-sdk-for-cpp"
-}
diff --git a/samples/integration/vcpkg-storage/CMakeLists.txt b/samples/integration/vcpkg-storage/CMakeLists.txt
deleted file mode 100644
index c6ca69c6459..00000000000
--- a/samples/integration/vcpkg-storage/CMakeLists.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# SPDX-License-Identifier: MIT
-
-# vcpkg integration.
-if(DEFINED ENV{VCPKG_ROOT} AND NOT DEFINED CMAKE_TOOLCHAIN_FILE)
- set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"
- CACHE STRING "")
-endif()
-if(DEFINED ENV{VCPKG_DEFAULT_TRIPLET} AND NOT DEFINED VCPKG_TARGET_TRIPLET)
- set(VCPKG_TARGET_TRIPLET "$ENV{VCPKG_DEFAULT_TRIPLET}" CACHE STRING "")
-endif()
-
-# Project set up
-cmake_minimum_required(VERSION 3.13)
-project(Application-using-storage-blobs-from-vcpkg LANGUAGES CXX)
-set(CMAKE_CXX_STANDARD 14)
-set(CMAKE_CXX_STANDARD_REQUIRED True)
-
-find_package(CURL REQUIRED)
-find_package(azure-storage-blobs-cpp CONFIG REQUIRED)
-
-add_executable (
- application
- src/main
-)
-
-# Link to Azure SDK
-target_link_libraries(application
- PRIVATE
- Azure::azure-storage-blobs
- get-env-helper
-)
diff --git a/samples/integration/vcpkg-storage/LICENSE b/samples/integration/vcpkg-storage/LICENSE
deleted file mode 100644
index 51b6a76e544..00000000000
--- a/samples/integration/vcpkg-storage/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
- MIT License
-
- Copyright (c) Microsoft Corporation. All rights reserved.
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
diff --git a/samples/integration/vcpkg-storage/README.md b/samples/integration/vcpkg-storage/README.md
deleted file mode 100644
index a1c4e789887..00000000000
--- a/samples/integration/vcpkg-storage/README.md
+++ /dev/null
@@ -1,67 +0,0 @@
-# Integrating the Azure SDK for C++ into your application using vcpkg
-
-This application shows how to integrate the Azure SDK for C++ in your application. It uses vcpkg to adquire and build the Azure SDK for C++ client libraries. Your CMake project needs to link the libraries from vcpkg by setting the toolchain file to vcpkg (shown below).
-
-## Pre-requisites
-
-There are two options to set up the development environment:
-
-### Manual installation
-
-Install the [Azure SDK for C++ dependencies](https://github.com/Azure/azure-sdk-for-cpp/blob/main/CONTRIBUTING.md#third-party-dependencies).
-
-- CMake project (min version 3.13).
-- C++ version 14 or greater.
-
-### Container
-
-The sample provides a .devcontainer folder which can be used by VS Code to build and run a docker container with the required C++ build tools and with vcpkg installed.
-
-This method requires VS Code + [Remote Container](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) to be installed in the system. Also make sure to have Docker installed and running. This method works for any operating system where Docker and VS Code is supported like Windows, Linux and macOS. The development environment will be Debian 10.
-
-- Open vcpkg folder in VS Code.
-- VS Code will detect the `devcontainer` configuration and ask you if you would like to re-open the folder in a container. Click Yes.
-- If VS Code did not ask, you can press F1 and type `Reopen in container` option.
-
-Once VS Code builds and run the container, open the terminal and continue to build step.
-
-> Note: The container is set up to automatically link vcpkg to CMake projects by setting env variables that the CMake sample project will use to set the toolchain.
-
-## Build
-
-### Linux terminal
-
-```bash
-#
-# Building the application.
-# Instructions from application root directory.
-#
-
-# Create build directory just the first time.
-mkdir build
-cd build
-
-# Generate and build
-# This code assumes that the SDK dependencies were installed with vcpkg
-# When using docker provided container, the TOOLCHAIN option is not required (cmake ..).
-cmake -DCMAKE_TOOLCHAIN_FILE=path/to/vcpkg/scripts/buildsystems/vcpkg.cmake ..
-cmake -build .
-```
-
-### Windows VS
-
-If you are using Visual Studio, the toolchain to link vcpkg is set with `CMakeSettings.json`. Upate this file and set the vcpkg toolchain file for vcpkg (VCPKG_ROOT\scripts\buildsystems\vcpkg.cmake). After setting the toolchain, VS can generate and build the sample. Use VS to open the sample folder only.
-
-## Run application
-
-Review source code header for `environment variables` that must be set up before running the app.
-
-```bash
-#
-# Running the Application
-# Instructions from inside the build directory.
-#
-
-# Run binary (.exe on Windows)
-./application
-```
diff --git a/samples/integration/vcpkg-storage/src/main.cpp b/samples/integration/vcpkg-storage/src/main.cpp
deleted file mode 100644
index 7d7f873a894..00000000000
--- a/samples/integration/vcpkg-storage/src/main.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-/**
- * @brief This sample provides the code implementation to use the Storage blobs SDK client for C++
- * to create a container and upload a blob to it.
- *
- * @remark The following environment variables must be set before running the sample.
- * - AZURE_STORAGE_CONNECTION_STRING: Set it Azure Storage connection string.
- *
- */
-
-#include "get_env.hpp"
-
-#include
-
-#include
-
-const std::string& GetConnectionString();
-
-int main()
-{
- using namespace Azure::Storage::Blobs;
-
- std::string containerName = "sample-container";
- std::string blobName = "sample-blob";
- std::string blobContent = "Hello Azure!";
-
- auto containerClient
- = BlobContainerClient::CreateFromConnectionString(GetConnectionString(), containerName);
-
- containerClient.CreateIfNotExists();
-
- BlockBlobClient blobClient = containerClient.GetBlockBlobClient(blobName);
-
- blobClient.UploadFrom(reinterpret_cast(blobContent.data()), blobContent.size());
-
- Azure::Storage::Metadata blobMetadata = {{"key1", "value1"}, {"key2", "value2"}};
- blobClient.SetMetadata(blobMetadata);
-
- auto properties = blobClient.GetProperties().Value;
- for (auto metadata : properties.Metadata)
- {
- std::cout << metadata.first << ":" << metadata.second << std::endl;
- }
- blobContent.resize(static_cast(properties.BlobSize));
-
- blobClient.DownloadTo(reinterpret_cast(&blobContent[0]), blobContent.size());
-
- std::cout << blobContent << std::endl;
-
- return 0;
-}
-
-const std::string& GetConnectionString()
-{
- const static std::string ConnectionString = "";
-
- if (!ConnectionString.empty())
- {
- return ConnectionString;
- }
- const static std::string envConnectionString = std::getenv("AZURE_STORAGE_CONNECTION_STRING");
- if (!envConnectionString.empty())
- {
- return envConnectionString;
- }
- throw std::runtime_error("Cannot find connection string");
-}
diff --git a/sdk/attestation/azure-security-attestation/CHANGELOG.md b/sdk/attestation/azure-security-attestation/CHANGELOG.md
index 115947daea6..b032e5a8d23 100644
--- a/sdk/attestation/azure-security-attestation/CHANGELOG.md
+++ b/sdk/attestation/azure-security-attestation/CHANGELOG.md
@@ -1,23 +1,31 @@
# Release History
-## 1.0.0-beta.3 (Unreleased)
+## 1.1.0-beta.1 (Unreleased)
### Features Added
### Breaking Changes
-- `ValueToSend` field in `TpmAttestationOptions` becomes `Payload`.
-- `AddIsolatedModeCertificatesOptions` becomes `AddIsolatedModeCertificateOptions`
-- `RemoveIsolatedModeCertificatesOptions` becomes `RemoveIsolatedModeCertificateOptions`
-- Renamed `AttestEnclaveOptions` to `AttestSgxEnclaveOptions` and `AttestOpenEnclaveOptions`.
-- Split out `AttestationClient::Create` into its own factory class `AttestationClientFactory`.
- - Note that the `AttestationClientFactory::Create` method returns a `std::unique_ptr` to the client object.
-- Split out `AttestationAdministrationClient::Create` into its own factory class `AttestationAdministrationClientFactory`.
- - Note that the `AttestationAdministrationClientFactory::Create` method returns a `std::unique_ptr` to the client object.
### Bugs Fixed
### Other Changes
+## 1.0.0 (2022-07-07)
+
+### Breaking Changes
+
+- Renamed `Version` field to `ApiVersion` and removed the `ServiceVersion` enumeration.
+
+## 1.0.0-beta.3 (2022-06-07)
+
+### Breaking Changes
+
+- `ValueToSend` field in `TpmAttestationOptions` becomes `Payload`.
+- `AddIsolatedModeCertificatesOptions` becomes `AddIsolatedModeCertificateOptions`
+- `RemoveIsolatedModeCertificatesOptions` becomes `RemoveIsolatedModeCertificateOptions`
+- Renamed `AttestEnclaveOptions` to `AttestSgxEnclaveOptions` and `AttestOpenEnclaveOptions`.
+- `AttestationClient` and `AttestationAdministrationClient` creation is now done using the factory method `AttestationClient::Create()` and `AttestationAdministrationClient::Create()`.
+
## 1.0.0-beta.2 (2022-05-10)
### Breaking Changes
diff --git a/sdk/attestation/azure-security-attestation/README.md b/sdk/attestation/azure-security-attestation/README.md
index b191f1a48b7..a04514ca14c 100644
--- a/sdk/attestation/azure-security-attestation/README.md
+++ b/sdk/attestation/azure-security-attestation/README.md
@@ -210,22 +210,21 @@ Isolated Mode Certificate Management APIs enable clients to add, remove or enume
#### Create an attestation client
-The `AttestationClientFactory::Create` method is used to create instances of the attestation client:
+The `AttestationClient::Create` method is used to create instances of the attestation client:
```cpp
std::string endpoint = std::getenv("ATTESTATION_AAD_URL");
- return Azure::Security::Attestation::AttestationClientFactory::CreatePointer(m_endpoint);
+ Azure::Security::Attestation::AttestationClient client = Azure::Security::Attestation::AttestationClient::Create(m_endpoint);
```
-If the attestation APIs require authentication, use the following (note that unlike the previous example,
-which returns a pointer to the client, this returns the client by value):
+If the attestation APIs require authentication, use the following:
```cpp
std::string endpoint = std::getenv("ATTESTATION_AAD_URL");
std::shared_ptr credential
= std::make_shared(
std::getenv("AZURE_TENANT_ID"), std::getenv("AZURE_CLIENT_ID"), std::getenv("AZURE_CLIENT_SECRET"));
-return Azure::Security::Attestation::AttestationClientFactory::Create(m_endpoint, credential);
+auto client = Azure::Security::Attestation::AttestationClient::Create(m_endpoint, credential);
```
The same pattern is used to create an `Azure::Security::Attestation::AttestationAdministrationClient`.
@@ -240,7 +239,7 @@ attestation service, however the APIs are provided for completeness and to facil
attestation results.
```cpp
-auto validationCertificates = attestationClient->GetTokenValidationCertificates();
+auto validationCertificates = attestationClient.GetTokenValidationCertificates();
// Enumerate the signers.
for (const auto& signer : validationCertificates.Value.Signers)
{
@@ -271,7 +270,7 @@ std::string endpoint = std::getenv("ATTESTATION_AAD_URL");
std::shared_ptr credential
= std::make_shared(
std::getenv("AZURE_TENANT_ID"), std::getenv("AZURE_CLIENT_ID"), std::getenv("AZURE_CLIENT_SECRET"));
-AttestationAdministrationClient adminClient(AttestationAdministrationClientFactory::Create(m_endpoint, credential));
+AttestationAdministrationClient adminClient(AttestationAdministrationClient::Create(m_endpoint, credential));
```
#### Retrieve current attestation policy for OpenEnclave
diff --git a/sdk/attestation/azure-security-attestation/inc/azure/attestation/attestation_administration_client.hpp b/sdk/attestation/azure-security-attestation/inc/azure/attestation/attestation_administration_client.hpp
index ddae7b9d429..aa17c5a18eb 100644
--- a/sdk/attestation/azure-security-attestation/inc/azure/attestation/attestation_administration_client.hpp
+++ b/sdk/attestation/azure-security-attestation/inc/azure/attestation/attestation_administration_client.hpp
@@ -6,6 +6,7 @@
#include "azure/attestation/attestation_client_models.hpp"
#include "azure/attestation/attestation_client_options.hpp"
#include
+#include
#include
#include
@@ -44,9 +45,23 @@ namespace Azure { namespace Security { namespace Attestation {
*
*/
class AttestationAdministrationClient final {
- friend class AttestationAdministrationClientFactory;
public:
+ /**
+ * @brief Construct a new Attestation Administration Client object.
+ *
+ * @param endpoint The URL address where the client will send the requests to.
+ * @param credential The authentication token to use.
+ * @param options The options to customize the client behavior.
+ * @return The newly created client.
+ */
+ static AttestationAdministrationClient Create(
+ std::string const& endpoint,
+ std::shared_ptr credential,
+ AttestationAdministrationClientOptions const& options
+ = AttestationAdministrationClientOptions{},
+ Azure::Core::Context const& context = Azure::Core::Context{});
+
/**
* @brief Construct a new Attestation Administration Client object from another attestation
* administration client.
@@ -54,9 +69,7 @@ namespace Azure { namespace Security { namespace Attestation {
* @param attestationClient An existing attestation client.
*/
AttestationAdministrationClient(AttestationAdministrationClient const& attestationClient)
- : m_endpoint(attestationClient.m_endpoint), m_apiVersion(attestationClient.m_apiVersion),
- m_pipeline(attestationClient.m_pipeline),
- m_tokenValidationOptions(attestationClient.m_tokenValidationOptions){};
+ = default;
/**
* @brief Destructor.
@@ -80,9 +93,6 @@ namespace Azure { namespace Security { namespace Attestation {
* @return Response> The returned policy from the
* service.
*
- * @note \b Note: The RetrieveResponseValidationCollateral API \b MUST be called before the
- * GetAttestationPolicy API is called to retrieve the information needed to validate the
- * result returned by the service.
*/
Response> GetAttestationPolicy(
Models::AttestationType const& attestationType,
@@ -116,9 +126,6 @@ namespace Azure { namespace Security { namespace Attestation {
* @return Response> The result of the set policy
* operation.
*
- * @note \b Note: The RetrieveResponseValidationCollateral API \b MUST be called before the
- * SetAttestationPolicy API is called to retrieve the information needed to validate the
- * result returned by the service.
*/
Response> SetAttestationPolicy(
Models::AttestationType const& attestationType,
@@ -135,9 +142,6 @@ namespace Azure { namespace Security { namespace Attestation {
* @return Response> The result of the reset
* policy operation.
*
- * @note \b Note: The RetrieveResponseValidationCollateral API \b MUST be called before the
- * ResetAttestationPolicy API is called to retrieve the information needed to validate the
- * result returned by the service.
*/
Response> ResetAttestationPolicy(
Models::AttestationType const& attestationType,
@@ -249,9 +253,9 @@ namespace Azure { namespace Security { namespace Attestation {
private:
Azure::Core::Url m_endpoint;
std::string m_apiVersion;
- std::shared_ptr m_credentials;
std::shared_ptr m_pipeline;
AttestationTokenValidationOptions m_tokenValidationOptions;
+ Azure::Core::Tracing::_internal::TracingContextFactory m_tracingFactory;
std::vector m_attestationSigners;
@@ -289,29 +293,4 @@ namespace Azure { namespace Security { namespace Attestation {
void RetrieveResponseValidationCollateral(
Azure::Core::Context const& context = Azure::Core::Context{});
};
-
- /** @brief Construct a new AttestationAdministrationClient object.
- *
- * The AttestationAdministrationClientFactory class is a factory class for instantiating new
- * AttestationAdministrationClient objects.
- *
- */
- class AttestationAdministrationClientFactory final {
- public:
- /**
- * @brief Construct a new Attestation Administration Client object.
- *
- * @param endpoint The URL address where the client will send the requests to.
- * @param credential The authentication token to use.
- * @param options The options to customize the client behavior.
- * @return std::unique_ptr The newly created client.
- */
- static std::unique_ptr Create(
- std::string const& endpoint,
- std::shared_ptr credential,
- AttestationAdministrationClientOptions const& options
- = AttestationAdministrationClientOptions{},
- Azure::Core::Context const& context = Azure::Core::Context{});
- };
-
}}} // namespace Azure::Security::Attestation
diff --git a/sdk/attestation/azure-security-attestation/inc/azure/attestation/attestation_client.hpp b/sdk/attestation/azure-security-attestation/inc/azure/attestation/attestation_client.hpp
index 623cfbd55b5..4aa60061ed1 100644
--- a/sdk/attestation/azure-security-attestation/inc/azure/attestation/attestation_client.hpp
+++ b/sdk/attestation/azure-security-attestation/inc/azure/attestation/attestation_client.hpp
@@ -6,6 +6,7 @@
#include "azure/attestation/attestation_client_models.hpp"
#include "azure/attestation/attestation_client_options.hpp"
#include
+#include
#include
#include
@@ -114,10 +115,44 @@ namespace Azure { namespace Security { namespace Attestation {
*/
class AttestationClient final {
- // Allow client factory to access private methods in the AttestationClient object.
- friend class AttestationClientFactory;
public:
+ /** @brief Construct a new Attestation Client object
+ *
+ * @details Constructs a new attestation client. Follows the
+ * factory pattern in [C++ Core Guidelines
+ * C.50](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c50-use-a-factory-function-if-you-need-virtual-behavior-during-initialization)
+ *
+ * @param endpoint The URL address where the client will send the requests to.
+ * @param credential The authentication method to use (required for TPM attestation). If the
+ * credential parameter is not supplied, the connection will be unauthenticated.
+ * @param options The options to customize the client behavior.
+ * @return The newly created client.
+ */
+ static AttestationClient Create(
+ std::string const& endpoint,
+ std::shared_ptr credential,
+ AttestationClientOptions const& options = AttestationClientOptions{},
+ Azure::Core::Context const& constext = Azure::Core::Context{});
+
+ /** @brief Construct a new anonymous Attestation Client object
+ *
+ * @details Constructs a new anonymous (unauthenticated) attestation client. Follows the
+ * factory pattern in [C++ Core Guidelines
+ * C.50](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c50-use-a-factory-function-if-you-need-virtual-behavior-during-initialization)
+ *
+ * @param endpoint The URL address where the client will send the requests to.
+ * @param options The options to customize the client behavior.
+ * @return The newly created attestation client.
+ *
+ * @note TPM attestation requires an authenticated attestation client.
+ *
+ */
+ static AttestationClient Create(
+ std::string const& endpoint,
+ AttestationClientOptions options = AttestationClientOptions{},
+ Azure::Core::Context const& constext = Azure::Core::Context{});
+
/**
* @brief Destructor.
*
@@ -128,10 +163,7 @@ namespace Azure { namespace Security { namespace Attestation {
*
* @param attestationClient An existing attestation client.
*/
- AttestationClient(AttestationClient const& attestationClient)
- : m_endpoint(attestationClient.m_endpoint), m_apiVersion(attestationClient.m_apiVersion),
- m_pipeline(attestationClient.m_pipeline),
- m_tokenValidationOptions(attestationClient.m_tokenValidationOptions){};
+ AttestationClient(AttestationClient const& attestationClient) = default;
std::string const Endpoint() const { return m_endpoint.GetAbsoluteUrl(); }
@@ -166,9 +198,6 @@ namespace Azure { namespace Security { namespace Attestation {
* @returns Response> - The result of the
* attestation operation.
*
- * @note \b Note: The RetrieveResponseValidationCollateral API \b MUST be called before the
- * AttestSgxEnclave API is called to retrieve the information needed to validate the
- * result returned by the service.
*/
Response> AttestSgxEnclave(
std::vector const& sgxQuoteToAttest,
@@ -187,9 +216,6 @@ namespace Azure { namespace Security { namespace Attestation {
* @returns Response> - The result of the attestation
* operation
- * @note \b Note: The RetrieveResponseValidationCollateral API \b MUST be called before the
- * AttestOpenEnclave API is called to retrieve information needed to used to validate the
- * result returned by the service.
*/
Response> AttestOpenEnclave(
std::vector const& openEnclaveReportToAttest,
@@ -222,11 +248,10 @@ namespace Azure { namespace Security { namespace Attestation {
private:
Azure::Core::Url m_endpoint;
std::string m_apiVersion;
- std::shared_ptr m_credentials;
std::shared_ptr m_pipeline;
AttestationTokenValidationOptions m_tokenValidationOptions;
-
std::vector m_attestationSigners;
+ Azure::Core::Tracing::_internal::TracingContextFactory m_tracingFactory;
/** @brief Construct a new Attestation Client object
*
@@ -249,49 +274,4 @@ namespace Azure { namespace Security { namespace Attestation {
Azure::Core::Context const& context = Azure::Core::Context{});
};
- /** @brief Construct a new AttestationClient object.
- *
- * The AttestationClientFactory class is a factory class for instantiating new AttestationClient
- * objects.
- *
- */
- class AttestationClientFactory final {
- public:
- /** @brief Construct a new Attestation Client object
- *
- * @details Constructs a new attestation client. Follows the
- * factory pattern in [C++ Core Guidelines
- * C.50](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c50-use-a-factory-function-if-you-need-virtual-behavior-during-initialization)
- *
- * @param endpoint The URL address where the client will send the requests to.
- * @param credential The authentication method to use (required for TPM attestation). If the
- * credential parameter is not supplied, the connection will be unauthenticated.
- * @param options The options to customize the client behavior.
- * @return std::unique_ptr The newly created client.
- */
- static std::unique_ptr Create(
- std::string const& endpoint,
- std::shared_ptr credential,
- AttestationClientOptions options = AttestationClientOptions{},
- Azure::Core::Context const& constext = Azure::Core::Context{});
-
- /** @brief Construct a new anonymous Attestation Client object
- *
- * @details Constructs a new anonymous (unauthenticated) attestation client. Follows the
- * factory pattern in [C++ Core Guidelines
- * C.50](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c50-use-a-factory-function-if-you-need-virtual-behavior-during-initialization)
- *
- * @param endpoint The URL address where the client will send the requests to.
- * @param options The options to customize the client behavior.
- * @return std::unique_ptr The newly created attestation client.
- *
- * @note TPM attestation requires an authenticated attestation client.
- *
- */
- static std::unique_ptr Create(
- std::string const& endpoint,
- AttestationClientOptions options = AttestationClientOptions{},
- Azure::Core::Context const& constext = Azure::Core::Context{});
- };
-
}}} // namespace Azure::Security::Attestation
diff --git a/sdk/attestation/azure-security-attestation/inc/azure/attestation/attestation_client_options.hpp b/sdk/attestation/azure-security-attestation/inc/azure/attestation/attestation_client_options.hpp
index bcd6e12fb7d..a94cf6092ef 100644
--- a/sdk/attestation/azure-security-attestation/inc/azure/attestation/attestation_client_options.hpp
+++ b/sdk/attestation/azure-security-attestation/inc/azure/attestation/attestation_client_options.hpp
@@ -16,28 +16,6 @@
namespace Azure { namespace Security { namespace Attestation {
- /** @brief Version to be used when communicating with the Attestation service.
- */
- class ServiceVersion final
- : public Azure::Core::_internal::ExtendableEnumeration {
- public:
- /**
- * @brief Construct a new Service Version object
- *
- * @param version The string version for the Attestation service.
- */
- explicit ServiceVersion(std::string version)
- : Azure::Core::_internal::ExtendableEnumeration(std::move(version))
- {
- }
-
- /**
- * @brief Use to send request to the 2020-10-01 version of Attestation service.
- *
- */
- AZ_ATTESTATION_DLLEXPORT static const ServiceVersion V2020_10_01;
- };
-
/**
* @brief The TokenValidationCallbackFn represents a callback which is called to allow the caller
* to perform additional token validation options beyond the validations performed by the
@@ -116,7 +94,7 @@ namespace Azure { namespace Security { namespace Attestation {
{
/** @brief Version to use when communicating with the attestation service.
*/
- ServiceVersion Version;
+ std::string ApiVersion{"2020-10-01"};
/** @brief Options sent when validating tokens received by the attestation service.
*/
@@ -125,15 +103,11 @@ namespace Azure { namespace Security { namespace Attestation {
/**
* @brief Construct a new Attestation Client Options object.
*
- * @param version Optional version for the client.
* @param tokenValidationOptions Options applied when validating attestation tokens returned by
* the service.
*/
- AttestationClientOptions(
- ServiceVersion version = ServiceVersion::V2020_10_01,
- AttestationTokenValidationOptions const& tokenValidationOptions = {})
- : Azure::Core::_internal::ClientOptions(), Version(version),
- TokenValidationOptions(tokenValidationOptions)
+ AttestationClientOptions(AttestationTokenValidationOptions const& tokenValidationOptions = {})
+ : Azure::Core::_internal::ClientOptions(), TokenValidationOptions(tokenValidationOptions)
{
}
};
@@ -145,22 +119,19 @@ namespace Azure { namespace Security { namespace Attestation {
{
/** @brief Version to use when communicating with the attestation service.
*/
- ServiceVersion Version;
+ std::string ApiVersion{"2020-10-01"};
/** @brief Options sent when validating tokens received by the attestation service.
*/
AttestationTokenValidationOptions TokenValidationOptions;
/**
* @brief Construct a new Attestation Client Options object.
*
- * @param version Optional version for the client.
* @param tokenValidationOptions Options applied when validating attestation tokens returned by
* the service.
*/
AttestationAdministrationClientOptions(
- ServiceVersion version = ServiceVersion::V2020_10_01,
AttestationTokenValidationOptions const& tokenValidationOptions = {})
- : Azure::Core::_internal::ClientOptions(), Version(version),
- TokenValidationOptions(tokenValidationOptions)
+ : Azure::Core::_internal::ClientOptions(), TokenValidationOptions(tokenValidationOptions)
{
}
};
diff --git a/sdk/attestation/azure-security-attestation/samples/attestation/attest_openenclave_shared.cpp b/sdk/attestation/azure-security-attestation/samples/attestation/attest_openenclave_shared.cpp
index a73a68a4201..6cf6cc47c03 100644
--- a/sdk/attestation/azure-security-attestation/samples/attestation/attest_openenclave_shared.cpp
+++ b/sdk/attestation/azure-security-attestation/samples/attestation/attest_openenclave_shared.cpp
@@ -47,13 +47,12 @@ int main()
std::string const endpoint
= "https://shared" + shortLocation + "." + shortLocation + ".attest.azure.net";
- std::unique_ptr attestationClient(
- AttestationClientFactory::Create(endpoint));
+ AttestationClient const attestationClient(AttestationClient::Create(endpoint));
std::vector const sgxEnclaveQuote = AttestationCollateral::SgxQuote();
Azure::Response> const sgxResult
- = attestationClient->AttestSgxEnclave(sgxEnclaveQuote);
+ = attestationClient.AttestSgxEnclave(sgxEnclaveQuote);
std::cout << "SGX Quote MRSIGNER is: "
<< Convert::Base64Encode(*sgxResult.Value.Body.SgxMrSigner) << std::endl;
diff --git a/sdk/attestation/azure-security-attestation/samples/attestation/attest_openenclave_with_draft_policy.cpp b/sdk/attestation/azure-security-attestation/samples/attestation/attest_openenclave_with_draft_policy.cpp
index 36826304d21..2547cf1899a 100644
--- a/sdk/attestation/azure-security-attestation/samples/attestation/attest_openenclave_with_draft_policy.cpp
+++ b/sdk/attestation/azure-security-attestation/samples/attestation/attest_openenclave_with_draft_policy.cpp
@@ -42,8 +42,8 @@ int main()
{
std::cout << "In function: SampleAttestSgxEnclaveSimple" << std::endl;
// create client
- std::unique_ptr attestationClient(
- AttestationClientFactory::Create(GetEnvHelper::GetEnv("ATTESTATION_AAD_URL")));
+ AttestationClient const attestationClient(
+ AttestationClient::Create(GetEnvHelper::GetEnv("ATTESTATION_AAD_URL")));
std::vector const openEnclaveReport = AttestationCollateral::OpenEnclaveReport();
@@ -61,7 +61,7 @@ issuancerules {
c:[type=="x-ms-sgx-mrsigner"] => issue(type="custom-name", value=c.value);
};)";
Azure::Response> const sgxResult(
- attestationClient->AttestOpenEnclave(openEnclaveReport, options));
+ attestationClient.AttestOpenEnclave(openEnclaveReport, options));
std::cout << "SGX Quote MRSIGNER is: "
<< Convert::Base64Encode(*sgxResult.Value.Body.SgxMrSigner) << std::endl;
diff --git a/sdk/attestation/azure-security-attestation/samples/attestation/attest_sgxenclave.cpp b/sdk/attestation/azure-security-attestation/samples/attestation/attest_sgxenclave.cpp
index b5a1622dc0f..9b9283c008a 100644
--- a/sdk/attestation/azure-security-attestation/samples/attestation/attest_sgxenclave.cpp
+++ b/sdk/attestation/azure-security-attestation/samples/attestation/attest_sgxenclave.cpp
@@ -42,13 +42,13 @@ int main()
{
std::cout << "In function: SampleAttestSgxEnclaveSimple" << std::endl;
// create client
- std::unique_ptr attestationClient(
- AttestationClientFactory::Create(GetEnvHelper::GetEnv("ATTESTATION_AAD_URL")));
+ AttestationClient attestationClient(
+ AttestationClient::Create(GetEnvHelper::GetEnv("ATTESTATION_AAD_URL")));
std::vector const sgxEnclaveQuote = AttestationCollateral::SgxQuote();
Azure::Response> const sgxResult
- = attestationClient->AttestSgxEnclave(sgxEnclaveQuote);
+ = attestationClient.AttestSgxEnclave(sgxEnclaveQuote);
std::cout << "SGX Quote MRSIGNER is: "
<< Convert::Base64Encode(*sgxResult.Value.Body.SgxMrSigner) << std::endl;
diff --git a/sdk/attestation/azure-security-attestation/samples/attestation/attest_sgxenclave_with_runtime_binary.cpp b/sdk/attestation/azure-security-attestation/samples/attestation/attest_sgxenclave_with_runtime_binary.cpp
index 94ed1053e8f..2ecc6ddacd3 100644
--- a/sdk/attestation/azure-security-attestation/samples/attestation/attest_sgxenclave_with_runtime_binary.cpp
+++ b/sdk/attestation/azure-security-attestation/samples/attestation/attest_sgxenclave_with_runtime_binary.cpp
@@ -45,7 +45,7 @@ int main()
// create client
std::string endpoint(GetEnvHelper::GetEnv("ATTESTATION_AAD_URL"));
std::shared_ptr attestationClient(
- AttestationClientFactory::Create(endpoint));
+ std::make_shared(AttestationClient::Create(endpoint)));
std::vector const sgxEnclaveQuote = AttestationCollateral::SgxQuote();
diff --git a/sdk/attestation/azure-security-attestation/samples/attestation/attest_sgxenclave_with_runtime_json.cpp b/sdk/attestation/azure-security-attestation/samples/attestation/attest_sgxenclave_with_runtime_json.cpp
index 8ebb520d36e..d70c5f43a36 100644
--- a/sdk/attestation/azure-security-attestation/samples/attestation/attest_sgxenclave_with_runtime_json.cpp
+++ b/sdk/attestation/azure-security-attestation/samples/attestation/attest_sgxenclave_with_runtime_json.cpp
@@ -44,8 +44,7 @@ int main()
// create client
std::string const endpoint(GetEnvHelper::GetEnv("ATTESTATION_AAD_URL"));
- std::unique_ptr attestationClient(
- AttestationClientFactory::Create(endpoint));
+ AttestationClient const attestationClient(AttestationClient::Create(endpoint));
std::vector const sgxEnclaveQuote = AttestationCollateral::SgxQuote();
@@ -57,7 +56,7 @@ int main()
= AttestationData{AttestationCollateral::RunTimeData(), AttestationDataType::Json};
Azure::Response> const sgxResult
- = attestationClient->AttestSgxEnclave(sgxEnclaveQuote, attestOptions);
+ = attestationClient.AttestSgxEnclave(sgxEnclaveQuote, attestOptions);
std::cout << "SGX Quote MRSIGNER is: "
<< Convert::Base64Encode(*sgxResult.Value.Body.SgxMrSigner) << std::endl;
diff --git a/sdk/attestation/azure-security-attestation/samples/basic-operations/create_admin_client.cpp b/sdk/attestation/azure-security-attestation/samples/basic-operations/create_admin_client.cpp
index 0d37c671d95..652f955970e 100644
--- a/sdk/attestation/azure-security-attestation/samples/basic-operations/create_admin_client.cpp
+++ b/sdk/attestation/azure-security-attestation/samples/basic-operations/create_admin_client.cpp
@@ -39,11 +39,10 @@ int main()
GetEnvHelper::GetEnv("AZURE_TENANT_ID"),
GetEnvHelper::GetEnv("AZURE_CLIENT_ID"),
GetEnvHelper::GetEnv("AZURE_CLIENT_SECRET"));
- std::unique_ptr adminClient(
- AttestationAdministrationClientFactory::Create(
- GetEnvHelper::GetEnv("ATTESTATION_AAD_URL"), credential));
+ AttestationAdministrationClient const adminClient(AttestationAdministrationClient::Create(
+ GetEnvHelper::GetEnv("ATTESTATION_AAD_URL"), credential));
- std::cout << "Admin client is Communicating with " << adminClient->Endpoint() << std::endl;
+ std::cout << "Admin client is Communicating with " << adminClient.Endpoint() << std::endl;
}
catch (Azure::Core::Credentials::AuthenticationException const& e)
{
diff --git a/sdk/attestation/azure-security-attestation/samples/basic-operations/create_client.cpp b/sdk/attestation/azure-security-attestation/samples/basic-operations/create_client.cpp
index 765b5f1243d..9c6d0a4c5fb 100644
--- a/sdk/attestation/azure-security-attestation/samples/basic-operations/create_client.cpp
+++ b/sdk/attestation/azure-security-attestation/samples/basic-operations/create_client.cpp
@@ -35,10 +35,10 @@ int main()
clientOptions.TokenValidationOptions.TimeValidationSlack = 10s;
// create client
- std::unique_ptr attestationClient(AttestationClientFactory::Create(
- GetEnvHelper::GetEnv("ATTESTATION_AAD_URL"), clientOptions));
+ AttestationClient attestationClient(
+ AttestationClient::Create(GetEnvHelper::GetEnv("ATTESTATION_AAD_URL"), clientOptions));
- attestationClient->GetOpenIdMetadata();
+ attestationClient.GetOpenIdMetadata();
}
catch (Azure::Core::Credentials::AuthenticationException const& e)
{
diff --git a/sdk/attestation/azure-security-attestation/samples/basic-operations/get_open-id_metadata.cpp b/sdk/attestation/azure-security-attestation/samples/basic-operations/get_open-id_metadata.cpp
index a35da27c2c1..02fa98dc22c 100644
--- a/sdk/attestation/azure-security-attestation/samples/basic-operations/get_open-id_metadata.cpp
+++ b/sdk/attestation/azure-security-attestation/samples/basic-operations/get_open-id_metadata.cpp
@@ -32,11 +32,11 @@ int main()
try
{
// create client
- std::unique_ptr attestationClient(
- AttestationClientFactory::Create(GetEnvHelper::GetEnv("ATTESTATION_AAD_URL")));
+ AttestationClient const attestationClient(
+ AttestationClient::Create(GetEnvHelper::GetEnv("ATTESTATION_AAD_URL")));
// Retrieve the OpenId metadata from this attestation service instance.
- Azure::Response const openIdMetadata = attestationClient->GetOpenIdMetadata();
+ Azure::Response const openIdMetadata = attestationClient.GetOpenIdMetadata();
std::cout << "Attestation Certificate Endpoint is: " << *openIdMetadata.Value.JsonWebKeySetUrl
<< std::endl;
}
diff --git a/sdk/attestation/azure-security-attestation/samples/basic-operations/get_signing_certificates.cpp b/sdk/attestation/azure-security-attestation/samples/basic-operations/get_signing_certificates.cpp
index dc7cede0311..1c1dec1ef04 100644
--- a/sdk/attestation/azure-security-attestation/samples/basic-operations/get_signing_certificates.cpp
+++ b/sdk/attestation/azure-security-attestation/samples/basic-operations/get_signing_certificates.cpp
@@ -32,12 +32,12 @@ int main()
try
{
// create client
- std::unique_ptr attestationClient(
- AttestationClientFactory::Create(GetEnvHelper::GetEnv("ATTESTATION_AAD_URL")));
+ AttestationClient const attestationClient(
+ AttestationClient::Create(GetEnvHelper::GetEnv("ATTESTATION_AAD_URL")));
// Retrieve the OpenId metadata from this attestation service instance.
Azure::Response const signingCertificates
- = attestationClient->GetTokenValidationCertificates();
+ = attestationClient.GetTokenValidationCertificates();
std::cout << "There are " << signingCertificates.Value.Signers.size() << "signing certificates."
<< std::endl;
diff --git a/sdk/attestation/azure-security-attestation/samples/policy-certificates/add_policy_certificate.cpp b/sdk/attestation/azure-security-attestation/samples/policy-certificates/add_policy_certificate.cpp
index eca470f7884..2103a441a56 100644
--- a/sdk/attestation/azure-security-attestation/samples/policy-certificates/add_policy_certificate.cpp
+++ b/sdk/attestation/azure-security-attestation/samples/policy-certificates/add_policy_certificate.cpp
@@ -50,9 +50,8 @@ int main()
GetEnvHelper::GetEnv("AZURE_TENANT_ID"),
GetEnvHelper::GetEnv("AZURE_CLIENT_ID"),
GetEnvHelper::GetEnv("AZURE_CLIENT_SECRET"));
- std::shared_ptr adminClient(
- AttestationAdministrationClientFactory::Create(
- GetEnvHelper::GetEnv("ATTESTATION_ISOLATED_URL"), credential));
+ AttestationAdministrationClient adminClient(AttestationAdministrationClient::Create(
+ GetEnvHelper::GetEnv("ATTESTATION_ISOLATED_URL"), credential));
std::string const signingKey(GetEnvHelper::GetEnv("ISOLATED_SIGNING_KEY"));
std::string const signingCert(GetEnvHelper::GetEnv("ISOLATED_SIGNING_CERTIFICATE"));
@@ -76,7 +75,7 @@ int main()
// Add the new certificate to the set of policy management certificates for this attestation
// service instance.
Azure::Response> const addResult
- = adminClient->AddIsolatedModeCertificate(pemCertificateToAdd, requestSigner);
+ = adminClient.AddIsolatedModeCertificate(pemCertificateToAdd, requestSigner);
std::cout << "The result of the certificate add operation is: "
<< addResult.Value.Body.CertificateModification.ToString() << std::endl;
@@ -115,7 +114,7 @@ int main()
// Add the new certificate to the set of policy management certificates for this attestation
// service instance.
Azure::Response> const addResult
- = adminClient->RemoveIsolatedModeCertificate(pemCertificateToRemove, requestSigner);
+ = adminClient.RemoveIsolatedModeCertificate(pemCertificateToRemove, requestSigner);
std::cout << "The result of the certificate remove operation is: "
<< addResult.Value.Body.CertificateModification.ToString() << std::endl;
diff --git a/sdk/attestation/azure-security-attestation/samples/policy-certificates/get_policy_certificates.cpp b/sdk/attestation/azure-security-attestation/samples/policy-certificates/get_policy_certificates.cpp
index 7bb0511888b..a5cbcd5cf43 100644
--- a/sdk/attestation/azure-security-attestation/samples/policy-certificates/get_policy_certificates.cpp
+++ b/sdk/attestation/azure-security-attestation/samples/policy-certificates/get_policy_certificates.cpp
@@ -45,13 +45,12 @@ int main()
// create an administration client
auto const credential = std::make_shared(
GetEnv("AZURE_TENANT_ID"), GetEnv("AZURE_CLIENT_ID"), GetEnv("AZURE_CLIENT_SECRET"));
- std::unique_ptr adminClient(
- AttestationAdministrationClientFactory::Create(
- GetEnv("ATTESTATION_ISOLATED_URL"), credential));
+ AttestationAdministrationClient adminClient(
+ AttestationAdministrationClient::Create(GetEnv("ATTESTATION_ISOLATED_URL"), credential));
// Retrieve the SGX Attestation Policy from this attestation service instance.
Azure::Response> const policyCertificates
- = adminClient->GetIsolatedModeCertificates();
+ = adminClient.GetIsolatedModeCertificates();
std::cout << "There are " << policyCertificates.Value.Body.Certificates.size()
<< " certificates configured on this instance." << std::endl;
diff --git a/sdk/attestation/azure-security-attestation/samples/policy/get_policy.cpp b/sdk/attestation/azure-security-attestation/samples/policy/get_policy.cpp
index 8d7691d0969..c469e4ada6b 100644
--- a/sdk/attestation/azure-security-attestation/samples/policy/get_policy.cpp
+++ b/sdk/attestation/azure-security-attestation/samples/policy/get_policy.cpp
@@ -40,13 +40,13 @@ int main()
GetEnvHelper::GetEnv("AZURE_TENANT_ID"),
GetEnvHelper::GetEnv("AZURE_CLIENT_ID"),
GetEnvHelper::GetEnv("AZURE_CLIENT_SECRET"));
- std::unique_ptr adminClient(
- AttestationAdministrationClientFactory::Create(
- GetEnvHelper::GetEnv("ATTESTATION_AAD_URL"), credential));
+
+ AttestationAdministrationClient adminClient(AttestationAdministrationClient::Create(
+ GetEnvHelper::GetEnv("ATTESTATION_AAD_URL"), credential));
// Retrieve the SGX Attestation Policy from this attestation service instance.
Azure::Response> const sgxPolicy
- = adminClient->GetAttestationPolicy(AttestationType::SgxEnclave);
+ = adminClient.GetAttestationPolicy(AttestationType::SgxEnclave);
std::cout << "SGX Attestation Policy is: " << sgxPolicy.Value.Body << std::endl;
}
catch (Azure::Core::Credentials::AuthenticationException const& e)
diff --git a/sdk/attestation/azure-security-attestation/samples/policy/reset_policy.cpp b/sdk/attestation/azure-security-attestation/samples/policy/reset_policy.cpp
index 88ae7bcbe9f..77403e3a418 100644
--- a/sdk/attestation/azure-security-attestation/samples/policy/reset_policy.cpp
+++ b/sdk/attestation/azure-security-attestation/samples/policy/reset_policy.cpp
@@ -59,11 +59,11 @@ int main()
GetEnvHelper::GetEnv("AZURE_TENANT_ID"),
GetEnvHelper::GetEnv("AZURE_CLIENT_ID"),
GetEnvHelper::GetEnv("AZURE_CLIENT_SECRET"));
- std::unique_ptr adminClient(
- AttestationAdministrationClientFactory::Create(endpoint, credential, clientOptions));
+ AttestationAdministrationClient const adminClient(
+ AttestationAdministrationClient::Create(endpoint, credential, clientOptions));
Azure::Response> const resetResult
- = adminClient->ResetAttestationPolicy(AttestationType::SgxEnclave);
+ = adminClient.ResetAttestationPolicy(AttestationType::SgxEnclave);
if (resetResult.Value.Body.PolicyResolution == PolicyModification::Removed)
{
diff --git a/sdk/attestation/azure-security-attestation/samples/policy/reset_sealed_policy.cpp b/sdk/attestation/azure-security-attestation/samples/policy/reset_sealed_policy.cpp
index 1cbcdb3d706..4ebdd8c80e6 100644
--- a/sdk/attestation/azure-security-attestation/samples/policy/reset_sealed_policy.cpp
+++ b/sdk/attestation/azure-security-attestation/samples/policy/reset_sealed_policy.cpp
@@ -60,8 +60,8 @@ int main()
GetEnvHelper::GetEnv("AZURE_TENANT_ID"),
GetEnvHelper::GetEnv("AZURE_CLIENT_ID"),
GetEnvHelper::GetEnv("AZURE_CLIENT_SECRET"));
- std::shared_ptr adminClient(
- AttestationAdministrationClientFactory::Create(endpoint, credential, clientOptions));
+ AttestationAdministrationClient const adminClient(
+ AttestationAdministrationClient::Create(endpoint, credential, clientOptions));
std::string const signingKey(GetEnvHelper::GetEnv("ISOLATED_SIGNING_KEY"));
std::string const signingCert(GetEnvHelper::GetEnv("ISOLATED_SIGNING_CERTIFICATE"));
@@ -76,7 +76,7 @@ int main()
resetOptions.SigningKey = AttestationSigningKey{pemSigningKey, pemSigningCert};
Azure::Response> const resetResult
- = adminClient->ResetAttestationPolicy(AttestationType::SgxEnclave, resetOptions);
+ = adminClient.ResetAttestationPolicy(AttestationType::SgxEnclave, resetOptions);
if (resetResult.Value.Body.PolicyResolution == PolicyModification::Updated)
{
diff --git a/sdk/attestation/azure-security-attestation/samples/policy/set_policy.cpp b/sdk/attestation/azure-security-attestation/samples/policy/set_policy.cpp
index ff382f38670..063ab26a793 100644
--- a/sdk/attestation/azure-security-attestation/samples/policy/set_policy.cpp
+++ b/sdk/attestation/azure-security-attestation/samples/policy/set_policy.cpp
@@ -58,8 +58,8 @@ int main()
GetEnvHelper::GetEnv("AZURE_TENANT_ID"),
GetEnvHelper::GetEnv("AZURE_CLIENT_ID"),
GetEnvHelper::GetEnv("AZURE_CLIENT_SECRET"));
- std::unique_ptr adminClient(
- AttestationAdministrationClientFactory::Create(endpoint, credential, clientOptions));
+ AttestationAdministrationClient const adminClient(
+ AttestationAdministrationClient::Create(endpoint, credential, clientOptions));
// Set the attestation policy on this attestation instance.
// Note that because this is an AAD mode instance, the caller does not need to sign the policy
@@ -73,7 +73,7 @@ authorizationrules
[ type=="x-ms-sgx-mrsigner", value=="mrsigner2"] => permit();
};)");
Azure::Response> const setResult
- = adminClient->SetAttestationPolicy(AttestationType::SgxEnclave, policyToSet);
+ = adminClient.SetAttestationPolicy(AttestationType::SgxEnclave, policyToSet);
if (setResult.Value.Body.PolicyResolution == PolicyModification::Updated)
{
@@ -89,7 +89,7 @@ authorizationrules
// by the attestation service, the customer can call CreateAttestationPolicyToken and then
// generate the SHA256 of that token and compare it with the value returned by the service - the
// two hash values should be identical.
- auto const setPolicyToken = adminClient->CreateAttestationPolicyToken(policyToSet);
+ auto const setPolicyToken = adminClient.CreateAttestationPolicyToken(policyToSet);
Sha256Hash shaHasher;
std::vector policyTokenHash = shaHasher.Final(
reinterpret_cast(setPolicyToken.RawToken.data()),
diff --git a/sdk/attestation/azure-security-attestation/samples/policy/set_sealed_policy.cpp b/sdk/attestation/azure-security-attestation/samples/policy/set_sealed_policy.cpp
index d9566f9eaa4..b65f24ef72d 100644
--- a/sdk/attestation/azure-security-attestation/samples/policy/set_sealed_policy.cpp
+++ b/sdk/attestation/azure-security-attestation/samples/policy/set_sealed_policy.cpp
@@ -62,8 +62,8 @@ int main()
GetEnvHelper::GetEnv("AZURE_TENANT_ID"),
GetEnvHelper::GetEnv("AZURE_CLIENT_ID"),
GetEnvHelper::GetEnv("AZURE_CLIENT_SECRET"));
- std::shared_ptr adminClient(
- AttestationAdministrationClientFactory::Create(endpoint, credential, clientOptions));
+ AttestationAdministrationClient const adminClient(
+ AttestationAdministrationClient::Create(endpoint, credential, clientOptions));
std::string const signingKey(GetEnvHelper::GetEnv("ISOLATED_SIGNING_KEY"));
std::string const signingCert(GetEnvHelper::GetEnv("ISOLATED_SIGNING_CERTIFICATE"));
@@ -87,7 +87,7 @@ authorizationrules
setOptions.SigningKey = AttestationSigningKey{pemSigningKey, pemSigningCert};
Azure::Response> const setResult
- = adminClient->SetAttestationPolicy(AttestationType::SgxEnclave, policyToSet, setOptions);
+ = adminClient.SetAttestationPolicy(AttestationType::SgxEnclave, policyToSet, setOptions);
if (setResult.Value.Body.PolicyResolution == PolicyModification::Updated)
{
@@ -104,7 +104,7 @@ authorizationrules
// generate the SHA256 of that token and compare it with the value returned by the service - the
// two hash values should be identical.
auto const setPolicyToken
- = adminClient->CreateAttestationPolicyToken(policyToSet, setOptions.SigningKey);
+ = adminClient.CreateAttestationPolicyToken(policyToSet, setOptions.SigningKey);
Sha256Hash shaHasher;
std::vector const policyTokenHash = shaHasher.Final(
reinterpret_cast(setPolicyToken.RawToken.data()),
diff --git a/sdk/attestation/azure-security-attestation/src/attestation_administration_client.cpp b/sdk/attestation/azure-security-attestation/src/attestation_administration_client.cpp
index 6ccf4c5a63d..a600b27a3e6 100644
--- a/sdk/attestation/azure-security-attestation/src/attestation_administration_client.cpp
+++ b/sdk/attestation/azure-security-attestation/src/attestation_administration_client.cpp
@@ -21,6 +21,7 @@ using namespace Azure::Security::Attestation;
using namespace Azure::Security::Attestation::Models;
using namespace Azure::Security::Attestation::_detail;
using namespace Azure::Security::Attestation::Models::_detail;
+using namespace Azure::Core::Tracing::_internal;
using namespace Azure::Core::Http;
using namespace Azure::Core::Http::Policies;
using namespace Azure::Core::Http::Policies::_internal;
@@ -41,39 +42,33 @@ AttestationAdministrationClient::AttestationAdministrationClient(
std::string const& endpoint,
std::shared_ptr credential,
AttestationAdministrationClientOptions const& options)
- : m_endpoint(endpoint), m_apiVersion(options.Version.ToString()),
- m_tokenValidationOptions(options.TokenValidationOptions)
+ : m_endpoint(endpoint), m_apiVersion(options.ApiVersion),
+ m_tokenValidationOptions(options.TokenValidationOptions),
+ m_tracingFactory(options, "security.attestation", PackageVersion::ToString())
{
std::vector> perRetrypolicies;
if (credential)
{
- m_credentials = credential;
Azure::Core::Credentials::TokenRequestContext const tokenContext
= {{"https://attest.azure.net/.default"}};
perRetrypolicies.emplace_back(
std::make_unique(credential, tokenContext));
}
- m_apiVersion = options.Version.ToString();
std::vector> perCallpolicies;
m_pipeline = std::make_shared(
- options,
- "Attestation",
- PackageVersion::ToString(),
- std::move(perRetrypolicies),
- std::move(perCallpolicies));
+ options, std::move(perRetrypolicies), std::move(perCallpolicies));
}
-std::unique_ptr AttestationAdministrationClientFactory::Create(
+AttestationAdministrationClient AttestationAdministrationClient::Create(
std::string const& endpoint,
std::shared_ptr credential,
AttestationAdministrationClientOptions const& options,
Azure::Core::Context const& context)
{
- std::unique_ptr returnValue(
- new AttestationAdministrationClient(endpoint, credential, options));
- returnValue->RetrieveResponseValidationCollateral(context);
+ AttestationAdministrationClient returnValue(endpoint, credential, options);
+ returnValue.RetrieveResponseValidationCollateral(context);
return returnValue;
}
@@ -87,53 +82,64 @@ AttestationAdministrationClient::GetAttestationPolicy(
GetPolicyOptions const& options,
Azure::Core::Context const& context) const
{
- auto request = AttestationCommonRequest::CreateRequest(
- m_endpoint,
- m_apiVersion,
- HttpMethod::Get,
- {"policies/" + attestationType.ToString()},
- nullptr);
-
- // Send the request to the service.
- auto response = AttestationCommonRequest::SendRequest(*m_pipeline, request, context);
+ auto tracingContext(m_tracingFactory.CreateTracingContext("GetAttestationPolicy", context));
+ try
+ {
- // Deserialize the Service response token and return the JSON web token returned by the
- // service.
- std::string responseToken = AttestationServiceTokenResponseSerializer::Deserialize(response);
+ auto request = AttestationCommonRequest::CreateRequest(
+ m_endpoint,
+ m_apiVersion,
+ HttpMethod::Get,
+ {"policies/" + attestationType.ToString()},
+ nullptr);
- // Parse the JWT returned by the attestation service.
- const auto resultToken
- = AttestationTokenInternal(
- responseToken);
+ // Send the request to the service.
+ auto response = AttestationCommonRequest::SendRequest(*m_pipeline, request, context);
- // Validate the token returned by the service. Use the cached attestation signers in the
- // validation.
- resultToken.ValidateToken(
- options.TokenValidationOptionsOverride ? *options.TokenValidationOptionsOverride
- : this->m_tokenValidationOptions,
- m_attestationSigners);
+ // Deserialize the Service response token and return the JSON web token returned by the
+ // service.
+ std::string responseToken = AttestationServiceTokenResponseSerializer::Deserialize(response);
+
+ // Parse the JWT returned by the attestation service.
+ const auto resultToken
+ = AttestationTokenInternal(
+ responseToken);
+
+ // Validate the token returned by the service. Use the cached attestation signers in the
+ // validation.
+ resultToken.ValidateToken(
+ options.TokenValidationOptionsOverride ? *options.TokenValidationOptionsOverride
+ : this->m_tokenValidationOptions,
+ m_attestationSigners);
+
+ // Extract the underlying policy token from the response.
+ std::string policyTokenValue
+ = *static_cast>(resultToken)
+ .Body.PolicyToken;
+
+ // TPM policies are empty by default, at least in our test instances, so handle the empty policy
+ // token case.
+ const auto policyTokenI
+ = AttestationTokenInternal(
+ policyTokenValue);
+ AttestationToken policyToken(policyTokenI);
+ std::string returnPolicy;
+ if (policyToken.Body.AttestationPolicy)
+ {
+ std::vector policyUtf8 = *policyToken.Body.AttestationPolicy;
+ returnPolicy = std::string(policyUtf8.begin(), policyUtf8.end());
+ }
- // Extract the underlying policy token from the response.
- std::string policyTokenValue
- = *static_cast>(resultToken).Body.PolicyToken;
-
- // TPM policies are empty by default, at least in our test instances, so handle the empty policy
- // token case.
- const auto policyTokenI
- = AttestationTokenInternal(
- policyTokenValue);
- AttestationToken policyToken(policyTokenI);
- std::string returnPolicy;
- if (policyToken.Body.AttestationPolicy)
+ // Construct a token whose body is the policy, but whose token is the response from the
+ // service.
+ const auto returnedToken = AttestationTokenInternal(responseToken, &returnPolicy);
+ return Response>(returnedToken, std::move(response));
+ }
+ catch (std::runtime_error const& ex)
{
- std::vector policyUtf8 = *policyToken.Body.AttestationPolicy;
- returnPolicy = std::string(policyUtf8.begin(), policyUtf8.end());
+ tracingContext.Span.AddEvent(ex);
+ throw;
}
-
- // Construct a token whose body is the policy, but whose token is the response from the
- // service.
- const auto returnedToken = AttestationTokenInternal(responseToken, &returnPolicy);
- return Response>(returnedToken, std::move(response));
}
Models::AttestationToken AttestationAdministrationClient::CreateAttestationPolicyToken(
@@ -164,62 +170,72 @@ AttestationAdministrationClient::SetAttestationPolicy(
SetPolicyOptions const& options,
Azure::Core::Context const& context) const
{
- // Calculate a signed (or unsigned) attestation policy token to send to the service.
- Models::AttestationToken const tokenToSend(
- CreateAttestationPolicyToken(newAttestationPolicy, options.SigningKey));
+ auto tracingContext(m_tracingFactory.CreateTracingContext("SetAttestationPolicy", context));
+ try
+ {
+ // Calculate a signed (or unsigned) attestation policy token to send to the service.
+ Models::AttestationToken const tokenToSend(
+ CreateAttestationPolicyToken(newAttestationPolicy, options.SigningKey));
- Azure::Core::IO::MemoryBodyStream stream(
- reinterpret_cast(tokenToSend.RawToken.data()), tokenToSend.RawToken.size());
+ Azure::Core::IO::MemoryBodyStream stream(
+ reinterpret_cast(tokenToSend.RawToken.data()), tokenToSend.RawToken.size());
- auto request = AttestationCommonRequest::CreateRequest(
- m_endpoint,
- m_apiVersion,
- HttpMethod::Put,
- {"policies/" + attestationType.ToString()},
- &stream);
+ auto request = AttestationCommonRequest::CreateRequest(
+ m_endpoint,
+ m_apiVersion,
+ HttpMethod::Put,
+ {"policies/" + attestationType.ToString()},
+ &stream);
- // Send the request to the service.
- auto response = AttestationCommonRequest::SendRequest(*m_pipeline, request, context);
+ // Send the request to the service.
+ auto response = AttestationCommonRequest::SendRequest(*m_pipeline, request, context);
- // Deserialize the Service response token and return the JSON web token returned by the
- // service.
- std::string responseToken = AttestationServiceTokenResponseSerializer::Deserialize(response);
+ // Deserialize the Service response token and return the JSON web token returned by the
+ // service.
+ std::string responseToken = AttestationServiceTokenResponseSerializer::Deserialize(response);
- // Parse the JWT returned by the attestation service.
- auto resultToken
- = AttestationTokenInternal(
- responseToken);
+ // Parse the JWT returned by the attestation service.
+ auto resultToken
+ = AttestationTokenInternal(
+ responseToken);
- // Validate the token returned by the service. Use the cached attestation signers in the
- // validation.
- resultToken.ValidateToken(
- options.TokenValidationOptionsOverride ? *options.TokenValidationOptionsOverride
- : this->m_tokenValidationOptions,
- m_attestationSigners);
+ // Validate the token returned by the service. Use the cached attestation signers in the
+ // validation.
+ resultToken.ValidateToken(
+ options.TokenValidationOptionsOverride ? *options.TokenValidationOptionsOverride
+ : this->m_tokenValidationOptions,
+ m_attestationSigners);
- // Extract the underlying policy token from the response.
- auto internalResult
- = static_cast>(resultToken).Body;
+ // Extract the underlying policy token from the response.
+ auto internalResult
+ = static_cast>(resultToken).Body;
- Models::PolicyResult returnedResult;
- if (internalResult.PolicyResolution)
- {
- returnedResult.PolicyResolution = Models::PolicyModification(*internalResult.PolicyResolution);
- }
- if (internalResult.PolicySigner)
- {
- returnedResult.PolicySigner = AttestationSignerInternal(*internalResult.PolicySigner);
+ Models::PolicyResult returnedResult;
+ if (internalResult.PolicyResolution)
+ {
+ returnedResult.PolicyResolution
+ = Models::PolicyModification(*internalResult.PolicyResolution);
+ }
+ if (internalResult.PolicySigner)
+ {
+ returnedResult.PolicySigner = AttestationSignerInternal(*internalResult.PolicySigner);
+ }
+ if (internalResult.PolicyTokenHash)
+ {
+ returnedResult.PolicyTokenHash = Base64Url::Base64UrlDecode(*internalResult.PolicyTokenHash);
+ }
+
+ // Construct a token whose body is the policy result, but whose token is the response from
+ // the service.
+ auto returnedToken
+ = AttestationTokenInternal(responseToken, &returnedResult);
+ return Response>(returnedToken, std::move(response));
}
- if (internalResult.PolicyTokenHash)
+ catch (std::runtime_error const& ex)
{
- returnedResult.PolicyTokenHash = Base64Url::Base64UrlDecode(*internalResult.PolicyTokenHash);
+ tracingContext.Span.AddEvent(ex);
+ throw;
}
-
- // Construct a token whose body is the policy result, but whose token is the response from the
- // service.
- auto returnedToken
- = AttestationTokenInternal(responseToken, &returnedResult);
- return Response>(returnedToken, std::move(response));
}
Azure::Response>
@@ -228,67 +244,78 @@ AttestationAdministrationClient::ResetAttestationPolicy(
SetPolicyOptions const& options,
Azure::Core::Context const& context) const
{
- // Calculate a signed (or unsigned) attestation policy token to send to the service.
- Models::AttestationToken tokenToSend(
- CreateAttestationPolicyToken(Azure::Nullable(), options.SigningKey));
+ auto tracingContext(m_tracingFactory.CreateTracingContext("ResetAttestationPolicy", context));
+ try
+ {
+ // Calculate a signed (or unsigned) attestation policy token to send to the service.
+ Models::AttestationToken tokenToSend(
+ CreateAttestationPolicyToken(Azure::Nullable(), options.SigningKey));
- Azure::Core::IO::MemoryBodyStream stream(
- reinterpret_cast(tokenToSend.RawToken.data()), tokenToSend.RawToken.size());
+ Azure::Core::IO::MemoryBodyStream stream(
+ reinterpret_cast(tokenToSend.RawToken.data()), tokenToSend.RawToken.size());
- auto request = AttestationCommonRequest::CreateRequest(
- m_endpoint,
- m_apiVersion,
- HttpMethod::Post,
- {"policies/" + attestationType.ToString() + ":reset"},
- &stream);
+ auto request = AttestationCommonRequest::CreateRequest(
+ m_endpoint,
+ m_apiVersion,
+ HttpMethod::Post,
+ {"policies/" + attestationType.ToString() + ":reset"},
+ &stream);
- // Send the request to the service.
- auto response = AttestationCommonRequest::SendRequest(*m_pipeline, request, context);
+ // Send the request to the service.
+ auto response = AttestationCommonRequest::SendRequest(*m_pipeline, request, context);
- // Deserialize the Service response token and return the JSON web token returned by the
- // service.
- std::string responseToken = AttestationServiceTokenResponseSerializer::Deserialize(response);
+ // Deserialize the Service response token and return the JSON web token returned by the
+ // service.
+ std::string responseToken = AttestationServiceTokenResponseSerializer::Deserialize(response);
- // Parse the JWT returned by the attestation service.
- auto resultToken
- = AttestationTokenInternal(
- responseToken);
+ // Parse the JWT returned by the attestation service.
+ auto resultToken
+ = AttestationTokenInternal(
+ responseToken);
- // Validate the token returned by the service. Use the cached attestation signers in the
- // validation.
- resultToken.ValidateToken(
- options.TokenValidationOptionsOverride ? *options.TokenValidationOptionsOverride
- : this->m_tokenValidationOptions,
- m_attestationSigners);
+ // Validate the token returned by the service. Use the cached attestation signers in the
+ // validation.
+ resultToken.ValidateToken(
+ options.TokenValidationOptionsOverride ? *options.TokenValidationOptionsOverride
+ : this->m_tokenValidationOptions,
+ m_attestationSigners);
- // Extract the underlying policy token from the response.
- auto internalResult
- = static_cast>(resultToken).Body;
+ // Extract the underlying policy token from the response.
+ auto internalResult
+ = static_cast>(resultToken).Body;
- Models::PolicyResult returnedResult;
- if (internalResult.PolicyResolution)
+ Models::PolicyResult returnedResult;
+ if (internalResult.PolicyResolution)
+ {
+ returnedResult.PolicyResolution
+ = Models::PolicyModification(*internalResult.PolicyResolution);
+ }
+ // Note that the attestation service currently never returns these values on Reset, even
+ // though they are meaningful. Commenting them out to improve code coverage numbers. At
+ // some point the attestation service may start returning these values, at which point
+ // they can be un-commented out.
+ // if (internalResult.PolicySigner)
+ // {
+ // returnedResult.PolicySigner =
+ // AttestationSignerInternal(*internalResult.PolicySigner);
+ // }
+ // if (internalResult.PolicyTokenHash)
+ // {
+ // returnedResult.PolicyTokenHash =
+ // Base64Url::Base64UrlDecode(*internalResult.PolicyTokenHash);
+ // }
+
+ // Construct a token whose body is the policy result, but whose token is the response from
+ // the service.
+ auto returnedToken
+ = AttestationTokenInternal(responseToken, &returnedResult);
+ return Response>(returnedToken, std::move(response));
+ }
+ catch (std::runtime_error const& ex)
{
- returnedResult.PolicyResolution = Models::PolicyModification(*internalResult.PolicyResolution);
+ tracingContext.Span.AddEvent(ex);
+ throw;
}
- // Note that the attestation service currently never returns these values on Reset, even though
- // they are meaningful. Commenting them out to improve code coverage numbers. At some point the
- // attestation service may start returning these values, at which point they can be un-commented
- // out.
- // if (internalResult.PolicySigner)
- // {
- // returnedResult.PolicySigner = AttestationSignerInternal(*internalResult.PolicySigner);
- // }
- // if (internalResult.PolicyTokenHash)
- // {
- // returnedResult.PolicyTokenHash =
- // Base64Url::Base64UrlDecode(*internalResult.PolicyTokenHash);
- // }
-
- // Construct a token whose body is the policy result, but whose token is the response from the
- // service.
- auto returnedToken
- = AttestationTokenInternal(responseToken, &returnedResult);
- return Response>(returnedToken, std::move(response));
}
Azure::Response>
@@ -296,44 +323,54 @@ AttestationAdministrationClient::GetIsolatedModeCertificates(
GetIsolatedModeCertificatesOptions const& options,
Azure::Core::Context const& context) const
{
- auto request = AttestationCommonRequest::CreateRequest(
- m_endpoint, m_apiVersion, HttpMethod::Get, {"certificates"}, nullptr);
-
- // Send the request to the service.
- auto response = AttestationCommonRequest::SendRequest(*m_pipeline, request, context);
+ auto tracingContext(
+ m_tracingFactory.CreateTracingContext("GetIsolatedModeCertificates", context));
+ try
+ {
+ auto request = AttestationCommonRequest::CreateRequest(
+ m_endpoint, m_apiVersion, HttpMethod::Get, {"certificates"}, nullptr);
- // Deserialize the Service response token and return the JSON web token returned by the
- // service.
- std::string responseToken = AttestationServiceTokenResponseSerializer::Deserialize(response);
+ // Send the request to the service.
+ auto response = AttestationCommonRequest::SendRequest(*m_pipeline, request, context);
- // Parse the JWT returned by the attestation service.
- auto resultToken = AttestationTokenInternal<
- Models::_detail::GetIsolatedModeCertificatesResult,
- IsolatedModeCertificateGetResultSerializer>(responseToken);
+ // Deserialize the Service response token and return the JSON web token returned by the
+ // service.
+ std::string responseToken = AttestationServiceTokenResponseSerializer::Deserialize(response);
+
+ // Parse the JWT returned by the attestation service.
+ auto resultToken = AttestationTokenInternal<
+ Models::_detail::GetIsolatedModeCertificatesResult,
+ IsolatedModeCertificateGetResultSerializer>(responseToken);
+
+ // Validate the token returned by the service. Use the cached attestation signers in the
+ // validation.
+ resultToken.ValidateToken(
+ options.TokenValidationOptionsOverride ? *options.TokenValidationOptionsOverride
+ : this->m_tokenValidationOptions,
+ m_attestationSigners);
+
+ Models::_detail::JsonWebKeySet jwks(
+ *static_cast>(
+ resultToken)
+ .Body.PolicyCertificates);
+ Models::IsolatedModeCertificateListResult returnedResult;
+ for (const auto& certificate : jwks.Keys)
+ {
+ returnedResult.Certificates.push_back(AttestationSignerInternal(certificate));
+ }
- // Validate the token returned by the service. Use the cached attestation signers in the
- // validation.
- resultToken.ValidateToken(
- options.TokenValidationOptionsOverride ? *options.TokenValidationOptionsOverride
- : this->m_tokenValidationOptions,
- m_attestationSigners);
-
- Models::_detail::JsonWebKeySet jwks(
- *static_cast>(
- resultToken)
- .Body.PolicyCertificates);
- Models::IsolatedModeCertificateListResult returnedResult;
- for (const auto& certificate : jwks.Keys)
+ // Construct a token whose body is the get policy certificates result, but whose token
+ // is the response from the service.
+ auto returnedToken = AttestationTokenInternal(
+ responseToken, &returnedResult);
+ return Response>(
+ returnedToken, std::move(response));
+ }
+ catch (std::runtime_error const& ex)
{
- returnedResult.Certificates.push_back(AttestationSignerInternal(certificate));
+ tracingContext.Span.AddEvent(ex);
+ throw;
}
-
- // Construct a token whose body is the get policy certificates result, but whose token is the
- // response from the service.
- auto returnedToken = AttestationTokenInternal(
- responseToken, &returnedResult);
- return Response>(
- returnedToken, std::move(response));
}
std::string AttestationAdministrationClient::CreateIsolatedModeModificationToken(
@@ -398,8 +435,8 @@ AttestationAdministrationClient::ProcessIsolatedModeModificationResult(
returnValue.CertificateThumbprint = (*internalResult.CertificateThumbprint);
}
- // Construct a token whose body is the policy result, but whose token is the response from the
- // service.
+ // Construct a token whose body is the policy result, but whose token is the response
+ // from the service.
auto const returnedToken
= AttestationTokenInternal(
responseToken, &returnValue);
@@ -413,23 +450,32 @@ AttestationAdministrationClient::AddIsolatedModeCertificate(
AddIsolatedModeCertificateOptions const& options,
Azure::Core::Context const& context) const
{
- auto const policyCertToken(
- CreateIsolatedModeModificationToken(pemEncodedX509CertificateToAdd, existingSigningKey));
- Azure::Core::IO::MemoryBodyStream stream(
- reinterpret_cast(policyCertToken.data()), policyCertToken.size());
-
- auto request = AttestationCommonRequest::CreateRequest(
- m_endpoint, m_apiVersion, HttpMethod::Post, {"certificates:add"}, &stream);
-
- // Send the request to the service.
- auto response = AttestationCommonRequest::SendRequest(*m_pipeline, request, context);
- AttestationToken returnValue(
- ProcessIsolatedModeModificationResult(
- response,
- options.TokenValidationOptionsOverride ? *options.TokenValidationOptionsOverride
- : this->m_tokenValidationOptions));
- return Response>(
- returnValue, std::move(response));
+ auto tracingContext(m_tracingFactory.CreateTracingContext("AddIsolatedModeCertificate", context));
+ try
+ {
+ auto const policyCertToken(
+ CreateIsolatedModeModificationToken(pemEncodedX509CertificateToAdd, existingSigningKey));
+ Azure::Core::IO::MemoryBodyStream stream(
+ reinterpret_cast(policyCertToken.data()), policyCertToken.size());
+
+ auto request = AttestationCommonRequest::CreateRequest(
+ m_endpoint, m_apiVersion, HttpMethod::Post, {"certificates:add"}, &stream);
+
+ // Send the request to the service.
+ auto response = AttestationCommonRequest::SendRequest(*m_pipeline, request, context);
+ AttestationToken returnValue(
+ ProcessIsolatedModeModificationResult(
+ response,
+ options.TokenValidationOptionsOverride ? *options.TokenValidationOptionsOverride
+ : this->m_tokenValidationOptions));
+ return Response>(
+ returnValue, std::move(response));
+ }
+ catch (std::runtime_error const& ex)
+ {
+ tracingContext.Span.AddEvent(ex);
+ throw;
+ }
}
Azure::Response>
@@ -439,31 +485,41 @@ AttestationAdministrationClient::RemoveIsolatedModeCertificate(
RemoveIsolatedModeCertificateOptions const& options,
Azure::Core::Context const& context) const
{
- // Calculate a signed (or unsigned) attestation policy token to send to the service.
- // Embed the encoded policy in the StoredAttestationPolicy.
- auto const policyCertToken(
- CreateIsolatedModeModificationToken(pemEncodedX509CertificateToRemove, existingSigningKey));
-
- Azure::Core::IO::MemoryBodyStream stream(
- reinterpret_cast(policyCertToken.data()), policyCertToken.size());
-
- auto request = AttestationCommonRequest::CreateRequest(
- m_endpoint, m_apiVersion, HttpMethod::Post, {"certificates:remove"}, &stream);
-
- // Send the request to the service.
- auto response = AttestationCommonRequest::SendRequest(*m_pipeline, request, context);
- AttestationToken returnValue(
- ProcessIsolatedModeModificationResult(
- response,
- options.TokenValidationOptionsOverride ? *options.TokenValidationOptionsOverride
- : this->m_tokenValidationOptions));
- return Response>(
- returnValue, std::move(response));
+ auto tracingContext(
+ m_tracingFactory.CreateTracingContext("RemoveIsolatedModeCertificate", context));
+ try
+ {
+ // Calculate a signed (or unsigned) attestation policy token to send to the service.
+ // Embed the encoded policy in the StoredAttestationPolicy.
+ auto const policyCertToken(
+ CreateIsolatedModeModificationToken(pemEncodedX509CertificateToRemove, existingSigningKey));
+
+ Azure::Core::IO::MemoryBodyStream stream(
+ reinterpret_cast(policyCertToken.data()), policyCertToken.size());
+
+ auto request = AttestationCommonRequest::CreateRequest(
+ m_endpoint, m_apiVersion, HttpMethod::Post, {"certificates:remove"}, &stream);
+
+ // Send the request to the service.
+ auto response = AttestationCommonRequest::SendRequest(*m_pipeline, request, context);
+ AttestationToken returnValue(
+ ProcessIsolatedModeModificationResult(
+ response,
+ options.TokenValidationOptionsOverride ? *options.TokenValidationOptionsOverride
+ : this->m_tokenValidationOptions));
+ return Response>(
+ returnValue, std::move(response));
+ }
+ catch (std::runtime_error const& ex)
+ {
+ tracingContext.Span.AddEvent(ex);
+ throw;
+ }
}
/**
- * @brief Retrieves the information needed to validate the response returned from the attestation
- * service.
+ * @brief Retrieves the information needed to validate the response returned from the
+ * attestation service.
*
* @details Validating the response returned by the attestation service requires a set of
* possible signers for the attestation token.
@@ -473,26 +529,35 @@ AttestationAdministrationClient::RemoveIsolatedModeCertificate(
void AttestationAdministrationClient::RetrieveResponseValidationCollateral(
Azure::Core::Context const& context)
{
- std::unique_lock stateLock(SharedStateLock);
-
- if (m_attestationSigners.empty())
+ auto tracingContext(m_tracingFactory.CreateTracingContext("Create", context));
+ try
{
- stateLock.unlock();
- auto request
- = AttestationCommonRequest::CreateRequest(m_endpoint, HttpMethod::Get, {"certs"}, nullptr);
- auto response = AttestationCommonRequest::SendRequest(*m_pipeline, request, context);
- auto jsonWebKeySet(JsonWebKeySetSerializer::Deserialize(response));
- TokenValidationCertificateResult returnValue;
- std::vector newValue;
- for (const auto& jwk : jsonWebKeySet.Keys)
- {
- AttestationSignerInternal internalSigner(jwk);
- newValue.push_back(internalSigner);
- }
- stateLock.lock();
+ std::unique_lock stateLock(SharedStateLock);
+
if (m_attestationSigners.empty())
{
- m_attestationSigners = newValue;
+ stateLock.unlock();
+ auto request = AttestationCommonRequest::CreateRequest(
+ m_endpoint, HttpMethod::Get, {"certs"}, nullptr);
+ auto response = AttestationCommonRequest::SendRequest(*m_pipeline, request, context);
+ auto jsonWebKeySet(JsonWebKeySetSerializer::Deserialize(response));
+ TokenValidationCertificateResult returnValue;
+ std::vector newValue;
+ for (const auto& jwk : jsonWebKeySet.Keys)
+ {
+ AttestationSignerInternal internalSigner(jwk);
+ newValue.push_back(internalSigner);
+ }
+ stateLock.lock();
+ if (m_attestationSigners.empty())
+ {
+ m_attestationSigners = newValue;
+ }
}
}
+ catch (std::runtime_error const& ex)
+ {
+ tracingContext.Span.AddEvent(ex);
+ throw;
+ }
}
diff --git a/sdk/attestation/azure-security-attestation/src/attestation_client.cpp b/sdk/attestation/azure-security-attestation/src/attestation_client.cpp
index 936954aa2d0..1e0077adc38 100644
--- a/sdk/attestation/azure-security-attestation/src/attestation_client.cpp
+++ b/sdk/attestation/azure-security-attestation/src/attestation_client.cpp
@@ -21,6 +21,7 @@ using namespace Azure::Security::Attestation;
using namespace Azure::Security::Attestation::Models;
using namespace Azure::Security::Attestation::_detail;
using namespace Azure::Security::Attestation::Models::_detail;
+using namespace Azure::Core::Tracing::_internal;
using namespace Azure::Core::Http;
using namespace Azure::Core::Http::Policies;
using namespace Azure::Core::Http::Policies::_internal;
@@ -30,56 +31,74 @@ AttestationClient::AttestationClient(
std::string const& endpoint,
std::shared_ptr credential,
AttestationClientOptions options)
- : m_endpoint(endpoint), m_credentials(credential),
- m_tokenValidationOptions(options.TokenValidationOptions)
+ : m_endpoint(endpoint), m_apiVersion(options.ApiVersion),
+ m_tokenValidationOptions(options.TokenValidationOptions),
+ m_tracingFactory(options, "security.attestation", PackageVersion::ToString())
{
std::vector> perRetrypolicies;
if (credential)
{
- m_credentials = credential;
Azure::Core::Credentials::TokenRequestContext const tokenContext
= {{"https://attest.azure.net/.default"}};
perRetrypolicies.emplace_back(
std::make_unique(credential, tokenContext));
}
- m_apiVersion = options.Version.ToString();
std::vector> perCallpolicies;
m_pipeline = std::make_shared(
- options,
- "Attestation",
- PackageVersion::ToString(),
- std::move(perRetrypolicies),
- std::move(perCallpolicies));
+ options, std::move(perRetrypolicies), std::move(perCallpolicies));
}
Azure::Response AttestationClient::GetOpenIdMetadata(
Azure::Core::Context const& context) const
{
- auto request = AttestationCommonRequest::CreateRequest(
- m_endpoint, HttpMethod::Get, {".well-known/openid-configuration"}, nullptr);
+ auto tracingContext(m_tracingFactory.CreateTracingContext("GetOpenIdMetadata", context));
+ try
+ {
+ auto request = AttestationCommonRequest::CreateRequest(
+ m_endpoint, HttpMethod::Get, {".well-known/openid-configuration"}, nullptr);
+
+ auto response
+ = AttestationCommonRequest::SendRequest(*m_pipeline, request, tracingContext.Context);
+ auto openIdMetadata(OpenIdMetadataSerializer::Deserialize(response));
- auto response = AttestationCommonRequest::SendRequest(*m_pipeline, request, context);
- auto openIdMetadata(OpenIdMetadataSerializer::Deserialize(response));
- return Response(std::move(openIdMetadata), std::move(response));
+ return Response(std::move(openIdMetadata), std::move(response));
+ }
+ catch (std::runtime_error const& ex)
+ {
+ tracingContext.Span.AddEvent(ex);
+ throw;
+ }
}
Azure::Response AttestationClient::GetTokenValidationCertificates(
Azure::Core::Context const& context) const
{
- auto request
- = AttestationCommonRequest::CreateRequest(m_endpoint, HttpMethod::Get, {"certs"}, nullptr);
+ auto tracingContext(
+ m_tracingFactory.CreateTracingContext("GetTokenValidationCertificates", context));
+ try
+ {
- auto response = AttestationCommonRequest::SendRequest(*m_pipeline, request, context);
- auto jsonWebKeySet(JsonWebKeySetSerializer::Deserialize(response));
- TokenValidationCertificateResult returnValue;
- for (const auto& jwk : jsonWebKeySet.Keys)
+ auto request
+ = AttestationCommonRequest::CreateRequest(m_endpoint, HttpMethod::Get, {"certs"}, nullptr);
+
+ auto response
+ = AttestationCommonRequest::SendRequest(*m_pipeline, request, tracingContext.Context);
+ auto jsonWebKeySet(JsonWebKeySetSerializer::Deserialize(response));
+ TokenValidationCertificateResult returnValue;
+ for (const auto& jwk : jsonWebKeySet.Keys)
+ {
+ AttestationSignerInternal internalSigner(jwk);
+ returnValue.Signers.push_back(internalSigner);
+ }
+ return Response(returnValue, std::move(response));
+ }
+ catch (std::runtime_error const& ex)
{
- AttestationSignerInternal internalSigner(jwk);
- returnValue.Signers.push_back(internalSigner);
+ tracingContext.Span.AddEvent(ex);
+ throw;
}
- return Response(returnValue, std::move(response));
}
Azure::Response> AttestationClient::AttestSgxEnclave(
@@ -87,41 +106,53 @@ Azure::Response> AttestationClient::AttestSg
AttestSgxEnclaveOptions options,
Azure::Core::Context const& context) const
{
- AttestSgxEnclaveRequest attestRequest{
- sgxQuote,
- options.InitTimeData,
- options.RunTimeData,
- options.DraftPolicyForAttestation,
- options.Nonce};
-
- const std::string serializedRequest(AttestSgxEnclaveRequestSerializer::Serialize(attestRequest));
-
- const auto encodedVector
- = std::vector(serializedRequest.begin(), serializedRequest.end());
- Azure::Core::IO::MemoryBodyStream stream(encodedVector);
- auto request = AttestationCommonRequest::CreateRequest(
- m_endpoint, m_apiVersion, HttpMethod::Post, {"attest/SgxEnclave"}, &stream);
-
- // Send the request to the service.
- auto response = AttestationCommonRequest::SendRequest(*m_pipeline, request, context);
-
- // Deserialize the Service response token and return the JSON web token returned by the service.
- std::string responseToken = AttestationServiceTokenResponseSerializer::Deserialize(response);
-
- // Parse the JWT returned by the attestation service.
- auto const token
- = AttestationTokenInternal(responseToken);
-
- // Validate the token returned by the service. Use the cached attestation signers in the
- // validation.
- token.ValidateToken(
- options.TokenValidationOptionsOverride ? *options.TokenValidationOptionsOverride
- : this->m_tokenValidationOptions,
- m_attestationSigners);
-
- // And return the attestation result to the caller.
- auto returnedToken = AttestationToken(token);
- return Response>(returnedToken, std::move(response));
+ auto tracingContext(m_tracingFactory.CreateTracingContext("AttestSgxEnclave", context));
+ try
+ {
+
+ AttestSgxEnclaveRequest attestRequest{
+ sgxQuote,
+ options.InitTimeData,
+ options.RunTimeData,
+ options.DraftPolicyForAttestation,
+ options.Nonce};
+
+ const std::string serializedRequest(
+ AttestSgxEnclaveRequestSerializer::Serialize(attestRequest));
+
+ const auto encodedVector
+ = std::vector(serializedRequest.begin(), serializedRequest.end());
+ Azure::Core::IO::MemoryBodyStream stream(encodedVector);
+ auto request = AttestationCommonRequest::CreateRequest(
+ m_endpoint, m_apiVersion, HttpMethod::Post, {"attest/SgxEnclave"}, &stream);
+
+ // Send the request to the service.
+ auto response
+ = AttestationCommonRequest::SendRequest(*m_pipeline, request, tracingContext.Context);
+
+ // Deserialize the Service response token and return the JSON web token returned by the service.
+ std::string responseToken = AttestationServiceTokenResponseSerializer::Deserialize(response);
+
+ // Parse the JWT returned by the attestation service.
+ auto const token
+ = AttestationTokenInternal(responseToken);
+
+ // Validate the token returned by the service. Use the cached attestation signers in the
+ // validation.
+ token.ValidateToken(
+ options.TokenValidationOptionsOverride ? *options.TokenValidationOptionsOverride
+ : this->m_tokenValidationOptions,
+ m_attestationSigners);
+
+ // And return the attestation result to the caller.
+ auto returnedToken = AttestationToken(token);
+ return Response>(returnedToken, std::move(response));
+ }
+ catch (std::runtime_error const& ex)
+ {
+ tracingContext.Span.AddEvent(ex);
+ throw;
+ }
}
Azure::Response> AttestationClient::AttestOpenEnclave(
@@ -129,46 +160,66 @@ Azure::Response> AttestationClient::AttestOp
AttestOpenEnclaveOptions options,
Azure::Core::Context const& context) const
{
- AttestOpenEnclaveRequest attestRequest{
- openEnclaveReport,
- options.InitTimeData,
- options.RunTimeData,
- options.DraftPolicyForAttestation,
- options.Nonce};
- std::string serializedRequest(AttestOpenEnclaveRequestSerializer::Serialize(attestRequest));
-
- auto encodedVector = std::vector(serializedRequest.begin(), serializedRequest.end());
- Azure::Core::IO::MemoryBodyStream stream(encodedVector);
- auto request = AttestationCommonRequest::CreateRequest(
- m_endpoint, m_apiVersion, HttpMethod::Post, {"attest/OpenEnclave"}, &stream);
-
- auto response = AttestationCommonRequest::SendRequest(*m_pipeline, request, context);
- std::string responseToken = AttestationServiceTokenResponseSerializer::Deserialize(response);
- auto token
- = AttestationTokenInternal(responseToken);
- token.ValidateToken(
- options.TokenValidationOptionsOverride ? *options.TokenValidationOptionsOverride
- : this->m_tokenValidationOptions,
- m_attestationSigners);
-
- return Response>(token, std::move(response));
+ auto tracingContext(m_tracingFactory.CreateTracingContext("AttestOpenEnclave", context));
+ try
+ {
+ AttestOpenEnclaveRequest attestRequest{
+ openEnclaveReport,
+ options.InitTimeData,
+ options.RunTimeData,
+ options.DraftPolicyForAttestation,
+ options.Nonce};
+ std::string serializedRequest(AttestOpenEnclaveRequestSerializer::Serialize(attestRequest));
+
+ auto encodedVector = std::vector(serializedRequest.begin(), serializedRequest.end());
+ Azure::Core::IO::MemoryBodyStream stream(encodedVector);
+ auto request = AttestationCommonRequest::CreateRequest(
+ m_endpoint, m_apiVersion, HttpMethod::Post, {"attest/OpenEnclave"}, &stream);
+
+ auto response
+ = AttestationCommonRequest::SendRequest(*m_pipeline, request, tracingContext.Context);
+ std::string responseToken = AttestationServiceTokenResponseSerializer::Deserialize(response);
+ auto token
+ = AttestationTokenInternal(responseToken);
+ token.ValidateToken(
+ options.TokenValidationOptionsOverride ? *options.TokenValidationOptionsOverride
+ : this->m_tokenValidationOptions,
+ m_attestationSigners);
+
+ return Response>(token, std::move(response));
+ }
+ catch (std::runtime_error const& ex)
+ {
+ tracingContext.Span.AddEvent(ex);
+ throw;
+ }
}
Azure::Response AttestationClient::AttestTpm(
AttestTpmOptions const& attestTpmOptions,
Azure::Core::Context const& context) const
{
- std::string jsonToSend = TpmDataSerializer::Serialize(attestTpmOptions.Payload);
- auto encodedVector = std::vector(jsonToSend.begin(), jsonToSend.end());
- Azure::Core::IO::MemoryBodyStream stream(encodedVector);
+ auto tracingContext(m_tracingFactory.CreateTracingContext("AttestTpm", context));
+ try
+ {
+ std::string jsonToSend = TpmDataSerializer::Serialize(attestTpmOptions.Payload);
+ auto encodedVector = std::vector(jsonToSend.begin(), jsonToSend.end());
+ Azure::Core::IO::MemoryBodyStream stream(encodedVector);
- auto request = AttestationCommonRequest::CreateRequest(
- m_endpoint, m_apiVersion, HttpMethod::Post, {"attest/Tpm"}, &stream);
+ auto request = AttestationCommonRequest::CreateRequest(
+ m_endpoint, m_apiVersion, HttpMethod::Post, {"attest/Tpm"}, &stream);
- // Send the request to the service.
- auto response = AttestationCommonRequest::SendRequest(*m_pipeline, request, context);
- std::string returnedBody(TpmDataSerializer::Deserialize(response));
- return Response(TpmAttestationResult{returnedBody}, std::move(response));
+ // Send the request to the service.
+ auto response
+ = AttestationCommonRequest::SendRequest(*m_pipeline, request, tracingContext.Context);
+ std::string returnedBody(TpmDataSerializer::Deserialize(response));
+ return Response(TpmAttestationResult{returnedBody}, std::move(response));
+ }
+ catch (std::runtime_error const& ex)
+ {
+ tracingContext.Span.AddEvent(ex);
+ throw;
+ }
}
namespace {
@@ -186,28 +237,39 @@ std::shared_timed_mutex SharedStateLock;
*/
void AttestationClient::RetrieveResponseValidationCollateral(Azure::Core::Context const& context)
{
- std::unique_lock stateLock(SharedStateLock);
-
- if (m_attestationSigners.empty())
+ auto tracingContext(m_tracingFactory.CreateTracingContext("Create", context));
+ try
{
- stateLock.unlock();
- auto request
- = AttestationCommonRequest::CreateRequest(m_endpoint, HttpMethod::Get, {"certs"}, nullptr);
- auto response = AttestationCommonRequest::SendRequest(*m_pipeline, request, context);
- auto jsonWebKeySet(JsonWebKeySetSerializer::Deserialize(response));
- TokenValidationCertificateResult returnValue;
- std::vector newValue;
- for (const auto& jwk : jsonWebKeySet.Keys)
- {
- AttestationSignerInternal internalSigner(jwk);
- newValue.push_back(internalSigner);
- }
- stateLock.lock();
+ std::unique_lock stateLock(SharedStateLock);
+
if (m_attestationSigners.empty())
{
- m_attestationSigners = newValue;
+ stateLock.unlock();
+ auto request = AttestationCommonRequest::CreateRequest(
+ m_endpoint, HttpMethod::Get, {"certs"}, nullptr);
+ auto response
+ = AttestationCommonRequest::SendRequest(*m_pipeline, request, tracingContext.Context);
+ auto jsonWebKeySet(JsonWebKeySetSerializer::Deserialize(response));
+ TokenValidationCertificateResult returnValue;
+ std::vector newValue;
+ for (const auto& jwk : jsonWebKeySet.Keys)
+ {
+ AttestationSignerInternal internalSigner(jwk);
+ newValue.push_back(internalSigner);
+ }
+ stateLock.lock();
+ if (m_attestationSigners.empty())
+ {
+ m_attestationSigners = newValue;
+ }
+ tracingContext.Span.SetStatus(SpanStatus::Ok);
}
}
+ catch (std::runtime_error const& ex)
+ {
+ tracingContext.Span.AddEvent(ex);
+ throw;
+ }
}
/** @brief Construct a new Attestation Client object
@@ -216,15 +278,14 @@ void AttestationClient::RetrieveResponseValidationCollateral(Azure::Core::Contex
* @param credential The authentication method to use (required for TPM attestation).
* @param options The options to customize the client behavior.
*/
-std::unique_ptr AttestationClientFactory::Create(
+Azure::Security::Attestation::AttestationClient AttestationClient::Create(
std::string const& endpoint,
std::shared_ptr credential,
- AttestationClientOptions options,
+ AttestationClientOptions const& options,
Azure::Core::Context const& context)
{
- std::unique_ptr returnValue(
- new AttestationClient(endpoint, credential, options));
- returnValue->RetrieveResponseValidationCollateral(context);
+ AttestationClient returnValue(endpoint, credential, options);
+ returnValue.RetrieveResponseValidationCollateral(context);
// Release the client pointer from the unique pointer to let the parent manage it.
return returnValue;
}
@@ -236,7 +297,7 @@ std::unique_ptr AttestationClientFactory::Create(
*
* @note TPM attestation requires an authenticated attestation client.
*/
-std::unique_ptr AttestationClientFactory::Create(
+Azure::Security::Attestation::AttestationClient AttestationClient::Create(
std::string const& endpoint,
AttestationClientOptions options,
Azure::Core::Context const& context)
diff --git a/sdk/attestation/azure-security-attestation/src/attestation_client_options.cpp b/sdk/attestation/azure-security-attestation/src/attestation_client_options.cpp
index e8839c1350d..1e743dca2cf 100644
--- a/sdk/attestation/azure-security-attestation/src/attestation_client_options.cpp
+++ b/sdk/attestation/azure-security-attestation/src/attestation_client_options.cpp
@@ -4,9 +4,8 @@
#include "azure/attestation/attestation_client_options.hpp"
namespace Azure { namespace Security { namespace Attestation {
- const ServiceVersion ServiceVersion::V2020_10_01("2020-10-01");
- const AttestationDataType AttestationDataType ::Binary("Binary");
+ const AttestationDataType AttestationDataType::Binary("Binary");
const AttestationDataType AttestationDataType::Json("JSON");
}}} // namespace Azure::Security::Attestation
diff --git a/sdk/attestation/azure-security-attestation/src/private/package_version.hpp b/sdk/attestation/azure-security-attestation/src/private/package_version.hpp
index 699f0f0131d..574c556d0c0 100644
--- a/sdk/attestation/azure-security-attestation/src/private/package_version.hpp
+++ b/sdk/attestation/azure-security-attestation/src/private/package_version.hpp
@@ -9,9 +9,9 @@
#pragma once
#define AZURE_ATTESTATION_VERSION_MAJOR 1
-#define AZURE_ATTESTATION_VERSION_MINOR 0
+#define AZURE_ATTESTATION_VERSION_MINOR 1
#define AZURE_ATTESTATION_VERSION_PATCH 0
-#define AZURE_ATTESTATION_VERSION_PRERELEASE "beta.3"
+#define AZURE_ATTESTATION_VERSION_PRERELEASE "beta.1"
#define AZURE_ATTESTATION_VERSION_ITOA_HELPER(i) #i
#define AZURE_ATTESTATION_VERSION_ITOA(i) AZURE_ATTESTATION_VERSION_ITOA_HELPER(i)
diff --git a/sdk/attestation/azure-security-attestation/test/ut/attestation_metadata.cpp b/sdk/attestation/azure-security-attestation/test/ut/attestation_metadata.cpp
index a9e9b366a94..e6dad5d89f6 100644
--- a/sdk/attestation/azure-security-attestation/test/ut/attestation_metadata.cpp
+++ b/sdk/attestation/azure-security-attestation/test/ut/attestation_metadata.cpp
@@ -50,14 +50,14 @@ namespace Azure { namespace Security { namespace Attestation { namespace Test {
}
}
- std::unique_ptr CreateClient()
+ AttestationClient CreateClient()
{
// `InitTestClient` takes care of setting up Record&Playback.
auto options = InitClientOptions();
- return AttestationClientFactory::Create(m_endpoint, options);
+ return AttestationClient::Create(m_endpoint, options);
}
- std::unique_ptr CreateAuthenticatedClient()
+ AttestationClient CreateAuthenticatedClient()
{
// `InitClientOptions` takes care of setting up Record&Playback.
AttestationClientOptions options = InitClientOptions();
@@ -65,7 +65,7 @@ namespace Azure { namespace Security { namespace Attestation { namespace Test {
= std::make_shared(
GetEnv("AZURE_TENANT_ID"), GetEnv("AZURE_CLIENT_ID"), GetEnv("AZURE_CLIENT_SECRET"));
- return AttestationClientFactory::Create(m_endpoint, credential, options);
+ return AttestationClient::Create(m_endpoint, credential, options);
}
};
@@ -73,9 +73,7 @@ namespace Azure { namespace Security { namespace Attestation { namespace Test {
{
auto attestationClient(CreateClient());
- EXPECT_FALSE(attestationClient->Endpoint().empty());
-
- auto openIdMetadata = attestationClient->GetOpenIdMetadata();
+ auto openIdMetadata = attestationClient.GetOpenIdMetadata();
EXPECT_TRUE(openIdMetadata.Value.Issuer);
EXPECT_TRUE(openIdMetadata.Value.JsonWebKeySetUrl);
@@ -94,7 +92,7 @@ namespace Azure { namespace Security { namespace Attestation { namespace Test {
{
auto attestationClient(CreateClient());
- auto attestationSigners = attestationClient->GetTokenValidationCertificates();
+ auto attestationSigners = attestationClient.GetTokenValidationCertificates();
EXPECT_LE(1UL, attestationSigners.Value.Signers.size());
for (const auto& signer : attestationSigners.Value.Signers)
{
diff --git a/sdk/attestation/azure-security-attestation/test/ut/attestation_test.cpp b/sdk/attestation/azure-security-attestation/test/ut/attestation_test.cpp
index 2fcaf070d73..1a4ff40f4fc 100644
--- a/sdk/attestation/azure-security-attestation/test/ut/attestation_test.cpp
+++ b/sdk/attestation/azure-security-attestation/test/ut/attestation_test.cpp
@@ -68,14 +68,14 @@ namespace Azure { namespace Security { namespace Attestation { namespace Test {
return returnValue;
}
- std::unique_ptr CreateClient()
+ AttestationClient CreateClient()
{
// `InitTestClient` takes care of setting up Record&Playback.
auto options = InitClientOptions();
options.TokenValidationOptions = GetTokenValidationOptions();
- return AttestationClientFactory::Create(m_endpoint, options);
+ return AttestationClient::Create(m_endpoint, options);
}
- std::unique_ptr