Skip to content

Commit 34ba544

Browse files
authored
[KeyVault] - Fix sovereign cloud tests (#18350)
## What - Suppress key rotation tests in sovereign clouds - Ensure AZURE_AUTHORITY_HOST env var is passed to the credential in tests - Suppress premium SKU tests when KV is not premium ## Why These are added to support sovereign cloud testing. The first is a must for us as key rotation is simply not available in all clouds yet as a preview feature. We still want to test this feature in public cloud though so suppressing it in government clouds is a reasonable approach. The second is necessary to authenticate correctly in different authorities. Finally, the third is a must as premium SKU is not available everywhere. Fixes #18142 Partially Fixes #18267 Fixes #18189
1 parent 4386511 commit 34ba544

10 files changed

Lines changed: 165 additions & 124 deletions

File tree

sdk/keyvault/keyvault-admin/test/utils/authentication.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Licensed under the MIT license.
33

44
import { ClientSecretCredential } from "@azure/identity";
5-
import { isPlaybackMode, record, RecorderEnvironmentSetup } from "@azure-tools/test-recorder";
5+
import { env, isPlaybackMode, record, RecorderEnvironmentSetup } from "@azure-tools/test-recorder";
66
import { KeyClient } from "@azure/keyvault-keys";
77
import { v4 as uuidv4 } from "uuid";
88

@@ -61,7 +61,10 @@ export async function authenticate(that: any): Promise<any> {
6161
const credential = new ClientSecretCredential(
6262
getEnvironmentVariable("AZURE_TENANT_ID"),
6363
getEnvironmentVariable("AZURE_CLIENT_ID"),
64-
getEnvironmentVariable("AZURE_CLIENT_SECRET")
64+
getEnvironmentVariable("AZURE_CLIENT_SECRET"),
65+
{
66+
authorityHost: env.AZURE_AUTHORITY_HOST // undefined by default is expected
67+
}
6568
);
6669

6770
const keyVaultHsmUrl = getEnvironmentVariable("AZURE_MANAGEDHSM_URI");

sdk/keyvault/keyvault-certificates/karma.conf.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ module.exports = function(config) {
4646
"AZURE_CLIENT_SECRET",
4747
"AZURE_TENANT_ID",
4848
"KEYVAULT_URI",
49-
"TEST_MODE"
49+
"TEST_MODE",
50+
"AZURE_AUTHORITY_HOST"
5051
],
5152

5253
reporters: ["mocha", "coverage", "junit", "json-to-file"],

sdk/keyvault/keyvault-certificates/test/utils/testAuthentication.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,13 @@ export async function authenticate(that: Context): Promise<any> {
3131
queryParametersToSkip: []
3232
};
3333
const recorder = record(that, recorderEnvSetup);
34-
const credential = await new ClientSecretCredential(
34+
const credential = new ClientSecretCredential(
3535
env.AZURE_TENANT_ID,
3636
env.AZURE_CLIENT_ID,
37-
env.AZURE_CLIENT_SECRET
37+
env.AZURE_CLIENT_SECRET,
38+
{
39+
authorityHost: env.AZURE_AUTHORITY_HOST
40+
}
3841
);
3942

4043
const keyVaultUrl = env.KEYVAULT_URI;

sdk/keyvault/keyvault-keys/karma.conf.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ module.exports = function(config) {
4949
"KEYVAULT_URI",
5050
"AZURE_MANAGEDHSM_URI",
5151
"AZURE_KEYVAULT_ATTESTATION_URI",
52-
"TEST_MODE"
52+
"TEST_MODE",
53+
"AZURE_AUTHORITY_HOST"
5354
],
5455

5556
reporters: ["mocha", "coverage", "junit", "json-to-file"],

sdk/keyvault/keyvault-keys/test/public/crypto.spec.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,12 @@ describe("CryptographyClient (all decrypts happen remotely)", () => {
190190

191191
describe("RSA-HSM keys", () => {
192192
beforeEach(async function(this: Context) {
193+
if (isLiveMode() && env.KEYVAULT_SKU !== "premium") {
194+
// RSA-HSM keys are only available in the premium KeyVault SKU which is not
195+
// available in all clouds.
196+
this.skip();
197+
}
198+
193199
const authentication = await authenticate(this, getServiceVersion());
194200
client = authentication.client;
195201
recorder = authentication.recorder;
@@ -205,7 +211,7 @@ describe("CryptographyClient (all decrypts happen remotely)", () => {
205211
if (!this.currentTest?.isPending()) {
206212
await testClient.flushKey(keyName);
207213
}
208-
await recorder.stop();
214+
await recorder?.stop();
209215
});
210216

211217
it("encrypt & decrypt with an RSA-HSM key and the RSA-OAEP algorithm", async function(this: Context) {

sdk/keyvault/keyvault-keys/test/public/keyClient.spec.ts

Lines changed: 125 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,26 @@
33

44
import chai, { assert } from "chai";
55
import chaiExclude from "chai-exclude";
6+
import chaiAsPromised from "chai-as-promised";
67
chai.use(chaiExclude);
8+
chai.use(chaiAsPromised);
79
import { Context } from "mocha";
810
import { RestError } from "@azure/core-http";
911
import { AbortController } from "@azure/abort-controller";
10-
import { env, Recorder } from "@azure-tools/test-recorder";
12+
import { env, isPlaybackMode, isRecordMode, Recorder } from "@azure-tools/test-recorder";
1113

1214
import {
1315
KeyClient,
1416
CreateEcKeyOptions,
1517
UpdateKeyPropertiesOptions,
1618
GetKeyOptions
1719
} from "../../src";
18-
import { assertThrowsAbortError, getServiceVersion, onVersions } from "../utils/utils.common";
20+
import {
21+
assertThrowsAbortError,
22+
getServiceVersion,
23+
isPublicCloud,
24+
onVersions
25+
} from "../utils/utils.common";
1926
import { testPollerProperties } from "../utils/recorderUtils";
2027
import { authenticate } from "../utils/testAuthentication";
2128
import TestClient from "../utils/testClient";
@@ -401,132 +408,136 @@ describe("Keys client - create, read, update and delete operations", () => {
401408
});
402409

403410
onVersions({ minVer: "7.3-preview" }).describe("key rotation", () => {
404-
it("rotateKey supports rotating a key", async () => {
405-
const keyName = recorder.getUniqueName("keyrotate");
406-
const key = await client.createKey(keyName, "RSA");
407-
const rotatedKey = await client.rotateKey(keyName);
408-
409-
// The rotated key should have mostly the same data, excluding properties that are rotated.
410-
assert.deepEqualExcludingEvery(rotatedKey, key, ["id", "kid", "version", "n", "e"] as any);
411-
412-
// A new version is created, and the key material is rotated (RSA key, check n and e).
413-
assert.notEqual(rotatedKey.id, key.id);
414-
assert.notEqual(rotatedKey.properties.version, key.properties.version);
415-
assert.notDeepEqual(rotatedKey.key?.n, key.key?.n);
416-
});
417-
418-
it("rotateKey supports tracing", async () => {
419-
const keyName = recorder.getUniqueName("keyrotatetracing");
420-
const key = await client.createKey(keyName, "RSA");
411+
if (isPublicCloud() || isRecordMode() || isPlaybackMode()) {
412+
// Key Rotation is a preview feature that is not supported in all clouds yet.
413+
// Once 7.3 GAs we should be able to run this unconditionally.
414+
it("rotateKey supports rotating a key", async () => {
415+
const keyName = recorder.getUniqueName("keyrotate");
416+
const key = await client.createKey(keyName, "RSA");
417+
const rotatedKey = await client.rotateKey(keyName);
418+
419+
// The rotated key should have mostly the same data, excluding properties that are rotated.
420+
assert.deepEqualExcludingEvery(rotatedKey, key, ["id", "kid", "version", "n", "e"] as any);
421+
422+
// A new version is created, and the key material is rotated (RSA key, check n and e).
423+
assert.notEqual(rotatedKey.id, key.id);
424+
assert.notEqual(rotatedKey.properties.version, key.properties.version);
425+
assert.notDeepEqual(rotatedKey.key?.n, key.key?.n);
426+
});
421427

422-
await supportsTracing((tracingOptions) => client.rotateKey(key.name, { tracingOptions }), [
423-
"Azure.KeyVault.Keys.KeyClient.rotateKey"
424-
]);
425-
});
428+
it("rotateKey supports tracing", async () => {
429+
const keyName = recorder.getUniqueName("keyrotatetracing");
430+
const key = await client.createKey(keyName, "RSA");
426431

427-
it("updateKeyRotationPolicy supports creating a new rotation policy and fetching it", async () => {
428-
const keyName = recorder.getUniqueName("keyrotationpolicy");
429-
const key = await client.createKey(keyName, "RSA");
430-
431-
const rotationPolicy = await client.updateKeyRotationPolicy(key.name, {
432-
expiresIn: "P90D",
433-
lifetimeActions: [
434-
{
435-
action: "Rotate",
436-
timeBeforeExpiry: "P30D"
437-
}
438-
]
432+
await supportsTracing((tracingOptions) => client.rotateKey(key.name, { tracingOptions }), [
433+
"Azure.KeyVault.Keys.KeyClient.rotateKey"
434+
]);
439435
});
440436

441-
const fetchedPolicy = await client.getKeyRotationPolicy(keyName);
437+
it("updateKeyRotationPolicy supports creating a new rotation policy and fetching it", async () => {
438+
const keyName = recorder.getUniqueName("keyrotationpolicy");
439+
const key = await client.createKey(keyName, "RSA");
442440

443-
assert.deepEqual(fetchedPolicy, rotationPolicy);
444-
});
441+
const rotationPolicy = await client.updateKeyRotationPolicy(key.name, {
442+
expiresIn: "P90D",
443+
lifetimeActions: [
444+
{
445+
action: "Rotate",
446+
timeBeforeExpiry: "P30D"
447+
}
448+
]
449+
});
445450

446-
it("updateKeyRotationPolicy supports updating an existing policy", async () => {
447-
const keyName = recorder.getUniqueName("keyrotationpolicy");
448-
const key = await client.createKey(keyName, "RSA");
449-
450-
// Create a policy which we will override later.
451-
await client.updateKeyRotationPolicy(key.name, {
452-
lifetimeActions: [
453-
{
454-
action: "Rotate",
455-
timeAfterCreate: "P2M"
456-
}
457-
]
458-
});
451+
const fetchedPolicy = await client.getKeyRotationPolicy(keyName);
459452

460-
const updatedPolicy = await client.updateKeyRotationPolicy(key.name, {
461-
expiresIn: "P90D",
462-
lifetimeActions: [
463-
{
464-
action: "Notify",
465-
timeBeforeExpiry: "P30D"
466-
}
467-
]
453+
assert.deepEqual(fetchedPolicy, rotationPolicy);
468454
});
469455

470-
assert.deepEqual(updatedPolicy, {
471-
id: updatedPolicy.id,
472-
createdOn: updatedPolicy.createdOn,
473-
updatedOn: updatedPolicy.updatedOn,
474-
expiresIn: "P90D",
475-
lifetimeActions: [
476-
{
477-
timeAfterCreate: undefined,
478-
action: "Notify",
479-
timeBeforeExpiry: "P30D"
480-
}
481-
]
482-
});
483-
});
484-
485-
it("updateKeyRotationPolicy supports tracing", async () => {
486-
const keyName = recorder.getUniqueName("updaterotationpolicy");
487-
const key = await client.createKey(keyName, "EC");
456+
it("updateKeyRotationPolicy supports updating an existing policy", async () => {
457+
const keyName = recorder.getUniqueName("keyrotationpolicy");
458+
const key = await client.createKey(keyName, "RSA");
488459

489-
await supportsTracing(
490-
(tracingOptions) =>
491-
client.updateKeyRotationPolicy(
492-
key.name,
460+
// Create a policy which we will override later.
461+
await client.updateKeyRotationPolicy(key.name, {
462+
lifetimeActions: [
493463
{
494-
lifetimeActions: [
495-
{
496-
action: "Notify",
497-
timeBeforeExpiry: "P30D"
498-
}
499-
],
500-
expiresIn: "P90D"
501-
},
502-
{ tracingOptions }
503-
),
504-
["Azure.KeyVault.Keys.KeyClient.updateKeyRotationPolicy"]
505-
);
506-
});
464+
action: "Rotate",
465+
timeAfterCreate: "P2M"
466+
}
467+
]
468+
});
469+
470+
const updatedPolicy = await client.updateKeyRotationPolicy(key.name, {
471+
expiresIn: "P90D",
472+
lifetimeActions: [
473+
{
474+
action: "Notify",
475+
timeBeforeExpiry: "P30D"
476+
}
477+
]
478+
});
479+
480+
assert.deepEqual(updatedPolicy, {
481+
id: updatedPolicy.id,
482+
createdOn: updatedPolicy.createdOn,
483+
updatedOn: updatedPolicy.updatedOn,
484+
expiresIn: "P90D",
485+
lifetimeActions: [
486+
{
487+
timeAfterCreate: undefined,
488+
action: "Notify",
489+
timeBeforeExpiry: "P30D"
490+
}
491+
]
492+
});
493+
});
507494

508-
it("throws when attempting to fetch a policy of a non-existent key", async () => {
509-
const keyName = recorder.getUniqueName("nonexistentkey");
510-
await assert.isRejected(client.getKeyRotationPolicy(keyName));
511-
});
495+
it("updateKeyRotationPolicy supports tracing", async () => {
496+
const keyName = recorder.getUniqueName("updaterotationpolicy");
497+
const key = await client.createKey(keyName, "EC");
498+
499+
await supportsTracing(
500+
(tracingOptions) =>
501+
client.updateKeyRotationPolicy(
502+
key.name,
503+
{
504+
lifetimeActions: [
505+
{
506+
action: "Notify",
507+
timeBeforeExpiry: "P30D"
508+
}
509+
],
510+
expiresIn: "P90D"
511+
},
512+
{ tracingOptions }
513+
),
514+
["Azure.KeyVault.Keys.KeyClient.updateKeyRotationPolicy"]
515+
);
516+
});
512517

513-
it("getKeyRotationPolicy supports tracing", async () => {
514-
const keyName = recorder.getUniqueName("rotationpolicytracing");
515-
const key = await client.createKey(keyName, "RSA");
516-
517-
await client.updateKeyRotationPolicy(key.name, {
518-
lifetimeActions: [
519-
{
520-
action: "Rotate",
521-
timeAfterCreate: "P2M"
522-
}
523-
]
518+
it("throws when attempting to fetch a policy of a non-existent key", async () => {
519+
const keyName = recorder.getUniqueName("nonexistentkey");
520+
await assert.isRejected(client.getKeyRotationPolicy(keyName));
524521
});
525522

526-
await supportsTracing(
527-
(tracingOptions) => client.getKeyRotationPolicy(key.name, { tracingOptions }),
528-
["Azure.KeyVault.Keys.KeyClient.getKeyRotationPolicy"]
529-
);
530-
});
523+
it("getKeyRotationPolicy supports tracing", async () => {
524+
const keyName = recorder.getUniqueName("rotationpolicytracing");
525+
const key = await client.createKey(keyName, "RSA");
526+
527+
await client.updateKeyRotationPolicy(key.name, {
528+
lifetimeActions: [
529+
{
530+
action: "Rotate",
531+
timeAfterCreate: "P2M"
532+
}
533+
]
534+
});
535+
536+
await supportsTracing(
537+
(tracingOptions) => client.getKeyRotationPolicy(key.name, { tracingOptions }),
538+
["Azure.KeyVault.Keys.KeyClient.getKeyRotationPolicy"]
539+
);
540+
});
541+
}
531542
});
532543
});

sdk/keyvault/keyvault-keys/test/utils/testAuthentication.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,10 @@ export async function authenticate(that: Context, version: string): Promise<any>
4848
const credential = new ClientSecretCredential(
4949
env.AZURE_TENANT_ID,
5050
env.AZURE_CLIENT_ID,
51-
env.AZURE_CLIENT_SECRET
51+
env.AZURE_CLIENT_SECRET,
52+
{
53+
authorityHost: env.AZURE_AUTHORITY_HOST
54+
}
5255
);
5356

5457
const keyVaultUrl = env.KEYVAULT_URI;

sdk/keyvault/keyvault-keys/test/utils/utils.common.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,12 @@ export function onVersions(
5959
): TestFunctionWrapper {
6060
return supports(serviceVersion || getServiceVersion(), supportedVersions, serviceVersions);
6161
}
62+
63+
/**
64+
* Acts as a proxy to check with we're running on public or sovereign cloud.
65+
*
66+
* @returns - true if running on public cloud, false otherwise.
67+
*/
68+
export function isPublicCloud(): boolean {
69+
return (env.AZURE_AUTHORITY_HOST ?? "").includes(".microsoftonline.com");
70+
}

sdk/keyvault/keyvault-secrets/karma.conf.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ module.exports = function(config) {
4646
"AZURE_CLIENT_SECRET",
4747
"AZURE_TENANT_ID",
4848
"KEYVAULT_URI",
49-
"TEST_MODE"
49+
"TEST_MODE",
50+
"AZURE_AUTHORITY_HOST"
5051
],
5152

5253
reporters: ["mocha", "coverage", "junit", "json-to-file"],

0 commit comments

Comments
 (0)