Skip to content

Commit

Permalink
[ContainerRegistry] Update cloud configuration API (#16992)
Browse files Browse the repository at this point in the history
We are moving from an `authenticationScope` string to an `audience`
extensible enum on `ContainerRegistryClientOptions`. We introduce the
`KnownContainerRegistryAudience` enum to hold the possible values, or
allow the customer to provide a different value if needed.

In addition, we require the `audience` value to be set in client
options to instantiate any instance of `ContainerRegistryClient`. This
allows us to postpone setting a default value for audience until after
the library's first GA.

See relevant .NET PR at
Azure/azure-sdk-for-net#23141.

This resolves #16127.
  • Loading branch information
jeremymeng authored Aug 27, 2021
1 parent 974a685 commit eeae1e5
Show file tree
Hide file tree
Showing 22 changed files with 184 additions and 85 deletions.
2 changes: 2 additions & 0 deletions sdk/containerregistry/container-registry/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

### Breaking Changes

- Replace `authenticationScope` with `audience` in `ContainerRegistryClientOptions`. An extensible enum `KnownContainerRegistryAudience` is introduced which has known audience values.

### Bugs Fixed

### Other Changes
Expand Down
54 changes: 41 additions & 13 deletions sdk/containerregistry/container-registry/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,17 @@ To use this client library in the browser, first you need to use a bundler. For
The [Azure Identity library][identity] provides easy Azure Active Directory support for authentication.

```javascript
const { ContainerRegistryClient } = require("@azure/container-registry");
const {
ContainerRegistryClient,
KnownContainerRegistryAudience
} = require("@azure/container-registry");
const { DefaultAzureCredential } = require("@azure/identity");

const endpoint = process.env.CONTAINER_REGISTRY_ENDPOINT;
// Create a ContainerRegistryClient that will authenticate through Active Directory
const client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential());
const client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential(), {
audience: KnownContainerRegistryAudience.AzureResourceManagerPublicCloud
});
```

Note that these samples assume you have a `CONTAINER_REGISTRY_ENDPOINT` environment variable set, which is the URL including the name of the login server and the `https://` prefix.
Expand All @@ -74,10 +79,13 @@ Note that these samples assume you have a `CONTAINER_REGISTRY_ENDPOINT` environm
To authenticate with a registry in a [National Cloud](https://docs.microsoft.com/azure/active-directory/develop/authentication-national-cloud), you will need to make the following additions to your configuration:

- Set the `authorityHost` in the credential options or via the `AZURE_AUTHORITY_HOST` environment variable
- Set the `authenticationScope` in `ContainerRegistryClientOptions`
- Set the `audience` in `ContainerRegistryClientOptions`

```javascript
const { ContainerRegistryClient } = require("@azure/container-registry");
const {
ContainerRegistryClient,
KnownContainerRegistryAudience
} = require("@azure/container-registry");
const { DefaultAzureCredential, AzureAuthorityHosts } = require("@azure/identity");

const endpoint = process.env.CONTAINER_REGISTRY_ENDPOINT;
Expand All @@ -86,7 +94,7 @@ const client = new ContainerRegistryClient(
endpoint,
new DefaultAzureCredential({ authorityHost: AzureAuthorityHosts.AzureChina }),
{
authenticationScope: "https://management.chinacloudapi.cn/.default"
audience: KnownContainerRegistryAudience.AzureResourceManagerChina
}
);
```
Expand All @@ -106,14 +114,19 @@ For more information please see [Container Registry Concepts](https://docs.micro
Iterate through the collection of repositories in the registry.

```javascript
const { ContainerRegistryClient } = require("@azure/container-registry");
const {
ContainerRegistryClient,
KnownContainerRegistryAudience
} = require("@azure/container-registry");
const { DefaultAzureCredential } = require("@azure/identity");

async function main() {
// endpoint should be in the form of "https://myregistryname.azurecr.io"
// where "myregistryname" is the actual name of your registry
const endpoint = process.env.CONTAINER_REGISTRY_ENDPOINT || "<endpoint>";
const client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential());
const client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential(), {
audience: KnownContainerRegistryAudience.AzureResourceManagerPublicCloud
});

console.log("Listing repositories");
const iterator = client.listRepositoryNames();
Expand All @@ -130,14 +143,19 @@ main().catch((err) => {
### List tags with anonymous access

```javascript
const { ContainerRegistryClient } = require("@azure/container-registry");
const {
ContainerRegistryClient,
KnownContainerRegistryAudience
} = require("@azure/container-registry");

async function main() {
// Get the service endpoint from the environment
const endpoint = process.env.CONTAINER_REGISTRY_ENDPOINT || "<endpoint>";

// Create a new ContainerRegistryClient for anonymous access
const client = new ContainerRegistryClient(endpoint);
const client = new ContainerRegistryClient(endpoint, {
audience: KnownContainerRegistryAudience.AzureResourceManagerPublicCloud
});

// Obtain a RegistryArtifact object to get access to image operations
const image = client.getArtifact("library/hello-world", "latest");
Expand All @@ -160,15 +178,20 @@ main().catch((err) => {
### Set artifact properties

```javascript
const { ContainerRegistryClient } = require("@azure/container-registry");
const {
ContainerRegistryClient,
KnownContainerRegistryAudience
} = require("@azure/container-registry");
const { DefaultAzureCredential } = require("@azure/identity");

async function main() {
// Get the service endpoint from the environment
const endpoint = process.env.CONTAINER_REGISTRY_ENDPOINT || "<endpoint>";

// Create a new ContainerRegistryClient and RegistryArtifact to access image operations
const client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential());
const client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential(), {
audience: KnownContainerRegistryAudience.AzureResourceManagerPublicCloud
});
const image = client.getArtifact("library/hello-world", "v1");

// Set permissions on the image's "latest" tag
Expand All @@ -183,14 +206,19 @@ main().catch((err) => {
### Delete images

```javascript
const { ContainerRegistryClient } = require("@azure/container-registry");
const {
ContainerRegistryClient,
KnownContainerRegistryAudience
} = require("@azure/container-registry");
const { DefaultAzureCredential } = require("@azure/identity");

async function main() {
// Get the service endpoint from the environment
const endpoint = process.env.CONTAINER_REGISTRY_ENDPOINT || "<endpoint>";
// Create a new ContainerRegistryClient
const client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential());
const client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential(), {
audience: KnownContainerRegistryAudience.AzureResourceManagerPublicCloud
});

// Iterate through repositories
const repositoryNames = client.listRepositoryNames();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export class ContainerRegistryClient {

// @public
export interface ContainerRegistryClientOptions extends PipelineOptions {
authenticationScope?: string;
audience?: string;
}

// @public
Expand Down Expand Up @@ -149,6 +149,14 @@ export enum KnownArtifactOperatingSystem {
Windows = "windows"
}

// @public
export enum KnownContainerRegistryAudience {
AzureResourceManagerChina = "https://management.chinacloudapi.cn",
AzureResourceManagerGermany = "https://management.microsoftazure.de",
AzureResourceManagerGovernment = "https://management.usgovcloudapi.net",
AzureResourceManagerPublicCloud = "https://management.azure.com"
}

// @public
export interface ListManifestPropertiesOptions extends OperationOptions {
orderBy?: ManifestOrderBy;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
// in a public registry that belongs to someone else. In this case, the user would need to access
// the registry anonymously. Anonymous access allows a user to list all the collections there, but
// they wouldn't have permissions to modify or delete any of the images in the registry.
import { ContainerRegistryClient } from "@azure/container-registry";
import { ContainerRegistryClient, KnownContainerRegistryAudience } from "@azure/container-registry";
import * as dotenv from "dotenv";
dotenv.config();

Expand All @@ -20,7 +20,9 @@ async function main() {
const endpoint = process.env.CONTAINER_REGISTRY_ENDPOINT || "<endpoint>";

// Create a new ContainerRegistryClient for anonymous access
const client = new ContainerRegistryClient(endpoint);
const client = new ContainerRegistryClient(endpoint, {
audience: KnownContainerRegistryAudience.AzureResourceManagerPublicCloud
});

// Obtain a RegistryArtifact object to get access to image operations
const image = client.getArtifact("library/hello-world", "latest");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* @azsdk-weight 10
*/

import { ContainerRegistryClient } from "@azure/container-registry";
import { ContainerRegistryClient, KnownContainerRegistryAudience } from "@azure/container-registry";
import { DefaultAzureCredential } from "@azure/identity";
import * as dotenv from "dotenv";
dotenv.config();
Expand All @@ -15,7 +15,9 @@ export async function main() {
// endpoint should be in the form of "https://myregistryname.azurecr.io"
// where "myregistryname" is the actual name of your registry
const endpoint = process.env.CONTAINER_REGISTRY_ENDPOINT || "<endpoint>";
const client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential());
const client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential(), {
audience: KnownContainerRegistryAudience.AzureResourceManagerPublicCloud
});
await listRepositoryNames(client);

// Advanced: listing by pages
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
// A common use case for Azure Container Registries is to scan the repositories
// in a registry and delete all but the most recent n images, or all images
// older than a certain date.
import { ContainerRegistryClient } from "@azure/container-registry";
import { ContainerRegistryClient, KnownContainerRegistryAudience } from "@azure/container-registry";
import { DefaultAzureCredential } from "@azure/identity";
import * as dotenv from "dotenv";
dotenv.config();
Expand All @@ -18,7 +18,9 @@ async function main() {
// Get the service endpoint from the environment
const endpoint = process.env.CONTAINER_REGISTRY_ENDPOINT || "<endpoint>";
// Create a new ContainerRegistryClient
const client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential());
const client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential(), {
audience: KnownContainerRegistryAudience.AzureResourceManagerPublicCloud
});

// Iterate through repositories
const repositoryNames = client.listRepositoryNames();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import {
ContainerRepository,
ArtifactManifestProperties,
ContainerRegistryClient,
RegistryArtifact
RegistryArtifact,
KnownContainerRegistryAudience
} from "@azure/container-registry";
import { DefaultAzureCredential } from "@azure/identity";
import * as dotenv from "dotenv";
Expand All @@ -23,7 +24,9 @@ export async function main() {
const repositoryName = process.env.REPOSITORY_NAME || "<repository name>";
const pageSize = 1;

const client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential());
const client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential(), {
audience: KnownContainerRegistryAudience.AzureResourceManagerPublicCloud
});
const repository = client.getRepository(repositoryName);
await getProperties(repository);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

// This sample assumes the registry has a repository `hello-world` with image tagged `v1`.

import { ContainerRegistryClient } from "@azure/container-registry";
import { ContainerRegistryClient, KnownContainerRegistryAudience } from "@azure/container-registry";
import { DefaultAzureCredential } from "@azure/identity";
import * as dotenv from "dotenv";
dotenv.config();
Expand All @@ -17,7 +17,9 @@ async function main() {
// Get the service endpoint from the environment
const endpoint = process.env.CONTAINER_REGISTRY_ENDPOINT || "<endpoint>";
// Create a new ContainerRegistryClient
const client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential());
const client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential(), {
audience: KnownContainerRegistryAudience.AzureResourceManagerPublicCloud
});
const image = client.getArtifact("library/hello-world", "v1");

// Set permissions on the image's "latest" tag
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
// in a public registry that belongs to someone else. In this case, the user would need to access
// the registry anonymously. Anonymous access allows a user to list all the collections there, but
// they wouldn't have permissions to modify or delete any of the images in the registry.
const { ContainerRegistryClient } = require("@azure/container-registry");
const {
ContainerRegistryClient,
KnownContainerRegistryAudience
} = require("@azure/container-registry");
const dotenv = require("dotenv");
dotenv.config();

Expand All @@ -18,7 +21,9 @@ async function main() {
const endpoint = process.env.CONTAINER_REGISTRY_ENDPOINT || "<endpoint>";

// Create a new ContainerRegistryClient for anonymous access
const client = new ContainerRegistryClient(endpoint);
const client = new ContainerRegistryClient(endpoint, {
audience: KnownContainerRegistryAudience.AzureResourceManagerPublicCloud
});

// Obtain a RegistryArtifact object to get access to image operations
const image = client.getArtifact("library/hello-world", "latest");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
* @summary Lists repository names and deletes a repository.
*/

const { ContainerRegistryClient } = require("@azure/container-registry");
const {
ContainerRegistryClient,
KnownContainerRegistryAudience
} = require("@azure/container-registry");
const { DefaultAzureCredential } = require("@azure/identity");
const dotenv = require("dotenv");
dotenv.config();
Expand All @@ -14,7 +17,9 @@ async function main() {
// endpoint should be in the form of "https://myregistryname.azurecr.io"
// where "myregistryname" is the actual name of your registry
const endpoint = process.env.CONTAINER_REGISTRY_ENDPOINT || "<endpoint>";
const client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential());
const client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential(), {
audience: KnownContainerRegistryAudience.AzureResourceManagerPublicCloud
});
await listRepositoryNames(client);

// Advanced: listing by pages
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@
// A common use case for Azure Container Registries is to scan the repositories
// in a registry and delete all but the most recent n images, or all images
// older than a certain date.
const { ContainerRegistryClient } = require("@azure/container-registry");
const {
ContainerRegistryClient,
KnownContainerRegistryAudience
} = require("@azure/container-registry");
const { DefaultAzureCredential } = require("@azure/identity");
const dotenv = require("dotenv");
dotenv.config();
Expand All @@ -17,7 +20,9 @@ async function main() {
// Get the service endpoint from the environment
const endpoint = process.env.CONTAINER_REGISTRY_ENDPOINT || "<endpoint>";
// Create a new ContainerRegistryClient
const client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential());
const client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential(), {
audience: KnownContainerRegistryAudience.AzureResourceManagerPublicCloud
});

// Iterate through repositories
const repositoryNames = client.listRepositoryNames();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
* @summary Uses ContainerRepository and RegistryArtifact to work with manifests, tags, and artifacts.
*/

const { ContainerRegistryClient } = require("@azure/container-registry");
const {
ContainerRegistryClient,
KnownContainerRegistryAudience
} = require("@azure/container-registry");
const { DefaultAzureCredential } = require("@azure/identity");
const dotenv = require("dotenv");
dotenv.config();
Expand All @@ -17,7 +20,9 @@ async function main() {
const repositoryName = process.env.REPOSITORY_NAME || "<repository name>";
const pageSize = 1;

const client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential());
const client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential(), {
audience: KnownContainerRegistryAudience.AzureResourceManagerPublicCloud
});
const repository = client.getRepository(repositoryName);
await getProperties(repository);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@

// This sample assumes the registry has a repository `hello-world` with image tagged `v1`.

const { ContainerRegistryClient } = require("@azure/container-registry");
const {
ContainerRegistryClient,
KnownContainerRegistryAudience
} = require("@azure/container-registry");
const { DefaultAzureCredential } = require("@azure/identity");
const dotenv = require("dotenv");
dotenv.config();
Expand All @@ -16,7 +19,9 @@ async function main() {
// Get the service endpoint from the environment
const endpoint = process.env.CONTAINER_REGISTRY_ENDPOINT || "<endpoint>";
// Create a new ContainerRegistryClient
const client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential());
const client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential(), {
audience: KnownContainerRegistryAudience.AzureResourceManagerPublicCloud
});
const image = client.getArtifact("library/hello-world", "v1");

// Set permissions on the image's "latest" tag
Expand Down
Loading

0 comments on commit eeae1e5

Please sign in to comment.