diff --git a/sdk/containerregistry/container-registry/CHANGELOG.md b/sdk/containerregistry/container-registry/CHANGELOG.md index 365262dde392..7ce94ef41eac 100644 --- a/sdk/containerregistry/container-registry/CHANGELOG.md +++ b/sdk/containerregistry/container-registry/CHANGELOG.md @@ -2,6 +2,21 @@ ## 1.0.0-beta.2 (Unreleased) +### Features Added + +- Added new properties to allow easier interaction with other docker tools: + - `loginServer` in `ContainerRegistryClient`. + - `fullyQualifiedName` in `ContainerRepository` + +### Breaking Changes + +The public API surface of this library has been re-designed. Notable changes include + +- Removed: `ContainerRepositoryClient`. Operations on repositories are now grouped in `ContainerRepository` type and operations on artifacts are now in `RegistryArtifact` type. Some `*Options` types are also renamed accordingly. +- Renamed: `endpoint` property is renamed to `registryUrl`. +- Renamed: `listRepositories()` is renamed to `listRepositoryNames()` in `ContainerRegistryClient`. +- Renamed: "RegistryArtifact" in property or function names replaced by "Manifest". +- Renamed: `*OrderBy` values is now capitalized as `timeDesc` and `timeAsc`. Previously they are all in lower case. ## 1.0.0-beta.1 (2021-04-06) diff --git a/sdk/containerregistry/container-registry/README.md b/sdk/containerregistry/container-registry/README.md index 7cf6583485ed..712c195494a0 100644 --- a/sdk/containerregistry/container-registry/README.md +++ b/sdk/containerregistry/container-registry/README.md @@ -55,12 +55,12 @@ The [Azure Identity library][identity] provides easy Azure Active Directory supp const { ContainerRegistryClient } = require("@azure/container-registry"); const { DefaultAzureCredential } = require("@azure/identity"); -const endpoint = process.env.REGISTRY_ENDPOINT; +const endpoint = process.env.CONTAINER_REGISTRY_ENDPOINT; // Create a ContainerRegistryClient that will authenticate through Active Directory const client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential()); ``` -Note that these samples assume you have a `REGISTRY_ENDPOINT` environment variable set, which is the URL including the name of the login server and the `https://` prefix. +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. For more information on using AAD with Azure Container Registry, please see the service's [Authentication Overview](https://docs.microsoft.com/azure/container-registry/container-registry-authentication). @@ -83,11 +83,11 @@ 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.REGISTRY_ENDPOINT; + const endpoint = process.env.CONTAINER_REGISTRY_ENDPOINT || ""; const client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential()); console.log("Listing repositories"); - const iterator = client.listRepositories(); + const iterator = client.listRepositoryNames(); for await (const repository of iterator) { console.log(` repository: ${repository}`); } diff --git a/sdk/containerregistry/container-registry/recordings/browsers/containerregistryclient_functional_tests/recording_deletes_repository_of_given_name.json b/sdk/containerregistry/container-registry/recordings/browsers/containerregistryclient_tests/recording_deletes_repository_of_given_name.json similarity index 100% rename from sdk/containerregistry/container-registry/recordings/browsers/containerregistryclient_functional_tests/recording_deletes_repository_of_given_name.json rename to sdk/containerregistry/container-registry/recordings/browsers/containerregistryclient_tests/recording_deletes_repository_of_given_name.json diff --git a/sdk/containerregistry/container-registry/recordings/browsers/containerregistryclient_functional_tests/recording_should_list_repositories.json b/sdk/containerregistry/container-registry/recordings/browsers/containerregistryclient_tests/recording_should_list_repositories.json similarity index 100% rename from sdk/containerregistry/container-registry/recordings/browsers/containerregistryclient_functional_tests/recording_should_list_repositories.json rename to sdk/containerregistry/container-registry/recordings/browsers/containerregistryclient_tests/recording_should_list_repositories.json diff --git a/sdk/containerregistry/container-registry/recordings/browsers/containerrepositoryclient_functional_tests/recording_deletes_a_given_tag.json b/sdk/containerregistry/container-registry/recordings/browsers/repository_and_artifact_tests/recording_deletes_a_given_tag.json similarity index 100% rename from sdk/containerregistry/container-registry/recordings/browsers/containerrepositoryclient_functional_tests/recording_deletes_a_given_tag.json rename to sdk/containerregistry/container-registry/recordings/browsers/repository_and_artifact_tests/recording_deletes_a_given_tag.json diff --git a/sdk/containerregistry/container-registry/recordings/browsers/containerrepositoryclient_functional_tests/recording_sets_manifest_properties.json b/sdk/containerregistry/container-registry/recordings/browsers/repository_and_artifact_tests/recording_sets_manifest_properties.json similarity index 95% rename from sdk/containerregistry/container-registry/recordings/browsers/containerrepositoryclient_functional_tests/recording_sets_manifest_properties.json rename to sdk/containerregistry/container-registry/recordings/browsers/repository_and_artifact_tests/recording_sets_manifest_properties.json index 4f8d77a56264..906f607721ca 100644 --- a/sdk/containerregistry/container-registry/recordings/browsers/containerrepositoryclient_functional_tests/recording_sets_manifest_properties.json +++ b/sdk/containerregistry/container-registry/recordings/browsers/repository_and_artifact_tests/recording_sets_manifest_properties.json @@ -85,7 +85,7 @@ "query": {}, "requestBody": null, "status": 200, - "response": "{\"registry\":\"myregistry.azurecr.io\",\"imageName\":\"library/hello-world\",\"tag\":{\"name\":\"test1\",\"digest\":\"sha256:f2266cbfc127c960fd30e76b7c792dc23b588c0db76233517e1891a4e357d519\",\"createdTime\":\"2021-04-16T21:16:56.1925402Z\",\"lastUpdateTime\":\"2021-04-16T21:16:56.1925402Z\",\"signed\":false,\"changeableAttributes\":{\"deleteEnabled\":true,\"writeEnabled\":true,\"readEnabled\":true,\"listEnabled\":true}}}\n", + "response": "{\"registry\":\"myregistry.azurecr.io\",\"imageName\":\"library/hello-world\",\"tag\":{\"name\":\"test1\",\"digest\":\"sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792\",\"createdTime\":\"2021-04-16T21:16:56.1925402Z\",\"lastUpdateTime\":\"2021-04-16T21:16:56.1925402Z\",\"signed\":false,\"changeableAttributes\":{\"deleteEnabled\":true,\"writeEnabled\":true,\"readEnabled\":true,\"listEnabled\":true}}}\n", "responseHeaders": { "access-control-expose-headers": "Docker-Content-Digest, WWW-Authenticate, Link, X-Ms-Correlation-Request-Id", "connection": "keep-alive", @@ -101,7 +101,7 @@ }, { "method": "GET", - "url": "https://myregistry.azurecr.io/acr/v1/library%2Fhello-world/_manifests/sha256%3Af2266cbfc127c960fd30e76b7c792dc23b588c0db76233517e1891a4e357d519", + "url": "https://myregistry.azurecr.io/acr/v1/library%2Fhello-world/_manifests/sha256%3A1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792", "query": {}, "requestBody": null, "status": 401, @@ -156,11 +156,11 @@ }, { "method": "GET", - "url": "https://myregistry.azurecr.io/acr/v1/library%2Fhello-world/_manifests/sha256%3Af2266cbfc127c960fd30e76b7c792dc23b588c0db76233517e1891a4e357d519", + "url": "https://myregistry.azurecr.io/acr/v1/library%2Fhello-world/_manifests/sha256%3A1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792", "query": {}, "requestBody": null, "status": 200, - "response": "{\"registry\":\"myregistry.azurecr.io\",\"imageName\":\"library/hello-world\",\"manifest\":{\"digest\":\"sha256:f2266cbfc127c960fd30e76b7c792dc23b588c0db76233517e1891a4e357d519\",\"imageSize\":0,\"createdTime\":\"2021-04-16T21:16:56.0686499Z\",\"lastUpdateTime\":\"2021-04-16T21:16:56.0686499Z\",\"mediaType\":\"application/vnd.docker.distribution.manifest.list.v2+json\",\"tags\":[\"test1\"],\"changeableAttributes\":{\"deleteEnabled\":true,\"writeEnabled\":true,\"readEnabled\":true,\"listEnabled\":true},\"references\":[{\"digest\":\"sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792\",\"architecture\":\"amd64\",\"os\":\"linux\"},{\"digest\":\"sha256:e5785cb0c62cebbed4965129bae371f0589cadd6d84798fb58c2c5f9e237efd9\",\"architecture\":\"arm\",\"os\":\"linux\"},{\"digest\":\"sha256:50b8560ad574c779908da71f7ce370c0a2471c098d44d1c8f6b513c5a55eeeb1\",\"architecture\":\"arm\",\"os\":\"linux\"},{\"digest\":\"sha256:963612c5503f3f1674f315c67089dee577d8cc6afc18565e0b4183ae355fb343\",\"architecture\":\"arm64\",\"os\":\"linux\"},{\"digest\":\"sha256:cb55d8f7347376e1ba38ca740904b43c9a52f66c7d2ae1ef1a0de1bc9f40df98\",\"architecture\":\"386\",\"os\":\"linux\"},{\"digest\":\"sha256:88b2e00179bd6c4064612403c8d42a13de7ca809d61fee966ce9e129860a8a90\",\"architecture\":\"mips64le\",\"os\":\"linux\"},{\"digest\":\"sha256:bb7ab0fa94fdd78aca84b27a1bd46c4b811051f9b69905d81f5f267fc6546a9d\",\"architecture\":\"ppc64le\",\"os\":\"linux\"},{\"digest\":\"sha256:e49abad529e5d9bd6787f3abeab94e09ba274fe34731349556a850b9aebbf7bf\",\"architecture\":\"s390x\",\"os\":\"linux\"},{\"digest\":\"sha256:ea0cfb27fd41ea0405d3095880c1efa45710f5bcdddb7d7d5a7317ad4825ae14\",\"architecture\":\"amd64\",\"os\":\"windows\"}]}}\n", + "response": "{\"registry\":\"myregistry.azurecr.io\",\"imageName\":\"library/hello-world\",\"manifest\":{\"digest\":\"sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792\",\"imageSize\":0,\"createdTime\":\"2021-04-16T21:16:56.0686499Z\",\"lastUpdateTime\":\"2021-04-16T21:16:56.0686499Z\",\"mediaType\":\"application/vnd.docker.distribution.manifest.list.v2+json\",\"tags\":[\"test1\"],\"changeableAttributes\":{\"deleteEnabled\":true,\"writeEnabled\":true,\"readEnabled\":true,\"listEnabled\":true},\"references\":[{\"digest\":\"sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792\",\"architecture\":\"amd64\",\"os\":\"linux\"},{\"digest\":\"sha256:e5785cb0c62cebbed4965129bae371f0589cadd6d84798fb58c2c5f9e237efd9\",\"architecture\":\"arm\",\"os\":\"linux\"},{\"digest\":\"sha256:50b8560ad574c779908da71f7ce370c0a2471c098d44d1c8f6b513c5a55eeeb1\",\"architecture\":\"arm\",\"os\":\"linux\"},{\"digest\":\"sha256:963612c5503f3f1674f315c67089dee577d8cc6afc18565e0b4183ae355fb343\",\"architecture\":\"arm64\",\"os\":\"linux\"},{\"digest\":\"sha256:cb55d8f7347376e1ba38ca740904b43c9a52f66c7d2ae1ef1a0de1bc9f40df98\",\"architecture\":\"386\",\"os\":\"linux\"},{\"digest\":\"sha256:88b2e00179bd6c4064612403c8d42a13de7ca809d61fee966ce9e129860a8a90\",\"architecture\":\"mips64le\",\"os\":\"linux\"},{\"digest\":\"sha256:bb7ab0fa94fdd78aca84b27a1bd46c4b811051f9b69905d81f5f267fc6546a9d\",\"architecture\":\"ppc64le\",\"os\":\"linux\"},{\"digest\":\"sha256:e49abad529e5d9bd6787f3abeab94e09ba274fe34731349556a850b9aebbf7bf\",\"architecture\":\"s390x\",\"os\":\"linux\"},{\"digest\":\"sha256:ea0cfb27fd41ea0405d3095880c1efa45710f5bcdddb7d7d5a7317ad4825ae14\",\"architecture\":\"amd64\",\"os\":\"windows\"}]}}\n", "responseHeaders": { "access-control-expose-headers": "Docker-Content-Digest, WWW-Authenticate, Link, X-Ms-Correlation-Request-Id", "connection": "keep-alive", @@ -176,7 +176,7 @@ }, { "method": "PATCH", - "url": "https://myregistry.azurecr.io/acr/v1/library%2Fhello-world/_manifests/sha256%3Af2266cbfc127c960fd30e76b7c792dc23b588c0db76233517e1891a4e357d519", + "url": "https://myregistry.azurecr.io/acr/v1/library%2Fhello-world/_manifests/sha256%3A1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792", "query": {}, "requestBody": "{\"deleteEnabled\":false,\"writeEnabled\":false,\"listEnabled\":false,\"readEnabled\":false}", "status": 401, @@ -231,11 +231,11 @@ }, { "method": "PATCH", - "url": "https://myregistry.azurecr.io/acr/v1/library%2Fhello-world/_manifests/sha256%3Af2266cbfc127c960fd30e76b7c792dc23b588c0db76233517e1891a4e357d519", + "url": "https://myregistry.azurecr.io/acr/v1/library%2Fhello-world/_manifests/sha256%3A1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792", "query": {}, "requestBody": "{\"deleteEnabled\":false,\"writeEnabled\":false,\"listEnabled\":false,\"readEnabled\":false}", "status": 200, - "response": "{\"registry\":\"myregistry.azurecr.io\",\"imageName\":\"library/hello-world\",\"manifest\":{\"digest\":\"sha256:f2266cbfc127c960fd30e76b7c792dc23b588c0db76233517e1891a4e357d519\",\"imageSize\":0,\"createdTime\":\"2021-04-16T21:16:56.0686499Z\",\"lastUpdateTime\":\"2021-04-16T21:16:56.0686499Z\",\"mediaType\":\"application/vnd.docker.distribution.manifest.list.v2+json\",\"tags\":[\"test1\"],\"changeableAttributes\":{\"deleteEnabled\":false,\"writeEnabled\":false,\"readEnabled\":false,\"listEnabled\":false},\"references\":[{\"digest\":\"sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792\",\"architecture\":\"amd64\",\"os\":\"linux\"},{\"digest\":\"sha256:e5785cb0c62cebbed4965129bae371f0589cadd6d84798fb58c2c5f9e237efd9\",\"architecture\":\"arm\",\"os\":\"linux\"},{\"digest\":\"sha256:50b8560ad574c779908da71f7ce370c0a2471c098d44d1c8f6b513c5a55eeeb1\",\"architecture\":\"arm\",\"os\":\"linux\"},{\"digest\":\"sha256:963612c5503f3f1674f315c67089dee577d8cc6afc18565e0b4183ae355fb343\",\"architecture\":\"arm64\",\"os\":\"linux\"},{\"digest\":\"sha256:cb55d8f7347376e1ba38ca740904b43c9a52f66c7d2ae1ef1a0de1bc9f40df98\",\"architecture\":\"386\",\"os\":\"linux\"},{\"digest\":\"sha256:88b2e00179bd6c4064612403c8d42a13de7ca809d61fee966ce9e129860a8a90\",\"architecture\":\"mips64le\",\"os\":\"linux\"},{\"digest\":\"sha256:bb7ab0fa94fdd78aca84b27a1bd46c4b811051f9b69905d81f5f267fc6546a9d\",\"architecture\":\"ppc64le\",\"os\":\"linux\"},{\"digest\":\"sha256:e49abad529e5d9bd6787f3abeab94e09ba274fe34731349556a850b9aebbf7bf\",\"architecture\":\"s390x\",\"os\":\"linux\"},{\"digest\":\"sha256:ea0cfb27fd41ea0405d3095880c1efa45710f5bcdddb7d7d5a7317ad4825ae14\",\"architecture\":\"amd64\",\"os\":\"windows\"}]}}\n", + "response": "{\"registry\":\"myregistry.azurecr.io\",\"imageName\":\"library/hello-world\",\"manifest\":{\"digest\":\"sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792\",\"imageSize\":0,\"createdTime\":\"2021-04-16T21:16:56.0686499Z\",\"lastUpdateTime\":\"2021-04-16T21:16:56.0686499Z\",\"mediaType\":\"application/vnd.docker.distribution.manifest.list.v2+json\",\"tags\":[\"test1\"],\"changeableAttributes\":{\"deleteEnabled\":false,\"writeEnabled\":false,\"readEnabled\":false,\"listEnabled\":false},\"references\":[{\"digest\":\"sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792\",\"architecture\":\"amd64\",\"os\":\"linux\"},{\"digest\":\"sha256:e5785cb0c62cebbed4965129bae371f0589cadd6d84798fb58c2c5f9e237efd9\",\"architecture\":\"arm\",\"os\":\"linux\"},{\"digest\":\"sha256:50b8560ad574c779908da71f7ce370c0a2471c098d44d1c8f6b513c5a55eeeb1\",\"architecture\":\"arm\",\"os\":\"linux\"},{\"digest\":\"sha256:963612c5503f3f1674f315c67089dee577d8cc6afc18565e0b4183ae355fb343\",\"architecture\":\"arm64\",\"os\":\"linux\"},{\"digest\":\"sha256:cb55d8f7347376e1ba38ca740904b43c9a52f66c7d2ae1ef1a0de1bc9f40df98\",\"architecture\":\"386\",\"os\":\"linux\"},{\"digest\":\"sha256:88b2e00179bd6c4064612403c8d42a13de7ca809d61fee966ce9e129860a8a90\",\"architecture\":\"mips64le\",\"os\":\"linux\"},{\"digest\":\"sha256:bb7ab0fa94fdd78aca84b27a1bd46c4b811051f9b69905d81f5f267fc6546a9d\",\"architecture\":\"ppc64le\",\"os\":\"linux\"},{\"digest\":\"sha256:e49abad529e5d9bd6787f3abeab94e09ba274fe34731349556a850b9aebbf7bf\",\"architecture\":\"s390x\",\"os\":\"linux\"},{\"digest\":\"sha256:ea0cfb27fd41ea0405d3095880c1efa45710f5bcdddb7d7d5a7317ad4825ae14\",\"architecture\":\"amd64\",\"os\":\"windows\"}]}}\n", "responseHeaders": { "access-control-expose-headers": "Docker-Content-Digest, WWW-Authenticate, Link, X-Ms-Correlation-Request-Id", "connection": "keep-alive", @@ -251,7 +251,7 @@ }, { "method": "PATCH", - "url": "https://myregistry.azurecr.io/acr/v1/library%2Fhello-world/_manifests/sha256%3Af2266cbfc127c960fd30e76b7c792dc23b588c0db76233517e1891a4e357d519", + "url": "https://myregistry.azurecr.io/acr/v1/library%2Fhello-world/_manifests/sha256%3A1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792", "query": {}, "requestBody": "{\"deleteEnabled\":true,\"writeEnabled\":true,\"listEnabled\":true,\"readEnabled\":true}", "status": 401, @@ -306,11 +306,11 @@ }, { "method": "PATCH", - "url": "https://myregistry.azurecr.io/acr/v1/library%2Fhello-world/_manifests/sha256%3Af2266cbfc127c960fd30e76b7c792dc23b588c0db76233517e1891a4e357d519", + "url": "https://myregistry.azurecr.io/acr/v1/library%2Fhello-world/_manifests/sha256%3A1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792", "query": {}, "requestBody": "{\"deleteEnabled\":true,\"writeEnabled\":true,\"listEnabled\":true,\"readEnabled\":true}", "status": 200, - "response": "{\"registry\":\"myregistry.azurecr.io\",\"imageName\":\"library/hello-world\",\"manifest\":{\"digest\":\"sha256:f2266cbfc127c960fd30e76b7c792dc23b588c0db76233517e1891a4e357d519\",\"imageSize\":0,\"createdTime\":\"2021-04-16T21:16:56.0686499Z\",\"lastUpdateTime\":\"2021-04-16T21:16:56.0686499Z\",\"mediaType\":\"application/vnd.docker.distribution.manifest.list.v2+json\",\"tags\":[\"test1\"],\"changeableAttributes\":{\"deleteEnabled\":true,\"writeEnabled\":true,\"readEnabled\":true,\"listEnabled\":true},\"references\":[{\"digest\":\"sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792\",\"architecture\":\"amd64\",\"os\":\"linux\"},{\"digest\":\"sha256:e5785cb0c62cebbed4965129bae371f0589cadd6d84798fb58c2c5f9e237efd9\",\"architecture\":\"arm\",\"os\":\"linux\"},{\"digest\":\"sha256:50b8560ad574c779908da71f7ce370c0a2471c098d44d1c8f6b513c5a55eeeb1\",\"architecture\":\"arm\",\"os\":\"linux\"},{\"digest\":\"sha256:963612c5503f3f1674f315c67089dee577d8cc6afc18565e0b4183ae355fb343\",\"architecture\":\"arm64\",\"os\":\"linux\"},{\"digest\":\"sha256:cb55d8f7347376e1ba38ca740904b43c9a52f66c7d2ae1ef1a0de1bc9f40df98\",\"architecture\":\"386\",\"os\":\"linux\"},{\"digest\":\"sha256:88b2e00179bd6c4064612403c8d42a13de7ca809d61fee966ce9e129860a8a90\",\"architecture\":\"mips64le\",\"os\":\"linux\"},{\"digest\":\"sha256:bb7ab0fa94fdd78aca84b27a1bd46c4b811051f9b69905d81f5f267fc6546a9d\",\"architecture\":\"ppc64le\",\"os\":\"linux\"},{\"digest\":\"sha256:e49abad529e5d9bd6787f3abeab94e09ba274fe34731349556a850b9aebbf7bf\",\"architecture\":\"s390x\",\"os\":\"linux\"},{\"digest\":\"sha256:ea0cfb27fd41ea0405d3095880c1efa45710f5bcdddb7d7d5a7317ad4825ae14\",\"architecture\":\"amd64\",\"os\":\"windows\"}]}}\n", + "response": "{\"registry\":\"myregistry.azurecr.io\",\"imageName\":\"library/hello-world\",\"manifest\":{\"digest\":\"sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792\",\"imageSize\":0,\"createdTime\":\"2021-04-16T21:16:56.0686499Z\",\"lastUpdateTime\":\"2021-04-16T21:16:56.0686499Z\",\"mediaType\":\"application/vnd.docker.distribution.manifest.list.v2+json\",\"tags\":[\"test1\"],\"changeableAttributes\":{\"deleteEnabled\":true,\"writeEnabled\":true,\"readEnabled\":true,\"listEnabled\":true},\"references\":[{\"digest\":\"sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792\",\"architecture\":\"amd64\",\"os\":\"linux\"},{\"digest\":\"sha256:e5785cb0c62cebbed4965129bae371f0589cadd6d84798fb58c2c5f9e237efd9\",\"architecture\":\"arm\",\"os\":\"linux\"},{\"digest\":\"sha256:50b8560ad574c779908da71f7ce370c0a2471c098d44d1c8f6b513c5a55eeeb1\",\"architecture\":\"arm\",\"os\":\"linux\"},{\"digest\":\"sha256:963612c5503f3f1674f315c67089dee577d8cc6afc18565e0b4183ae355fb343\",\"architecture\":\"arm64\",\"os\":\"linux\"},{\"digest\":\"sha256:cb55d8f7347376e1ba38ca740904b43c9a52f66c7d2ae1ef1a0de1bc9f40df98\",\"architecture\":\"386\",\"os\":\"linux\"},{\"digest\":\"sha256:88b2e00179bd6c4064612403c8d42a13de7ca809d61fee966ce9e129860a8a90\",\"architecture\":\"mips64le\",\"os\":\"linux\"},{\"digest\":\"sha256:bb7ab0fa94fdd78aca84b27a1bd46c4b811051f9b69905d81f5f267fc6546a9d\",\"architecture\":\"ppc64le\",\"os\":\"linux\"},{\"digest\":\"sha256:e49abad529e5d9bd6787f3abeab94e09ba274fe34731349556a850b9aebbf7bf\",\"architecture\":\"s390x\",\"os\":\"linux\"},{\"digest\":\"sha256:ea0cfb27fd41ea0405d3095880c1efa45710f5bcdddb7d7d5a7317ad4825ae14\",\"architecture\":\"amd64\",\"os\":\"windows\"}]}}\n", "responseHeaders": { "access-control-expose-headers": "Docker-Content-Digest, WWW-Authenticate, Link, X-Ms-Correlation-Request-Id", "connection": "keep-alive", @@ -330,4 +330,4 @@ "newDate": {} }, "hash": "f3720920182c1b873c6dc783e4a13215" -} \ No newline at end of file +} diff --git a/sdk/containerregistry/container-registry/recordings/browsers/containerrepositoryclient_functional_tests/recording_sets_repository_properties.json b/sdk/containerregistry/container-registry/recordings/browsers/repository_and_artifact_tests/recording_sets_repository_properties.json similarity index 100% rename from sdk/containerregistry/container-registry/recordings/browsers/containerrepositoryclient_functional_tests/recording_sets_repository_properties.json rename to sdk/containerregistry/container-registry/recordings/browsers/repository_and_artifact_tests/recording_sets_repository_properties.json diff --git a/sdk/containerregistry/container-registry/recordings/browsers/containerrepositoryclient_functional_tests/recording_sets_tag_properties.json b/sdk/containerregistry/container-registry/recordings/browsers/repository_and_artifact_tests/recording_sets_tag_properties.json similarity index 100% rename from sdk/containerregistry/container-registry/recordings/browsers/containerrepositoryclient_functional_tests/recording_sets_tag_properties.json rename to sdk/containerregistry/container-registry/recordings/browsers/repository_and_artifact_tests/recording_sets_tag_properties.json diff --git a/sdk/containerregistry/container-registry/recordings/browsers/containerrepositoryclient_functional_tests/recording_should_list_registry_artifacts.json b/sdk/containerregistry/container-registry/recordings/browsers/repository_and_artifact_tests/recording_should_list_registry_manifests.json similarity index 100% rename from sdk/containerregistry/container-registry/recordings/browsers/containerrepositoryclient_functional_tests/recording_should_list_registry_artifacts.json rename to sdk/containerregistry/container-registry/recordings/browsers/repository_and_artifact_tests/recording_should_list_registry_manifests.json diff --git a/sdk/containerregistry/container-registry/recordings/browsers/containerrepositoryclient_functional_tests/recording_should_list_registry_artifacts_by_pages.json b/sdk/containerregistry/container-registry/recordings/browsers/repository_and_artifact_tests/recording_should_list_registry_manifests_by_pages.json similarity index 100% rename from sdk/containerregistry/container-registry/recordings/browsers/containerrepositoryclient_functional_tests/recording_should_list_registry_artifacts_by_pages.json rename to sdk/containerregistry/container-registry/recordings/browsers/repository_and_artifact_tests/recording_should_list_registry_manifests_by_pages.json diff --git a/sdk/containerregistry/container-registry/recordings/browsers/containerrepositoryclient_functional_tests/recording_should_list_tags.json b/sdk/containerregistry/container-registry/recordings/browsers/repository_and_artifact_tests/recording_should_list_tags.json similarity index 100% rename from sdk/containerregistry/container-registry/recordings/browsers/containerrepositoryclient_functional_tests/recording_should_list_tags.json rename to sdk/containerregistry/container-registry/recordings/browsers/repository_and_artifact_tests/recording_should_list_tags.json diff --git a/sdk/containerregistry/container-registry/recordings/browsers/containerrepositoryclient_functional_tests/recording_should_list_tags_by_pages.json b/sdk/containerregistry/container-registry/recordings/browsers/repository_and_artifact_tests/recording_should_list_tags_by_pages.json similarity index 100% rename from sdk/containerregistry/container-registry/recordings/browsers/containerrepositoryclient_functional_tests/recording_should_list_tags_by_pages.json rename to sdk/containerregistry/container-registry/recordings/browsers/repository_and_artifact_tests/recording_should_list_tags_by_pages.json diff --git a/sdk/containerregistry/container-registry/recordings/browsers/containerrepositoryclient_functional_tests/recording_should_retrive_registry_artifact_properties_for_a_digest.json b/sdk/containerregistry/container-registry/recordings/browsers/repository_and_artifact_tests/recording_should_retrive_registry_artifact_properties_for_a_digest.json similarity index 100% rename from sdk/containerregistry/container-registry/recordings/browsers/containerrepositoryclient_functional_tests/recording_should_retrive_registry_artifact_properties_for_a_digest.json rename to sdk/containerregistry/container-registry/recordings/browsers/repository_and_artifact_tests/recording_should_retrive_registry_artifact_properties_for_a_digest.json diff --git a/sdk/containerregistry/container-registry/recordings/browsers/containerrepositoryclient_functional_tests/recording_should_retrive_registry_artifact_properties_for_a_tag.json b/sdk/containerregistry/container-registry/recordings/browsers/repository_and_artifact_tests/recording_should_retrive_registry_artifact_properties_for_a_tag.json similarity index 100% rename from sdk/containerregistry/container-registry/recordings/browsers/containerrepositoryclient_functional_tests/recording_should_retrive_registry_artifact_properties_for_a_tag.json rename to sdk/containerregistry/container-registry/recordings/browsers/repository_and_artifact_tests/recording_should_retrive_registry_artifact_properties_for_a_tag.json diff --git a/sdk/containerregistry/container-registry/recordings/browsers/containerrepositoryclient_functional_tests/recording_should_retrive_tag_properties.json b/sdk/containerregistry/container-registry/recordings/browsers/repository_and_artifact_tests/recording_should_retrive_tag_properties.json similarity index 100% rename from sdk/containerregistry/container-registry/recordings/browsers/containerrepositoryclient_functional_tests/recording_should_retrive_tag_properties.json rename to sdk/containerregistry/container-registry/recordings/browsers/repository_and_artifact_tests/recording_should_retrive_tag_properties.json diff --git a/sdk/containerregistry/container-registry/recordings/node/containerregistryclient_functional_tests/recording_deletes_repository_of_given_name.js b/sdk/containerregistry/container-registry/recordings/node/containerregistryclient_tests/recording_deletes_repository_of_given_name.js similarity index 100% rename from sdk/containerregistry/container-registry/recordings/node/containerregistryclient_functional_tests/recording_deletes_repository_of_given_name.js rename to sdk/containerregistry/container-registry/recordings/node/containerregistryclient_tests/recording_deletes_repository_of_given_name.js diff --git a/sdk/containerregistry/container-registry/recordings/node/containerregistryclient_functional_tests/recording_should_list_repositories.js b/sdk/containerregistry/container-registry/recordings/node/containerregistryclient_tests/recording_should_list_repositories.js similarity index 100% rename from sdk/containerregistry/container-registry/recordings/node/containerregistryclient_functional_tests/recording_should_list_repositories.js rename to sdk/containerregistry/container-registry/recordings/node/containerregistryclient_tests/recording_should_list_repositories.js diff --git a/sdk/containerregistry/container-registry/recordings/node/containerrepositoryclient_functional_tests/recording_deletes_a_given_tag.js b/sdk/containerregistry/container-registry/recordings/node/repository_and_artifact_tests/recording_deletes_a_given_tag.js similarity index 100% rename from sdk/containerregistry/container-registry/recordings/node/containerrepositoryclient_functional_tests/recording_deletes_a_given_tag.js rename to sdk/containerregistry/container-registry/recordings/node/repository_and_artifact_tests/recording_deletes_a_given_tag.js diff --git a/sdk/containerregistry/container-registry/recordings/node/containerrepositoryclient_functional_tests/recording_sets_manifest_properties.js b/sdk/containerregistry/container-registry/recordings/node/repository_and_artifact_tests/recording_sets_manifest_properties.js similarity index 93% rename from sdk/containerregistry/container-registry/recordings/node/containerrepositoryclient_functional_tests/recording_sets_manifest_properties.js rename to sdk/containerregistry/container-registry/recordings/node/repository_and_artifact_tests/recording_sets_manifest_properties.js index f74ea7820237..8575edc4425a 100644 --- a/sdk/containerregistry/container-registry/recordings/node/containerrepositoryclient_functional_tests/recording_sets_manifest_properties.js +++ b/sdk/containerregistry/container-registry/recordings/node/repository_and_artifact_tests/recording_sets_manifest_properties.js @@ -114,7 +114,7 @@ nock('https://myregistry.azurecr.io:443', {"encodedQueryParams":true}) nock('https://myregistry.azurecr.io:443', {"encodedQueryParams":true}) .get('/acr/v1/library%2Fhello-world/_tags/test1') - .reply(200, {"registry":"myregistry.azurecr.io","imageName":"library/hello-world","tag":{"name":"test1","digest":"sha256:f2266cbfc127c960fd30e76b7c792dc23b588c0db76233517e1891a4e357d519","createdTime":"2021-04-16T21:07:13.4693627Z","lastUpdateTime":"2021-04-16T21:07:13.4693627Z","signed":false,"changeableAttributes":{"deleteEnabled":true,"writeEnabled":true,"readEnabled":true,"listEnabled":true}}}, [ + .reply(200, {"registry":"myregistry.azurecr.io","imageName":"library/hello-world","tag":{"name":"test1","digest":"sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792","createdTime":"2021-04-16T21:07:13.4693627Z","lastUpdateTime":"2021-04-16T21:07:13.4693627Z","signed":false,"changeableAttributes":{"deleteEnabled":true,"writeEnabled":true,"readEnabled":true,"listEnabled":true}}}, [ 'Server', 'openresty', 'Date', @@ -146,7 +146,7 @@ nock('https://myregistry.azurecr.io:443', {"encodedQueryParams":true}) ]); nock('https://myregistry.azurecr.io:443', {"encodedQueryParams":true}) - .get('/acr/v1/library%2Fhello-world/_manifests/sha256%3Af2266cbfc127c960fd30e76b7c792dc23b588c0db76233517e1891a4e357d519') + .get('/acr/v1/library%2Fhello-world/_manifests/sha256%3A1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792') .reply(401, {"errors":[{"code":"UNAUTHORIZED","message":"authentication required, visit https://aka.ms/acr/authorization for more information.","detail":[{"Type":"repository","Name":"library/hello-world","Action":"metadata_read"}]}]}, [ 'Server', 'openresty', @@ -219,8 +219,8 @@ nock('https://myregistry.azurecr.io:443', {"encodedQueryParams":true}) ]); nock('https://myregistry.azurecr.io:443', {"encodedQueryParams":true}) - .get('/acr/v1/library%2Fhello-world/_manifests/sha256%3Af2266cbfc127c960fd30e76b7c792dc23b588c0db76233517e1891a4e357d519') - .reply(200, {"registry":"myregistry.azurecr.io","imageName":"library/hello-world","manifest":{"digest":"sha256:f2266cbfc127c960fd30e76b7c792dc23b588c0db76233517e1891a4e357d519","imageSize":0,"createdTime":"2021-04-16T21:07:13.5318345Z","lastUpdateTime":"2021-04-16T21:07:13.5318345Z","mediaType":"application/vnd.docker.distribution.manifest.list.v2+json","tags":["test1"],"changeableAttributes":{"deleteEnabled":true,"writeEnabled":true,"readEnabled":true,"listEnabled":true},"references":[{"digest":"sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792","architecture":"amd64","os":"linux"},{"digest":"sha256:e5785cb0c62cebbed4965129bae371f0589cadd6d84798fb58c2c5f9e237efd9","architecture":"arm","os":"linux"},{"digest":"sha256:50b8560ad574c779908da71f7ce370c0a2471c098d44d1c8f6b513c5a55eeeb1","architecture":"arm","os":"linux"},{"digest":"sha256:963612c5503f3f1674f315c67089dee577d8cc6afc18565e0b4183ae355fb343","architecture":"arm64","os":"linux"},{"digest":"sha256:cb55d8f7347376e1ba38ca740904b43c9a52f66c7d2ae1ef1a0de1bc9f40df98","architecture":"386","os":"linux"},{"digest":"sha256:88b2e00179bd6c4064612403c8d42a13de7ca809d61fee966ce9e129860a8a90","architecture":"mips64le","os":"linux"},{"digest":"sha256:bb7ab0fa94fdd78aca84b27a1bd46c4b811051f9b69905d81f5f267fc6546a9d","architecture":"ppc64le","os":"linux"},{"digest":"sha256:e49abad529e5d9bd6787f3abeab94e09ba274fe34731349556a850b9aebbf7bf","architecture":"s390x","os":"linux"},{"digest":"sha256:ea0cfb27fd41ea0405d3095880c1efa45710f5bcdddb7d7d5a7317ad4825ae14","architecture":"amd64","os":"windows"}]}}, [ + .get('/acr/v1/library%2Fhello-world/_manifests/sha256%3A1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792') + .reply(200, {"registry":"myregistry.azurecr.io","imageName":"library/hello-world","manifest":{"digest":"sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792","imageSize":0,"createdTime":"2021-04-16T21:07:13.5318345Z","lastUpdateTime":"2021-04-16T21:07:13.5318345Z","mediaType":"application/vnd.docker.distribution.manifest.list.v2+json","tags":["test1"],"changeableAttributes":{"deleteEnabled":true,"writeEnabled":true,"readEnabled":true,"listEnabled":true},"references":[{"digest":"sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792","architecture":"amd64","os":"linux"},{"digest":"sha256:e5785cb0c62cebbed4965129bae371f0589cadd6d84798fb58c2c5f9e237efd9","architecture":"arm","os":"linux"},{"digest":"sha256:50b8560ad574c779908da71f7ce370c0a2471c098d44d1c8f6b513c5a55eeeb1","architecture":"arm","os":"linux"},{"digest":"sha256:963612c5503f3f1674f315c67089dee577d8cc6afc18565e0b4183ae355fb343","architecture":"arm64","os":"linux"},{"digest":"sha256:cb55d8f7347376e1ba38ca740904b43c9a52f66c7d2ae1ef1a0de1bc9f40df98","architecture":"386","os":"linux"},{"digest":"sha256:88b2e00179bd6c4064612403c8d42a13de7ca809d61fee966ce9e129860a8a90","architecture":"mips64le","os":"linux"},{"digest":"sha256:bb7ab0fa94fdd78aca84b27a1bd46c4b811051f9b69905d81f5f267fc6546a9d","architecture":"ppc64le","os":"linux"},{"digest":"sha256:e49abad529e5d9bd6787f3abeab94e09ba274fe34731349556a850b9aebbf7bf","architecture":"s390x","os":"linux"},{"digest":"sha256:ea0cfb27fd41ea0405d3095880c1efa45710f5bcdddb7d7d5a7317ad4825ae14","architecture":"amd64","os":"windows"}]}}, [ 'Server', 'openresty', 'Date', @@ -252,7 +252,7 @@ nock('https://myregistry.azurecr.io:443', {"encodedQueryParams":true}) ]); nock('https://myregistry.azurecr.io:443', {"encodedQueryParams":true}) - .patch('/acr/v1/library%2Fhello-world/_manifests/sha256%3Af2266cbfc127c960fd30e76b7c792dc23b588c0db76233517e1891a4e357d519', {"deleteEnabled":false,"writeEnabled":false,"listEnabled":false,"readEnabled":false}) + .patch('/acr/v1/library%2Fhello-world/_manifests/sha256%3A1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792', {"deleteEnabled":false,"writeEnabled":false,"listEnabled":false,"readEnabled":false}) .reply(401, {"errors":[{"code":"UNAUTHORIZED","message":"authentication required, visit https://aka.ms/acr/authorization for more information.","detail":[{"Type":"repository","Name":"library/hello-world","Action":"metadata_write"}]}]}, [ 'Server', 'openresty', @@ -325,8 +325,8 @@ nock('https://myregistry.azurecr.io:443', {"encodedQueryParams":true}) ]); nock('https://myregistry.azurecr.io:443', {"encodedQueryParams":true}) - .patch('/acr/v1/library%2Fhello-world/_manifests/sha256%3Af2266cbfc127c960fd30e76b7c792dc23b588c0db76233517e1891a4e357d519', {"deleteEnabled":false,"writeEnabled":false,"listEnabled":false,"readEnabled":false}) - .reply(200, {"registry":"myregistry.azurecr.io","imageName":"library/hello-world","manifest":{"digest":"sha256:f2266cbfc127c960fd30e76b7c792dc23b588c0db76233517e1891a4e357d519","imageSize":0,"createdTime":"2021-04-16T21:07:13.5318345Z","lastUpdateTime":"2021-04-16T21:07:13.5318345Z","mediaType":"application/vnd.docker.distribution.manifest.list.v2+json","tags":["test1"],"changeableAttributes":{"deleteEnabled":false,"writeEnabled":false,"readEnabled":false,"listEnabled":false},"references":[{"digest":"sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792","architecture":"amd64","os":"linux"},{"digest":"sha256:e5785cb0c62cebbed4965129bae371f0589cadd6d84798fb58c2c5f9e237efd9","architecture":"arm","os":"linux"},{"digest":"sha256:50b8560ad574c779908da71f7ce370c0a2471c098d44d1c8f6b513c5a55eeeb1","architecture":"arm","os":"linux"},{"digest":"sha256:963612c5503f3f1674f315c67089dee577d8cc6afc18565e0b4183ae355fb343","architecture":"arm64","os":"linux"},{"digest":"sha256:cb55d8f7347376e1ba38ca740904b43c9a52f66c7d2ae1ef1a0de1bc9f40df98","architecture":"386","os":"linux"},{"digest":"sha256:88b2e00179bd6c4064612403c8d42a13de7ca809d61fee966ce9e129860a8a90","architecture":"mips64le","os":"linux"},{"digest":"sha256:bb7ab0fa94fdd78aca84b27a1bd46c4b811051f9b69905d81f5f267fc6546a9d","architecture":"ppc64le","os":"linux"},{"digest":"sha256:e49abad529e5d9bd6787f3abeab94e09ba274fe34731349556a850b9aebbf7bf","architecture":"s390x","os":"linux"},{"digest":"sha256:ea0cfb27fd41ea0405d3095880c1efa45710f5bcdddb7d7d5a7317ad4825ae14","architecture":"amd64","os":"windows"}]}}, [ + .patch('/acr/v1/library%2Fhello-world/_manifests/sha256%3A1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792', {"deleteEnabled":false,"writeEnabled":false,"listEnabled":false,"readEnabled":false}) + .reply(200, {"registry":"myregistry.azurecr.io","imageName":"library/hello-world","manifest":{"digest":"sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792","imageSize":0,"createdTime":"2021-04-16T21:07:13.5318345Z","lastUpdateTime":"2021-04-16T21:07:13.5318345Z","mediaType":"application/vnd.docker.distribution.manifest.list.v2+json","tags":["test1"],"changeableAttributes":{"deleteEnabled":false,"writeEnabled":false,"readEnabled":false,"listEnabled":false},"references":[{"digest":"sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792","architecture":"amd64","os":"linux"},{"digest":"sha256:e5785cb0c62cebbed4965129bae371f0589cadd6d84798fb58c2c5f9e237efd9","architecture":"arm","os":"linux"},{"digest":"sha256:50b8560ad574c779908da71f7ce370c0a2471c098d44d1c8f6b513c5a55eeeb1","architecture":"arm","os":"linux"},{"digest":"sha256:963612c5503f3f1674f315c67089dee577d8cc6afc18565e0b4183ae355fb343","architecture":"arm64","os":"linux"},{"digest":"sha256:cb55d8f7347376e1ba38ca740904b43c9a52f66c7d2ae1ef1a0de1bc9f40df98","architecture":"386","os":"linux"},{"digest":"sha256:88b2e00179bd6c4064612403c8d42a13de7ca809d61fee966ce9e129860a8a90","architecture":"mips64le","os":"linux"},{"digest":"sha256:bb7ab0fa94fdd78aca84b27a1bd46c4b811051f9b69905d81f5f267fc6546a9d","architecture":"ppc64le","os":"linux"},{"digest":"sha256:e49abad529e5d9bd6787f3abeab94e09ba274fe34731349556a850b9aebbf7bf","architecture":"s390x","os":"linux"},{"digest":"sha256:ea0cfb27fd41ea0405d3095880c1efa45710f5bcdddb7d7d5a7317ad4825ae14","architecture":"amd64","os":"windows"}]}}, [ 'Server', 'openresty', 'Date', @@ -358,7 +358,7 @@ nock('https://myregistry.azurecr.io:443', {"encodedQueryParams":true}) ]); nock('https://myregistry.azurecr.io:443', {"encodedQueryParams":true}) - .patch('/acr/v1/library%2Fhello-world/_manifests/sha256%3Af2266cbfc127c960fd30e76b7c792dc23b588c0db76233517e1891a4e357d519', {"deleteEnabled":true,"writeEnabled":true,"listEnabled":true,"readEnabled":true}) + .patch('/acr/v1/library%2Fhello-world/_manifests/sha256%3A1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792', {"deleteEnabled":true,"writeEnabled":true,"listEnabled":true,"readEnabled":true}) .reply(401, {"errors":[{"code":"UNAUTHORIZED","message":"authentication required, visit https://aka.ms/acr/authorization for more information.","detail":[{"Type":"repository","Name":"library/hello-world","Action":"metadata_write"}]}]}, [ 'Server', 'openresty', @@ -431,8 +431,8 @@ nock('https://myregistry.azurecr.io:443', {"encodedQueryParams":true}) ]); nock('https://myregistry.azurecr.io:443', {"encodedQueryParams":true}) - .patch('/acr/v1/library%2Fhello-world/_manifests/sha256%3Af2266cbfc127c960fd30e76b7c792dc23b588c0db76233517e1891a4e357d519', {"deleteEnabled":true,"writeEnabled":true,"listEnabled":true,"readEnabled":true}) - .reply(200, {"registry":"myregistry.azurecr.io","imageName":"library/hello-world","manifest":{"digest":"sha256:f2266cbfc127c960fd30e76b7c792dc23b588c0db76233517e1891a4e357d519","imageSize":0,"createdTime":"2021-04-16T21:07:13.5318345Z","lastUpdateTime":"2021-04-16T21:07:13.5318345Z","mediaType":"application/vnd.docker.distribution.manifest.list.v2+json","tags":["test1"],"changeableAttributes":{"deleteEnabled":true,"writeEnabled":true,"readEnabled":true,"listEnabled":true},"references":[{"digest":"sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792","architecture":"amd64","os":"linux"},{"digest":"sha256:e5785cb0c62cebbed4965129bae371f0589cadd6d84798fb58c2c5f9e237efd9","architecture":"arm","os":"linux"},{"digest":"sha256:50b8560ad574c779908da71f7ce370c0a2471c098d44d1c8f6b513c5a55eeeb1","architecture":"arm","os":"linux"},{"digest":"sha256:963612c5503f3f1674f315c67089dee577d8cc6afc18565e0b4183ae355fb343","architecture":"arm64","os":"linux"},{"digest":"sha256:cb55d8f7347376e1ba38ca740904b43c9a52f66c7d2ae1ef1a0de1bc9f40df98","architecture":"386","os":"linux"},{"digest":"sha256:88b2e00179bd6c4064612403c8d42a13de7ca809d61fee966ce9e129860a8a90","architecture":"mips64le","os":"linux"},{"digest":"sha256:bb7ab0fa94fdd78aca84b27a1bd46c4b811051f9b69905d81f5f267fc6546a9d","architecture":"ppc64le","os":"linux"},{"digest":"sha256:e49abad529e5d9bd6787f3abeab94e09ba274fe34731349556a850b9aebbf7bf","architecture":"s390x","os":"linux"},{"digest":"sha256:ea0cfb27fd41ea0405d3095880c1efa45710f5bcdddb7d7d5a7317ad4825ae14","architecture":"amd64","os":"windows"}]}}, [ + .patch('/acr/v1/library%2Fhello-world/_manifests/sha256%3A1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792', {"deleteEnabled":true,"writeEnabled":true,"listEnabled":true,"readEnabled":true}) + .reply(200, {"registry":"myregistry.azurecr.io","imageName":"library/hello-world","manifest":{"digest":"sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792","imageSize":0,"createdTime":"2021-04-16T21:07:13.5318345Z","lastUpdateTime":"2021-04-16T21:07:13.5318345Z","mediaType":"application/vnd.docker.distribution.manifest.list.v2+json","tags":["test1"],"changeableAttributes":{"deleteEnabled":true,"writeEnabled":true,"readEnabled":true,"listEnabled":true},"references":[{"digest":"sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792","architecture":"amd64","os":"linux"},{"digest":"sha256:e5785cb0c62cebbed4965129bae371f0589cadd6d84798fb58c2c5f9e237efd9","architecture":"arm","os":"linux"},{"digest":"sha256:50b8560ad574c779908da71f7ce370c0a2471c098d44d1c8f6b513c5a55eeeb1","architecture":"arm","os":"linux"},{"digest":"sha256:963612c5503f3f1674f315c67089dee577d8cc6afc18565e0b4183ae355fb343","architecture":"arm64","os":"linux"},{"digest":"sha256:cb55d8f7347376e1ba38ca740904b43c9a52f66c7d2ae1ef1a0de1bc9f40df98","architecture":"386","os":"linux"},{"digest":"sha256:88b2e00179bd6c4064612403c8d42a13de7ca809d61fee966ce9e129860a8a90","architecture":"mips64le","os":"linux"},{"digest":"sha256:bb7ab0fa94fdd78aca84b27a1bd46c4b811051f9b69905d81f5f267fc6546a9d","architecture":"ppc64le","os":"linux"},{"digest":"sha256:e49abad529e5d9bd6787f3abeab94e09ba274fe34731349556a850b9aebbf7bf","architecture":"s390x","os":"linux"},{"digest":"sha256:ea0cfb27fd41ea0405d3095880c1efa45710f5bcdddb7d7d5a7317ad4825ae14","architecture":"amd64","os":"windows"}]}}, [ 'Server', 'openresty', 'Date', diff --git a/sdk/containerregistry/container-registry/recordings/node/containerrepositoryclient_functional_tests/recording_sets_repository_properties.js b/sdk/containerregistry/container-registry/recordings/node/repository_and_artifact_tests/recording_sets_repository_properties.js similarity index 100% rename from sdk/containerregistry/container-registry/recordings/node/containerrepositoryclient_functional_tests/recording_sets_repository_properties.js rename to sdk/containerregistry/container-registry/recordings/node/repository_and_artifact_tests/recording_sets_repository_properties.js diff --git a/sdk/containerregistry/container-registry/recordings/node/containerrepositoryclient_functional_tests/recording_sets_tag_properties.js b/sdk/containerregistry/container-registry/recordings/node/repository_and_artifact_tests/recording_sets_tag_properties.js similarity index 100% rename from sdk/containerregistry/container-registry/recordings/node/containerrepositoryclient_functional_tests/recording_sets_tag_properties.js rename to sdk/containerregistry/container-registry/recordings/node/repository_and_artifact_tests/recording_sets_tag_properties.js diff --git a/sdk/containerregistry/container-registry/recordings/node/containerrepositoryclient_functional_tests/recording_should_list_registry_artifacts.js b/sdk/containerregistry/container-registry/recordings/node/repository_and_artifact_tests/recording_should_list_registry_manifests.js similarity index 100% rename from sdk/containerregistry/container-registry/recordings/node/containerrepositoryclient_functional_tests/recording_should_list_registry_artifacts.js rename to sdk/containerregistry/container-registry/recordings/node/repository_and_artifact_tests/recording_should_list_registry_manifests.js diff --git a/sdk/containerregistry/container-registry/recordings/node/containerrepositoryclient_functional_tests/recording_should_list_registry_artifacts_by_pages.js b/sdk/containerregistry/container-registry/recordings/node/repository_and_artifact_tests/recording_should_list_registry_manifests_by_pages.js similarity index 100% rename from sdk/containerregistry/container-registry/recordings/node/containerrepositoryclient_functional_tests/recording_should_list_registry_artifacts_by_pages.js rename to sdk/containerregistry/container-registry/recordings/node/repository_and_artifact_tests/recording_should_list_registry_manifests_by_pages.js diff --git a/sdk/containerregistry/container-registry/recordings/node/containerrepositoryclient_functional_tests/recording_should_list_tags.js b/sdk/containerregistry/container-registry/recordings/node/repository_and_artifact_tests/recording_should_list_tags.js similarity index 100% rename from sdk/containerregistry/container-registry/recordings/node/containerrepositoryclient_functional_tests/recording_should_list_tags.js rename to sdk/containerregistry/container-registry/recordings/node/repository_and_artifact_tests/recording_should_list_tags.js diff --git a/sdk/containerregistry/container-registry/recordings/node/containerrepositoryclient_functional_tests/recording_should_list_tags_by_pages.js b/sdk/containerregistry/container-registry/recordings/node/repository_and_artifact_tests/recording_should_list_tags_by_pages.js similarity index 100% rename from sdk/containerregistry/container-registry/recordings/node/containerrepositoryclient_functional_tests/recording_should_list_tags_by_pages.js rename to sdk/containerregistry/container-registry/recordings/node/repository_and_artifact_tests/recording_should_list_tags_by_pages.js diff --git a/sdk/containerregistry/container-registry/recordings/node/containerrepositoryclient_functional_tests/recording_should_retrive_registry_artifact_properties_for_a_digest.js b/sdk/containerregistry/container-registry/recordings/node/repository_and_artifact_tests/recording_should_retrive_registry_artifact_properties_for_a_digest.js similarity index 100% rename from sdk/containerregistry/container-registry/recordings/node/containerrepositoryclient_functional_tests/recording_should_retrive_registry_artifact_properties_for_a_digest.js rename to sdk/containerregistry/container-registry/recordings/node/repository_and_artifact_tests/recording_should_retrive_registry_artifact_properties_for_a_digest.js diff --git a/sdk/containerregistry/container-registry/recordings/node/containerrepositoryclient_functional_tests/recording_should_retrive_registry_artifact_properties_for_a_tag.js b/sdk/containerregistry/container-registry/recordings/node/repository_and_artifact_tests/recording_should_retrive_registry_artifact_properties_for_a_tag.js similarity index 100% rename from sdk/containerregistry/container-registry/recordings/node/containerrepositoryclient_functional_tests/recording_should_retrive_registry_artifact_properties_for_a_tag.js rename to sdk/containerregistry/container-registry/recordings/node/repository_and_artifact_tests/recording_should_retrive_registry_artifact_properties_for_a_tag.js diff --git a/sdk/containerregistry/container-registry/recordings/node/containerrepositoryclient_functional_tests/recording_should_retrive_tag_properties.js b/sdk/containerregistry/container-registry/recordings/node/repository_and_artifact_tests/recording_should_retrive_tag_properties.js similarity index 100% rename from sdk/containerregistry/container-registry/recordings/node/containerrepositoryclient_functional_tests/recording_should_retrive_tag_properties.js rename to sdk/containerregistry/container-registry/recordings/node/repository_and_artifact_tests/recording_should_retrive_tag_properties.js diff --git a/sdk/containerregistry/container-registry/review/container-registry.api.md b/sdk/containerregistry/container-registry/review/container-registry.api.md index c63fd28dd91a..bb38249e1d91 100644 --- a/sdk/containerregistry/container-registry/review/container-registry.api.md +++ b/sdk/containerregistry/container-registry/review/container-registry.api.md @@ -9,36 +9,56 @@ import { PagedAsyncIterableIterator } from '@azure/core-paging'; import { PipelineOptions } from '@azure/core-rest-pipeline'; import { TokenCredential } from '@azure/core-auth'; +// @public +export interface ArtifactManifestProperties { + readonly architecture?: string; + readonly createdOn?: Date; + readonly digest?: string; + readonly lastUpdatedOn?: Date; + manifests: ArtifactManifestProperties[]; + readonly operatingSystem?: string; + readonly repositoryName?: string; + readonly size?: number; + readonly tags: string[]; + readonly writeableProperties?: ContentProperties; +} + +// @public +export interface ArtifactTagProperties { + readonly createdOn: Date; + readonly digest: string; + readonly lastUpdatedOn: Date; + readonly name: string; + readonly repository: string; + readonly writeableProperties: ContentProperties; +} + // @public export class ContainerRegistryClient { constructor(endpointUrl: string, credential: TokenCredential, options?: ContainerRegistryClientOptions); - deleteRepository(name: string, options?: DeleteRepositoryOptions): Promise; - endpoint: string; - getRepositoryClient(repository: string): ContainerRepositoryClient; - listRepositories(options?: ListRepositoriesOptions): PagedAsyncIterableIterator; - } + deleteRepository(repositoryName: string, options?: DeleteRepositoryOptions): Promise; + getArtifact(repositoryName: string, tagOrDigest: string): RegistryArtifact; + getRepository(repositoryName: string): ContainerRepository; + listRepositoryNames(options?: ListRepositoriesOptions): PagedAsyncIterableIterator; + readonly loginServer: string; + readonly name: string; + readonly registryUrl: string; +} // @public export interface ContainerRegistryClientOptions extends PipelineOptions { } // @public -export class ContainerRepositoryClient { - constructor(endpointUrl: string, repository: string, credential: TokenCredential, options?: ContainerRegistryClientOptions); +export interface ContainerRepository { delete(options?: DeleteRepositoryOptions): Promise; - deleteRegistryArtifact(digest: string, options?: DeleteRegistryArtifactOptions): Promise; - deleteTag(tag: string, options?: DeleteTagOptions): Promise; - endpoint: string; + readonly fullyQualifiedName: string; + getArtifact(tagOrDigest: string): RegistryArtifact; getProperties(options?: GetRepositoryPropertiesOptions): Promise; - getRegistryArtifactProperties(tagOrDigest: string, options?: GetRegistryArtifactPropertiesOptions): Promise; - getTagProperties(tag: string, options?: GetTagPropertiesOptions): Promise; - listRegistryArtifacts(options?: ListRegistryArtifactsOptions): PagedAsyncIterableIterator; - listTags(options?: ListTagsOptions): PagedAsyncIterableIterator; - registry: string; - repository: string; - setManifestProperties(digest: string, value: ContentProperties, options?: SetManifestPropertiesOptions): Promise; - setProperties(value: ContentProperties, options?: SetRepositoryPropertiesOptions): Promise; - setTagProperties(tag: string, value: ContentProperties, options?: SetTagPropertiesOptions): Promise; + listManifests(options?: ListManifestsOptions): PagedAsyncIterableIterator; + readonly name: string; + readonly registryUrl: string; + setProperties(options: SetRepositoryPropertiesOptions): Promise; } // @public @@ -50,7 +70,7 @@ export interface ContentProperties { } // @public -export interface DeleteRegistryArtifactOptions extends OperationOptions { +export interface DeleteArtifactOptions extends OperationOptions { } // @public @@ -59,8 +79,8 @@ export interface DeleteRepositoryOptions extends OperationOptions { // @public export interface DeleteRepositoryResult { - deletedRegistryArtifactDigests?: string[]; - deletedTags?: string[]; + readonly deletedManifests: string[]; + readonly deletedTags: string[]; } // @public @@ -68,7 +88,7 @@ export interface DeleteTagOptions extends OperationOptions { } // @public -export interface GetRegistryArtifactPropertiesOptions extends OperationOptions { +export interface GetManifestPropertiesOptions extends OperationOptions { } // @public @@ -80,8 +100,14 @@ export interface GetTagPropertiesOptions extends OperationOptions { } // @public -export interface ListRegistryArtifactsOptions extends OperationOptions { - orderBy?: RegistryArtifactOrderBy; +export type KnownArtifactArchitecture = "386" | "amd64" | "arm" | "arm64" | "mips" | "mipsle" | "mips64" | "mips64le" | "ppc64" | "ppc64le" | "riscv64" | "s390x" | "wasm"; + +// @public +export type KnownArtifactOperatingSystem = "aix" | "android" | "darwin" | "dragonfly" | "freebsd" | "illumos" | "ios" | "js" | "linux" | "netbsd" | "openbsd" | "plan9" | "solaris" | "windows"; + +// @public +export interface ListManifestsOptions extends OperationOptions { + orderBy?: ManifestOrderBy; } // @public @@ -94,56 +120,44 @@ export interface ListTagsOptions extends OperationOptions { } // @public -export type RegistryArtifactOrderBy = "timedesc" | "timeasc"; +export type ManifestOrderBy = "timeDesc" | "timeAsc"; // @public -export interface RegistryArtifactProperties { - cpuArchitecture?: string; - createdOn?: Date; - digest?: string; - lastUpdatedOn?: Date; - operatingSystem?: string; - registryArtifacts?: RegistryArtifactProperties[]; - repository?: string; - size?: number; - tags?: string[]; - writeableProperties?: ContentProperties; +export interface RegistryArtifact { + delete(options?: DeleteArtifactOptions): Promise; + deleteTag(tag: string, options?: DeleteTagOptions): Promise; + readonly fullyQualifiedName: string; + getManifestProperties(options?: GetManifestPropertiesOptions): Promise; + getTagProperties(tag: string, options?: GetTagPropertiesOptions): Promise; + listTags(options?: ListTagsOptions): PagedAsyncIterableIterator; + readonly registryUrl: string; + readonly repositoryName: string; + setManifestProperties(options?: SetManifestPropertiesOptions): Promise; + setTagProperties(tag: string, options: SetTagPropertiesOptions): Promise; + readonly tagOrDigest: string; } // @public export interface RepositoryProperties { - createdOn: Date; - lastUpdatedOn: Date; - name: string; - registryArtifactCount: number; - tagCount: number; - writeableProperties: ContentProperties; + readonly createdOn: Date; + readonly lastUpdatedOn: Date; + readonly manifestCount: number; + readonly name: string; + readonly tagCount: number; + readonly writeableProperties: ContentProperties; } // @public -export interface SetManifestPropertiesOptions extends OperationOptions { -} +export type SetManifestPropertiesOptions = ContentProperties & OperationOptions; // @public -export interface SetRepositoryPropertiesOptions extends OperationOptions { -} +export type SetRepositoryPropertiesOptions = ContentProperties & OperationOptions; // @public -export interface SetTagPropertiesOptions extends OperationOptions { -} - -// @public -export type TagOrderBy = "timedesc" | "timeasc"; +export type SetTagPropertiesOptions = ContentProperties & OperationOptions; // @public -export interface TagProperties { - createdOn: Date; - digest: string; - lastUpdatedOn: Date; - name: string; - repository: string; - writeableProperties: ContentProperties; -} +export type TagOrderBy = "timeDesc" | "timeAsc"; // (No @packageDocumentation comment for this package) diff --git a/sdk/containerregistry/container-registry/samples-dev/containerRegistryClient.ts b/sdk/containerregistry/container-registry/samples-dev/containerRegistryClient.ts index 2ebf23d45c92..3638d918a18c 100644 --- a/sdk/containerregistry/container-registry/samples-dev/containerRegistryClient.ts +++ b/sdk/containerregistry/container-registry/samples-dev/containerRegistryClient.ts @@ -19,7 +19,7 @@ export async function main() { await listRepositories(client); // Advanced: listing by pages - const pageSize = 2; + const pageSize = 1; await listRepositoriesByPages(client, pageSize); const repositoryName = "repository-name-to-delete"; @@ -28,15 +28,15 @@ export async function main() { async function listRepositories(client: ContainerRegistryClient) { console.log("Listing repositories"); - const iterator = client.listRepositories(); + const iterator = client.listRepositoryNames(); for await (const repository of iterator) { console.log(` repository: ${repository}`); } } -async function listRepositoriesByPages(client: any, pageSize: number) { +async function listRepositoriesByPages(client: ContainerRegistryClient, pageSize: number) { console.log("Listing repositories by pages"); - const pages = client.listRepositories().byPage({ maxPageSize: pageSize }); + const pages = client.listRepositoryNames().byPage({ maxPageSize: pageSize }); let result = await pages.next(); while (!result.done) { console.log(" -- page -- "); @@ -52,14 +52,12 @@ async function deleteRepository(client: ContainerRegistryClient, repositoryName: const response = await client.deleteRepository(repositoryName); console.log( `Artifacts deleted: ${(response && - response.deletedRegistryArtifactDigests && - response.deletedRegistryArtifactDigests.length) || + response.deletedManifests && + response.deletedManifests.length) || 0}` ); console.log( - `Tags deleted: ${(response && - response.deletedRegistryArtifactDigests && - response.deletedRegistryArtifactDigests.length) || + `Tags deleted: ${(response && response.deletedManifests && response.deletedManifests.length) || 0}` ); } diff --git a/sdk/containerregistry/container-registry/samples-dev/containerRepositoryClient.ts b/sdk/containerregistry/container-registry/samples-dev/repositoryAndArtifact.ts similarity index 51% rename from sdk/containerregistry/container-registry/samples-dev/containerRepositoryClient.ts rename to sdk/containerregistry/container-registry/samples-dev/repositoryAndArtifact.ts index a4059f0225db..888f727b1f1f 100644 --- a/sdk/containerregistry/container-registry/samples-dev/containerRepositoryClient.ts +++ b/sdk/containerregistry/container-registry/samples-dev/repositoryAndArtifact.ts @@ -2,11 +2,16 @@ // Licensed under the MIT License. /** - * @summary Demonstrates the use of a ContainerRepositoryClient. + * @summary Demonstrates the use of ContainerRepository and RegistryArtifact. * @azsdk-weight 5 */ -import { ContainerRepositoryClient, RegistryArtifactProperties } from "@azure/container-registry"; +import { + ContainerRepository, + ArtifactManifestProperties, + ContainerRegistryClient, + RegistryArtifact +} from "@azure/container-registry"; import { DefaultAzureCredential } from "@azure/identity"; import * as dotenv from "dotenv"; dotenv.config(); @@ -15,32 +20,40 @@ 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 || ""; - const repository = process.env.REPOSITORY_NAME || ""; + const repositoryName = process.env.REPOSITORY_NAME || ""; + const pageSize = 1; - const client = new ContainerRepositoryClient(endpoint, repository, new DefaultAzureCredential()); - await getProperties(client); - await listTags(client); + const client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential()); + const repository = client.getRepository(repositoryName); + await getProperties(repository); - const artifacts = await listArtifacts(client); + const manifests = await listManifests(repository); - if (artifacts && artifacts.length) { - const digest = artifacts[0].digest; + if (manifests && manifests.length) { + const digest = manifests[0].digest; if (digest) { - await getArtifactProperties(client, digest); + const artifact = repository.getArtifact(digest); - await deleteArtifact(client, digest); + console.log(`Retrieving registry artifact properties for ${digest}`); + await getArtifactProperties(artifact); + + console.log(`Listing tags for ${digest}`); + await listTags(artifact); + + // Advanced: listing by pages + console.log(`Listing tags by pages for ${digest}`); + await listTagsByPages(artifact, pageSize); + + console.log(`Deleting registry artifact for ${digest}`); + await artifact.delete(); } } - // Advanced: listing by pages - const pageSize = 2; - await listTagsByPages(client, pageSize); - await listArtifactsByPages(client, pageSize); + await listManifestsByPages(repository, pageSize); } -async function listTags(client: ContainerRepositoryClient) { - console.log("Listing tags"); - const iterator = client.listTags({ orderBy: "timeasc" }); +async function listTags(artifact: RegistryArtifact) { + const iterator = artifact.listTags({ orderBy: "timeAsc" }); for await (const tag of iterator) { console.log(` tag: ${tag.name}`); console.log(` digest: ${tag.digest}`); @@ -49,9 +62,8 @@ async function listTags(client: ContainerRepositoryClient) { } } -async function listTagsByPages(client: ContainerRepositoryClient, pagesSize: number) { - console.log("Listing tags by pages"); - const pages = client.listTags().byPage({ maxPageSize: pagesSize }); +async function listTagsByPages(artifact: RegistryArtifact, pagesSize: number) { + const pages = artifact.listTags().byPage({ maxPageSize: pagesSize }); let result = await pages.next(); while (!result.done) { console.log(" -- page -- "); @@ -66,12 +78,12 @@ async function listTagsByPages(client: ContainerRepositoryClient, pagesSize: num } } -async function listArtifacts( - client: ContainerRepositoryClient -): Promise { +async function listManifests( + repository: ContainerRepository +): Promise { console.log("Listing artifacts"); - const artifacts: RegistryArtifactProperties[] = []; - const iterator = client.listRegistryArtifacts(); + const artifacts: ArtifactManifestProperties[] = []; + const iterator = repository.listManifests(); for await (const artifact of iterator) { artifacts.push(artifact); console.log(` digest: ${artifact.digest}`); @@ -82,9 +94,9 @@ async function listArtifacts( return artifacts; } -async function listArtifactsByPages(client: any, pageSize: number) { - console.log("Listing artifacts by pages"); - const pages = client.listRegistryArtifacts().byPage({ maxPageSize: pageSize }); +async function listManifestsByPages(repository: ContainerRepository, pageSize: number) { + console.log("Listing manifest by pages"); + const pages = repository.listManifests().byPage({ maxPageSize: pageSize }); let result = await pages.next(); while (!result.done) { console.log(" -- page -- "); @@ -98,38 +110,36 @@ async function listArtifactsByPages(client: any, pageSize: number) { } } -async function getProperties(client: ContainerRepositoryClient) { +async function getProperties(repository: ContainerRepository) { console.log("Retrieving repository properties..."); - const properties = await client.getProperties(); + const properties = await repository.getProperties(); console.log(` name: ${properties.name}`); console.log(` created on: ${properties.createdOn}`); console.log(` last updated on: ${properties.lastUpdatedOn}`); - console.log(` artifact count: ${properties.registryArtifactCount}`); + console.log(` artifact count: ${properties.manifestCount}`); console.log(` tag count: ${properties.tagCount}`); const writableProps = properties.writeableProperties; if (writableProps) { - console.log(" writable properties:"); + console.log(" writable properties: {"); console.log( - ` { canDelete: ${writableProps.canDelete}, canList: ${writableProps.canList}, canRead: ${writableProps.canRead}, canWrite: ${writableProps.canWrite}}` + ` canDelete: ${writableProps.canDelete}, + canList: ${writableProps.canList}, + canRead: ${writableProps.canRead}, + canWrite: ${writableProps.canWrite}` ); + console.log(" }"); } } -async function getArtifactProperties(client: ContainerRepositoryClient, digest: string) { - console.log(`Retrieving registry artifact properties for ${digest}`); - const properties = await client.getRegistryArtifactProperties(digest); +async function getArtifactProperties(artifact: RegistryArtifact) { + const properties = await artifact.getManifestProperties(); console.log(` created on: ${properties.createdOn}`); console.log(` last updated on: ${properties.lastUpdatedOn}`); - console.log(` arch : ${properties.cpuArchitecture}`); + console.log(` arch : ${properties.architecture}`); console.log(` os : ${properties.operatingSystem}`); console.log(` size : ${properties.size} bytes`); } -async function deleteArtifact(client: ContainerRepositoryClient, digest: string) { - console.log(`Deleting registry artifact for ${digest}`); - await client.deleteRegistryArtifact(digest); -} - main().catch((err) => { console.error("The sample encountered an error:", err); }); diff --git a/sdk/containerregistry/container-registry/samples/v1/javascript/README.md b/sdk/containerregistry/container-registry/samples/v1/javascript/README.md index 7d332191c0c8..f3bf1bdb0266 100644 --- a/sdk/containerregistry/container-registry/samples/v1/javascript/README.md +++ b/sdk/containerregistry/container-registry/samples/v1/javascript/README.md @@ -12,10 +12,10 @@ urlFragment: container-registry-javascript These sample programs show how to use the JavaScript client libraries for Azure Container Registry in some common scenarios. -| **File Name** | **Description** | -| --------------------------------------------------------- | ---------------------------------------------------- | -| [containerRegistryClient.js][containerregistryclient] | Demonstrates the use of a ContainerRegistryClient. | -| [containerRepositoryClient.js][containerrepositoryclient] | Demonstrates the use of a ContainerRepositoryClient. | +| **File Name** | **Description** | +| ----------------------------------------------------- | ----------------------------------------------------------------- | +| [containerRegistryClient.js][containerregistryclient] | Demonstrates the use of a ContainerRegistryClient. | +| [repositoryAndArtifact.js][repositoryandartifact] | Demonstrates the use of ContainerRepository and RegistryArtifact. | ## Prerequisites @@ -58,8 +58,8 @@ npx cross-env CONTAINER_REGISTRY_ENDPOINT="" node c Take a look at our [API Documentation][apiref] for more information about the APIs that are available in the clients. [containerregistryclient]: https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/containerregistry/container-registry/samples/v1/javascript/containerRegistryClient.js -[containerrepositoryclient]: https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/containerregistry/container-registry/samples/v1/javascript/containerRepositoryClient.js -[apiref]: https://azuresdkdocs.blob.core.windows.net/$web/javascript/azure-container-registry/1.0.0-beta.1/index.html +[repositoryandartifact]: https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/containerregistry/container-registry/samples/v1/javascript/repositoryAndArtifact.js +[apiref]: https://docs.microsoft.com/javascript/api/@azure/container-registry [freesub]: https://azure.microsoft.com/free/ [createinstance_azurecontainerregistry]: https://docs.microsoft.com/azure/container-registry/container-registry-get-started-portal [package]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/containerregistry/container-registry/README.md diff --git a/sdk/containerregistry/container-registry/samples/v1/javascript/containerRegistryClient.js b/sdk/containerregistry/container-registry/samples/v1/javascript/containerRegistryClient.js index a8001bfae60f..cba1917444a2 100644 --- a/sdk/containerregistry/container-registry/samples/v1/javascript/containerRegistryClient.js +++ b/sdk/containerregistry/container-registry/samples/v1/javascript/containerRegistryClient.js @@ -18,7 +18,7 @@ async function main() { await listRepositories(client); // Advanced: listing by pages - const pageSize = 2; + const pageSize = 1; await listRepositoriesByPages(client, pageSize); const repositoryName = "repository-name-to-delete"; @@ -27,7 +27,7 @@ async function main() { async function listRepositories(client) { console.log("Listing repositories"); - const iterator = client.listRepositories(); + const iterator = client.listRepositoryNames(); for await (const repository of iterator) { console.log(` repository: ${repository}`); } @@ -35,7 +35,7 @@ async function listRepositories(client) { async function listRepositoriesByPages(client, pageSize) { console.log("Listing repositories by pages"); - const pages = client.listRepositories().byPage({ maxPageSize: pageSize }); + const pages = client.listRepositoryNames().byPage({ maxPageSize: pageSize }); let result = await pages.next(); while (!result.done) { console.log(" -- page -- "); @@ -51,14 +51,12 @@ async function deleteRepository(client, repositoryName) { const response = await client.deleteRepository(repositoryName); console.log( `Artifacts deleted: ${(response && - response.deletedRegistryArtifactDigests && - response.deletedRegistryArtifactDigests.length) || + response.deletedManifests && + response.deletedManifests.length) || 0}` ); console.log( - `Tags deleted: ${(response && - response.deletedRegistryArtifactDigests && - response.deletedRegistryArtifactDigests.length) || + `Tags deleted: ${(response && response.deletedManifests && response.deletedManifests.length) || 0}` ); } diff --git a/sdk/containerregistry/container-registry/samples/v1/javascript/package.json b/sdk/containerregistry/container-registry/samples/v1/javascript/package.json index f576c0b6fa01..f9330ee70d41 100644 --- a/sdk/containerregistry/container-registry/samples/v1/javascript/package.json +++ b/sdk/containerregistry/container-registry/samples/v1/javascript/package.json @@ -14,7 +14,7 @@ "keywords": [ "azure", "cloud", - "javascript" + "typescript" ], "author": "Microsoft Corporation", "license": "MIT", diff --git a/sdk/containerregistry/container-registry/samples/v1/javascript/containerRepositoryClient.js b/sdk/containerregistry/container-registry/samples/v1/javascript/repositoryAndArtifact.js similarity index 53% rename from sdk/containerregistry/container-registry/samples/v1/javascript/containerRepositoryClient.js rename to sdk/containerregistry/container-registry/samples/v1/javascript/repositoryAndArtifact.js index a20951494a6b..4a203e83fce8 100644 --- a/sdk/containerregistry/container-registry/samples/v1/javascript/containerRepositoryClient.js +++ b/sdk/containerregistry/container-registry/samples/v1/javascript/repositoryAndArtifact.js @@ -2,10 +2,10 @@ // Licensed under the MIT License. /** - * @summary Demonstrates the use of a ContainerRepositoryClient. + * @summary Demonstrates the use of ContainerRepository and RegistryArtifact. */ -const { ContainerRepositoryClient } = require("@azure/container-registry"); +const { ContainerRegistryClient } = require("@azure/container-registry"); const { DefaultAzureCredential } = require("@azure/identity"); const dotenv = require("dotenv"); dotenv.config(); @@ -14,32 +14,40 @@ 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 || ""; - const repository = process.env.REPOSITORY_NAME || ""; + const repositoryName = process.env.REPOSITORY_NAME || ""; + const pageSize = 1; - const client = new ContainerRepositoryClient(endpoint, repository, new DefaultAzureCredential()); - await getProperties(client); - await listTags(client); + const client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential()); + const repository = client.getRepository(repositoryName); + await getProperties(repository); - const artifacts = await listArtifacts(client); + const manifests = await listManifests(repository); - if (artifacts && artifacts.length) { - const digest = artifacts[0].digest; + if (manifests && manifests.length) { + const digest = manifests[0].digest; if (digest) { - await getArtifactProperties(client, digest); + const artifact = repository.getArtifact(digest); - await deleteArtifact(client, digest); + console.log(`Retrieving registry artifact properties for ${digest}`); + await getArtifactProperties(artifact); + + console.log(`Listing tags for ${digest}`); + await listTags(artifact); + + // Advanced: listing by pages + console.log(`Listing tags by pages for ${digest}`); + await listTagsByPages(artifact, pageSize); + + console.log(`Deleting registry artifact for ${digest}`); + await artifact.delete(); } } - // Advanced: listing by pages - const pageSize = 2; - await listTagsByPages(client, pageSize); - await listArtifactsByPages(client, pageSize); + await listManifestsByPages(repository, pageSize); } -async function listTags(client) { - console.log("Listing tags"); - const iterator = client.listTags({ orderBy: "timeasc" }); +async function listTags(artifact) { + const iterator = artifact.listTags({ orderBy: "timeAsc" }); for await (const tag of iterator) { console.log(` tag: ${tag.name}`); console.log(` digest: ${tag.digest}`); @@ -48,9 +56,8 @@ async function listTags(client) { } } -async function listTagsByPages(client, pagesSize) { - console.log("Listing tags by pages"); - const pages = client.listTags().byPage({ maxPageSize: pagesSize }); +async function listTagsByPages(artifact, pagesSize) { + const pages = artifact.listTags().byPage({ maxPageSize: pagesSize }); let result = await pages.next(); while (!result.done) { console.log(" -- page -- "); @@ -65,10 +72,10 @@ async function listTagsByPages(client, pagesSize) { } } -async function listArtifacts(client) { +async function listManifests(repository) { console.log("Listing artifacts"); const artifacts = []; - const iterator = client.listRegistryArtifacts(); + const iterator = repository.listManifests(); for await (const artifact of iterator) { artifacts.push(artifact); console.log(` digest: ${artifact.digest}`); @@ -79,9 +86,9 @@ async function listArtifacts(client) { return artifacts; } -async function listArtifactsByPages(client, pageSize) { - console.log("Listing artifacts by pages"); - const pages = client.listRegistryArtifacts().byPage({ maxPageSize: pageSize }); +async function listManifestsByPages(repository, pageSize) { + console.log("Listing manifest by pages"); + const pages = repository.listManifests().byPage({ maxPageSize: pageSize }); let result = await pages.next(); while (!result.done) { console.log(" -- page -- "); @@ -95,38 +102,34 @@ async function listArtifactsByPages(client, pageSize) { } } -async function getProperties(client) { +async function getProperties(repository) { console.log("Retrieving repository properties..."); - const properties = await client.getProperties(); + const properties = await repository.getProperties(); console.log(` name: ${properties.name}`); console.log(` created on: ${properties.createdOn}`); console.log(` last updated on: ${properties.lastUpdatedOn}`); - console.log(` artifact count: ${properties.registryArtifactCount}`); + console.log(` artifact count: ${properties.manifestCount}`); console.log(` tag count: ${properties.tagCount}`); const writableProps = properties.writeableProperties; if (writableProps) { - console.log(" writable properties:"); - console.log( - ` { canDelete: ${writableProps.canDelete}, canList: ${writableProps.canList}, canRead: ${writableProps.canRead}, canWrite: ${writableProps.canWrite}}` - ); + console.log(" writable properties: {"); + console.log(` canDelete: ${writableProps.canDelete}, + canList: ${writableProps.canList}, + canRead: ${writableProps.canRead}, + canWrite: ${writableProps.canWrite}`); + console.log(" }"); } } -async function getArtifactProperties(client, digest) { - console.log(`Retrieving registry artifact properties for ${digest}`); - const properties = await client.getRegistryArtifactProperties(digest); +async function getArtifactProperties(artifact) { + const properties = await artifact.getManifestProperties(); console.log(` created on: ${properties.createdOn}`); console.log(` last updated on: ${properties.lastUpdatedOn}`); - console.log(` arch : ${properties.cpuArchitecture}`); + console.log(` arch : ${properties.architecture}`); console.log(` os : ${properties.operatingSystem}`); console.log(` size : ${properties.size} bytes`); } -async function deleteArtifact(client, digest) { - console.log(`Deleting registry artifact for ${digest}`); - await client.deleteRegistryArtifact(digest); -} - main().catch((err) => { console.error("The sample encountered an error:", err); }); diff --git a/sdk/containerregistry/container-registry/samples/v1/javascript/sample.env b/sdk/containerregistry/container-registry/samples/v1/javascript/sample.env index d59b955c63ec..e1cc50fae02f 100644 --- a/sdk/containerregistry/container-registry/samples/v1/javascript/sample.env +++ b/sdk/containerregistry/container-registry/samples/v1/javascript/sample.env @@ -2,7 +2,7 @@ # Portal. # Retrieve this value from a Container Registry instance in the Azure Portal. CONTAINER_REGISTRY_ENDPOINT: "", -REPOSITORY_NAME="Repository Name" +REPOSITORY_NAME="" # Used to authenticate using Azure AD as a service principal for role-based # authentication in the tokenAuth sample. diff --git a/sdk/containerregistry/container-registry/samples/v1/typescript/README.md b/sdk/containerregistry/container-registry/samples/v1/typescript/README.md index 130f18421964..fdebc0b16336 100644 --- a/sdk/containerregistry/container-registry/samples/v1/typescript/README.md +++ b/sdk/containerregistry/container-registry/samples/v1/typescript/README.md @@ -12,10 +12,10 @@ urlFragment: container-registry-typescript These sample programs show how to use the TypeScript client libraries for Azure Container Registry in some common scenarios. -| **File Name** | **Description** | -| --------------------------------------------------------- | ---------------------------------------------------- | -| [containerRegistryClient.ts][containerregistryclient] | Demonstrates the use of a ContainerRegistryClient. | -| [containerRepositoryClient.ts][containerrepositoryclient] | Demonstrates the use of a ContainerRepositoryClient. | +| **File Name** | **Description** | +| ----------------------------------------------------- | ----------------------------------------------------------------- | +| [containerRegistryClient.ts][containerregistryclient] | Demonstrates the use of a ContainerRegistryClient. | +| [repositoryAndArtifact.ts][repositoryandartifact] | Demonstrates the use of ContainerRepository and RegistryArtifact. | ## Prerequisites @@ -70,8 +70,8 @@ npx cross-env CONTAINER_REGISTRY_ENDPOINT="" node d Take a look at our [API Documentation][apiref] for more information about the APIs that are available in the clients. [containerregistryclient]: https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/containerregistry/container-registry/samples/v1/typescript/src/containerRegistryClient.ts -[containerrepositoryclient]: https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/containerregistry/container-registry/samples/v1/typescript/src/containerRepositoryClient.ts -[apiref]: https://azuresdkdocs.blob.core.windows.net/$web/javascript/azure-container-registry/1.0.0-beta.1/index.html +[repositoryandartifact]: https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/containerregistry/container-registry/samples/v1/typescript/src/repositoryAndArtifact.ts +[apiref]: https://docs.microsoft.com/javascript/api/@azure/container-registry [freesub]: https://azure.microsoft.com/free/ [createinstance_azurecontainerregistry]: https://docs.microsoft.com/azure/container-registry/container-registry-get-started-portal [package]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/containerregistry/container-registry/README.md diff --git a/sdk/containerregistry/container-registry/samples/v1/typescript/sample.env b/sdk/containerregistry/container-registry/samples/v1/typescript/sample.env index d59b955c63ec..e1cc50fae02f 100644 --- a/sdk/containerregistry/container-registry/samples/v1/typescript/sample.env +++ b/sdk/containerregistry/container-registry/samples/v1/typescript/sample.env @@ -2,7 +2,7 @@ # Portal. # Retrieve this value from a Container Registry instance in the Azure Portal. CONTAINER_REGISTRY_ENDPOINT: "", -REPOSITORY_NAME="Repository Name" +REPOSITORY_NAME="" # Used to authenticate using Azure AD as a service principal for role-based # authentication in the tokenAuth sample. diff --git a/sdk/containerregistry/container-registry/samples/v1/typescript/src/containerRegistryClient.ts b/sdk/containerregistry/container-registry/samples/v1/typescript/src/containerRegistryClient.ts index 5b06d83aeead..f1b301daa2d2 100644 --- a/sdk/containerregistry/container-registry/samples/v1/typescript/src/containerRegistryClient.ts +++ b/sdk/containerregistry/container-registry/samples/v1/typescript/src/containerRegistryClient.ts @@ -18,24 +18,24 @@ export async function main() { await listRepositories(client); // Advanced: listing by pages - const pageSize = 2; + const pageSize = 1; await listRepositoriesByPages(client, pageSize); - const repositoryName = "hello-world"; + const repositoryName = "repository-name-to-delete"; await deleteRepository(client, repositoryName); } async function listRepositories(client: ContainerRegistryClient) { console.log("Listing repositories"); - const iterator = client.listRepositories(); + const iterator = client.listRepositoryNames(); for await (const repository of iterator) { console.log(` repository: ${repository}`); } } -async function listRepositoriesByPages(client: any, pageSize: number) { +async function listRepositoriesByPages(client: ContainerRegistryClient, pageSize: number) { console.log("Listing repositories by pages"); - const pages = client.listRepositories().byPage({ maxPageSize: pageSize }); + const pages = client.listRepositoryNames().byPage({ maxPageSize: pageSize }); let result = await pages.next(); while (!result.done) { console.log(" -- page -- "); @@ -51,14 +51,12 @@ async function deleteRepository(client: ContainerRegistryClient, repositoryName: const response = await client.deleteRepository(repositoryName); console.log( `Artifacts deleted: ${(response && - response.deletedRegistryArtifactDigests && - response.deletedRegistryArtifactDigests.length) || + response.deletedManifests && + response.deletedManifests.length) || 0}` ); console.log( - `Tags deleted: ${(response && - response.deletedRegistryArtifactDigests && - response.deletedRegistryArtifactDigests.length) || + `Tags deleted: ${(response && response.deletedManifests && response.deletedManifests.length) || 0}` ); } diff --git a/sdk/containerregistry/container-registry/samples/v1/typescript/src/containerRepositoryClient.ts b/sdk/containerregistry/container-registry/samples/v1/typescript/src/repositoryAndArtifact.ts similarity index 50% rename from sdk/containerregistry/container-registry/samples/v1/typescript/src/containerRepositoryClient.ts rename to sdk/containerregistry/container-registry/samples/v1/typescript/src/repositoryAndArtifact.ts index e7f40a067ef4..eb24d3ba9efc 100644 --- a/sdk/containerregistry/container-registry/samples/v1/typescript/src/containerRepositoryClient.ts +++ b/sdk/containerregistry/container-registry/samples/v1/typescript/src/repositoryAndArtifact.ts @@ -2,10 +2,15 @@ // Licensed under the MIT License. /** - * @summary Demonstrates the use of a ContainerRepositoryClient. + * @summary Demonstrates the use of ContainerRepository and RegistryArtifact. */ -import { ContainerRepositoryClient, RegistryArtifactProperties } from "@azure/container-registry"; +import { + ContainerRepository, + ArtifactManifestProperties, + ContainerRegistryClient, + RegistryArtifact +} from "@azure/container-registry"; import { DefaultAzureCredential } from "@azure/identity"; import * as dotenv from "dotenv"; dotenv.config(); @@ -14,32 +19,40 @@ 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 || ""; - const repository = process.env.REPOSITORY_NAME || ""; + const repositoryName = process.env.REPOSITORY_NAME || ""; + const pageSize = 1; - const client = new ContainerRepositoryClient(endpoint, repository, new DefaultAzureCredential()); - await getProperties(client); - await listTags(client); + const client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential()); + const repository = client.getRepository(repositoryName); + await getProperties(repository); - const artifacts = await listArtifacts(client); + const manifests = await listManifests(repository); - if (artifacts && artifacts.length) { - const digest = artifacts[0].digest; + if (manifests && manifests.length) { + const digest = manifests[0].digest; if (digest) { - await getArtifactProperties(client, digest); + const artifact = repository.getArtifact(digest); - await deleteArtifact(client, digest); + console.log(`Retrieving registry artifact properties for ${digest}`); + await getArtifactProperties(artifact); + + console.log(`Listing tags for ${digest}`); + await listTags(artifact); + + // Advanced: listing by pages + console.log(`Listing tags by pages for ${digest}`); + await listTagsByPages(artifact, pageSize); + + console.log(`Deleting registry artifact for ${digest}`); + await artifact.delete(); } } - // Advanced: listing by pages - const pageSize = 2; - await listTagsByPages(client, pageSize); - await listArtifactsByPages(client, pageSize); + await listManifestsByPages(repository, pageSize); } -async function listTags(client: ContainerRepositoryClient) { - console.log("Listing tags"); - const iterator = client.listTags({ orderBy: "timeasc" }); +async function listTags(artifact: RegistryArtifact) { + const iterator = artifact.listTags({ orderBy: "timeAsc" }); for await (const tag of iterator) { console.log(` tag: ${tag.name}`); console.log(` digest: ${tag.digest}`); @@ -48,9 +61,8 @@ async function listTags(client: ContainerRepositoryClient) { } } -async function listTagsByPages(client: ContainerRepositoryClient, pagesSize: number) { - console.log("Listing tags by pages"); - const pages = client.listTags().byPage({ maxPageSize: pagesSize }); +async function listTagsByPages(artifact: RegistryArtifact, pagesSize: number) { + const pages = artifact.listTags().byPage({ maxPageSize: pagesSize }); let result = await pages.next(); while (!result.done) { console.log(" -- page -- "); @@ -65,12 +77,12 @@ async function listTagsByPages(client: ContainerRepositoryClient, pagesSize: num } } -async function listArtifacts( - client: ContainerRepositoryClient -): Promise { +async function listManifests( + repository: ContainerRepository +): Promise { console.log("Listing artifacts"); - const artifacts: RegistryArtifactProperties[] = []; - const iterator = client.listRegistryArtifacts(); + const artifacts: ArtifactManifestProperties[] = []; + const iterator = repository.listManifests(); for await (const artifact of iterator) { artifacts.push(artifact); console.log(` digest: ${artifact.digest}`); @@ -81,9 +93,9 @@ async function listArtifacts( return artifacts; } -async function listArtifactsByPages(client: any, pageSize: number) { - console.log("Listing artifacts by pages"); - const pages = client.listRegistryArtifacts().byPage({ maxPageSize: pageSize }); +async function listManifestsByPages(repository: ContainerRepository, pageSize: number) { + console.log("Listing manifest by pages"); + const pages = repository.listManifests().byPage({ maxPageSize: pageSize }); let result = await pages.next(); while (!result.done) { console.log(" -- page -- "); @@ -97,38 +109,36 @@ async function listArtifactsByPages(client: any, pageSize: number) { } } -async function getProperties(client: ContainerRepositoryClient) { +async function getProperties(repository: ContainerRepository) { console.log("Retrieving repository properties..."); - const properties = await client.getProperties(); + const properties = await repository.getProperties(); console.log(` name: ${properties.name}`); console.log(` created on: ${properties.createdOn}`); console.log(` last updated on: ${properties.lastUpdatedOn}`); - console.log(` artifact count: ${properties.registryArtifactCount}`); + console.log(` artifact count: ${properties.manifestCount}`); console.log(` tag count: ${properties.tagCount}`); const writableProps = properties.writeableProperties; if (writableProps) { - console.log(" writable properties:"); + console.log(" writable properties: {"); console.log( - ` { canDelete: ${writableProps.canDelete}, canList: ${writableProps.canList}, canRead: ${writableProps.canRead}, canWrite: ${writableProps.canWrite}}` + ` canDelete: ${writableProps.canDelete}, + canList: ${writableProps.canList}, + canRead: ${writableProps.canRead}, + canWrite: ${writableProps.canWrite}` ); + console.log(" }"); } } -async function getArtifactProperties(client: ContainerRepositoryClient, digest: string) { - console.log(`Retrieving registry artifact properties for ${digest}`); - const properties = await client.getRegistryArtifactProperties(digest); +async function getArtifactProperties(artifact: RegistryArtifact) { + const properties = await artifact.getManifestProperties(); console.log(` created on: ${properties.createdOn}`); console.log(` last updated on: ${properties.lastUpdatedOn}`); - console.log(` arch : ${properties.cpuArchitecture}`); + console.log(` arch : ${properties.architecture}`); console.log(` os : ${properties.operatingSystem}`); console.log(` size : ${properties.size} bytes`); } -async function deleteArtifact(client: ContainerRepositoryClient, digest: string) { - console.log(`Deleting registry artifact for ${digest}`); - await client.deleteRegistryArtifact(digest); -} - main().catch((err) => { console.error("The sample encountered an error:", err); }); diff --git a/sdk/containerregistry/container-registry/src/containerRegistryClient.ts b/sdk/containerregistry/container-registry/src/containerRegistryClient.ts index ddf52999b356..34bdf07bcc99 100644 --- a/sdk/containerregistry/container-registry/src/containerRegistryClient.ts +++ b/sdk/containerregistry/container-registry/src/containerRegistryClient.ts @@ -21,7 +21,13 @@ import { createSpan } from "./tracing"; import { ContainerRegistryClientOptions, DeleteRepositoryResult } from "./model"; import { extractNextLink } from "./utils"; import { ChallengeHandler } from "./containerRegistryChallengeHandler"; -import { ContainerRepositoryClient, DeleteRepositoryOptions } from "./containerRepositoryClient"; +import { + ContainerRepository, + ContainerRepositoryImpl, + DeleteRepositoryOptions +} from "./containerRepository"; +import { URL } from "./url"; +import { RegistryArtifact } from "./registryArtifact"; /** * Options for the `listRepositories` method of `ContainerRegistryClient`. @@ -35,11 +41,15 @@ export class ContainerRegistryClient { /** * The Azure Container Registry endpoint. */ - public endpoint: string; - private credential: TokenCredential; - private clientOptions: ContainerRegistryClientOptions; + public readonly registryUrl: string; + + /** The login server of the registry */ + public readonly loginServer: string; + + /** The name of the registry */ + public readonly name: string; + private client: GeneratedClient; - private authClient: GeneratedClient; /** * Creates an instance of a ContainerRegistryClient. @@ -63,9 +73,11 @@ export class ContainerRegistryClient { credential: TokenCredential, options: ContainerRegistryClientOptions = {} ) { - this.endpoint = endpointUrl; - this.credential = credential; - this.clientOptions = options; + this.registryUrl = endpointUrl; + const parsedUrl = new URL(endpointUrl); + this.loginServer = parsedUrl.hostname; + this.name = parsedUrl.pathname; + // The below code helps us set a proper User-Agent header on all requests const libInfo = `azsdk-js-container-registry/${SDK_VERSION}`; if (!options.userAgentOptions) { @@ -88,13 +100,13 @@ export class ContainerRegistryClient { } }; - this.authClient = new GeneratedClient(endpointUrl, internalPipelineOptions); + const authClient = new GeneratedClient(endpointUrl, internalPipelineOptions); this.client = new GeneratedClient(endpointUrl, internalPipelineOptions); this.client.pipeline.addPolicy( bearerTokenChallengeAuthenticationPolicy({ credential, scopes: [`https://management.core.windows.net/.default`], - challengeCallbacks: new ChallengeHandler(this.authClient) + challengeCallbacks: new ChallengeHandler(authClient) }) ); } @@ -102,11 +114,11 @@ export class ContainerRegistryClient { /** * Deletes the repository identified by the given name. * - * @param name - the name of repository to delete + * @param repositoryName - the name of repository to delete * @param options - optional configuration for the operation */ public async deleteRepository( - name: string, + repositoryName: string, options: DeleteRepositoryOptions = {} ): Promise { const { span, updatedOptions } = createSpan( @@ -115,8 +127,14 @@ export class ContainerRegistryClient { ); try { - const result = await this.client.containerRegistry.deleteRepository(name, updatedOptions); - return result; + const result = await this.client.containerRegistry.deleteRepository( + repositoryName, + updatedOptions + ); + return { + deletedManifests: result.deletedManifests ?? [], + deletedTags: result.deletedTags ?? [] + }; } catch (e) { span.setStatus({ code: SpanStatusCode.ERROR, message: e.message }); throw e; @@ -125,21 +143,26 @@ export class ContainerRegistryClient { } } + /** + * Returns an artifact for given repository name, and a tag or digest. + * + * @param repositoryName - the name of repository + * @param tagOrDigest - tag or digest of the artifact to retrieve + */ + public getArtifact(repositoryName: string, tagOrDigest: string): RegistryArtifact { + return new ContainerRepositoryImpl(this.registryUrl, repositoryName, this.client).getArtifact( + tagOrDigest + ); + } + /** * Returns a ContainerRepositoryClient instance for the given repository. * - * @param name - the name of repository to delete + * @param repositoryName - the name of repository to delete * @param options - optional configuration for the operation */ - // The method name follows beta.1 API design - // eslint-disable-next-line @azure/azure-sdk/ts-naming-subclients - public getRepositoryClient(repository: string): ContainerRepositoryClient { - return new ContainerRepositoryClient( - this.endpoint, - repository, - this.credential, - this.clientOptions - ); + public getRepository(repositoryName: string): ContainerRepository { + return new ContainerRepositoryImpl(this.registryUrl, repositoryName, this.client); } /** @@ -148,19 +171,17 @@ export class ContainerRegistryClient { * Example usage: * ```ts * let client = new ContainerRegistryClient(url, credentials); - * for await (const repository of client.listRepositories()) { + * for await (const repository of client.listRepositoryNames()) { * console.log("repository name: ", repository); * } * ``` * @param options - */ - public listRepositories( + public listRepositoryNames( options: ListRepositoriesOptions = {} ): PagedAsyncIterableIterator { - const { span, updatedOptions } = createSpan("listRepositories", options); - const iter = this.listRepositoryItems(updatedOptions); + const iter = this.listRepositoryItems(options); - span.end(); return { next() { return iter.next(); @@ -168,7 +189,7 @@ export class ContainerRegistryClient { [Symbol.asyncIterator]() { return this; }, - byPage: (settings: PageSettings = {}) => this.listRepositoriesPage(settings, updatedOptions) + byPage: (settings: PageSettings = {}) => this.listRepositoriesPage(settings, options) }; } diff --git a/sdk/containerregistry/container-registry/src/containerRepository.ts b/sdk/containerregistry/container-registry/src/containerRepository.ts new file mode 100644 index 000000000000..daed13ebb560 --- /dev/null +++ b/sdk/containerregistry/container-registry/src/containerRepository.ts @@ -0,0 +1,295 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +/// + +import { OperationOptions } from "@azure/core-client"; +import { SpanStatusCode } from "@azure/core-tracing"; +import "@azure/core-paging"; +import { PageSettings, PagedAsyncIterableIterator } from "@azure/core-paging"; +import { URL } from "./url"; + +import { GeneratedClient } from "./generated"; +import { createSpan } from "./tracing"; +import { + ContentProperties, + DeleteRepositoryResult, + ManifestOrderBy, + ArtifactManifestProperties, + RepositoryProperties +} from "./model"; +import { RegistryArtifact, RegistryArtifactImpl } from "./registryArtifact"; +import { toArtifactManifestProperties, toServiceManifestOrderBy } from "./transformations"; +import { extractNextLink } from "./utils"; + +/** + * Options for delete repository operation. + */ +export interface DeleteRepositoryOptions extends OperationOptions {} +/** + * Options for the `listRegistryArtifacts` method of `ContainerRepository`. + */ +export interface ListManifestsOptions extends OperationOptions { + /** orderby query parameter */ + orderBy?: ManifestOrderBy; +} +/** + * Options for the `getProperties` method of `ContainerRepository`. + */ +export interface GetRepositoryPropertiesOptions extends OperationOptions {} +/** + * Options for the `setProperties` method of `ContainerRepository`. + */ +export type SetRepositoryPropertiesOptions = ContentProperties & OperationOptions; + +/** + * The helper used to interact with the Container Registry service. + */ +export interface ContainerRepository { + /** + * The Azure Container Registry endpoint. + */ + readonly registryUrl: string; + /** + * Repository name. + */ + readonly name: string; + /** + * Registry name. + */ + readonly fullyQualifiedName: string; + /** + * Deletes this repository. + * + * @param options - optional configuration for the operation + */ + delete(options?: DeleteRepositoryOptions): Promise; + /** + * Returns an instance of RegistryArtifact. + * @param tagOrDigest - the tag or digest of the artifact + */ + getArtifact(tagOrDigest: string): RegistryArtifact; + /** + * Retrieves properties of this repository. + * @param options - + */ + getProperties(options?: GetRepositoryPropertiesOptions): Promise; + /** + * Updates repository attributes. + * @param options - + */ + setProperties(options: SetRepositoryPropertiesOptions): Promise; + /** + * Iterates manifests. + * + * Example usage: + * ```ts + * const client = new ContainerRegistryClient(url, credentials); + * const repository = client.getRepository(repositoryName) + * for await (const manifest of repository.listManifests()) { + * console.log("manifest: ", manifest); + * } + * ``` + * @param options - + */ + listManifests( + options?: ListManifestsOptions + ): PagedAsyncIterableIterator; +} + +/** + * The client class used to interact with the Container Registry service. + * @internal + */ +export class ContainerRepositoryImpl { + private readonly client: GeneratedClient; + /** + * The Azure Container Registry endpoint. + */ + public readonly registryUrl: string; + /** + * Repository name. + */ + public readonly name: string; + /** + * Registry name. + */ + public readonly fullyQualifiedName: string; + + /** + * Creates an instance of a ContainerRepository. + * @param registryUrl - the URL to the Container Registry endpoint + * @param name - the name of the repository + * @param client - the generated client that interacts with service + */ + constructor(registryUrl: string, name: string, client: GeneratedClient) { + this.registryUrl = registryUrl; + this.name = name; + const parsedUrl = new URL(registryUrl); + this.fullyQualifiedName = `${parsedUrl.hostname}/${name}`; + + this.client = client; + } + + /** + * Deletes this repository. + * + * @param options - optional configuration for the operation + */ + public async delete(options: DeleteRepositoryOptions = {}): Promise { + const { span, updatedOptions } = createSpan("ContainerRepository-delete", options); + + try { + const result = await this.client.containerRegistry.deleteRepository( + this.name, + updatedOptions + ); + return { + deletedManifests: result.deletedManifests ?? [], + deletedTags: result.deletedTags ?? [] + }; + } catch (e) { + span.setStatus({ code: SpanStatusCode.ERROR, message: e.message }); + throw e; + } finally { + span.end(); + } + } + + /** + * Returns an instance of RegistryArtifact. + * @param tagOrDigest - the tag or digest of the artifact + */ + public getArtifact(tagOrDigest: string): RegistryArtifact { + return new RegistryArtifactImpl(this.registryUrl, this.name, tagOrDigest, this.client); + } + + /** + * Retrieves properties of this repository. + * @param options - + */ + public async getProperties( + options: GetRepositoryPropertiesOptions = {} + ): Promise { + const { span, updatedOptions } = createSpan("ContainerRepository-getProperties", options); + + try { + const result = await this.client.containerRegistry.getProperties(this.name, updatedOptions); + return result; + } catch (e) { + span.setStatus({ code: SpanStatusCode.ERROR, message: e.message }); + throw e; + } finally { + span.end(); + } + } + + /** + * Updates repository attributes. + * @param options - + */ + public async setProperties( + options: SetRepositoryPropertiesOptions + ): Promise { + const { span, updatedOptions } = createSpan("ContainerRepository-setProperties", { + ...options, + value: { + canDelete: options.canDelete, + canWrite: options.canWrite, + canList: options.canList, + canRead: options.canRead + } + }); + + try { + const properties = await this.client.containerRegistry.setProperties( + this.name, + updatedOptions + ); + return { + ...properties, + writeableProperties: { + canDelete: properties.writeableProperties.canDelete, + canList: properties.writeableProperties.canList, + canRead: properties.writeableProperties.canRead, + canWrite: properties.writeableProperties.canWrite + } + }; + } catch (e) { + span.setStatus({ code: SpanStatusCode.ERROR, message: e.message }); + throw e; + } finally { + span.end(); + } + } + + /** + * Iterates manifests. + * + * Example usage: + * ```ts + * const client = new ContainerRegistryClient(url, credentials); + * const repository = client.getRepository(repositoryName) + * for await (const manifest of repository.listManifests()) { + * console.log("manifest: ", manifest); + * } + * ``` + * @param options - + */ + public listManifests( + options: ListManifestsOptions = {} + ): PagedAsyncIterableIterator { + const iter = this.listManifestsItems(options); + + return { + next() { + return iter.next(); + }, + [Symbol.asyncIterator]() { + return this; + }, + byPage: (settings: PageSettings = {}) => this.listManifestsPage(settings, options) + }; + } + + private async *listManifestsItems( + options: ListManifestsOptions = {} + ): AsyncIterableIterator { + for await (const page of this.listManifestsPage({}, options)) { + yield* page; + } + } + + private async *listManifestsPage( + continuationState: PageSettings, + options: ListManifestsOptions = {} + ): AsyncIterableIterator { + const orderby = toServiceManifestOrderBy(options.orderBy); + if (!continuationState.continuationToken) { + const optionsComplete = { + ...options, + n: continuationState.maxPageSize, + orderby + }; + const currentPage = await this.client.containerRegistry.getManifests( + this.name, + optionsComplete + ); + continuationState.continuationToken = extractNextLink(currentPage.link); + if (currentPage.manifests) { + yield currentPage.manifests.map((t) => toArtifactManifestProperties(t, this.name)); + } + } + while (continuationState.continuationToken) { + const currentPage = await this.client.containerRegistry.getManifestsNext( + this.name, + continuationState.continuationToken, + options + ); + continuationState.continuationToken = extractNextLink(currentPage.link); + if (currentPage.manifests) { + yield currentPage.manifests.map((t) => toArtifactManifestProperties(t, this.name)); + } + } + } +} diff --git a/sdk/containerregistry/container-registry/src/containerRepositoryClient.ts b/sdk/containerregistry/container-registry/src/containerRepositoryClient.ts deleted file mode 100644 index 760233670fcc..000000000000 --- a/sdk/containerregistry/container-registry/src/containerRepositoryClient.ts +++ /dev/null @@ -1,607 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. - -/// - -import { TokenCredential } from "@azure/core-auth"; -import { - InternalPipelineOptions, - bearerTokenChallengeAuthenticationPolicy -} from "@azure/core-rest-pipeline"; -import { OperationOptions } from "@azure/core-client"; -import { SpanStatusCode } from "@azure/core-tracing"; -import "@azure/core-paging"; -import { PageSettings, PagedAsyncIterableIterator } from "@azure/core-paging"; -import { URL } from "./url"; - -import { SDK_VERSION } from "./constants"; -import { logger } from "./logger"; -import { GeneratedClient } from "./generated"; -import { createSpan } from "./tracing"; -import { - ContainerRegistryClientOptions, - ContentProperties, - DeleteRepositoryResult, - RegistryArtifactOrderBy, - RegistryArtifactProperties, - RepositoryProperties, - TagOrderBy, - TagProperties -} from "./model"; -import { extractNextLink } from "./utils"; -import { ChallengeHandler } from "./containerRegistryChallengeHandler"; - -/** - * Options for the `getProperties` method of `ContainerRepositoryClient`. - */ -export interface GetRepositoryPropertiesOptions extends OperationOptions {} - -/** - * Options for delete repository operation. - */ -export interface DeleteRepositoryOptions extends OperationOptions {} - -/** - * Options for the `deleteRegistryArtifact` method of `ContainerRepositoryClient`. - */ -export interface DeleteRegistryArtifactOptions extends OperationOptions {} - -/** - * Options for the `deleteTag` method of `ContainerRepositoryClient`. - */ -export interface DeleteTagOptions extends OperationOptions {} - -/** - * Options for the `getRegistryArtifactProperties` method of `ContainerRepositoryClient`. - */ -export interface GetRegistryArtifactPropertiesOptions extends OperationOptions {} - -/** - * Options for the `getTagProperties` method of `ContainerRepositoryClient`. - */ -export interface GetTagPropertiesOptions extends OperationOptions {} - -/** - * Options for the `setManifestProperties` method of `ContainerRepositoryClient`. - */ -export interface SetManifestPropertiesOptions extends OperationOptions {} - -/** - * Options for the `setProperties` method of `ContainerRepositoryClient`. - */ -export interface SetRepositoryPropertiesOptions extends OperationOptions {} -/** - * Options for the `setTagProperties` method of `ContainerRepositoryClient`. - */ -export interface SetTagPropertiesOptions extends OperationOptions {} - -/** - * Options for the `listRegistryArtifacts` method of `ContainerRepositoryClient`. - */ -export interface ListRegistryArtifactsOptions extends OperationOptions { - /** orderby query parameter */ - orderBy?: RegistryArtifactOrderBy; -} - -/** - * Options for the `listTags` method of `ContainerRepositoryClient`. - */ -export interface ListTagsOptions extends OperationOptions { - /** orderby query parameter */ - orderBy?: TagOrderBy; -} - -function isDigest(tagOrDigest: string): boolean { - return tagOrDigest.includes(":"); -} - -/** - * The client class used to interact with the Container Registry service. - */ -export class ContainerRepositoryClient { - private client: GeneratedClient; - private authClient: GeneratedClient; - /** - * The Azure Container Registry endpoint. - */ - public endpoint: string; - /** - * Repository name. - */ - public repository: string; - /** - * Registry name. - */ - public registry: string; - - /** - * Creates an instance of a ContainerRepositoryClient. - * - * Example usage: - * ```ts - * import { ContainerRepositoryClient } from "@azure/container-registry"; - * import { DefaultAzureCredential} from "@azure/identity"; - * - * const client = new ContainerRepositoryClient( - * "", - * "" - * new DefaultAzureCredential() - * ); - * ``` - * @param endpointUrl - the URL to the Container Registry endpoint - * @param repository - the URL to the Container Registry endpoint - * @param credential - used to authenticate requests to the service - * @param options - optional configuration used to send requests to the service - */ - constructor( - endpointUrl: string, - repository: string, - credential: TokenCredential, - options: ContainerRegistryClientOptions = {} - ) { - this.endpoint = endpointUrl; - this.repository = repository; - const parsedUrl = new URL(endpointUrl); - this.registry = parsedUrl.hostname; - - // The below code helps us set a proper User-Agent header on all requests - const libInfo = `azsdk-js-container-registry/${SDK_VERSION}`; - if (!options.userAgentOptions) { - options.userAgentOptions = {}; - } - if (options.userAgentOptions.userAgentPrefix) { - options.userAgentOptions.userAgentPrefix = `${options.userAgentOptions.userAgentPrefix} ${libInfo}`; - } else { - options.userAgentOptions.userAgentPrefix = libInfo; - } - - const internalPipelineOptions: InternalPipelineOptions = { - ...options, - loggingOptions: { - logger: logger.info, - // This array contains header names we want to log that are not already - // included as safe. Unknown/unsafe headers are logged as "". - additionalAllowedHeaderNames: ["x-ms-correlation-request-id"], - additionalAllowedQueryParameters: ["last", "n", "orderby", "digest"] - } - }; - - this.authClient = new GeneratedClient(endpointUrl, internalPipelineOptions); - this.client = new GeneratedClient(endpointUrl, internalPipelineOptions); - const authPolicy = bearerTokenChallengeAuthenticationPolicy({ - credential, - scopes: [`https://management.core.windows.net/.default`], - challengeCallbacks: new ChallengeHandler(this.authClient) - }); - this.client.pipeline.addPolicy(authPolicy); - } - - /** - * Deletes this repository. - * - * @param options - optional configuration for the operation - */ - public async delete(options: DeleteRepositoryOptions = {}): Promise { - const { span, updatedOptions } = createSpan("ContainerRepositoryClient-delete", options); - - try { - const result = await this.client.containerRegistry.deleteRepository( - this.repository, - updatedOptions - ); - return result; - } catch (e) { - span.setStatus({ code: SpanStatusCode.ERROR, message: e.message }); - throw e; - } finally { - span.end(); - } - } - - /** - * Deletes a registry artifact in this repository. - * @param digest - the digest of the artifact to be deleted. - * @param options - - */ - public async deleteRegistryArtifact( - digest: string, - options: DeleteRegistryArtifactOptions = {} - ): Promise { - const { span, updatedOptions } = createSpan( - "ContainerRepositoryClient-deleteRegistryArtifact", - options - ); - - try { - await this.client.containerRegistryRepository.deleteManifest( - this.repository, - digest, - updatedOptions - ); - } catch (e) { - span.setStatus({ code: SpanStatusCode.ERROR, message: e.message }); - throw e; - } finally { - span.end(); - } - } - - /** - * Deletes a tag. - * @param tag - the name of the tag to be deleted. - * @param options - - */ - public async deleteTag(tag: string, options: DeleteTagOptions = {}): Promise { - const { span, updatedOptions } = createSpan("ContainerRepositoryClient-deleteTag", options); - - try { - await this.client.containerRegistryRepository.deleteTag(this.repository, tag, updatedOptions); - } catch (e) { - span.setStatus({ code: SpanStatusCode.ERROR, message: e.message }); - throw e; - } finally { - span.end(); - } - } - - /** - * Retrieves properties of this repository. - * @param options - - */ - public async getProperties( - options: GetRepositoryPropertiesOptions = {} - ): Promise { - const { span, updatedOptions } = createSpan("ContainerRepositoryClient-getProperties", options); - - try { - const result = await this.client.containerRegistryRepository.getProperties( - this.repository, - updatedOptions - ); - return result; - } catch (e) { - span.setStatus({ code: SpanStatusCode.ERROR, message: e.message }); - throw e; - } finally { - span.end(); - } - } - - /** - * Retrieves properties of a registry artifact. - * @param tagOrDigest - the tag or digest of the registry artifact. - * @param options - - */ - public async getRegistryArtifactProperties( - tagOrDigest: string, - options: GetRegistryArtifactPropertiesOptions = {} - ): Promise { - const { span, updatedOptions } = createSpan( - "ContainerRepositoryClient-getRegistryArtifactProperties", - options - ); - - let digest: string = tagOrDigest; - if (!isDigest(tagOrDigest)) { - digest = (await this.getTagProperties(tagOrDigest)).digest!; // TODO: (jeremymeng) swagger update to make digest non-optional - } - - try { - const result = await this.client.containerRegistryRepository.getRegistryArtifactProperties( - this.repository, - digest, - updatedOptions - ); - const registryArtifacts = result.references; - delete result.references; - return { ...result, registryArtifacts }; - } catch (e) { - span.setStatus({ code: SpanStatusCode.ERROR, message: e.message }); - throw e; - } finally { - span.end(); - } - } - - /** - * Retrieves properties of a tag. - * @param digest - the tag to be deleted. - * @param options - - */ - public async getTagProperties( - tag: string, - options: GetTagPropertiesOptions = {} - ): Promise { - const { span, updatedOptions } = createSpan( - "ContainerRepositoryClient-getTagProperties", - options - ); - try { - const result = await this.client.containerRegistryRepository.getTagProperties( - this.repository, - tag, - updatedOptions - ); - return result; - } catch (e) { - span.setStatus({ code: SpanStatusCode.ERROR, message: e.message }); - throw e; - } finally { - span.end(); - } - } - - /** - * Updates manifest artifact attributes. - * @param digest - the digest of the manifest. - * @param options - - */ - public async setManifestProperties( - digest: string, - value: ContentProperties, - options: SetManifestPropertiesOptions = {} - ): Promise { - const { span, updatedOptions } = createSpan("ContainerRepositoryClient-setManifestProperties", { - ...options, - value: value - }); - - try { - const properties = await this.client.containerRegistryRepository.updateManifestAttributes( - this.repository, - digest, - updatedOptions - ); - return { - ...properties, - writeableProperties: properties.writeableProperties - ? { - canDelete: properties.writeableProperties.canDelete, - canList: properties.writeableProperties.canList, - canRead: properties.writeableProperties.canRead, - canWrite: properties.writeableProperties.canWrite - } - : undefined - }; - } catch (e) { - span.setStatus({ code: SpanStatusCode.ERROR, message: e.message }); - throw e; - } finally { - span.end(); - } - } - - /** - * Updates repository attributes. - * @param options - - */ - public async setProperties( - value: ContentProperties, - options: SetRepositoryPropertiesOptions = {} - ): Promise { - const { span, updatedOptions } = createSpan("ContainerRepositoryClient-setProperties", { - ...options, - value: value - }); - - try { - const properties = await this.client.containerRegistryRepository.setProperties( - this.repository, - updatedOptions - ); - return { - ...properties, - writeableProperties: { - canDelete: properties.writeableProperties.canDelete, - canList: properties.writeableProperties.canList, - canRead: properties.writeableProperties.canRead, - canWrite: properties.writeableProperties.canWrite - } - }; - } catch (e) { - span.setStatus({ code: SpanStatusCode.ERROR, message: e.message }); - throw e; - } finally { - span.end(); - } - } - - /** - * Updates tag attributes. - * @param tag - name of the tag - * @param options - - */ - public async setTagProperties( - tag: string, - value: ContentProperties, - options: SetTagPropertiesOptions = {} - ): Promise { - const { span, updatedOptions } = createSpan("ContainerRepositoryClient-setTagProperties", { - ...options, - value: value - }); - - try { - return await this.client.containerRegistryRepository.updateTagAttributes( - this.repository, - tag, - updatedOptions - ); - } catch (e) { - span.setStatus({ code: SpanStatusCode.ERROR, message: e.message }); - throw e; - } finally { - span.end(); - } - } - - /** - * Iterates artifacts. - * - * Example usage: - * ```ts - * let client = new ContainerRepositoryClient(url, repository, credentials); - * for await (const repository of client.listRegistryArtifacts()) { - * console.log("artifact: ", artifact); - * } - * ``` - * @param options - - */ - public listRegistryArtifacts( - options: ListRegistryArtifactsOptions = {} - ): PagedAsyncIterableIterator { - const { span, updatedOptions } = createSpan("listRegistryArtifacts", options); - const iter = this.listArtifactItems(updatedOptions); - - span.end(); - return { - next() { - return iter.next(); - }, - [Symbol.asyncIterator]() { - return this; - }, - byPage: (settings: PageSettings = {}) => this.listArtifactPage(settings, updatedOptions) - }; - } - - private async *listArtifactItems( - options: ListRegistryArtifactsOptions = {} - ): AsyncIterableIterator { - for await (const page of this.listArtifactPage({}, options)) { - yield* page; - } - } - - private async *listArtifactPage( - continuationState: PageSettings, - options: ListRegistryArtifactsOptions = {} - ): AsyncIterableIterator { - if (!continuationState.continuationToken) { - const optionsComplete = { - ...options, - n: continuationState.maxPageSize, - orderby: options.orderBy - }; - const currentPage = await this.client.containerRegistryRepository.getManifests( - this.repository, - optionsComplete - ); - if (currentPage.link) { - continuationState.continuationToken = currentPage.link.substr( - 1, - currentPage.link.indexOf(">") - 1 - ); - } else { - continuationState.continuationToken = undefined; - } - if (currentPage.manifests) { - yield currentPage.manifests.map((t) => { - return { - ...t, - repository: currentPage.repository! - }; - }); - } - } - while (continuationState.continuationToken) { - const currentPage = await this.client.containerRegistryRepository.getManifestsNext( - this.repository, - continuationState.continuationToken, - options - ); - if (currentPage.link) { - continuationState.continuationToken = currentPage.link.substr( - 1, - currentPage.link.indexOf(">") - 1 - ); - } else { - continuationState.continuationToken = undefined; - } - if (currentPage.manifests) { - yield currentPage.manifests.map((t) => { - return { - ...t, - repository: currentPage.repository! - }; - }); - } - } - } - - /** - * Iterates tags. - * - * Example usage: - * ```ts - * let client = new ContainerRepositoryClient(url, repository, credentials); - * for await (const repository of client.listTags()) { - * console.log("tag: ", tag); - * } - * ``` - * @param options - - */ - public listTags(options: ListTagsOptions = {}): PagedAsyncIterableIterator { - const { span, updatedOptions } = createSpan("listTags", options); - const iter = this.listTagItems(updatedOptions); - - span.end(); - return { - next() { - return iter.next(); - }, - [Symbol.asyncIterator]() { - return this; - }, - byPage: (settings: PageSettings = {}) => this.listTagsPage(settings, updatedOptions) - }; - } - - private async *listTagItems(options: ListTagsOptions = {}): AsyncIterableIterator { - for await (const page of this.listTagsPage({}, options)) { - yield* page; - } - } - - private async *listTagsPage( - continuationState: PageSettings, - options: ListTagsOptions = {} - ): AsyncIterableIterator { - if (!continuationState.continuationToken) { - const optionsComplete = { - ...options, - n: continuationState.maxPageSize, - orderby: options.orderBy - }; - const currentPage = await this.client.containerRegistryRepository.getTags( - this.repository, - optionsComplete - ); - continuationState.continuationToken = extractNextLink(currentPage.link); - if (currentPage.tagAttributeBases) { - yield currentPage.tagAttributeBases.map((t) => { - return { - ...t, - repository: currentPage.repository - }; - }); - } - } - while (continuationState.continuationToken) { - const currentPage = await this.client.containerRegistryRepository.getTagsNext( - this.repository, - continuationState.continuationToken, - options - ); - continuationState.continuationToken = extractNextLink(currentPage.link); - if (currentPage.tagAttributeBases) { - yield currentPage.tagAttributeBases.map((t) => { - return { - ...t, - repository: currentPage.repository - }; - }); - } - } - } -} diff --git a/sdk/containerregistry/container-registry/src/generated/generatedClient.ts b/sdk/containerregistry/container-registry/src/generated/generatedClient.ts index 9c2b3524427b..802392a69460 100644 --- a/sdk/containerregistry/container-registry/src/generated/generatedClient.ts +++ b/sdk/containerregistry/container-registry/src/generated/generatedClient.ts @@ -8,7 +8,6 @@ import { ContainerRegistry, - ContainerRegistryRepository, ContainerRegistryBlob, Authentication } from "./operations"; @@ -25,13 +24,11 @@ export class GeneratedClient extends GeneratedClientContext { constructor(url: string, options?: GeneratedClientOptionalParams) { super(url, options); this.containerRegistry = new ContainerRegistry(this); - this.containerRegistryRepository = new ContainerRegistryRepository(this); this.containerRegistryBlob = new ContainerRegistryBlob(this); this.authentication = new Authentication(this); } containerRegistry: ContainerRegistry; - containerRegistryRepository: ContainerRegistryRepository; containerRegistryBlob: ContainerRegistryBlob; authentication: Authentication; } diff --git a/sdk/containerregistry/container-registry/src/generated/models/index.ts b/sdk/containerregistry/container-registry/src/generated/models/index.ts index 5122d7371a01..91b00f3e8639 100644 --- a/sdk/containerregistry/container-registry/src/generated/models/index.ts +++ b/sdk/containerregistry/container-registry/src/generated/models/index.ts @@ -40,18 +40,36 @@ export interface Repositories { /** Repository attributes */ export interface RepositoryProperties { - /** Image name */ - name: string; - /** Image created time */ - createdOn: Date; - /** Image last update time */ - lastUpdatedOn: Date; - /** Number of the manifests */ - registryArtifactCount: number; - /** Number of the tags */ - tagCount: number; - /** Writeable properties of the resource */ - writeableProperties: ContentProperties; + /** + * Image name + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly name: string; + /** + * Image created time + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly createdOn: Date; + /** + * Image last update time + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly lastUpdatedOn: Date; + /** + * Number of the manifests + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly manifestCount: number; + /** + * Number of the tags + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly tagCount: number; + /** + * Writeable properties of the resource + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly writeableProperties: ContentProperties; } /** Changeable attributes */ @@ -68,10 +86,16 @@ export interface ContentProperties { /** Deleted repository */ export interface DeleteRepositoryResult { - /** SHA of the deleted image */ - deletedRegistryArtifactDigests?: string[]; - /** Tag of the deleted image */ - deletedTags?: string[]; + /** + * SHA of the deleted image + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly deletedManifests?: string[]; + /** + * Tag of the deleted image + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly deletedTags?: string[]; } /** List of tag details */ @@ -85,32 +109,65 @@ export interface TagList { /** Tag attribute details */ export interface TagAttributesBase { - /** Tag name */ - name: string; - /** Tag digest */ - digest: string; - /** Tag created time */ - createdOn: Date; - /** Tag last update time */ - lastUpdatedOn: Date; - /** Writeable properties of the resource */ - writeableProperties: ContentProperties; + /** + * Tag name + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly name: string; + /** + * Tag digest + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly digest: string; + /** + * Tag created time + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly createdOn: Date; + /** + * Tag last update time + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly lastUpdatedOn: Date; + /** + * Writeable properties of the resource + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly writeableProperties: ContentProperties; } /** Tag attributes */ -export interface TagProperties { - /** Image name */ - repository: string; - /** Tag name */ - name: string; - /** Tag digest */ - digest: string; - /** Tag created time */ - createdOn: Date; - /** Tag last update time */ - lastUpdatedOn: Date; - /** Writeable properties of the resource */ - writeableProperties: ContentProperties; +export interface ArtifactTagProperties { + /** + * Image name + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly repository: string; + /** + * Tag name + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly name: string; + /** + * Tag digest + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly digest: string; + /** + * Tag created time + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly createdOn: Date; + /** + * Tag last update time + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly lastUpdatedOn: Date; + /** + * Writeable properties of the resource + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly writeableProperties: ContentProperties; } /** Manifest attributes */ @@ -124,58 +181,124 @@ export interface AcrManifests { /** Manifest details */ export interface ManifestAttributesBase { - /** Manifest */ - digest: string; - /** Image size */ - size?: number; - /** Created time */ - createdOn?: Date; - /** Last update time */ - lastUpdatedOn?: Date; - /** CPU architecture */ - cpuArchitecture?: string; - /** Operating system */ - operatingSystem?: string; - /** List of manifest attributes details */ - references?: ManifestAttributesManifestReferences[]; - /** List of tags */ - tags?: string[]; - /** Writeable properties of the resource */ - writeableProperties?: ContentProperties; + /** + * Manifest + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly digest: string; + /** + * Image size + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly size?: number; + /** + * Created time + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly createdOn?: Date; + /** + * Last update time + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly lastUpdatedOn?: Date; + /** + * CPU architecture + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly architecture?: ArtifactArchitecture | null; + /** + * Operating system + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly operatingSystem?: ArtifactOperatingSystem | null; + /** + * List of manifest attributes details + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly references?: ManifestAttributesManifestReferences[]; + /** + * List of tags + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly tags?: string[]; + /** + * Writeable properties of the resource + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly writeableProperties?: ContentProperties; } /** Manifest attributes details */ export interface ManifestAttributesManifestReferences { - /** Manifest digest */ - digest: string; - /** CPU architecture */ - cpuArchitecture: string; - /** Operating system */ - operatingSystem: string; + /** + * Manifest digest + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly digest: string; + /** + * CPU architecture + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly architecture: ArtifactArchitecture; + /** + * Operating system + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly operatingSystem: ArtifactOperatingSystem; } /** Manifest attributes details */ -export interface RegistryArtifactProperties { - /** Image name */ - repository?: string; - /** Manifest */ - digest?: string; - /** Image size */ - size?: number; - /** Created time */ - createdOn?: Date; - /** Last update time */ - lastUpdatedOn?: Date; - /** CPU architecture */ - cpuArchitecture?: string; - /** Operating system */ - operatingSystem?: string; - /** List of manifest attributes details */ - references?: ManifestAttributesManifestReferences[]; - /** List of tags */ - tags?: string[]; - /** Writeable properties of the resource */ - writeableProperties?: ContentProperties; +export interface ArtifactManifestProperties { + /** + * Repository name + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly repositoryName?: string; + /** + * Manifest + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly digest?: string; + /** + * Image size + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly size?: number; + /** + * Created time + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly createdOn?: Date; + /** + * Last update time + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly lastUpdatedOn?: Date; + /** + * CPU architecture + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly architecture?: ArtifactArchitecture | null; + /** + * Operating system + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly operatingSystem?: ArtifactOperatingSystem | null; + /** + * List of manifest attributes details + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly references?: ManifestAttributesManifestReferences[]; + /** + * List of tags + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly tags?: string[]; + /** + * Writeable properties of the resource + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly writeableProperties?: ContentProperties; } export interface Paths108HwamOauth2ExchangePostRequestbodyContentApplicationXWwwFormUrlencodedSchema { @@ -184,7 +307,7 @@ export interface Paths108HwamOauth2ExchangePostRequestbodyContentApplicationXWww /** Indicates the name of your Azure container registry. */ service: string; /** AAD access token, mandatory when grant_type is access_token_refresh_token or access_token. */ - aadAccesstoken: string; + aadAccessToken: string; } export interface AcrRefreshToken { @@ -439,48 +562,48 @@ export type V1Manifest = Manifest & { signatures?: ImageSignature[]; }; +/** Defines headers for ContainerRegistry_createManifest operation. */ +export interface ContainerRegistryCreateManifestHeaders { + /** Identifies the docker upload uuid for the current request. */ + dockerContentDigest?: string; + /** The canonical location url of the uploaded manifest. */ + location?: string; + /** The length of the requested blob content. */ + contentLength?: number; +} + /** Defines headers for ContainerRegistry_getRepositories operation. */ export interface ContainerRegistryGetRepositoriesHeaders { /** next paginated result */ link?: string; } -/** Defines headers for ContainerRegistry_getRepositoriesNext operation. */ -export interface ContainerRegistryGetRepositoriesNextHeaders { +/** Defines headers for ContainerRegistry_getTags operation. */ +export interface ContainerRegistryGetTagsHeaders { /** next paginated result */ link?: string; } -/** Defines headers for ContainerRegistryRepository_createManifest operation. */ -export interface ContainerRegistryRepositoryCreateManifestHeaders { - /** Identifies the docker upload uuid for the current request. */ - dockerContentDigest?: string; - /** The canonical location url of the uploaded manifest. */ - location?: string; - /** The length of the requested blob content. */ - contentLength?: number; -} - -/** Defines headers for ContainerRegistryRepository_getTags operation. */ -export interface ContainerRegistryRepositoryGetTagsHeaders { +/** Defines headers for ContainerRegistry_getManifests operation. */ +export interface ContainerRegistryGetManifestsHeaders { /** next paginated result */ link?: string; } -/** Defines headers for ContainerRegistryRepository_getManifests operation. */ -export interface ContainerRegistryRepositoryGetManifestsHeaders { +/** Defines headers for ContainerRegistry_getRepositoriesNext operation. */ +export interface ContainerRegistryGetRepositoriesNextHeaders { /** next paginated result */ link?: string; } -/** Defines headers for ContainerRegistryRepository_getTagsNext operation. */ -export interface ContainerRegistryRepositoryGetTagsNextHeaders { +/** Defines headers for ContainerRegistry_getTagsNext operation. */ +export interface ContainerRegistryGetTagsNextHeaders { /** next paginated result */ link?: string; } -/** Defines headers for ContainerRegistryRepository_getManifestsNext operation. */ -export interface ContainerRegistryRepositoryGetManifestsNextHeaders { +/** Defines headers for ContainerRegistry_getManifestsNext operation. */ +export interface ContainerRegistryGetManifestsNextHeaders { /** next paginated result */ link?: string; } @@ -571,60 +694,106 @@ export interface ContainerRegistryBlobCheckChunkExistsHeaders { contentRange?: string; } -/** Known values of {@link TagOrderBy} that the service accepts. */ -export const enum KnownTagOrderBy { - /** Order tags by LastUpdatedOn field, from most recently updated to least recently updated. */ - LastUpdatedOnDescending = "timedesc", - /** Order tags by LastUpdatedOn field, from least recently updated to most recently updated. */ - LastUpdatedOnAscending = "timeasc" +/** Known values of {@link ArtifactArchitecture} that the service accepts. */ +export const enum KnownArtifactArchitecture { + I386 = "386", + Amd64 = "amd64", + Arm = "arm", + Arm64 = "arm64", + Mips = "mips", + MipsLe = "mipsle", + Mips64 = "mips64", + Mips64Le = "mips64le", + Ppc64 = "ppc64", + Ppc64Le = "ppc64le", + RiscV64 = "riscv64", + S390X = "s390x", + Wasm = "wasm" } /** - * Defines values for TagOrderBy. \ - * {@link KnownTagOrderBy} can be used interchangeably with TagOrderBy, + * Defines values for ArtifactArchitecture. \ + * {@link KnownArtifactArchitecture} can be used interchangeably with ArtifactArchitecture, * this enum contains the known values that the service supports. * ### Know values supported by the service - * **timedesc**: Order tags by LastUpdatedOn field, from most recently updated to least recently updated. \ - * **timeasc**: Order tags by LastUpdatedOn field, from least recently updated to most recently updated. + * **386** \ + * **amd64** \ + * **arm** \ + * **arm64** \ + * **mips** \ + * **mipsle** \ + * **mips64** \ + * **mips64le** \ + * **ppc64** \ + * **ppc64le** \ + * **riscv64** \ + * **s390x** \ + * **wasm** */ -export type TagOrderBy = string; - -/** Known values of {@link RegistryArtifactOrderBy} that the service accepts. */ -export const enum KnownRegistryArtifactOrderBy { - /** Order registry artifacts by LastUpdatedOn field, from most recently updated to least recently updated. */ - LastUpdatedOnDescending = "timedesc", - /** Order registry artifacts by LastUpdatedOn field, from least recently updated to most recently updated. */ - LastUpdatedOnAscending = "timeasc" +export type ArtifactArchitecture = string; + +/** Known values of {@link ArtifactOperatingSystem} that the service accepts. */ +export const enum KnownArtifactOperatingSystem { + Aix = "aix", + Android = "android", + Darwin = "darwin", + Dragonfly = "dragonfly", + FreeBsd = "freebsd", + Illumos = "illumos", + IOs = "ios", + Js = "js", + Linux = "linux", + NetBsd = "netbsd", + OpenBsd = "openbsd", + Plan9 = "plan9", + Solaris = "solaris", + Windows = "windows" } /** - * Defines values for RegistryArtifactOrderBy. \ - * {@link KnownRegistryArtifactOrderBy} can be used interchangeably with RegistryArtifactOrderBy, + * Defines values for ArtifactOperatingSystem. \ + * {@link KnownArtifactOperatingSystem} can be used interchangeably with ArtifactOperatingSystem, * this enum contains the known values that the service supports. * ### Know values supported by the service - * **timedesc**: Order registry artifacts by LastUpdatedOn field, from most recently updated to least recently updated. \ - * **timeasc**: Order registry artifacts by LastUpdatedOn field, from least recently updated to most recently updated. + * **aix** \ + * **android** \ + * **darwin** \ + * **dragonfly** \ + * **freebsd** \ + * **illumos** \ + * **ios** \ + * **js** \ + * **linux** \ + * **netbsd** \ + * **openbsd** \ + * **plan9** \ + * **solaris** \ + * **windows** */ -export type RegistryArtifactOrderBy = string; +export type ArtifactOperatingSystem = string; +/** Defines values for TagOrderBy. */ +export type TagOrderBy = "none" | "timedesc" | "timeasc"; +/** Defines values for ManifestOrderBy. */ +export type ManifestOrderBy = "none" | "timedesc" | "timeasc"; /** Optional parameters. */ -export interface ContainerRegistryGetRepositoriesOptionalParams +export interface ContainerRegistryGetManifestOptionalParams extends coreClient.OperationOptions { - /** Query parameter for the last item in previous query. Result set will include values lexically after last. */ - last?: string; - /** query parameter for max number of items */ - n?: number; + /** Accept header string delimited by comma. For example, application/vnd.docker.distribution.manifest.v2+json */ + accept?: string; } -/** Contains response data for the getRepositories operation. */ -export type ContainerRegistryGetRepositoriesResponse = ContainerRegistryGetRepositoriesHeaders & - Repositories; +/** Contains response data for the getManifest operation. */ +export type ContainerRegistryGetManifestResponse = Manifest; -/** Contains response data for the deleteRepository operation. */ -export type ContainerRegistryDeleteRepositoryResponse = DeleteRepositoryResult; +/** Contains response data for the createManifest operation. */ +export type ContainerRegistryCreateManifestResponse = ContainerRegistryCreateManifestHeaders & { + /** The parsed response body. */ + body: any; +}; /** Optional parameters. */ -export interface ContainerRegistryGetRepositoriesNextOptionalParams +export interface ContainerRegistryGetRepositoriesOptionalParams extends coreClient.OperationOptions { /** Query parameter for the last item in previous query. Result set will include values lexically after last. */ last?: string; @@ -632,41 +801,28 @@ export interface ContainerRegistryGetRepositoriesNextOptionalParams n?: number; } -/** Contains response data for the getRepositoriesNext operation. */ -export type ContainerRegistryGetRepositoriesNextResponse = ContainerRegistryGetRepositoriesNextHeaders & +/** Contains response data for the getRepositories operation. */ +export type ContainerRegistryGetRepositoriesResponse = ContainerRegistryGetRepositoriesHeaders & Repositories; -/** Optional parameters. */ -export interface ContainerRegistryRepositoryGetManifestOptionalParams - extends coreClient.OperationOptions { - /** Accept header string delimited by comma. For example, application/vnd.docker.distribution.manifest.v2+json */ - accept?: string; -} - -/** Contains response data for the getManifest operation. */ -export type ContainerRegistryRepositoryGetManifestResponse = Manifest; - -/** Contains response data for the createManifest operation. */ -export type ContainerRegistryRepositoryCreateManifestResponse = ContainerRegistryRepositoryCreateManifestHeaders & { - /** The parsed response body. */ - body: any; -}; - /** Contains response data for the getProperties operation. */ -export type ContainerRegistryRepositoryGetPropertiesResponse = RepositoryProperties; +export type ContainerRegistryGetPropertiesResponse = RepositoryProperties; + +/** Contains response data for the deleteRepository operation. */ +export type ContainerRegistryDeleteRepositoryResponse = DeleteRepositoryResult; /** Optional parameters. */ -export interface ContainerRegistryRepositorySetPropertiesOptionalParams +export interface ContainerRegistrySetPropertiesOptionalParams extends coreClient.OperationOptions { /** Repository attribute value */ value?: ContentProperties; } /** Contains response data for the setProperties operation. */ -export type ContainerRegistryRepositorySetPropertiesResponse = RepositoryProperties; +export type ContainerRegistrySetPropertiesResponse = RepositoryProperties; /** Optional parameters. */ -export interface ContainerRegistryRepositoryGetTagsOptionalParams +export interface ContainerRegistryGetTagsOptionalParams extends coreClient.OperationOptions { /** Query parameter for the last item in previous query. Result set will include values lexically after last. */ last?: string; @@ -679,24 +835,24 @@ export interface ContainerRegistryRepositoryGetTagsOptionalParams } /** Contains response data for the getTags operation. */ -export type ContainerRegistryRepositoryGetTagsResponse = ContainerRegistryRepositoryGetTagsHeaders & +export type ContainerRegistryGetTagsResponse = ContainerRegistryGetTagsHeaders & TagList; /** Contains response data for the getTagProperties operation. */ -export type ContainerRegistryRepositoryGetTagPropertiesResponse = TagProperties; +export type ContainerRegistryGetTagPropertiesResponse = ArtifactTagProperties; /** Optional parameters. */ -export interface ContainerRegistryRepositoryUpdateTagAttributesOptionalParams +export interface ContainerRegistryUpdateTagAttributesOptionalParams extends coreClient.OperationOptions { /** Repository attribute value */ value?: ContentProperties; } /** Contains response data for the updateTagAttributes operation. */ -export type ContainerRegistryRepositoryUpdateTagAttributesResponse = TagProperties; +export type ContainerRegistryUpdateTagAttributesResponse = ArtifactTagProperties; /** Optional parameters. */ -export interface ContainerRegistryRepositoryGetManifestsOptionalParams +export interface ContainerRegistryGetManifestsOptionalParams extends coreClient.OperationOptions { /** Query parameter for the last item in previous query. Result set will include values lexically after last. */ last?: string; @@ -707,24 +863,37 @@ export interface ContainerRegistryRepositoryGetManifestsOptionalParams } /** Contains response data for the getManifests operation. */ -export type ContainerRegistryRepositoryGetManifestsResponse = ContainerRegistryRepositoryGetManifestsHeaders & +export type ContainerRegistryGetManifestsResponse = ContainerRegistryGetManifestsHeaders & AcrManifests; -/** Contains response data for the getRegistryArtifactProperties operation. */ -export type ContainerRegistryRepositoryGetRegistryArtifactPropertiesResponse = RegistryArtifactProperties; +/** Contains response data for the getManifestProperties operation. */ +export type ContainerRegistryGetManifestPropertiesResponse = ArtifactManifestProperties; /** Optional parameters. */ -export interface ContainerRegistryRepositoryUpdateManifestAttributesOptionalParams +export interface ContainerRegistryUpdateManifestPropertiesOptionalParams extends coreClient.OperationOptions { /** Repository attribute value */ value?: ContentProperties; } -/** Contains response data for the updateManifestAttributes operation. */ -export type ContainerRegistryRepositoryUpdateManifestAttributesResponse = RegistryArtifactProperties; +/** Contains response data for the updateManifestProperties operation. */ +export type ContainerRegistryUpdateManifestPropertiesResponse = ArtifactManifestProperties; + +/** Optional parameters. */ +export interface ContainerRegistryGetRepositoriesNextOptionalParams + extends coreClient.OperationOptions { + /** Query parameter for the last item in previous query. Result set will include values lexically after last. */ + last?: string; + /** query parameter for max number of items */ + n?: number; +} + +/** Contains response data for the getRepositoriesNext operation. */ +export type ContainerRegistryGetRepositoriesNextResponse = ContainerRegistryGetRepositoriesNextHeaders & + Repositories; /** Optional parameters. */ -export interface ContainerRegistryRepositoryGetTagsNextOptionalParams +export interface ContainerRegistryGetTagsNextOptionalParams extends coreClient.OperationOptions { /** Query parameter for the last item in previous query. Result set will include values lexically after last. */ last?: string; @@ -737,11 +906,11 @@ export interface ContainerRegistryRepositoryGetTagsNextOptionalParams } /** Contains response data for the getTagsNext operation. */ -export type ContainerRegistryRepositoryGetTagsNextResponse = ContainerRegistryRepositoryGetTagsNextHeaders & +export type ContainerRegistryGetTagsNextResponse = ContainerRegistryGetTagsNextHeaders & TagList; /** Optional parameters. */ -export interface ContainerRegistryRepositoryGetManifestsNextOptionalParams +export interface ContainerRegistryGetManifestsNextOptionalParams extends coreClient.OperationOptions { /** Query parameter for the last item in previous query. Result set will include values lexically after last. */ last?: string; @@ -752,7 +921,7 @@ export interface ContainerRegistryRepositoryGetManifestsNextOptionalParams } /** Contains response data for the getManifestsNext operation. */ -export type ContainerRegistryRepositoryGetManifestsNextResponse = ContainerRegistryRepositoryGetManifestsNextHeaders & +export type ContainerRegistryGetManifestsNextResponse = ContainerRegistryGetManifestsNextHeaders & AcrManifests; /** Contains response data for the getBlob operation. */ @@ -840,7 +1009,7 @@ export type ContainerRegistryBlobCheckChunkExistsResponse = ContainerRegistryBlo /** Optional parameters. */ export interface AuthenticationExchangeAadAccessTokenForAcrRefreshTokenOptionalParams extends coreClient.OperationOptions { - aadAccesstoken?: Paths108HwamOauth2ExchangePostRequestbodyContentApplicationXWwwFormUrlencodedSchema; + aadAccessToken?: Paths108HwamOauth2ExchangePostRequestbodyContentApplicationXWwwFormUrlencodedSchema; } /** Contains response data for the exchangeAadAccessTokenForAcrRefreshToken operation. */ diff --git a/sdk/containerregistry/container-registry/src/generated/models/mappers.ts b/sdk/containerregistry/container-registry/src/generated/models/mappers.ts index e206827757e5..26b9ecd5c3fa 100644 --- a/sdk/containerregistry/container-registry/src/generated/models/mappers.ts +++ b/sdk/containerregistry/container-registry/src/generated/models/mappers.ts @@ -105,6 +105,7 @@ export const RepositoryProperties: coreClient.CompositeMapper = { name: { serializedName: "imageName", required: true, + readOnly: true, type: { name: "String" } @@ -112,6 +113,7 @@ export const RepositoryProperties: coreClient.CompositeMapper = { createdOn: { serializedName: "createdTime", required: true, + readOnly: true, type: { name: "DateTime" } @@ -119,13 +121,15 @@ export const RepositoryProperties: coreClient.CompositeMapper = { lastUpdatedOn: { serializedName: "lastUpdateTime", required: true, + readOnly: true, type: { name: "DateTime" } }, - registryArtifactCount: { + manifestCount: { serializedName: "manifestCount", required: true, + readOnly: true, type: { name: "Number" } @@ -133,6 +137,7 @@ export const RepositoryProperties: coreClient.CompositeMapper = { tagCount: { serializedName: "tagCount", required: true, + readOnly: true, type: { name: "Number" } @@ -186,8 +191,9 @@ export const DeleteRepositoryResult: coreClient.CompositeMapper = { name: "Composite", className: "DeleteRepositoryResult", modelProperties: { - deletedRegistryArtifactDigests: { + deletedManifests: { serializedName: "manifestsDeleted", + readOnly: true, type: { name: "Sequence", element: { @@ -199,6 +205,7 @@ export const DeleteRepositoryResult: coreClient.CompositeMapper = { }, deletedTags: { serializedName: "tagsDeleted", + readOnly: true, type: { name: "Sequence", element: { @@ -255,6 +262,7 @@ export const TagAttributesBase: coreClient.CompositeMapper = { name: { serializedName: "name", required: true, + readOnly: true, type: { name: "String" } @@ -262,6 +270,7 @@ export const TagAttributesBase: coreClient.CompositeMapper = { digest: { serializedName: "digest", required: true, + readOnly: true, type: { name: "String" } @@ -269,6 +278,7 @@ export const TagAttributesBase: coreClient.CompositeMapper = { createdOn: { serializedName: "createdTime", required: true, + readOnly: true, type: { name: "DateTime" } @@ -276,6 +286,7 @@ export const TagAttributesBase: coreClient.CompositeMapper = { lastUpdatedOn: { serializedName: "lastUpdateTime", required: true, + readOnly: true, type: { name: "DateTime" } @@ -291,14 +302,15 @@ export const TagAttributesBase: coreClient.CompositeMapper = { } }; -export const TagProperties: coreClient.CompositeMapper = { +export const ArtifactTagProperties: coreClient.CompositeMapper = { type: { name: "Composite", - className: "TagProperties", + className: "ArtifactTagProperties", modelProperties: { repository: { serializedName: "imageName", required: true, + readOnly: true, type: { name: "String" } @@ -306,6 +318,7 @@ export const TagProperties: coreClient.CompositeMapper = { name: { serializedName: "tag.name", required: true, + readOnly: true, type: { name: "String" } @@ -313,6 +326,7 @@ export const TagProperties: coreClient.CompositeMapper = { digest: { serializedName: "tag.digest", required: true, + readOnly: true, type: { name: "String" } @@ -320,6 +334,7 @@ export const TagProperties: coreClient.CompositeMapper = { createdOn: { serializedName: "tag.createdTime", required: true, + readOnly: true, type: { name: "DateTime" } @@ -327,6 +342,7 @@ export const TagProperties: coreClient.CompositeMapper = { lastUpdatedOn: { serializedName: "tag.lastUpdateTime", required: true, + readOnly: true, type: { name: "DateTime" } @@ -383,42 +399,52 @@ export const ManifestAttributesBase: coreClient.CompositeMapper = { digest: { serializedName: "digest", required: true, + readOnly: true, type: { name: "String" } }, size: { serializedName: "imageSize", + readOnly: true, type: { name: "Number" } }, createdOn: { serializedName: "createdTime", + readOnly: true, type: { name: "DateTime" } }, lastUpdatedOn: { serializedName: "lastUpdateTime", + readOnly: true, type: { name: "DateTime" } }, - cpuArchitecture: { + architecture: { + defaultValue: "none", serializedName: "architecture", + readOnly: true, + nullable: true, type: { name: "String" } }, operatingSystem: { serializedName: "os", + readOnly: true, + nullable: true, type: { name: "String" } }, references: { serializedName: "references", + readOnly: true, type: { name: "Sequence", element: { @@ -431,6 +457,7 @@ export const ManifestAttributesBase: coreClient.CompositeMapper = { }, tags: { serializedName: "tags", + readOnly: true, type: { name: "Sequence", element: { @@ -459,13 +486,16 @@ export const ManifestAttributesManifestReferences: coreClient.CompositeMapper = digest: { serializedName: "digest", required: true, + readOnly: true, type: { name: "String" } }, - cpuArchitecture: { + architecture: { + defaultValue: "none", serializedName: "architecture", required: true, + readOnly: true, type: { name: "String" } @@ -473,6 +503,7 @@ export const ManifestAttributesManifestReferences: coreClient.CompositeMapper = operatingSystem: { serializedName: "os", required: true, + readOnly: true, type: { name: "String" } @@ -481,55 +512,66 @@ export const ManifestAttributesManifestReferences: coreClient.CompositeMapper = } }; -export const RegistryArtifactProperties: coreClient.CompositeMapper = { +export const ArtifactManifestProperties: coreClient.CompositeMapper = { type: { name: "Composite", - className: "RegistryArtifactProperties", + className: "ArtifactManifestProperties", modelProperties: { - repository: { + repositoryName: { serializedName: "imageName", + readOnly: true, type: { name: "String" } }, digest: { serializedName: "manifest.digest", + readOnly: true, type: { name: "String" } }, size: { serializedName: "manifest.imageSize", + readOnly: true, type: { name: "Number" } }, createdOn: { serializedName: "manifest.createdTime", + readOnly: true, type: { name: "DateTime" } }, lastUpdatedOn: { serializedName: "manifest.lastUpdateTime", + readOnly: true, type: { name: "DateTime" } }, - cpuArchitecture: { + architecture: { + defaultValue: "none", serializedName: "manifest.architecture", + readOnly: true, + nullable: true, type: { name: "String" } }, operatingSystem: { serializedName: "manifest.os", + readOnly: true, + nullable: true, type: { name: "String" } }, references: { serializedName: "manifest.references", + readOnly: true, type: { name: "Sequence", element: { @@ -542,6 +584,7 @@ export const RegistryArtifactProperties: coreClient.CompositeMapper = { }, tags: { serializedName: "manifest.tags", + readOnly: true, type: { name: "Sequence", element: { @@ -583,7 +626,7 @@ export const Paths108HwamOauth2ExchangePostRequestbodyContentApplicationXWwwForm name: "String" } }, - aadAccesstoken: { + aadAccessToken: { serializedName: "access_token", required: true, type: { @@ -1416,25 +1459,37 @@ export const V1Manifest: coreClient.CompositeMapper = { } }; -export const ContainerRegistryGetRepositoriesHeaders: coreClient.CompositeMapper = { +export const ContainerRegistryCreateManifestHeaders: coreClient.CompositeMapper = { type: { name: "Composite", - className: "ContainerRegistryGetRepositoriesHeaders", + className: "ContainerRegistryCreateManifestHeaders", modelProperties: { - link: { - serializedName: "link", + dockerContentDigest: { + serializedName: "docker-content-digest", + type: { + name: "String" + } + }, + location: { + serializedName: "location", type: { name: "String" } + }, + contentLength: { + serializedName: "content-length", + type: { + name: "Number" + } } } } }; -export const ContainerRegistryGetRepositoriesNextHeaders: coreClient.CompositeMapper = { +export const ContainerRegistryGetRepositoriesHeaders: coreClient.CompositeMapper = { type: { name: "Composite", - className: "ContainerRegistryGetRepositoriesNextHeaders", + className: "ContainerRegistryGetRepositoriesHeaders", modelProperties: { link: { serializedName: "link", @@ -1446,37 +1501,25 @@ export const ContainerRegistryGetRepositoriesNextHeaders: coreClient.CompositeMa } }; -export const ContainerRegistryRepositoryCreateManifestHeaders: coreClient.CompositeMapper = { +export const ContainerRegistryGetTagsHeaders: coreClient.CompositeMapper = { type: { name: "Composite", - className: "ContainerRegistryRepositoryCreateManifestHeaders", + className: "ContainerRegistryGetTagsHeaders", modelProperties: { - dockerContentDigest: { - serializedName: "docker-content-digest", - type: { - name: "String" - } - }, - location: { - serializedName: "location", + link: { + serializedName: "link", type: { name: "String" } - }, - contentLength: { - serializedName: "content-length", - type: { - name: "Number" - } } } } }; -export const ContainerRegistryRepositoryGetTagsHeaders: coreClient.CompositeMapper = { +export const ContainerRegistryGetManifestsHeaders: coreClient.CompositeMapper = { type: { name: "Composite", - className: "ContainerRegistryRepositoryGetTagsHeaders", + className: "ContainerRegistryGetManifestsHeaders", modelProperties: { link: { serializedName: "link", @@ -1488,10 +1531,10 @@ export const ContainerRegistryRepositoryGetTagsHeaders: coreClient.CompositeMapp } }; -export const ContainerRegistryRepositoryGetManifestsHeaders: coreClient.CompositeMapper = { +export const ContainerRegistryGetRepositoriesNextHeaders: coreClient.CompositeMapper = { type: { name: "Composite", - className: "ContainerRegistryRepositoryGetManifestsHeaders", + className: "ContainerRegistryGetRepositoriesNextHeaders", modelProperties: { link: { serializedName: "link", @@ -1503,10 +1546,10 @@ export const ContainerRegistryRepositoryGetManifestsHeaders: coreClient.Composit } }; -export const ContainerRegistryRepositoryGetTagsNextHeaders: coreClient.CompositeMapper = { +export const ContainerRegistryGetTagsNextHeaders: coreClient.CompositeMapper = { type: { name: "Composite", - className: "ContainerRegistryRepositoryGetTagsNextHeaders", + className: "ContainerRegistryGetTagsNextHeaders", modelProperties: { link: { serializedName: "link", @@ -1518,10 +1561,10 @@ export const ContainerRegistryRepositoryGetTagsNextHeaders: coreClient.Composite } }; -export const ContainerRegistryRepositoryGetManifestsNextHeaders: coreClient.CompositeMapper = { +export const ContainerRegistryGetManifestsNextHeaders: coreClient.CompositeMapper = { type: { name: "Composite", - className: "ContainerRegistryRepositoryGetManifestsNextHeaders", + className: "ContainerRegistryGetManifestsNextHeaders", modelProperties: { link: { serializedName: "link", diff --git a/sdk/containerregistry/container-registry/src/generated/models/parameters.ts b/sdk/containerregistry/container-registry/src/generated/models/parameters.ts index e40414c471a8..3b9281f27eb7 100644 --- a/sdk/containerregistry/container-registry/src/generated/models/parameters.ts +++ b/sdk/containerregistry/container-registry/src/generated/models/parameters.ts @@ -42,26 +42,6 @@ export const url: OperationURLParameter = { skipEncoding: true }; -export const last: OperationQueryParameter = { - parameterPath: ["options", "last"], - mapper: { - serializedName: "last", - type: { - name: "String" - } - } -}; - -export const n: OperationQueryParameter = { - parameterPath: ["options", "n"], - mapper: { - serializedName: "n", - type: { - name: "Number" - } - } -}; - export const name: OperationURLParameter = { parameterPath: "name", mapper: { @@ -73,18 +53,6 @@ export const name: OperationURLParameter = { } }; -export const nextLink: OperationURLParameter = { - parameterPath: "nextLink", - mapper: { - serializedName: "nextLink", - required: true, - type: { - name: "String" - } - }, - skipEncoding: true -}; - export const reference: OperationURLParameter = { parameterPath: "reference", mapper: { @@ -123,6 +91,26 @@ export const payload: OperationParameter = { mapper: ManifestMapper }; +export const last: OperationQueryParameter = { + parameterPath: ["options", "last"], + mapper: { + serializedName: "last", + type: { + name: "String" + } + } +}; + +export const n: OperationQueryParameter = { + parameterPath: ["options", "n"], + mapper: { + serializedName: "n", + type: { + name: "Number" + } + } +}; + export const contentType1: OperationParameter = { parameterPath: ["options", "contentType"], mapper: { @@ -171,6 +159,18 @@ export const digest1: OperationURLParameter = { } }; +export const nextLink: OperationURLParameter = { + parameterPath: "nextLink", + mapper: { + serializedName: "nextLink", + required: true, + type: { + name: "String" + } + }, + skipEncoding: true +}; + export const accept2: OperationParameter = { parameterPath: "accept", mapper: { @@ -296,8 +296,8 @@ export const contentType3: OperationParameter = { } }; -export const aadAccesstoken: OperationParameter = { - parameterPath: ["options", "aadAccesstoken"], +export const aadAccessToken: OperationParameter = { + parameterPath: ["options", "aadAccessToken"], mapper: Paths108HwamOauth2ExchangePostRequestbodyContentApplicationXWwwFormUrlencodedSchemaMapper }; diff --git a/sdk/containerregistry/container-registry/src/generated/operations/authentication.ts b/sdk/containerregistry/container-registry/src/generated/operations/authentication.ts index 1da49c5b6960..4adc5bd654e6 100644 --- a/sdk/containerregistry/container-registry/src/generated/operations/authentication.ts +++ b/sdk/containerregistry/container-registry/src/generated/operations/authentication.ts @@ -69,7 +69,7 @@ const exchangeAadAccessTokenForAcrRefreshTokenOperationSpec: coreClient.Operatio bodyMapper: Mappers.AcrErrors } }, - formDataParameters: [Parameters.aadAccesstoken], + formDataParameters: [Parameters.aadAccessToken], urlParameters: [Parameters.url], headerParameters: [Parameters.contentType3, Parameters.accept4], serializer diff --git a/sdk/containerregistry/container-registry/src/generated/operations/containerRegistry.ts b/sdk/containerregistry/container-registry/src/generated/operations/containerRegistry.ts index b100482f1696..4008fbcd5f37 100644 --- a/sdk/containerregistry/container-registry/src/generated/operations/containerRegistry.ts +++ b/sdk/containerregistry/container-registry/src/generated/operations/containerRegistry.ts @@ -11,11 +11,32 @@ import * as Mappers from "../models/mappers"; import * as Parameters from "../models/parameters"; import { GeneratedClientContext } from "../generatedClientContext"; import { + ContainerRegistryGetManifestOptionalParams, + ContainerRegistryGetManifestResponse, + Manifest, + ContainerRegistryCreateManifestResponse, ContainerRegistryGetRepositoriesOptionalParams, ContainerRegistryGetRepositoriesResponse, + ContainerRegistryGetPropertiesResponse, ContainerRegistryDeleteRepositoryResponse, + ContainerRegistrySetPropertiesOptionalParams, + ContainerRegistrySetPropertiesResponse, + ContainerRegistryGetTagsOptionalParams, + ContainerRegistryGetTagsResponse, + ContainerRegistryGetTagPropertiesResponse, + ContainerRegistryUpdateTagAttributesOptionalParams, + ContainerRegistryUpdateTagAttributesResponse, + ContainerRegistryGetManifestsOptionalParams, + ContainerRegistryGetManifestsResponse, + ContainerRegistryGetManifestPropertiesResponse, + ContainerRegistryUpdateManifestPropertiesOptionalParams, + ContainerRegistryUpdateManifestPropertiesResponse, ContainerRegistryGetRepositoriesNextOptionalParams, - ContainerRegistryGetRepositoriesNextResponse + ContainerRegistryGetRepositoriesNextResponse, + ContainerRegistryGetTagsNextOptionalParams, + ContainerRegistryGetTagsNextResponse, + ContainerRegistryGetManifestsNextOptionalParams, + ContainerRegistryGetManifestsNextResponse } from "../models"; /** Class representing a ContainerRegistry. */ @@ -41,6 +62,60 @@ export class ContainerRegistry { ); } + /** + * Get the manifest identified by `name` and `reference` where `reference` can be a tag or digest. + * @param name Name of the image (including the namespace) + * @param reference A tag or a digest, pointing to a specific image + * @param options The options parameters. + */ + getManifest( + name: string, + reference: string, + options?: ContainerRegistryGetManifestOptionalParams + ): Promise { + return this.client.sendOperationRequest( + { name, reference, options }, + getManifestOperationSpec + ); + } + + /** + * Put the manifest identified by `name` and `reference` where `reference` can be a tag or digest. + * @param name Name of the image (including the namespace) + * @param reference A tag or a digest, pointing to a specific image + * @param payload Manifest body, can take v1 or v2 values depending on accept header + * @param options The options parameters. + */ + createManifest( + name: string, + reference: string, + payload: Manifest, + options?: coreClient.OperationOptions + ): Promise { + return this.client.sendOperationRequest( + { name, reference, payload, options }, + createManifestOperationSpec + ); + } + + /** + * Delete the manifest identified by `name` and `reference`. Note that a manifest can _only_ be deleted + * by `digest`. + * @param name Name of the image (including the namespace) + * @param reference Digest of a BLOB + * @param options The options parameters. + */ + deleteManifest( + name: string, + reference: string, + options?: coreClient.OperationOptions + ): Promise { + return this.client.sendOperationRequest( + { name, reference, options }, + deleteManifestOperationSpec + ); + } + /** * List repositories * @param options The options parameters. @@ -54,6 +129,21 @@ export class ContainerRegistry { ); } + /** + * Get repository attributes + * @param name Name of the image (including the namespace) + * @param options The options parameters. + */ + getProperties( + name: string, + options?: coreClient.OperationOptions + ): Promise { + return this.client.sendOperationRequest( + { name, options }, + getPropertiesOperationSpec + ); + } + /** * Delete the repository identified by `name` * @param name Name of the image (including the namespace) @@ -69,6 +159,136 @@ export class ContainerRegistry { ); } + /** + * Update the attribute identified by `name` where `reference` is the name of the repository. + * @param name Name of the image (including the namespace) + * @param options The options parameters. + */ + setProperties( + name: string, + options?: ContainerRegistrySetPropertiesOptionalParams + ): Promise { + return this.client.sendOperationRequest( + { name, options }, + setPropertiesOperationSpec + ); + } + + /** + * List tags of a repository + * @param name Name of the image (including the namespace) + * @param options The options parameters. + */ + getTags( + name: string, + options?: ContainerRegistryGetTagsOptionalParams + ): Promise { + return this.client.sendOperationRequest( + { name, options }, + getTagsOperationSpec + ); + } + + /** + * Get tag attributes by tag + * @param name Name of the image (including the namespace) + * @param reference Tag name + * @param options The options parameters. + */ + getTagProperties( + name: string, + reference: string, + options?: coreClient.OperationOptions + ): Promise { + return this.client.sendOperationRequest( + { name, reference, options }, + getTagPropertiesOperationSpec + ); + } + + /** + * Update tag attributes + * @param name Name of the image (including the namespace) + * @param reference Tag name + * @param options The options parameters. + */ + updateTagAttributes( + name: string, + reference: string, + options?: ContainerRegistryUpdateTagAttributesOptionalParams + ): Promise { + return this.client.sendOperationRequest( + { name, reference, options }, + updateTagAttributesOperationSpec + ); + } + + /** + * Delete tag + * @param name Name of the image (including the namespace) + * @param reference Tag name + * @param options The options parameters. + */ + deleteTag( + name: string, + reference: string, + options?: coreClient.OperationOptions + ): Promise { + return this.client.sendOperationRequest( + { name, reference, options }, + deleteTagOperationSpec + ); + } + + /** + * List manifests of a repository + * @param name Name of the image (including the namespace) + * @param options The options parameters. + */ + getManifests( + name: string, + options?: ContainerRegistryGetManifestsOptionalParams + ): Promise { + return this.client.sendOperationRequest( + { name, options }, + getManifestsOperationSpec + ); + } + + /** + * Get manifest attributes + * @param name Name of the image (including the namespace) + * @param digest Digest of a BLOB + * @param options The options parameters. + */ + getManifestProperties( + name: string, + digest: string, + options?: coreClient.OperationOptions + ): Promise { + return this.client.sendOperationRequest( + { name, digest, options }, + getManifestPropertiesOperationSpec + ); + } + + /** + * Update properties of a manifest + * @param name Name of the image (including the namespace) + * @param digest Digest of a BLOB + * @param options The options parameters. + */ + updateManifestProperties( + name: string, + digest: string, + options?: ContainerRegistryUpdateManifestPropertiesOptionalParams + ): Promise { + return this.client.sendOperationRequest( + { name, digest, options }, + updateManifestPropertiesOperationSpec + ); + } + /** * GetRepositoriesNext * @param nextLink The nextLink from the previous successful call to the GetRepositories method. @@ -83,6 +303,40 @@ export class ContainerRegistry { getRepositoriesNextOperationSpec ); } + + /** + * GetTagsNext + * @param name Name of the image (including the namespace) + * @param nextLink The nextLink from the previous successful call to the GetTags method. + * @param options The options parameters. + */ + getTagsNext( + name: string, + nextLink: string, + options?: ContainerRegistryGetTagsNextOptionalParams + ): Promise { + return this.client.sendOperationRequest( + { name, nextLink, options }, + getTagsNextOperationSpec + ); + } + + /** + * GetManifestsNext + * @param name Name of the image (including the namespace) + * @param nextLink The nextLink from the previous successful call to the GetManifests method. + * @param options The options parameters. + */ + getManifestsNext( + name: string, + nextLink: string, + options?: ContainerRegistryGetManifestsNextOptionalParams + ): Promise { + return this.client.sendOperationRequest( + { name, nextLink, options }, + getManifestsNextOperationSpec + ); + } } // Operation Specifications const serializer = coreClient.createSerializer(Mappers, /* isXml */ false); @@ -100,6 +354,52 @@ const checkDockerV2SupportOperationSpec: coreClient.OperationSpec = { headerParameters: [Parameters.accept], serializer }; +const getManifestOperationSpec: coreClient.OperationSpec = { + path: "/v2/{name}/manifests/{reference}", + httpMethod: "GET", + responses: { + 200: { + bodyMapper: Mappers.Manifest + }, + default: { + bodyMapper: Mappers.AcrErrors + } + }, + urlParameters: [Parameters.url, Parameters.name, Parameters.reference], + headerParameters: [Parameters.accept, Parameters.accept1], + serializer +}; +const createManifestOperationSpec: coreClient.OperationSpec = { + path: "/v2/{name}/manifests/{reference}", + httpMethod: "PUT", + responses: { + 201: { + bodyMapper: { type: { name: "any" } }, + headersMapper: Mappers.ContainerRegistryCreateManifestHeaders + }, + default: { + bodyMapper: Mappers.AcrErrors + } + }, + requestBody: Parameters.payload, + urlParameters: [Parameters.url, Parameters.name, Parameters.reference], + headerParameters: [Parameters.accept, Parameters.contentType], + mediaType: "json", + serializer +}; +const deleteManifestOperationSpec: coreClient.OperationSpec = { + path: "/v2/{name}/manifests/{reference}", + httpMethod: "DELETE", + responses: { + 202: {}, + default: { + bodyMapper: Mappers.AcrErrors + } + }, + urlParameters: [Parameters.url, Parameters.name, Parameters.reference], + headerParameters: [Parameters.accept], + serializer +}; const getRepositoriesOperationSpec: coreClient.OperationSpec = { path: "/acr/v1/_catalog", httpMethod: "GET", @@ -117,6 +417,21 @@ const getRepositoriesOperationSpec: coreClient.OperationSpec = { headerParameters: [Parameters.accept], serializer }; +const getPropertiesOperationSpec: coreClient.OperationSpec = { + path: "/acr/v1/{name}", + httpMethod: "GET", + responses: { + 200: { + bodyMapper: Mappers.RepositoryProperties + }, + default: { + bodyMapper: Mappers.AcrErrors + } + }, + urlParameters: [Parameters.url, Parameters.name], + headerParameters: [Parameters.accept], + serializer +}; const deleteRepositoryOperationSpec: coreClient.OperationSpec = { path: "/acr/v1/{name}", httpMethod: "DELETE", @@ -132,6 +447,139 @@ const deleteRepositoryOperationSpec: coreClient.OperationSpec = { headerParameters: [Parameters.accept], serializer }; +const setPropertiesOperationSpec: coreClient.OperationSpec = { + path: "/acr/v1/{name}", + httpMethod: "PATCH", + responses: { + 200: { + bodyMapper: Mappers.RepositoryProperties + }, + default: { + bodyMapper: Mappers.AcrErrors + } + }, + requestBody: Parameters.value, + urlParameters: [Parameters.url, Parameters.name], + headerParameters: [Parameters.accept, Parameters.contentType1], + mediaType: "json", + serializer +}; +const getTagsOperationSpec: coreClient.OperationSpec = { + path: "/acr/v1/{name}/_tags", + httpMethod: "GET", + responses: { + 200: { + bodyMapper: Mappers.TagList, + headersMapper: Mappers.ContainerRegistryGetTagsHeaders + }, + default: { + bodyMapper: Mappers.AcrErrors + } + }, + queryParameters: [ + Parameters.last, + Parameters.n, + Parameters.orderby, + Parameters.digest + ], + urlParameters: [Parameters.url, Parameters.name], + headerParameters: [Parameters.accept], + serializer +}; +const getTagPropertiesOperationSpec: coreClient.OperationSpec = { + path: "/acr/v1/{name}/_tags/{reference}", + httpMethod: "GET", + responses: { + 200: { + bodyMapper: Mappers.ArtifactTagProperties + }, + default: { + bodyMapper: Mappers.AcrErrors + } + }, + urlParameters: [Parameters.url, Parameters.name, Parameters.reference], + headerParameters: [Parameters.accept], + serializer +}; +const updateTagAttributesOperationSpec: coreClient.OperationSpec = { + path: "/acr/v1/{name}/_tags/{reference}", + httpMethod: "PATCH", + responses: { + 200: { + bodyMapper: Mappers.ArtifactTagProperties + }, + default: { + bodyMapper: Mappers.AcrErrors + } + }, + requestBody: Parameters.value, + urlParameters: [Parameters.url, Parameters.name, Parameters.reference], + headerParameters: [Parameters.accept, Parameters.contentType1], + mediaType: "json", + serializer +}; +const deleteTagOperationSpec: coreClient.OperationSpec = { + path: "/acr/v1/{name}/_tags/{reference}", + httpMethod: "DELETE", + responses: { + 202: {}, + default: { + bodyMapper: Mappers.AcrErrors + } + }, + urlParameters: [Parameters.url, Parameters.name, Parameters.reference], + headerParameters: [Parameters.accept], + serializer +}; +const getManifestsOperationSpec: coreClient.OperationSpec = { + path: "/acr/v1/{name}/_manifests", + httpMethod: "GET", + responses: { + 200: { + bodyMapper: Mappers.AcrManifests, + headersMapper: Mappers.ContainerRegistryGetManifestsHeaders + }, + default: { + bodyMapper: Mappers.AcrErrors + } + }, + queryParameters: [Parameters.last, Parameters.n, Parameters.orderby], + urlParameters: [Parameters.url, Parameters.name], + headerParameters: [Parameters.accept], + serializer +}; +const getManifestPropertiesOperationSpec: coreClient.OperationSpec = { + path: "/acr/v1/{name}/_manifests/{digest}", + httpMethod: "GET", + responses: { + 200: { + bodyMapper: Mappers.ArtifactManifestProperties + }, + default: { + bodyMapper: Mappers.AcrErrors + } + }, + urlParameters: [Parameters.url, Parameters.name, Parameters.digest1], + headerParameters: [Parameters.accept], + serializer +}; +const updateManifestPropertiesOperationSpec: coreClient.OperationSpec = { + path: "/acr/v1/{name}/_manifests/{digest}", + httpMethod: "PATCH", + responses: { + 200: { + bodyMapper: Mappers.ArtifactManifestProperties + }, + default: { + bodyMapper: Mappers.AcrErrors + } + }, + requestBody: Parameters.value, + urlParameters: [Parameters.url, Parameters.name, Parameters.digest1], + headerParameters: [Parameters.accept, Parameters.contentType1], + mediaType: "json", + serializer +}; const getRepositoriesNextOperationSpec: coreClient.OperationSpec = { path: "{nextLink}", httpMethod: "GET", @@ -149,3 +597,42 @@ const getRepositoriesNextOperationSpec: coreClient.OperationSpec = { headerParameters: [Parameters.accept], serializer }; +const getTagsNextOperationSpec: coreClient.OperationSpec = { + path: "{nextLink}", + httpMethod: "GET", + responses: { + 200: { + bodyMapper: Mappers.TagList, + headersMapper: Mappers.ContainerRegistryGetTagsNextHeaders + }, + default: { + bodyMapper: Mappers.AcrErrors + } + }, + queryParameters: [ + Parameters.last, + Parameters.n, + Parameters.orderby, + Parameters.digest + ], + urlParameters: [Parameters.url, Parameters.name, Parameters.nextLink], + headerParameters: [Parameters.accept], + serializer +}; +const getManifestsNextOperationSpec: coreClient.OperationSpec = { + path: "{nextLink}", + httpMethod: "GET", + responses: { + 200: { + bodyMapper: Mappers.AcrManifests, + headersMapper: Mappers.ContainerRegistryGetManifestsNextHeaders + }, + default: { + bodyMapper: Mappers.AcrErrors + } + }, + queryParameters: [Parameters.last, Parameters.n, Parameters.orderby], + urlParameters: [Parameters.url, Parameters.name, Parameters.nextLink], + headerParameters: [Parameters.accept], + serializer +}; diff --git a/sdk/containerregistry/container-registry/src/generated/operations/containerRegistryRepository.ts b/sdk/containerregistry/container-registry/src/generated/operations/containerRegistryRepository.ts deleted file mode 100644 index 37ad53650a89..000000000000 --- a/sdk/containerregistry/container-registry/src/generated/operations/containerRegistryRepository.ts +++ /dev/null @@ -1,517 +0,0 @@ -/* - * Copyright (c) Microsoft Corporation. - * Licensed under the MIT License. - * - * Code generated by Microsoft (R) AutoRest Code Generator. - * Changes may cause incorrect behavior and will be lost if the code is regenerated. - */ - -import * as coreClient from "@azure/core-client"; -import * as Mappers from "../models/mappers"; -import * as Parameters from "../models/parameters"; -import { GeneratedClientContext } from "../generatedClientContext"; -import { - ContainerRegistryRepositoryGetManifestOptionalParams, - ContainerRegistryRepositoryGetManifestResponse, - Manifest, - ContainerRegistryRepositoryCreateManifestResponse, - ContainerRegistryRepositoryGetPropertiesResponse, - ContainerRegistryRepositorySetPropertiesOptionalParams, - ContainerRegistryRepositorySetPropertiesResponse, - ContainerRegistryRepositoryGetTagsOptionalParams, - ContainerRegistryRepositoryGetTagsResponse, - ContainerRegistryRepositoryGetTagPropertiesResponse, - ContainerRegistryRepositoryUpdateTagAttributesOptionalParams, - ContainerRegistryRepositoryUpdateTagAttributesResponse, - ContainerRegistryRepositoryGetManifestsOptionalParams, - ContainerRegistryRepositoryGetManifestsResponse, - ContainerRegistryRepositoryGetRegistryArtifactPropertiesResponse, - ContainerRegistryRepositoryUpdateManifestAttributesOptionalParams, - ContainerRegistryRepositoryUpdateManifestAttributesResponse, - ContainerRegistryRepositoryGetTagsNextOptionalParams, - ContainerRegistryRepositoryGetTagsNextResponse, - ContainerRegistryRepositoryGetManifestsNextOptionalParams, - ContainerRegistryRepositoryGetManifestsNextResponse -} from "../models"; - -/** Class representing a ContainerRegistryRepository. */ -export class ContainerRegistryRepository { - private readonly client: GeneratedClientContext; - - /** - * Initialize a new instance of the class ContainerRegistryRepository class. - * @param client Reference to the service client - */ - constructor(client: GeneratedClientContext) { - this.client = client; - } - - /** - * Get the manifest identified by `name` and `reference` where `reference` can be a tag or digest. - * @param name Name of the image (including the namespace) - * @param reference A tag or a digest, pointing to a specific image - * @param options The options parameters. - */ - getManifest( - name: string, - reference: string, - options?: ContainerRegistryRepositoryGetManifestOptionalParams - ): Promise { - return this.client.sendOperationRequest( - { name, reference, options }, - getManifestOperationSpec - ); - } - - /** - * Put the manifest identified by `name` and `reference` where `reference` can be a tag or digest. - * @param name Name of the image (including the namespace) - * @param reference A tag or a digest, pointing to a specific image - * @param payload Manifest body, can take v1 or v2 values depending on accept header - * @param options The options parameters. - */ - createManifest( - name: string, - reference: string, - payload: Manifest, - options?: coreClient.OperationOptions - ): Promise { - return this.client.sendOperationRequest( - { name, reference, payload, options }, - createManifestOperationSpec - ); - } - - /** - * Delete the manifest identified by `name` and `reference`. Note that a manifest can _only_ be deleted - * by `digest`. - * @param name Name of the image (including the namespace) - * @param reference Digest of a BLOB - * @param options The options parameters. - */ - deleteManifest( - name: string, - reference: string, - options?: coreClient.OperationOptions - ): Promise { - return this.client.sendOperationRequest( - { name, reference, options }, - deleteManifestOperationSpec - ); - } - - /** - * Get repository attributes - * @param name Name of the image (including the namespace) - * @param options The options parameters. - */ - getProperties( - name: string, - options?: coreClient.OperationOptions - ): Promise { - return this.client.sendOperationRequest( - { name, options }, - getPropertiesOperationSpec - ); - } - - /** - * Update the attribute identified by `name` where `reference` is the name of the repository. - * @param name Name of the image (including the namespace) - * @param options The options parameters. - */ - setProperties( - name: string, - options?: ContainerRegistryRepositorySetPropertiesOptionalParams - ): Promise { - return this.client.sendOperationRequest( - { name, options }, - setPropertiesOperationSpec - ); - } - - /** - * List tags of a repository - * @param name Name of the image (including the namespace) - * @param options The options parameters. - */ - getTags( - name: string, - options?: ContainerRegistryRepositoryGetTagsOptionalParams - ): Promise { - return this.client.sendOperationRequest( - { name, options }, - getTagsOperationSpec - ); - } - - /** - * Get tag attributes by tag - * @param name Name of the image (including the namespace) - * @param reference Tag name - * @param options The options parameters. - */ - getTagProperties( - name: string, - reference: string, - options?: coreClient.OperationOptions - ): Promise { - return this.client.sendOperationRequest( - { name, reference, options }, - getTagPropertiesOperationSpec - ); - } - - /** - * Update tag attributes - * @param name Name of the image (including the namespace) - * @param reference Tag name - * @param options The options parameters. - */ - updateTagAttributes( - name: string, - reference: string, - options?: ContainerRegistryRepositoryUpdateTagAttributesOptionalParams - ): Promise { - return this.client.sendOperationRequest( - { name, reference, options }, - updateTagAttributesOperationSpec - ); - } - - /** - * Delete tag - * @param name Name of the image (including the namespace) - * @param reference Tag name - * @param options The options parameters. - */ - deleteTag( - name: string, - reference: string, - options?: coreClient.OperationOptions - ): Promise { - return this.client.sendOperationRequest( - { name, reference, options }, - deleteTagOperationSpec - ); - } - - /** - * List manifests of a repository - * @param name Name of the image (including the namespace) - * @param options The options parameters. - */ - getManifests( - name: string, - options?: ContainerRegistryRepositoryGetManifestsOptionalParams - ): Promise { - return this.client.sendOperationRequest( - { name, options }, - getManifestsOperationSpec - ); - } - - /** - * Get manifest attributes - * @param name Name of the image (including the namespace) - * @param digest Digest of a BLOB - * @param options The options parameters. - */ - getRegistryArtifactProperties( - name: string, - digest: string, - options?: coreClient.OperationOptions - ): Promise { - return this.client.sendOperationRequest( - { name, digest, options }, - getRegistryArtifactPropertiesOperationSpec - ); - } - - /** - * Update attributes of a manifest - * @param name Name of the image (including the namespace) - * @param digest Digest of a BLOB - * @param options The options parameters. - */ - updateManifestAttributes( - name: string, - digest: string, - options?: ContainerRegistryRepositoryUpdateManifestAttributesOptionalParams - ): Promise { - return this.client.sendOperationRequest( - { name, digest, options }, - updateManifestAttributesOperationSpec - ); - } - - /** - * GetTagsNext - * @param name Name of the image (including the namespace) - * @param nextLink The nextLink from the previous successful call to the GetTags method. - * @param options The options parameters. - */ - getTagsNext( - name: string, - nextLink: string, - options?: ContainerRegistryRepositoryGetTagsNextOptionalParams - ): Promise { - return this.client.sendOperationRequest( - { name, nextLink, options }, - getTagsNextOperationSpec - ); - } - - /** - * GetManifestsNext - * @param name Name of the image (including the namespace) - * @param nextLink The nextLink from the previous successful call to the GetManifests method. - * @param options The options parameters. - */ - getManifestsNext( - name: string, - nextLink: string, - options?: ContainerRegistryRepositoryGetManifestsNextOptionalParams - ): Promise { - return this.client.sendOperationRequest( - { name, nextLink, options }, - getManifestsNextOperationSpec - ); - } -} -// Operation Specifications -const serializer = coreClient.createSerializer(Mappers, /* isXml */ false); - -const getManifestOperationSpec: coreClient.OperationSpec = { - path: "/v2/{name}/manifests/{reference}", - httpMethod: "GET", - responses: { - 200: { - bodyMapper: Mappers.Manifest - }, - default: { - bodyMapper: Mappers.AcrErrors - } - }, - urlParameters: [Parameters.url, Parameters.name, Parameters.reference], - headerParameters: [Parameters.accept, Parameters.accept1], - serializer -}; -const createManifestOperationSpec: coreClient.OperationSpec = { - path: "/v2/{name}/manifests/{reference}", - httpMethod: "PUT", - responses: { - 201: { - bodyMapper: { type: { name: "any" } }, - headersMapper: Mappers.ContainerRegistryRepositoryCreateManifestHeaders - }, - default: { - bodyMapper: Mappers.AcrErrors - } - }, - requestBody: Parameters.payload, - urlParameters: [Parameters.url, Parameters.name, Parameters.reference], - headerParameters: [Parameters.accept, Parameters.contentType], - mediaType: "json", - serializer -}; -const deleteManifestOperationSpec: coreClient.OperationSpec = { - path: "/v2/{name}/manifests/{reference}", - httpMethod: "DELETE", - responses: { - 202: {}, - default: { - bodyMapper: Mappers.AcrErrors - } - }, - urlParameters: [Parameters.url, Parameters.name, Parameters.reference], - headerParameters: [Parameters.accept], - serializer -}; -const getPropertiesOperationSpec: coreClient.OperationSpec = { - path: "/acr/v1/{name}", - httpMethod: "GET", - responses: { - 200: { - bodyMapper: Mappers.RepositoryProperties - }, - default: { - bodyMapper: Mappers.AcrErrors - } - }, - urlParameters: [Parameters.url, Parameters.name], - headerParameters: [Parameters.accept], - serializer -}; -const setPropertiesOperationSpec: coreClient.OperationSpec = { - path: "/acr/v1/{name}", - httpMethod: "PATCH", - responses: { - 200: { - bodyMapper: Mappers.RepositoryProperties - }, - default: { - bodyMapper: Mappers.AcrErrors - } - }, - requestBody: Parameters.value, - urlParameters: [Parameters.url, Parameters.name], - headerParameters: [Parameters.accept, Parameters.contentType1], - mediaType: "json", - serializer -}; -const getTagsOperationSpec: coreClient.OperationSpec = { - path: "/acr/v1/{name}/_tags", - httpMethod: "GET", - responses: { - 200: { - bodyMapper: Mappers.TagList, - headersMapper: Mappers.ContainerRegistryRepositoryGetTagsHeaders - }, - default: { - bodyMapper: Mappers.AcrErrors - } - }, - queryParameters: [ - Parameters.last, - Parameters.n, - Parameters.orderby, - Parameters.digest - ], - urlParameters: [Parameters.url, Parameters.name], - headerParameters: [Parameters.accept], - serializer -}; -const getTagPropertiesOperationSpec: coreClient.OperationSpec = { - path: "/acr/v1/{name}/_tags/{reference}", - httpMethod: "GET", - responses: { - 200: { - bodyMapper: Mappers.TagProperties - }, - default: { - bodyMapper: Mappers.AcrErrors - } - }, - urlParameters: [Parameters.url, Parameters.name, Parameters.reference], - headerParameters: [Parameters.accept], - serializer -}; -const updateTagAttributesOperationSpec: coreClient.OperationSpec = { - path: "/acr/v1/{name}/_tags/{reference}", - httpMethod: "PATCH", - responses: { - 200: { - bodyMapper: Mappers.TagProperties - }, - default: { - bodyMapper: Mappers.AcrErrors - } - }, - requestBody: Parameters.value, - urlParameters: [Parameters.url, Parameters.name, Parameters.reference], - headerParameters: [Parameters.accept, Parameters.contentType1], - mediaType: "json", - serializer -}; -const deleteTagOperationSpec: coreClient.OperationSpec = { - path: "/acr/v1/{name}/_tags/{reference}", - httpMethod: "DELETE", - responses: { - 202: {}, - default: { - bodyMapper: Mappers.AcrErrors - } - }, - urlParameters: [Parameters.url, Parameters.name, Parameters.reference], - headerParameters: [Parameters.accept], - serializer -}; -const getManifestsOperationSpec: coreClient.OperationSpec = { - path: "/acr/v1/{name}/_manifests", - httpMethod: "GET", - responses: { - 200: { - bodyMapper: Mappers.AcrManifests, - headersMapper: Mappers.ContainerRegistryRepositoryGetManifestsHeaders - }, - default: { - bodyMapper: Mappers.AcrErrors - } - }, - queryParameters: [Parameters.last, Parameters.n, Parameters.orderby], - urlParameters: [Parameters.url, Parameters.name], - headerParameters: [Parameters.accept], - serializer -}; -const getRegistryArtifactPropertiesOperationSpec: coreClient.OperationSpec = { - path: "/acr/v1/{name}/_manifests/{digest}", - httpMethod: "GET", - responses: { - 200: { - bodyMapper: Mappers.RegistryArtifactProperties - }, - default: { - bodyMapper: Mappers.AcrErrors - } - }, - urlParameters: [Parameters.url, Parameters.name, Parameters.digest1], - headerParameters: [Parameters.accept], - serializer -}; -const updateManifestAttributesOperationSpec: coreClient.OperationSpec = { - path: "/acr/v1/{name}/_manifests/{digest}", - httpMethod: "PATCH", - responses: { - 200: { - bodyMapper: Mappers.RegistryArtifactProperties - }, - default: { - bodyMapper: Mappers.AcrErrors - } - }, - requestBody: Parameters.value, - urlParameters: [Parameters.url, Parameters.name, Parameters.digest1], - headerParameters: [Parameters.accept, Parameters.contentType1], - mediaType: "json", - serializer -}; -const getTagsNextOperationSpec: coreClient.OperationSpec = { - path: "{nextLink}", - httpMethod: "GET", - responses: { - 200: { - bodyMapper: Mappers.TagList, - headersMapper: Mappers.ContainerRegistryRepositoryGetTagsNextHeaders - }, - default: { - bodyMapper: Mappers.AcrErrors - } - }, - queryParameters: [ - Parameters.last, - Parameters.n, - Parameters.orderby, - Parameters.digest - ], - urlParameters: [Parameters.url, Parameters.name, Parameters.nextLink], - headerParameters: [Parameters.accept], - serializer -}; -const getManifestsNextOperationSpec: coreClient.OperationSpec = { - path: "{nextLink}", - httpMethod: "GET", - responses: { - 200: { - bodyMapper: Mappers.AcrManifests, - headersMapper: Mappers.ContainerRegistryRepositoryGetManifestsNextHeaders - }, - default: { - bodyMapper: Mappers.AcrErrors - } - }, - queryParameters: [Parameters.last, Parameters.n, Parameters.orderby], - urlParameters: [Parameters.url, Parameters.name, Parameters.nextLink], - headerParameters: [Parameters.accept], - serializer -}; diff --git a/sdk/containerregistry/container-registry/src/generated/operations/index.ts b/sdk/containerregistry/container-registry/src/generated/operations/index.ts index 30f9150b6fb4..b6666ac1ae96 100644 --- a/sdk/containerregistry/container-registry/src/generated/operations/index.ts +++ b/sdk/containerregistry/container-registry/src/generated/operations/index.ts @@ -7,6 +7,5 @@ */ export * from "./containerRegistry"; -export * from "./containerRegistryRepository"; export * from "./containerRegistryBlob"; export * from "./authentication"; diff --git a/sdk/containerregistry/container-registry/src/index.ts b/sdk/containerregistry/container-registry/src/index.ts index 267f0c6c492b..34baddcf1d57 100644 --- a/sdk/containerregistry/container-registry/src/index.ts +++ b/sdk/containerregistry/container-registry/src/index.ts @@ -2,5 +2,21 @@ // Licensed under the MIT license. export * from "./containerRegistryClient"; -export * from "./containerRepositoryClient"; +export { + ContainerRepository, + DeleteRepositoryOptions, + GetRepositoryPropertiesOptions, + SetRepositoryPropertiesOptions, + ListManifestsOptions +} from "./containerRepository"; +export { + RegistryArtifact, + DeleteArtifactOptions, + DeleteTagOptions, + GetManifestPropertiesOptions, + GetTagPropertiesOptions, + SetManifestPropertiesOptions, + SetTagPropertiesOptions, + ListTagsOptions +} from "./registryArtifact"; export * from "./model"; diff --git a/sdk/containerregistry/container-registry/src/model.ts b/sdk/containerregistry/container-registry/src/model.ts index 0dfb5b561d59..2ecfea82e021 100644 --- a/sdk/containerregistry/container-registry/src/model.ts +++ b/sdk/containerregistry/container-registry/src/model.ts @@ -2,17 +2,12 @@ // Licensed under the MIT license. import { PipelineOptions } from "@azure/core-rest-pipeline"; -import { - ContentProperties, - DeleteRepositoryResult, - RepositoryProperties, - TagProperties -} from "./generated"; +import { ContentProperties, RepositoryProperties, ArtifactTagProperties } from "./generated"; /** * Re-export generated types that are used as public interfaces. */ -export { ContentProperties, DeleteRepositoryResult, RepositoryProperties, TagProperties }; +export { ContentProperties, RepositoryProperties, ArtifactTagProperties }; /** * Client options used to configure Container Registry Repository API requests. @@ -21,28 +16,92 @@ export interface ContainerRegistryClientOptions extends PipelineOptions { // Any custom options configured at the client level go here. } +/** + * Defines known {@link ArtifactArchitecture} that the service supports. + */ +export type KnownArtifactArchitecture = + | "386" + | "amd64" + | "arm" + | "arm64" + | "mips" + | "mipsle" + | "mips64" + | "mips64le" + | "ppc64" + | "ppc64le" + | "riscv64" + | "s390x" + | "wasm"; + +/** + * Defines known {@link ArtifactOperatingSystem} values that the service supports. + */ +export type KnownArtifactOperatingSystem = + | "aix" + | "android" + | "darwin" + | "dragonfly" + | "freebsd" + | "illumos" + | "ios" + | "js" + | "linux" + | "netbsd" + | "openbsd" + | "plan9" + | "solaris" + | "windows"; + /** Manifest attributes details */ -export interface RegistryArtifactProperties { - /** Image name */ - repository?: string; - /** Manifest */ - digest?: string; - /** Image size */ - size?: number; - /** Created time */ - createdOn?: Date; - /** Last update time */ - lastUpdatedOn?: Date; - /** CPU architecture */ - cpuArchitecture?: string; - /** Operating system */ - operatingSystem?: string; +export interface ArtifactManifestProperties { + /** + * Repository name + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly repositoryName?: string; + /** + * Manifest + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly digest?: string; + /** + * Image size + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly size?: number; + /** + * Created time + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly createdOn?: Date; + /** + * Last update time + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly lastUpdatedOn?: Date; + /** + * CPU architecture. See {@link KnownArtifactArchitecture} for values supported by the service. + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly architecture?: string; + /** + * Operating system. See {@link KnownArtifactOperatingSystem} for values supported by the service. + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly operatingSystem?: string; /** List of manifest attributes details */ - registryArtifacts?: RegistryArtifactProperties[]; - /** List of tags */ - tags?: string[]; - /** Writeable properties of the resource */ - writeableProperties?: ContentProperties; + manifests: ArtifactManifestProperties[]; + /** + * List of tags + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly tags: string[]; + /** + * Writeable properties of the resource + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly writeableProperties?: ContentProperties; } /** @@ -52,7 +111,7 @@ export interface RegistryArtifactProperties { * **timedesc**: Order tags by LastUpdatedOn field, from most recently updated to least recently updated. * **timeasc**: Order tags by LastUpdatedOn field, from least recently updated to most recently updated. */ -export type TagOrderBy = "timedesc" | "timeasc"; +export type TagOrderBy = "timeDesc" | "timeAsc"; /** * Defines values for RegistryArtifactOrderBy. @@ -61,4 +120,18 @@ export type TagOrderBy = "timedesc" | "timeasc"; * **timedesc**: Order registry artifacts by LastUpdatedOn field, from most recently updated to least recently updated. * **timeasc**: Order registry artifacts by LastUpdatedOn field, from least recently updated to most recently updated. */ -export type RegistryArtifactOrderBy = "timedesc" | "timeasc"; +export type ManifestOrderBy = "timeDesc" | "timeAsc"; + +/** Deleted repository */ +export interface DeleteRepositoryResult { + /** + * SHA of the deleted image + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly deletedManifests: string[]; + /** + * Tag of the deleted image + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly deletedTags: string[]; +} diff --git a/sdk/containerregistry/container-registry/src/registryArtifact.ts b/sdk/containerregistry/container-registry/src/registryArtifact.ts new file mode 100644 index 000000000000..9b2f9d202fae --- /dev/null +++ b/sdk/containerregistry/container-registry/src/registryArtifact.ts @@ -0,0 +1,455 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +/// + +import { OperationOptions } from "@azure/core-client"; +import { SpanStatusCode } from "@azure/core-tracing"; +import "@azure/core-paging"; +import { PageSettings, PagedAsyncIterableIterator } from "@azure/core-paging"; + +import { + ArtifactTagProperties, + ArtifactManifestProperties, + ContentProperties, + TagOrderBy +} from "./model"; +import { URL } from "./url"; +import { createSpan } from "./tracing"; +import { GeneratedClient } from "./generated"; +import { extractNextLink, isDigest } from "./utils"; +import { toServiceTagOrderBy } from "./transformations"; + +/** + * Options for the `delete` method of `RegistryArtifact`. + */ +export interface DeleteArtifactOptions extends OperationOptions {} +/** + * Options for the `deleteTag` method of `RegistryArtifact`. + */ +export interface DeleteTagOptions extends OperationOptions {} +/** + * Options for the `getManifestProperties` method of `RegistryArtifact`. + */ +export interface GetManifestPropertiesOptions extends OperationOptions {} +/** + * Options for the `getTagProperties` method of `RegistryArtifact`. + */ +export interface GetTagPropertiesOptions extends OperationOptions {} + +/** + * Options for the `setTagProperties` method of `RegistryArtifact`. + */ +export type SetTagPropertiesOptions = ContentProperties & OperationOptions; + +/** + * Options for the `setManifestProperties` method of `RegistryArtifact`. + */ +export type SetManifestPropertiesOptions = ContentProperties & OperationOptions; + +/** + * Options for the `listTags` method of `RegistryArtifact`. + */ +export interface ListTagsOptions extends OperationOptions { + /** orderby query parameter */ + orderBy?: TagOrderBy; +} + +/** + * The helper used to interact with the Container Registry service. + */ +export interface RegistryArtifact { + /** + * The Azure Container Registry endpoint. + */ + readonly registryUrl: string; + /** + * Repository name. + */ + readonly repositoryName: string; + /** + * Registry name. + */ + readonly tagOrDigest: string; + + /** + * fully qualified name of the artifact. + */ + readonly fullyQualifiedName: string; + /** + * Deletes this artifact. + * @param options - + */ + delete(options?: DeleteArtifactOptions): Promise; + /** + * Deletes a tag. + * @param tag - the name of the tag to be deleted. + * @param options - + */ + deleteTag(tag: string, options?: DeleteTagOptions): Promise; + /** + * Retrieves properties of this registry artifact. + * @param options - + */ + getManifestProperties( + options?: GetManifestPropertiesOptions + ): Promise; + /** + * Updates manifest artifact attributes. + * @param options - + */ + setManifestProperties( + options?: SetManifestPropertiesOptions + ): Promise; + /** + * Retrieves properties of a tag. + * @param tag - the tag to retrieve properties. + * @param options - + */ + getTagProperties(tag: string, options?: GetTagPropertiesOptions): Promise; + /** + * Updates tag properties. + * @param tag - name of the tag + * @param options - + */ + setTagProperties(tag: string, options: SetTagPropertiesOptions): Promise; + /** + * Iterates tags. + * + * Example usage: + * ```ts + * const client = new ContainerRegistryClient(url, credentials); + * const repository = client.getRepository(repositoryName); + * const artifact = repository.getArtifact(digest) + * for await (const tag of artifact.listTags()) { + * console.log("tag: ", tag); + * } + * ``` + * @param options - + */ + listTags(options?: ListTagsOptions): PagedAsyncIterableIterator; +} + +/** + * The client class used to interact with the Container Registry service. + * @internal + */ +export class RegistryArtifactImpl { + private client: GeneratedClient; + /** + * The Azure Container Registry endpoint. + */ + public readonly registryUrl: string; + /** + * Repository name. + */ + public readonly repositoryName: string; + /** + * Registry name. + */ + public readonly tagOrDigest: string; + + public readonly fullyQualifiedName: string; + + /** + * Creates an instance of a RegistryArtifact. + * @param registryUrl - the URL to the Container Registry endpoint + * @param repositoryName - the name of the repository + * @param tagOrDigest - the tag or digest of this artifact + * @param client - the generated client that interacts with service + */ + constructor( + registryUrl: string, + repositoryName: string, + tagOrDigest: string, + client: GeneratedClient + ) { + this.registryUrl = registryUrl; + this.repositoryName = repositoryName; + this.tagOrDigest = tagOrDigest; + const parsedUrl = new URL(registryUrl); + this.fullyQualifiedName = `${parsedUrl.hostname}/${repositoryName}${ + isDigest(tagOrDigest) ? "@" : ":" + }${tagOrDigest}`; + + this.client = client; + } + + /** + * Deletes this artifact. + * @param options - + */ + public async delete(options: DeleteArtifactOptions = {}): Promise { + const { span, updatedOptions } = createSpan("RegistryArtifact-delete", options); + + try { + await this.client.containerRegistry.deleteManifest( + this.repositoryName, + this.tagOrDigest, + updatedOptions + ); + } catch (e) { + span.setStatus({ code: SpanStatusCode.ERROR, message: e.message }); + throw e; + } finally { + span.end(); + } + } + + /** + * Deletes a tag. + * @param tag - the name of the tag to be deleted. + * @param options - + */ + public async deleteTag(tag: string, options: DeleteTagOptions = {}): Promise { + const { span, updatedOptions } = createSpan("RegistryArtifact-deleteTag", options); + + try { + await this.client.containerRegistry.deleteTag(this.repositoryName, tag, updatedOptions); + } catch (e) { + span.setStatus({ code: SpanStatusCode.ERROR, message: e.message }); + throw e; + } finally { + span.end(); + } + } + + /** + * Retrieves properties of this registry artifact. + * @param options - + */ + public async getManifestProperties( + options: GetManifestPropertiesOptions = {} + ): Promise { + const { span, updatedOptions } = createSpan("RegistryArtifact-getManifestProperties", options); + + let digest: string = this.tagOrDigest; + if (!isDigest(this.tagOrDigest)) { + digest = (await this.getTagProperties(this.tagOrDigest)).digest; + } + + try { + const result = await this.client.containerRegistry.getManifestProperties( + this.repositoryName, + digest, + updatedOptions + ); + return { + repositoryName: result.repositoryName, + digest: result.digest, + size: result.size, + createdOn: result.createdOn, + lastUpdatedOn: result.lastUpdatedOn, + architecture: result.architecture ?? undefined, + operatingSystem: result.operatingSystem ?? undefined, + manifests: + result.references?.map((r) => { + return { ...r, manifests: [], tags: [] }; + }) ?? [], + tags: result.tags ?? [], + writeableProperties: result.writeableProperties + }; + } catch (e) { + span.setStatus({ code: SpanStatusCode.ERROR, message: e.message }); + throw e; + } finally { + span.end(); + } + } + + /** + * Updates manifest artifact attributes. + * @param options - + */ + public async setManifestProperties( + options: SetManifestPropertiesOptions = {} + ): Promise { + const { span, updatedOptions } = createSpan("RegistryArtifact-setManifestProperties", { + ...options, + value: { + canDelete: options.canDelete, + canWrite: options.canWrite, + canList: options.canList, + canRead: options.canRead + } + }); + + let digest: string = this.tagOrDigest; + if (!isDigest(this.tagOrDigest)) { + digest = (await this.getTagProperties(this.tagOrDigest)).digest; + } + try { + const t = await this.client.containerRegistry.updateManifestProperties( + this.repositoryName, + digest, + updatedOptions + ); + return { + repositoryName: this.repositoryName, + digest: t.digest, + size: t.size, + createdOn: t.createdOn, + lastUpdatedOn: t.lastUpdatedOn, + architecture: t.architecture ?? undefined, + operatingSystem: t.operatingSystem ?? undefined, + manifests: + t.references?.map((r) => { + return { ...r, manifests: [], tags: [] }; + }) ?? [], + tags: t.tags ?? [], + writeableProperties: t.writeableProperties + ? { + canDelete: t.writeableProperties.canDelete, + canList: t.writeableProperties.canList, + canRead: t.writeableProperties.canRead, + canWrite: t.writeableProperties.canWrite + } + : undefined + }; + } catch (e) { + span.setStatus({ code: SpanStatusCode.ERROR, message: e.message }); + throw e; + } finally { + span.end(); + } + } + + /** + * Retrieves properties of a tag. + * @param tag - the tag to retrieve properties. + * @param options - + */ + public async getTagProperties( + tag: string, + options: GetTagPropertiesOptions = {} + ): Promise { + const { span, updatedOptions } = createSpan("RegistryArtifact-getTagProperties", options); + try { + const result = await this.client.containerRegistry.getTagProperties( + this.repositoryName, + tag, + updatedOptions + ); + return result; + } catch (e) { + span.setStatus({ code: SpanStatusCode.ERROR, message: e.message }); + throw e; + } finally { + span.end(); + } + } + + /** + * Updates tag properties. + * @param tag - name of the tag + * @param options - + */ + public async setTagProperties( + tag: string, + options: SetTagPropertiesOptions + ): Promise { + const { span, updatedOptions } = createSpan("RegistryArtifact-setTagProperties", { + ...options, + value: { + canDelete: options.canDelete, + canWrite: options.canWrite, + canList: options.canList, + canRead: options.canRead + } + }); + + try { + return await this.client.containerRegistry.updateTagAttributes( + this.repositoryName, + tag, + updatedOptions + ); + } catch (e) { + span.setStatus({ code: SpanStatusCode.ERROR, message: e.message }); + throw e; + } finally { + span.end(); + } + } + + /** + * Iterates tags. + * + * Example usage: + * ```ts + * const client = new ContainerRegistryClient(url, credentials); + * const repository = client.getRepository(repositoryName); + * const artifact = repository.getArtifact(digest) + * for await (const tag of artifact.listTags()) { + * console.log("tag: ", tag); + * } + * ``` + * @param options - + */ + public listTags( + options: ListTagsOptions = {} + ): PagedAsyncIterableIterator { + const iter = this.listTagsItems(options); + + return { + next() { + return iter.next(); + }, + [Symbol.asyncIterator]() { + return this; + }, + byPage: (settings: PageSettings = {}) => this.listTagsPage(settings, options) + }; + } + + private async *listTagsItems( + options: ListTagsOptions = {} + ): AsyncIterableIterator { + for await (const page of this.listTagsPage({}, options)) { + yield* page; + } + } + + private async *listTagsPage( + continuationState: PageSettings, + options: ListTagsOptions = {} + ): AsyncIterableIterator { + const orderby = toServiceTagOrderBy(options.orderBy); + if (!continuationState.continuationToken) { + const optionsComplete = { + ...options, + n: continuationState.maxPageSize, + orderby + }; + const currentPage = await this.client.containerRegistry.getTags( + this.repositoryName, + optionsComplete + ); + continuationState.continuationToken = extractNextLink(currentPage.link); + if (currentPage.tagAttributeBases) { + yield currentPage.tagAttributeBases.map((t) => { + return { + ...t, + repository: currentPage.repository + }; + }); + } + } + while (continuationState.continuationToken) { + const currentPage = await this.client.containerRegistry.getTagsNext( + this.repositoryName, + continuationState.continuationToken, + options + ); + continuationState.continuationToken = extractNextLink(currentPage.link); + if (currentPage.tagAttributeBases) { + yield currentPage.tagAttributeBases.map((t) => { + return { + ...t, + repository: currentPage.repository + }; + }); + } + } + } +} diff --git a/sdk/containerregistry/container-registry/src/transformations.ts b/sdk/containerregistry/container-registry/src/transformations.ts new file mode 100644 index 000000000000..2e73f0cf2f95 --- /dev/null +++ b/sdk/containerregistry/container-registry/src/transformations.ts @@ -0,0 +1,40 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { + ManifestAttributesBase, + TagOrderBy as ServiceTagOrderBy, + ManifestOrderBy as ServiceManifestOrderBy +} from "./generated/models"; +import { ArtifactManifestProperties, TagOrderBy, ManifestOrderBy } from "./model"; + +export function toArtifactManifestProperties( + from: ManifestAttributesBase, + repositoryName: string +): ArtifactManifestProperties { + return { + repositoryName: repositoryName, + digest: from.digest, + size: from.size, + createdOn: from.createdOn, + lastUpdatedOn: from.lastUpdatedOn, + architecture: from.architecture ?? undefined, + operatingSystem: from.operatingSystem ?? undefined, + manifests: + from.references?.map((r) => { + return { ...r, manifests: [], tags: [] }; + }) ?? [], + tags: from.tags ?? [], + writeableProperties: from.writeableProperties + }; +} + +export function toServiceTagOrderBy(orderBy?: TagOrderBy): ServiceTagOrderBy | undefined { + return orderBy === "timeAsc" ? "timeasc" : orderBy === "timeDesc" ? "timedesc" : undefined; +} + +export function toServiceManifestOrderBy( + orderBy?: ManifestOrderBy +): ServiceManifestOrderBy | undefined { + return orderBy === "timeAsc" ? "timeasc" : orderBy === "timeDesc" ? "timedesc" : undefined; +} diff --git a/sdk/containerregistry/container-registry/src/utils.ts b/sdk/containerregistry/container-registry/src/utils.ts index d2cb15c65750..65afe1972a78 100644 --- a/sdk/containerregistry/container-registry/src/utils.ts +++ b/sdk/containerregistry/container-registry/src/utils.ts @@ -11,3 +11,11 @@ export function extractNextLink(value: string | undefined): string | undefined { // and we only want the part inside of <...> return value?.substr(1, value.indexOf(">") - 1); } + +/** + * Checks whether a string is a digest + * @internal + */ +export function isDigest(tagOrDigest: string): boolean { + return tagOrDigest.includes(":"); +} diff --git a/sdk/containerregistry/container-registry/swagger/README.md b/sdk/containerregistry/container-registry/swagger/README.md index d6a326f5ed7e..9fed32c5a492 100644 --- a/sdk/containerregistry/container-registry/swagger/README.md +++ b/sdk/containerregistry/container-registry/swagger/README.md @@ -13,7 +13,7 @@ generate-metadata: false license-header: MICROSOFT_MIT_NO_VERSION output-folder: ../ source-code-folder-path: ./src/generated -input-file: ./containerregistry.json +input-file: c:/github/jeremymeng/rest-api-specs/specification/containerregistry/data-plane/Azure.ContainerRegistry/preview/2019-08-15-preview/containerregistry.json add-credentials: false override-client-name: GeneratedClient disable-async-iterators: true diff --git a/sdk/containerregistry/container-registry/test/public/containerRegistryClient.spec.ts b/sdk/containerregistry/container-registry/test/public/containerRegistryClient.spec.ts index 7e72ccb5a9ec..b2e31a393d69 100644 --- a/sdk/containerregistry/container-registry/test/public/containerRegistryClient.spec.ts +++ b/sdk/containerregistry/container-registry/test/public/containerRegistryClient.spec.ts @@ -15,7 +15,7 @@ if (isNode) { dotenv.config(); } -describe("ContainerRegistryClient functional tests", function() { +describe("ContainerRegistryClient tests", function() { // Declare the client and recorder instances. We will set them using the // beforeEach hook. let client: ContainerRegistryClient; @@ -42,7 +42,7 @@ describe("ContainerRegistryClient functional tests", function() { }); it("should list repositories", async () => { - const iter = client.listRepositories(); + const iter = client.listRepositoryNames(); const first = await iter.next(); assert.ok(first.value, "Expecting a valid repository"); }); @@ -51,7 +51,7 @@ describe("ContainerRegistryClient functional tests", function() { const response = await client.deleteRepository(repositoryName); assert.ok(response); await delay(5 * 1000); - const iter = client.listRepositories(); + const iter = client.listRepositoryNames(); for await (const repository of iter) { if (repository === repositoryName) { assert.fail(`Unexpected: '${repositoryName}' repository should have been deleted`); diff --git a/sdk/containerregistry/container-registry/test/public/containerRepositoryClient.spec.ts b/sdk/containerregistry/container-registry/test/public/repositoryAndArtifact.spec.ts similarity index 66% rename from sdk/containerregistry/container-registry/test/public/containerRepositoryClient.spec.ts rename to sdk/containerregistry/container-registry/test/public/repositoryAndArtifact.spec.ts index 2d5f5673ba97..9645d40f677e 100644 --- a/sdk/containerregistry/container-registry/test/public/containerRepositoryClient.spec.ts +++ b/sdk/containerregistry/container-registry/test/public/repositoryAndArtifact.spec.ts @@ -4,21 +4,21 @@ import { assert } from "chai"; import { Context } from "mocha"; import * as dotenv from "dotenv"; -import { ContainerRegistryClient, ContainerRepositoryClient } from "../../src"; +import { ContainerRegistryClient, ContainerRepository } from "../../src"; import { delay, record, Recorder } from "@azure/test-utils-recorder"; import { RestError } from "@azure/core-rest-pipeline"; import { isNode } from "@azure/core-util"; -import { createRegistryClient, createRepositoryClient, recorderEnvSetup } from "./utils"; +import { createRegistryClient, recorderEnvSetup } from "./utils"; if (isNode) { dotenv.config(); } -describe("ContainerRepositoryClient functional tests", function() { +describe("Repository and artifact tests", function() { // Declare the client and recorder instances. We will set them using the // beforeEach hook. let registryClient: ContainerRegistryClient; - let repositoryClient: ContainerRepositoryClient; + let repository: ContainerRepository; let recorder: Recorder; const repositoryName = "library/hello-world"; // NOTE: use of "function" and not ES6 arrow-style functions with the @@ -31,7 +31,7 @@ describe("ContainerRepositoryClient functional tests", function() { recorder = record(this, recorderEnvSetup); registryClient = createRegistryClient(); - repositoryClient = createRepositoryClient(repositoryName); + repository = registryClient.getRepository(repositoryName); }); // After each test, we need to stop the recording. @@ -39,30 +39,15 @@ describe("ContainerRepositoryClient functional tests", function() { await recorder.stop(); }); - it("should list tags", async () => { - const client = registryClient.getRepositoryClient(repositoryName); - const iter = client.listTags(); - const first = await iter.next(); - assert.ok(first.value, "Expecting a valid tag"); - }); - - it("should list tags by pages", async () => { - const iterator = repositoryClient.listTags().byPage({ maxPageSize: 1 }); - let result = await iterator.next(); - assert.equal(result.value.length, 1, "Expecting one tag in first page"); - result = await iterator.next(); - assert.equal(result.value.length, 1, "Expecting one tag in second page"); - }); - - it("should list registry artifacts", async () => { - const iter = repositoryClient.listRegistryArtifacts(); + it("should list registry manifests", async () => { + const iter = repository.listManifests(); const first = await iter.next(); - assert.ok(first.value, "Expecting a valid artifact"); + assert.ok(first.value, "Expecting a valid manifest"); }); let artifactDigest: string; - it("should list registry artifacts by pages", async () => { - const iterator = repositoryClient.listRegistryArtifacts().byPage({ maxPageSize: 1 }); + it("should list registry manifests by pages", async () => { + const iterator = repository.listManifests().byPage({ maxPageSize: 1 }); let result = await iterator.next(); assert.equal(result.value.length, 1, "Expecting one artifact in first page"); if (!result.done) { @@ -73,41 +58,17 @@ describe("ContainerRepositoryClient functional tests", function() { assert.equal(result.value.length, 1, "Expecting one artifact in second page"); }); - it("should retrive tag properties", async () => { - const properties = await repositoryClient.getTagProperties("test1"); - assert.equal(properties.name, "test1"); - }); - - it("should retrive registry artifact properties for a tag", async () => { - const properties = await repositoryClient.getRegistryArtifactProperties("test1"); - assert.ok(properties.createdOn, "Expecting valid createdOn property for the artifact"); - assert.ok(properties.registryArtifacts?.length, "Expecting valid registry artifacts"); - assert.ok(properties.registryArtifacts![0].cpuArchitecture, "Expecting valid cpuArchitecture"); - }); - - it("should retrive registry artifact properties for a digest", async () => { - const properties = await repositoryClient.getRegistryArtifactProperties(artifactDigest); - assert.ok(properties.createdOn, "Expecting valid createdOn property for the artifact"); - }); - - it("deletes a given tag", async () => { - await repositoryClient.deleteTag("test-delete"); - await delay(5 * 1000); - try { - await repositoryClient.getTagProperties("test-delete"); - assert.fail("Expecting an error but didn't get one."); - } catch (err) { - assert.isTrue((err as RestError).message.includes("TAG_UNKNOWN")); - } - }); - - it("sets tag properties", async () => { - const tag = "test1"; - const tagProperties = await repositoryClient.getTagProperties(tag); - const original = tagProperties.writeableProperties!; + it("sets manifest properties", async () => { + const artifact = repository.getArtifact(artifactDigest); + const artifactProperties = await artifact.getManifestProperties(); + assert.ok( + artifactProperties.writeableProperties, + "Expect valid artifactProperties.writeableProperties" + ); + const original = artifactProperties.writeableProperties!; try { - const updated = await repositoryClient.setTagProperties(tag, { + const updated = await artifact.setManifestProperties({ canDelete: false, canList: false, canRead: false, @@ -121,22 +82,15 @@ describe("ContainerRepositoryClient functional tests", function() { canWrite: false }); } finally { - await repositoryClient.setTagProperties(tag, original); + await artifact.setManifestProperties(original); } }); - it("sets manifest properties", async () => { - const tagProperties = await repositoryClient.getTagProperties("test1"); - const digest = tagProperties.digest!; - const artifactProperties = await repositoryClient.getRegistryArtifactProperties(digest); - assert.ok( - artifactProperties.writeableProperties, - "Expect valid artifactProperties.writeableProperties" - ); - const original = artifactProperties.writeableProperties!; - + it("sets repository properties", async () => { + const repositoryProperties = await repository.getProperties(); + const original = repositoryProperties.writeableProperties!; try { - const updated = await repositoryClient.setManifestProperties(digest, { + const updated = await repository.setProperties({ canDelete: false, canList: false, canRead: false, @@ -150,15 +104,54 @@ describe("ContainerRepositoryClient functional tests", function() { canWrite: false }); } finally { - await repositoryClient.setManifestProperties(digest, original); + await repository.setProperties(original); } }); - it("sets repository properties", async () => { - const repositoryProperties = await repositoryClient.getProperties(); - const original = repositoryProperties.writeableProperties!; + it("should list tags", async () => { + const artifact = repository.getArtifact(artifactDigest); + const iter = artifact.listTags(); + const first = await iter.next(); + assert.ok(first.value, "Expecting a valid tag"); + }); + + it("should list tags by pages", async () => { + const artifact = repository.getArtifact(artifactDigest); + const iterator = artifact.listTags().byPage({ maxPageSize: 1 }); + let result = await iterator.next(); + assert.equal(result.value.length, 1, "Expecting one tag in first page"); + result = await iterator.next(); + assert.equal(result.value.length, 1, "Expecting one tag in second page"); + }); + + it("should retrive tag properties", async () => { + const artifact = repository.getArtifact(artifactDigest); + const properties = await artifact.getTagProperties("test1"); + assert.equal(properties.name, "test1"); + }); + + it("should retrive registry artifact properties for a tag", async () => { + const artifact = repository.getArtifact("test1"); + const properties = await artifact.getManifestProperties(); + assert.ok(properties.createdOn, "Expecting valid createdOn property for the artifact"); + assert.ok(properties.manifests?.length, "Expecting valid registry artifacts"); + assert.ok(properties.manifests![0].architecture, "Expecting valid architecture"); + }); + + it("should retrive registry artifact properties for a digest", async () => { + const artifact = repository.getArtifact(artifactDigest); + const properties = await artifact.getManifestProperties(); + assert.ok(properties.createdOn, "Expecting valid createdOn property for the artifact"); + }); + + it("sets tag properties", async () => { + const tag = "test1"; + const artifact = repository.getArtifact(tag); + const tagProperties = await artifact.getTagProperties(tag); + const original = tagProperties.writeableProperties!; + try { - const updated = await repositoryClient.setProperties({ + const updated = await artifact.setTagProperties(tag, { canDelete: false, canList: false, canRead: false, @@ -172,7 +165,19 @@ describe("ContainerRepositoryClient functional tests", function() { canWrite: false }); } finally { - await repositoryClient.setProperties(original); + await artifact.setTagProperties(tag, original); + } + }); + + it("deletes a given tag", async () => { + const artifact = repository.getArtifact(artifactDigest); + await artifact.deleteTag("test-delete"); + await delay(5 * 1000); + try { + await artifact.getTagProperties("test-delete"); + assert.fail("Expecting an error but didn't get one."); + } catch (err) { + assert.isTrue((err as RestError).message.includes("TAG_UNKNOWN")); } }); }); diff --git a/sdk/containerregistry/container-registry/test/public/utils.ts b/sdk/containerregistry/container-registry/test/public/utils.ts index f0d8fb0b0f7f..ff6b58e10ae1 100644 --- a/sdk/containerregistry/container-registry/test/public/utils.ts +++ b/sdk/containerregistry/container-registry/test/public/utils.ts @@ -3,7 +3,7 @@ import { ClientSecretCredential } from "@azure/identity"; import { env, RecorderEnvironmentSetup } from "@azure/test-utils-recorder"; -import { ContainerRegistryClient, ContainerRepositoryClient } from "../../src"; +import { ContainerRegistryClient } from "../../src"; // When the recorder observes the values of these environment variables in any // recorded HTTP request or response, it will replace them with the values they @@ -60,22 +60,3 @@ export function createRegistryClient(): ContainerRegistryClient { return new ContainerRegistryClient(endpoint, credential); } - -export function createRepositoryClient(repository: string): ContainerRepositoryClient { - // Retrieve the endpoint from the environment variable - // we saved to the .env file earlier - const endpoint = env.CONTAINER_REGISTRY_ENDPOINT; - - // We use ClientSecretCredential instead of DefaultAzureCredential in order - // to ensure that the requests made to the AAD server are always the same. If - // we used DefaultAzureCredential, they might be different on some machines - // than on others, depending on which credentials are available (such as - // Managed Identity or developer credentials). - const credential = new ClientSecretCredential( - env.AZURE_TENANT_ID, - env.AZURE_CLIENT_ID, - env.AZURE_CLIENT_SECRET - ); - - return new ContainerRepositoryClient(endpoint, repository, credential); -}