Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[keyvault] samples updates for doc publishing #6626

Merged
merged 15 commits into from
Jan 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 31 additions & 2 deletions common/scripts/prep-samples.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@

const baseFS = require("fs");
const path = require("path");
const promisify = require("util").promisify;

const exec = promisify(require("child_process").execFile);

// Node >= 10 provide fs.promises, but since we're still building Node 8 for now
// we need to use util.promisify if fs.promises doesn't exist
const fs =
baseFS.promises ||
(() => {
const promisify = require("util").promisify;
return {
readdir: promisify(baseFS.readdir),
readFile: promisify(baseFS.readFile),
Expand Down Expand Up @@ -154,6 +156,33 @@ async function main() {
`${package.name}@${package.version}`
);

// Check if the package samples directory is dirty using git
// Refuse to proceed if this script may overwrite changes to samples.
try {
const gitDiff = await exec("git", [
"status",
"-s",
path.join(baseDir, "samples")
]);
if (gitDiff.stdout !== "") {
console.error(
"[prep-samples] Error: The samples tree is dirty. Refusing to continue."
);
console.error(
"[prep-samples] Stash or commit your changes to the following files:"
);
for (const line of gitDiff.stdout.trim().split("\n")) {
console.error(" -", line);
}
process.exit(1);
}
} catch (err) {
console.error(
"[prep-samples] Error: Failed to check the git status. Refusing to continue."
);
process.exit(1);
}

const tsDir = path.join(baseDir, "samples", "typescript", "src");
for await (const fileName of findMatchingFiles(
tsDir,
Expand All @@ -175,6 +204,6 @@ async function main() {
}

main().catch(err => {
console.error("[prep-samples] Error:", err);
console.error("[prep-samples]", err);
process.exit(1);
});
10 changes: 6 additions & 4 deletions sdk/keyvault/keyvault-certificates/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,16 @@
"scripts": {
"audit": "node ../../../common/scripts/rush-audit.js && rimraf node_modules package-lock.json && npm i --package-lock-only 2>&1 && npm audit",
"build:minify": "uglifyjs -c -m --comments --source-map \"content='./dist/index.js.map'\" -o ./dist/index.min.js ./dist/index.js 2>&1",
"build:samples": "tsc -p tsconfig.samples.json",
"build:samples": "node ../../../common/scripts/prep-samples.js && cd samples && tsc",
"build:es6": "tsc -p tsconfig.json",
"build:nodebrowser": "rollup -c 2>&1",
"build:test": "npm run build:es6 && rollup -c rollup.test.config.js 2>&1",
"build": "npm run extract-api && npm run build:samples && npm run build:es6 && npm run build:nodebrowser",
"build": "npm run extract-api && npm run build:es6 && npm run build:nodebrowser",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to keep building the samples in here in some capacity so that if we break the samples the CI will warn us.

"check-format": "prettier --list-different --config ../../.prettierrc.json \"src/**/*.ts\" \"*.{js,json}\"",
"clean": "rimraf dist-esm dist-test typings *.tgz *.log",
"execute:samples": "echo skipped",
"clean": "rimraf dist-esm dist-test typings *.tgz *.log samples/typescript/dist",
"execute:js-samples": "node ../../../common/scripts/run-samples.js samples/javascript/",
"execute:ts-samples": "node ../../../common/scripts/run-samples.js samples/typescript/dist/samples/typescript/src/",
"execute:samples": "npm run build:samples && npm run execute:js-samples && npm run execute:ts-samples",
"extract-api": "tsc -p . && api-extractor run --local",
"format": "prettier --write --config ../../.prettierrc.json \"src/**/*.ts\" \"samples/*.ts\" \"*.{js,json}\"",
"integration-test:browser": "karma start --single-run",
Expand Down
80 changes: 80 additions & 0 deletions sdk/keyvault/keyvault-certificates/samples/javascript/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
---
page_type: sample
languages:
- javascript
products:
- azure
- azure-key-vault
urlFragment: keyvault-certificates-javascript
---

# Azure Key Vault Certificates client library samples for JavaScript

These sample programs show how to use the JavaScript client libraries for Azure Key Vault Certificates in some common scenarios.

| **File Name** | **Description** |
| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [backupAndRestore.js][backupandrestore] | creates a self-signed certificate, then makes a backup from it, then deletes it and purges it, and finally restores it |
| [contacts.js][contacts] | creates, updates and deletes certificate contacts |
| [deleteAndRecover.js][deleteandrecover] | creates a self-signed certificate, then deletes it, then recovers it (soft-delete is required for this sample to run, see: https://docs.microsoft.com/en-us/azure/key-vault/key-vault-ovw-soft-delete) |
| [helloWorld.js][helloworld] | creates a self-signed certificate, reads it in various ways, updates the tags of the certificate and finally deletes the certificate |
| [issuers.js][issuers] | creates, updates and deletes certificate issuers |
| [listCertificates.js][listcertificates] | lists previously created certificates in a single chunk and by page, then changes one of them and lists all the versions of that certificate, then deletes them and lists the deleted certificates. |
| [mergeCertificate.js][mergecertificate] | creates a certificate with an Unknown issuer, then signs this certificate using a fake certificate authority and the mergeCertificate API method |
| [operations.js][operations] | creates, updates and deletes a certificate's operation |

## Prerequisites

The samples are compatible with Node.js >= 8.0.0.

You need [an Azure subscription][freesub] and [an Azure Key Vault][azkeyvault] to run these sample programs. To quickly create the needed Key Vault resources in Azure and to receive a connection string for them, you can deploy our sample template by clicking:

[![](http://azuredeploy.net/deploybutton.png)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2Fazure-sdk-for-js%2Fmaster%2Fsdk%2Fkeyvault%2Fkeyvault-certificates%2Ftests-resources.json)

If creating the Key Vault manually using the Azure Portal, be aware that the samples require that the soft-delete feature be enabled. Our template above will enable this feature automatically, but it is possible to enable it manually using the Azure CLI. See [this page][kvsoftdelete] for more information.

Samples retrieve credentials to access the Key Vault from environment variables. Alternatively, edit the source code to include the appropriate credentials. See each individual sample for details on which environment variables/credentials it requires to function.

Adapting the samples to run in the browser may require some additional consideration. For details, please see the [package README][package].

## Setup

To run the samples using the published version of the package:

1. Install the dependencies using `npm`:

```bash
npm install
```

2. Edit the file `sample.env`, adding the correct credentials to access the Azure service and run the samples. Then rename the file from `sample.env` to just `.env`. The sample programs will read this file automatically.

3. Run whichever samples you like (note that some samples may require additional setup, see the table above):

```bash
node helloWorld.js
```

Alternatively, run a single sample with the correct environment variables set (step 2 is not required if you do this), for example (cross-platform):

```bash
npx cross-env KEYVAULT_NAME="<key vault name>" AZURE_TENANT_ID="<AAD tenant id>" AZURE_CLIENT_ID="<AAD client id>" AZURE_CLIENT_SECRET="<AAD client secret>" node helloWorld.js
```

## Next Steps

Take a look at our [API Documentation][apiref] for more information about the APIs that are available in the clients.

[backupandrestore]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/keyvault/keyvault-certificates/samples/javascript/backupAndRestore.js
[contacts]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/keyvault/keyvault-certificates/samples/javascript/contacts.js
[deleteandrecover]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/keyvault/keyvault-certificates/samples/javascript/deleteAndRecover.js
[helloworld]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/keyvault/keyvault-certificates/samples/javascript/helloWorld.js
[issuers]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/keyvault/keyvault-certificates/samples/javascript/issuers.js
[listcertificates]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/keyvault/keyvault-certificates/samples/javascript/listCertificates.js
[mergecertificate]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/keyvault/keyvault-certificates/samples/javascript/mergeCertificate.js
[operations]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/keyvault/keyvault-certificates/samples/javascript/operations.js
[apiref]: https://docs.microsoft.com/javascript/api/@azure/keyvault-certificates
[azkeyvault]: https://docs.microsoft.com/azure/key-vault/quick-create-portal
[kvsoftdelete]: https://docs.microsoft.com/azure/key-vault/key-vault-soft-delete-cli
[freesub]: https://azure.microsoft.com/free/
[package]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/keyvault/keyvault-certificates/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
const { CertificateClient } = require("../../dist");
// Copyright (c) Microsoft corporation.
// Licensed under the MIT license.

const { CertificateClient } = require("@azure/keyvault-certificates");
const { DefaultAzureCredential } = require("@azure/identity");

// Load the .env file if it exists
require("dotenv").config();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Going forward, are we recommending users put this in their projects?


// This sample creates a self-signed certificate, then makes a backup from it,
// then deletes it and purges it, and finally restores it.

Expand All @@ -20,7 +26,7 @@ async function main() {

const client = new CertificateClient(url, credential);

const certificateName = "MyCertificate123129";
const certificateName = "MyCertificateBackupAndRestoreJS";

// Creating a self-signed certificate
const createPoller = await client.beginCreateCertificate(certificateName, {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
const { CertificateClient } = require("../../dist");
// Copyright (c) Microsoft corporation.
// Licensed under the MIT license.

const { CertificateClient } = require("@azure/keyvault-certificates");
const { DefaultAzureCredential } = require("@azure/identity");

// Load the .env file if it exists
require("dotenv").config();

// This sample creates, updates and deletes certificate contacts.

async function main() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
const { CertificateClient } = require("../../dist");
// Copyright (c) Microsoft corporation.
// Licensed under the MIT license.

const { CertificateClient } = require("@azure/keyvault-certificates");
const { DefaultAzureCredential } = require("@azure/identity");

// Load the .env file if it exists
require("dotenv").config();

// This sample creates a self-signed certificate, then deletes it, then recovers it.
// Soft-delete is required for this sample to run: https://docs.microsoft.com/en-us/azure/key-vault/key-vault-ovw-soft-delete

Expand All @@ -16,7 +22,7 @@ async function main() {

const client = new CertificateClient(url, credential);

const certificateName = "MyCertificate";
const certificateName = "MyCertificateDeleteAndRecoverJS";

// Creating a self-signed certificate
const createPoller = await client.beginCreateCertificate(certificateName, {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
const { CertificateClient } = require("../../dist");
// Copyright (c) Microsoft corporation.
// Licensed under the MIT license.

const { CertificateClient } = require("@azure/keyvault-certificates");
const { DefaultAzureCredential } = require("@azure/identity");

// Load the .env file if it exists
require("dotenv").config();

// This sample creates a self-signed certificate, reads it in various ways,
// updates the tags of the certificate and finally deletes the certificate.

Expand All @@ -16,7 +22,7 @@ async function main() {

const client = new CertificateClient(url, credential);

const certificateName = "MyCertificate";
const certificateName = "MyCertificateHelloWorldJS";

// Creating a self-signed certificate
const createPoller = await client.beginCreateCertificate(certificateName, {
Expand Down
12 changes: 9 additions & 3 deletions sdk/keyvault/keyvault-certificates/samples/javascript/issuers.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
const { CertificateClient } = require("../../dist");
// Copyright (c) Microsoft corporation.
// Licensed under the MIT license.

const { CertificateClient } = require("@azure/keyvault-certificates");
const { DefaultAzureCredential } = require("@azure/identity");

// Load the .env file if it exists
require("dotenv").config();

// This sample creates, updates and deletes certificate issuers.

async function main() {
Expand All @@ -15,8 +21,8 @@ async function main() {

const client = new CertificateClient(url, credential);

const certificateName = "MyCertificate";
const issuerName = "issuerName";
const certificateName = "MyCertificateIssuersJS";
const issuerName = "issuerNameIssuersJS";

// Create
await client.createIssuer(issuerName, "Test", {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
const { CertificateClient } = require("../../dist");
// Copyright (c) Microsoft corporation.
// Licensed under the MIT license.

const { CertificateClient } = require("@azure/keyvault-certificates");
const { DefaultAzureCredential } = require("@azure/identity");

// Load the .env file if it exists
require("dotenv").config();

// This sample list previously created certificates in a single chunk and by page,
// then changes one of them and lists all the versions of that certificate,
// then deletes them, then lists the deleted certificates.
Expand All @@ -17,8 +23,8 @@ async function main() {

const client = new CertificateClient(url, credential);

const certificateName1 = "MyCertificate1";
const certificateName2 = "MyCertificate2";
const certificateName1 = "MyCertificateListCertificatesJS1";
const certificateName2 = "MyCertificateListCertificatesJS2";

// Creating two self-signed certificates. They will appear as pending initially.
await client.beginCreateCertificate(certificateName1, {
Expand All @@ -43,7 +49,9 @@ async function main() {

// Listing all the available certificates by pages.
let pageCount = 0;
let listPropertiesOfCertificatesByPage = client.listPropertiesOfCertificates({ includePending: true }).byPage();
let listPropertiesOfCertificatesByPage = client
.listPropertiesOfCertificates({ includePending: true })
.byPage();
while (true) {
let { done, value } = await listPropertiesOfCertificatesByPage.next();
if (done) {
Expand All @@ -64,7 +72,10 @@ async function main() {
console.log("Updated certificate:", updatedCertificate);

// Listing a certificate's versions
let listPropertiesOfCertificateVersions = client.listPropertiesOfCertificateVersions(certificateName1, {});
let listPropertiesOfCertificateVersions = client.listPropertiesOfCertificateVersions(
certificateName1,
{}
);
while (true) {
let { done, value } = await listPropertiesOfCertificateVersions.next();
if (done) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
// Copyright (c) Microsoft corporation.
// Licensed under the MIT license.

const fs = require("fs");
const childProcess = require("child_process");
const { CertificateClient } = require("../../dist");

const { CertificateClient } = require("@azure/keyvault-certificates");
const { DefaultAzureCredential } = require("@azure/identity");

// Load the .env file if it exists
require("dotenv").config();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to auto-generate this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dotenv bits are for end-users of the samples. CI won't need them. The sample readme presents use of dotenv as an option, so this part has to be checked in for that to work when a customer downloads the sample zip file.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking through the concepts we're asking the user to understand to use the samples, I wonder if we should just mention this in the docs but not in the samples to keep the samples "as simple as possible".

It's nice to have the option to use .env if that's what the user wants to do, but if they'd rather just update the environment where their app lives, they don't actually need the .env part for the sample to work.


// This sample creates a certificate with an Unknown issuer, then signs this certificate using a fake
// certificate authority and the mergeCertificate API method.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
const { CertificateClient } = require("../../dist");
// Copyright (c) Microsoft corporation.
// Licensed under the MIT license.

const { CertificateClient } = require("@azure/keyvault-certificates");
const { DefaultAzureCredential } = require("@azure/identity");

// Load the .env file if it exists
require("dotenv").config();

// This sample creates, updates and deletes a certificate's operation.

async function main() {
Expand All @@ -14,7 +20,7 @@ async function main() {
const credential = new DefaultAzureCredential();

const client = new CertificateClient(url, credential);
const certificateName = "MyCertificate986632";
const certificateName = "MyCertificateOperationJS";

// Certificates' operations will be pending for some time right after they're created.
const createPoller = await client.beginCreateCertificate(certificateName, {
Expand Down
35 changes: 35 additions & 0 deletions sdk/keyvault/keyvault-certificates/samples/javascript/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"name": "azure-keyvault-certificates-samples-js",
"private": true,
"version": "0.1.0",
"description": "Azure Key Vault Certificates client library samples for JavaScript",
"engine": {
"node": ">=8.0.0"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Azure/azure-sdk-for-js.git"
},
"keywords": [
"Azure",
"Key Vault",
"Certificates",
"Node.js",
"JavaScript"
],
"author": "Microsoft Corporation",
"license": "MIT",
"bugs": {
"url": "https://github.com/Azure/azure-sdk-for-js/issues"
},
"homepage": "https://github.com/Azure/azure-sdk-for-js#readme",
"sideEffects": false,
"dependencies": {
"@azure/identity": "latest",
"@azure/keyvault-certificates": "latest",
"dotenv": "^8.2.0"
},
"devDependencies": {
"rimraf": "^3.0.0"
}
}
Loading