From 3edf794f50e7478b1299afd156eb7901c6e0c040 Mon Sep 17 00:00:00 2001 From: Fan Shang Xiang Date: Fri, 26 Jul 2024 15:00:08 +0800 Subject: [PATCH] migrate credential provider to track2 client --- cmd/acr-credential-provider/main.go | 2 +- go.mod | 1 + go.sum | 2 + pkg/credentialprovider/azure_credentials.go | 100 ++- .../azure_credentials_test.go | 64 +- .../azcontainerregistry/CHANGELOG.md | 39 + .../azcontainerregistry/LICENSE.txt | 21 + .../containers/azcontainerregistry/README.md | 98 ++ .../azcontainerregistry/TROUBLESHOOTING.md | 177 ++++ .../azcontainerregistry/assets.json | 6 + .../authentication_client.go | 158 ++++ .../authentication_custom_client.go | 37 + .../authentication_policy.go | 249 +++++ .../azcontainerregistry/autorest.md | 486 ++++++++++ .../azcontainerregistry/blob_client.go | 664 ++++++++++++++ .../azcontainerregistry/blob_custom_client.go | 109 +++ .../containers/azcontainerregistry/build.go | 10 + .../sdk/containers/azcontainerregistry/ci.yml | 36 + .../containers/azcontainerregistry/client.go | 850 ++++++++++++++++++ .../azcontainerregistry/cloud_config.go | 30 + .../azcontainerregistry/constants.go | 198 ++++ .../azcontainerregistry/custom_client.go | 67 ++ .../azcontainerregistry/custom_constants.go | 13 + .../azcontainerregistry/digest_helper.go | 163 ++++ .../containers/azcontainerregistry/models.go | 215 +++++ .../azcontainerregistry/models_serde.go | 472 ++++++++++ .../containers/azcontainerregistry/options.go | 182 ++++ .../azcontainerregistry/response_types.go | 230 +++++ .../azcontainerregistry/test-resources.bicep | 18 + .../azcontainerregistry/time_rfc3339.go | 86 ++ vendor/modules.txt | 3 + 31 files changed, 4731 insertions(+), 55 deletions(-) create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/CHANGELOG.md create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/LICENSE.txt create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/README.md create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/TROUBLESHOOTING.md create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/assets.json create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/authentication_client.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/authentication_custom_client.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/authentication_policy.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/autorest.md create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/blob_client.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/blob_custom_client.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/build.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/ci.yml create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/client.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/cloud_config.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/constants.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/custom_client.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/custom_constants.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/digest_helper.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/models.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/models_serde.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/options.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/response_types.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/test-resources.bicep create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/time_rfc3339.go diff --git a/cmd/acr-credential-provider/main.go b/cmd/acr-credential-provider/main.go index 56faf431a7..93a78925bc 100644 --- a/cmd/acr-credential-provider/main.go +++ b/cmd/acr-credential-provider/main.go @@ -44,7 +44,7 @@ func main() { os.Exit(1) } - acrProvider, err := credentialprovider.NewAcrProvider(args[0]) + acrProvider, err := credentialprovider.NewAcrProviderFromConfig(args[0]) if err != nil { klog.Errorf("Failed to initialize ACR provider: %v", err) os.Exit(1) diff --git a/go.mod b/go.mod index b7e754509c..c8cd9773c5 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/Azure/azure-sdk-for-go v68.0.0+incompatible github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0 github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 + github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry v0.2.1 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.7.0 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerregistry/armcontainerregistry v1.2.0 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v4 v4.3.0 diff --git a/go.sum b/go.sum index a7958ca38d..3868ecd403 100644 --- a/go.sum +++ b/go.sum @@ -9,6 +9,8 @@ github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0 h1:nyQWyZvwGTvunIMxi1Y9uXkc github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0/go.mod h1:l38EPgmsp71HHLq9j7De57JcKOWPyhrsW1Awm1JS6K0= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 h1:tfLQ34V6F7tVSwoTf/4lH5sE0o6eCJuNDTmH09nDpbc= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg= +github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry v0.2.1 h1:Rj6ScDn/5amy1qlQwodwbh+eqXjlopD0LpS6TuN8qcU= +github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry v0.2.1/go.mod h1:QRmL+qp2wYVnAlyVlik0w/vBo3OXf6SP0/WY2IZmYVs= github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY= github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2 v2.2.0 h1:Hp+EScFOu9HeCbeW8WU2yQPJd4gGwhMgKxWe+G6jNzw= diff --git a/pkg/credentialprovider/azure_credentials.go b/pkg/credentialprovider/azure_credentials.go index 08d010f759..2b929b9ab7 100644 --- a/pkg/credentialprovider/azure_credentials.go +++ b/pkg/credentialprovider/azure_credentials.go @@ -18,18 +18,23 @@ package credentialprovider import ( "context" + "encoding/json" "errors" "fmt" - "io" "os" "regexp" "strings" "time" + "sigs.k8s.io/cloud-provider-azure/pkg/azclient" + "sigs.k8s.io/cloud-provider-azure/pkg/azclient/armauth" + "sigs.k8s.io/cloud-provider-azure/pkg/azclient/configloader" providerconfig "sigs.k8s.io/cloud-provider-azure/pkg/provider/config" - "github.com/Azure/go-autorest/autorest/adal" - "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azidentity" + "github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/klog/v2" v1 "k8s.io/kubelet/pkg/apis/credentialprovider/v1" @@ -55,45 +60,73 @@ type CredentialProvider interface { // acrProvider implements the credential provider interface for Azure Container Registry. type acrProvider struct { - config *providerconfig.AzureAuthConfig - environment *azure.Environment - servicePrincipalToken *adal.ServicePrincipalToken + config *providerconfig.AzureAuthConfig + environment *azclient.Environment + credential azcore.TokenCredential +} + +func NewAcrProvider(config *providerconfig.AzureAuthConfig, environment *azclient.Environment, credential azcore.TokenCredential) CredentialProvider { + return &acrProvider{ + config: config, + credential: credential, + environment: environment, + } } // NewAcrProvider creates a new instance of the ACR provider. -func NewAcrProvider(configFile string) (CredentialProvider, error) { +func NewAcrProviderFromConfig(configFile string) (CredentialProvider, error) { if len(configFile) == 0 { return nil, errors.New("no azure credential file is provided") } - - f, err := os.Open(configFile) + config, err := configloader.Load[providerconfig.AzureAuthConfig](context.Background(), nil, &configloader.FileLoaderConfig{FilePath: configFile}) if err != nil { - return nil, fmt.Errorf("failed to load config from file %s: %w", configFile, err) + return nil, fmt.Errorf("failed to load config: %w", err) } - defer f.Close() - - return newAcrProviderFromConfigReader(f) -} -func newAcrProviderFromConfigReader(configReader io.Reader) (*acrProvider, error) { - config, env, err := providerconfig.ParseAzureAuthConfig(configReader) - if err != nil { - return nil, fmt.Errorf("failed to load config: %w", err) + var envConfig azclient.Environment + envFilePath, ok := os.LookupEnv(azclient.EnvironmentFilepathName) + if ok { + content, err := os.ReadFile(envFilePath) + if err != nil { + return nil, err + } + if err = json.Unmarshal(content, &envConfig); err != nil { + return nil, err + } } - servicePrincipalToken, err := providerconfig.GetServicePrincipalToken(config, env, env.ServiceManagementEndpoint) + var managedIdentityCredential azcore.TokenCredential + + clientOption, err := azclient.GetAzCoreClientOption(&config.ARMClientConfig) if err != nil { - return nil, fmt.Errorf("failed to create service principal token: %w", err) + return nil, err + } + if config.UseManagedIdentityExtension { + credOptions := &azidentity.ManagedIdentityCredentialOptions{ + ClientOptions: *clientOption, + } + if len(config.UserAssignedIdentityID) > 0 { + if strings.Contains(strings.ToUpper(config.UserAssignedIdentityID), "/SUBSCRIPTIONS/") { + credOptions.ID = azidentity.ResourceID(config.UserAssignedIdentityID) + } else { + credOptions.ID = azidentity.ClientID(config.UserAssignedIdentityID) + } + } + managedIdentityCredential, err = azidentity.NewManagedIdentityCredential(credOptions) + if err != nil { + return nil, err + } + managedIdentityCredential = armauth.NewExpireEarlyTokenWrapper(managedIdentityCredential) } return &acrProvider{ - config: config, - environment: env, - servicePrincipalToken: servicePrincipalToken, + config: config, + credential: managedIdentityCredential, + environment: &envConfig, }, nil } -func (a *acrProvider) GetCredentials(_ context.Context, image string, _ []string) (*v1.CredentialProviderResponse, error) { +func (a *acrProvider) GetCredentials(ctx context.Context, image string, _ []string) (*v1.CredentialProviderResponse, error) { loginServer := a.parseACRLoginServerFromImage(image) if loginServer == "" { klog.V(2).Infof("image(%s) is not from ACR, return empty authentication", image) @@ -117,7 +150,7 @@ func (a *acrProvider) GetCredentials(_ context.Context, image string, _ []string } if a.config.UseManagedIdentityExtension { - username, password, err := a.getFromACR(loginServer) + username, password, err := a.getFromACR(ctx, loginServer) if err != nil { klog.Errorf("error getting credentials from ACR for %s: %s", loginServer, err) return nil, err @@ -163,13 +196,20 @@ func (a *acrProvider) GetCredentials(_ context.Context, image string, _ []string } // getFromACR gets credentials from ACR. -func (a *acrProvider) getFromACR(loginServer string) (string, string, error) { - // Run EnsureFresh to make sure the token is valid and does not expire - if err := a.servicePrincipalToken.EnsureFresh(); err != nil { +func (a *acrProvider) getFromACR(ctx context.Context, loginServer string) (string, string, error) { + config, err := azclient.GetAzureCloudConfig(&a.config.ARMClientConfig) + if err != nil { + return "", "", err + } + var armAccessToken azcore.AccessToken + if armAccessToken, err = a.credential.GetToken(ctx, policy.TokenRequestOptions{ + Scopes: []string{ + strings.TrimRight(config.Services[azcontainerregistry.ServiceName].Audience, "/") + "/.default", + }, + }); err != nil { klog.Errorf("Failed to ensure fresh service principal token: %v", err) return "", "", err } - armAccessToken := a.servicePrincipalToken.OAuthToken() klog.V(4).Infof("discovering auth redirects for: %s", loginServer) directive, err := receiveChallengeFromLoginServer(loginServer, "https") @@ -180,7 +220,7 @@ func (a *acrProvider) getFromACR(loginServer string) (string, string, error) { klog.V(4).Infof("exchanging an acr refresh_token") registryRefreshToken, err := performTokenExchange( - loginServer, directive, a.config.TenantID, armAccessToken) + loginServer, directive, a.config.TenantID, armAccessToken.Token) if err != nil { klog.Errorf("failed to perform token exchange: %s", err) return "", "", err diff --git a/pkg/credentialprovider/azure_credentials_test.go b/pkg/credentialprovider/azure_credentials_test.go index 7a705bc681..5097e5ff39 100644 --- a/pkg/credentialprovider/azure_credentials_test.go +++ b/pkg/credentialprovider/azure_credentials_test.go @@ -17,15 +17,16 @@ limitations under the License. package credentialprovider import ( - "bytes" "context" "net/http" "net/http/httptest" "os" "testing" - "github.com/Azure/go-autorest/autorest/azure" "github.com/stretchr/testify/assert" + + "sigs.k8s.io/cloud-provider-azure/pkg/azclient" + "sigs.k8s.io/cloud-provider-azure/pkg/provider/config" ) const ( @@ -36,11 +37,6 @@ const ( ) func TestGetCredentials(t *testing.T) { - configStr := ` - { - "aadClientId": "foo", - "aadClientSecret": "bar" - }` result := []string{ "*.azurecr.io", "*.azurecr.cn", @@ -48,10 +44,12 @@ func TestGetCredentials(t *testing.T) { "*.azurecr.us", } - provider, err := newAcrProviderFromConfigReader(bytes.NewBufferString(configStr)) - if err != nil { - t.Fatalf("Unexpected error when creating new acr provider: %v", err) - } + provider := NewAcrProvider(&config.AzureAuthConfig{ + AzureAuthConfig: azclient.AzureAuthConfig{ + AADClientID: "foo", + AADClientSecret: "bar", + }, + }, nil, nil) credResponse, err := provider.GetCredentials(context.TODO(), "foo.azurecr.io/nginx:v1", nil) if err != nil { @@ -75,7 +73,6 @@ func TestGetCredentials(t *testing.T) { } } } - func TestGetCredentialsConfig(t *testing.T) { // msiEndpointEnv and msiSecretEnv are required because autorest/adal requires IMDS endpoint to be available. server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -128,15 +125,35 @@ func TestGetCredentialsConfig(t *testing.T) { } for i, test := range testCases { - provider, err := newAcrProviderFromConfigReader(bytes.NewBufferString(test.configStr)) + configFile, err := os.CreateTemp(".", "config.json") + if err != nil { + t.Fatalf("Unexpected error when creating temp file: %v", err) + } + _, err = configFile.WriteString(test.configStr) + if err != nil { + t.Fatalf("Unexpected error when writing to temp file: %v", err) + } + err = configFile.Close() + if err != nil { + t.Fatalf("Unexpected error when closing temp file: %v", err) + } + provider, err := NewAcrProviderFromConfig(configFile.Name()) if err != nil && !test.expectError { t.Fatalf("Unexpected error when creating new acr provider: %v", err) } if err != nil && test.expectError { + err = os.Remove(configFile.Name()) + if err != nil { + t.Fatalf("Unexpected error when writing to temp file: %v", err) + } continue } + err = os.Remove(configFile.Name()) + if err != nil { + t.Fatalf("Unexpected error when writing to temp file: %v", err) + } - credResponse, err := provider.GetCredentials(context.TODO(), test.image, nil) + credResponse, err := provider.GetCredentials(context.Background(), test.image, nil) if err != nil { t.Fatalf("Unexpected error when fetching acr credentials: %v", err) } @@ -147,18 +164,17 @@ func TestGetCredentialsConfig(t *testing.T) { } func TestParseACRLoginServerFromImage(t *testing.T) { - configStr := ` - { - "aadClientId": "foo", - "aadClientSecret": "bar" - }` - provider, err := newAcrProviderFromConfigReader(bytes.NewBufferString(configStr)) - if err != nil { - t.Fatalf("Unexpected error when creating new acr provider: %v", err) - } + providerInterface := NewAcrProvider(&config.AzureAuthConfig{ + AzureAuthConfig: azclient.AzureAuthConfig{ + AADClientID: "foo", + AADClientSecret: "bar", + }, + }, nil, nil) + + provider := providerInterface.(*acrProvider) - provider.environment = &azure.Environment{ + provider.environment = &azclient.Environment{ ContainerRegistryDNSSuffix: ".azurecr.my.cloud", } tests := []struct { diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/CHANGELOG.md b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/CHANGELOG.md new file mode 100644 index 0000000000..94ed06404c --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/CHANGELOG.md @@ -0,0 +1,39 @@ +# Release History + +## 0.2.1 (2024-01-24) + +### Features Added +* Add `ConfigMediaType` and `MediaType` properties to `ManifestAttributes` +* Enabled spans for distributed tracing + +### Other Changes +* Refine some logics and comments +* Updated to latest version of azcore + +## 0.2.0 (2023-06-06) + +### Features Added +* Add `DigestValidationReader` to help to do digest validation when read manifest or blob + +### Breaking Changes +* Remove `MarshalJSON` for some of the types that are not used in the request. + +### Bugs Fixed +* Add state restore for hash calculator when upload fails +* Do not re-calculate digest when retry + +### Other Changes +* Change default audience to https://containerregistry.azure.net +* Refine examples of image upload and download + +## 0.1.1 (2023-03-07) + +### Bugs Fixed +* Fix possible failure when request retry + +### Other Changes +* Rewrite auth policy to promote efficiency of auth process + +## 0.1.0 (2023-02-07) + +* This is the initial release of the `azcontainerregistry` library diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/LICENSE.txt b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/LICENSE.txt new file mode 100644 index 0000000000..d1ca00f20a --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/LICENSE.txt @@ -0,0 +1,21 @@ + MIT License + + Copyright (c) Microsoft Corporation. All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE \ No newline at end of file diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/README.md b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/README.md new file mode 100644 index 0000000000..d46926ea83 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/README.md @@ -0,0 +1,98 @@ +# Azure Container Registry client module for Go + +Azure Container Registry allows you to store and manage container images and artifacts in a private registry for all types of container deployments. + +Use the client library for Azure Container Registry to: + +- List images or artifacts in a registry +- Obtain metadata for images and artifacts, repositories and tags +- Set read/write/delete properties on registry items +- Delete images and artifacts, repositories and tags +- Upload and download images + +[Source code](https://github.com/Azure/azure-sdk-for-go/tree/main/sdk/containers/azcontainerregistry) | [Package (pkg.go.dev)](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry) | [REST API documentation](https://docs.microsoft.com/rest/api/containerregistry/) | [Product documentation](https://docs.microsoft.com/azure/container-registry/) + +## Getting started + +### Install packages + +Install `azcontainerregistry` and `azidentity` with `go get`: +```Bash +go get github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry +go get github.com/Azure/azure-sdk-for-go/sdk/azidentity +``` +[azidentity](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity) is used for Azure Active Directory authentication as demonstrated below. + +### Prerequisites + +- An [Azure subscription](https://azure.microsoft.com/free/) +- A supported Go version (the Azure SDK supports the two most recent Go releases) +- A [Container Registry service instance](https://docs.microsoft.com/azure/container-registry/container-registry-intro) + +To create a new Container Registry, you can use the [Azure Portal](https://docs.microsoft.com/azure/container-registry/container-registry-get-started-portal), +[Azure PowerShell](https://docs.microsoft.com/azure/container-registry/container-registry-get-started-powershell), or the [Azure CLI](https://docs.microsoft.com/azure/container-registry/container-registry-get-started-azure-cli). +Here's an example using the Azure CLI: + +```Powershell +az acr create --name MyContainerRegistry --resource-group MyResourceGroup --location westus --sku Basic +``` +### Authentication + +This document demonstrates using [azidentity.NewDefaultAzureCredential](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#NewDefaultAzureCredential) to authenticate. +This credential type works in both local development and production environments. +We recommend using a [managed identity](https://docs.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview) in production. + +[Client](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry#Client) and [BlobClient](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry#BlobClient) accepts any [azidentity][https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity] credential. +See the [azidentity](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity) documentation for more information about other credential types. + +#### Create a client + +Constructing the client requires your Container Registry's endpoint URL, which you can get from the Azure CLI (`loginServer` value returned by `az acr list`) or the Azure Portal (`Login server` value on registry overview page). + +```go +import ( + "github.com/Azure/azure-sdk-for-go/sdk/azidentity" + "github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry" + "log" +) + +func main() { + cred, err := azidentity.NewDefaultAzureCredential(nil) + if err != nil { + log.Fatalf("failed to obtain a credential: %v", err) + } + + client, err := azcontainerregistry.NewClient("", cred, nil) + if err != nil { + log.Fatalf("failed to create client: %v", err) + } +} +``` + +## Key concepts + +A **registry** stores Docker images and [OCI Artifacts](https://opencontainers.org/). +An image or artifact consists of a **manifest** and **layers**. +An image's manifest describes the layers that make up the image, and is uniquely identified by its **digest**. +An image can also be "tagged" to give it a human-readable alias. +An image or artifact can have zero or more **tags** associated with it, and each tag uniquely identifies the image. +A collection of images that share the same name but have different tags, is referred to as a **repository**. + +For more information please see [Container Registry Concepts](https://docs.microsoft.com/azure/container-registry/container-registry-concepts). + +## Examples + +Get started with our [examples](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry#pkg-examples). + +## Troubleshooting + +For information about troubleshooting, refer to the [troubleshooting guide](https://github.com/Azure/azure-sdk-for-go/blob/main/sdk/containers/azcontainerregistry/TROUBLESHOOTING.md). + +## Contributing + +This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com. + +When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA. + +This project has adopted the [Microsoft Open Source Code of Conduct][https://opensource.microsoft.com/codeofconduct/]. For more information, see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact opencode@microsoft.com with any additional questions or comments. + diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/TROUBLESHOOTING.md b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/TROUBLESHOOTING.md new file mode 100644 index 0000000000..c59565d489 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/TROUBLESHOOTING.md @@ -0,0 +1,177 @@ +# Troubleshoot Azure Container Registry client library issues + +This troubleshooting guide contains instructions to diagnose frequently encountered issues while using the Azure Container Registry client library for Go. + +## General Troubleshooting + +### Error Handling + +All methods which send HTTP requests return `*azcore.ResponseError` when these requests fail. `ResponseError` has error details and the raw response from Container Registry. + +```go +import "github.com/Azure/azure-sdk-for-go/sdk/azcore" + +resp, err := client.GetRepositoryProperties(ctx, "library/hello-world", nil) +if err != nil { + var httpErr *azcore.ResponseError + if errors.As(err, &httpErr) { + // TODO: investigate httpErr + } else { + // TODO: not an HTTP error + } +} +``` + +### Logging + +This module uses the logging implementation in `azcore`. To turn on logging for all Azure SDK modules, set `AZURE_SDK_GO_LOGGING` to `all`. By default, the logger writes to stderr. Use the `azcore/log` package to control log output. For example, logging only HTTP request and response events, and printing them to stdout: + +```go +import azlog "github.com/Azure/azure-sdk-for-go/sdk/azcore/log" + +// Print log events to stdout +azlog.SetListener(func(cls azlog.Event, msg string) { + fmt.Println(msg) +}) + +// Includes only requests and responses in credential logs +azlog.SetEvents(azlog.EventRequest, azlog.EventResponse) +``` + +### Accessing `http.Response` + +You can access the raw `*http.Response` returned by Container Registry using the `runtime.WithCaptureResponse` method and a context passed to any client method. + +```go +import "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + +var response *http.Response +ctx := runtime.WithCaptureResponse(context.TODO(), &response) +_, err = client.GetRepositoryProperties(ctx, "library/hello-world", nil) +if err != nil { + // TODO: handle error +} +// TODO: do something with response +``` + +## Troubleshooting authentication errors + +### HTTP 401 Errors + +HTTP 401 errors indicates problems authenticating. Check exception message or logs for more information. + +#### ARM access token is disabled + +You may see error similar to the one below, it indicates authentication with ARM access token was disabled on accessed Container Registry resource. +Refer to [ACR CLI reference](https://learn.microsoft.com/cli/azure/acr/config/authentication-as-arm?view=azure-cli-latest) for information on how to +check and configure authentication with ARM tokens. + +```text +-------------------------------------------------------------------------------- +RESPONSE 401: 401 Unauthorized +ERROR CODE UNAVAILABLE +-------------------------------------------------------------------------------- +{ + "errors": [ + { + "code": "UNAUTHORIZED", + "message": "arm aad token disallowed" + } + ] +} +-------------------------------------------------------------------------------- +``` + +#### Anonymous access issues +You may see error similar to the one below, it indicates an attempt to perform operation that requires authentication without credentials. + +```text +-------------------------------------------------------------------------------- +RESPONSE 401: 401 Unauthorized +ERROR CODE UNAVAILABLE +-------------------------------------------------------------------------------- +{ + "errors": [ + { + "code": "UNAUTHORIZED", + "message": "authentication required, visit https://aka.ms/acr/authorization for more information." + } + ] +} +-------------------------------------------------------------------------------- +``` + +Unauthorized access can only be enabled for read (pull) operations such as listing repositories, getting properties or tags. +Refer to [Anonymous pull access](https://docs.microsoft.com/azure/container-registry/anonymous-pull-access) to learn about anonymous access limitation. + +### HTTP 403 Errors + +HTTP 403 errors indicate the user is not authorized to perform a specific operation in Azure Container Registry. + +#### Insufficient permissions + +If you see an error similar to the one below, it means that the provided credentials does not have permissions to access the registry. +```text +-------------------------------------------------------------------------------- +RESPONSE 403: 403 Forbidden +ERROR CODE UNAVAILABLE +-------------------------------------------------------------------------------- +{ + "errors": [ + { + "code": "DENIED", + "message": "retrieving permissions failed" + } + ] +} +-------------------------------------------------------------------------------- +``` + +1. Check that the application or user that is making the request has sufficient permissions. + Check [Troubleshoot registry login](https://docs.microsoft.com/azure/container-registry/container-registry-troubleshoot-login) for possible solutions. +2. If the user or application is granted sufficient privileges to query the workspace, make sure you are + authenticating as that user/application. See the [azidentity](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity) documentation for more information. + +#### Network access issues + +You may see an error similar to the one below, it indicates that public access to Azure Container registry is disabled or restricted. +Refer to [Troubleshoot network issues with registry](https://docs.microsoft.com/azure/container-registry/container-registry-troubleshoot-access) for more information. +```text +-------------------------------------------------------------------------------- +RESPONSE 403: 403 Forbidden +ERROR CODE UNAVAILABLE +-------------------------------------------------------------------------------- +{ + "errors": [ + { + "code": "DENIED", + "message": "client with IP <> is not allowed access. Refer https://aka.ms/acr/firewall to grant access." + } + ] +} +-------------------------------------------------------------------------------- +``` + +## Service errors + +When working with `azcontainerregistry.Client` and `azcontainerregistry.BlobClient` you may get `*azcore.ResponseError` with +message containing additional information and [Docker error code](https://docs.docker.com/registry/spec/api/#errors-2). + +### Getting BLOB_UPLOAD_INVALID + +In rare cases, transient error (such as connection reset) can happen during upload chunk. You may see an error similar to the one below. In this case upload should to be restarted from the beginning. +```text +-------------------------------------------------------------------------------- +RESPONSE 404: 404 Not Found Error +ERROR CODE UNAVAILABLE +-------------------------------------------------------------------------------- +{ + "errors": [ + { + "code": "BLOB_UPLOAD_INVALID", + "message": "blob upload invalid" + } + ] +} +-------------------------------------------------------------------------------- +``` \ No newline at end of file diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/assets.json b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/assets.json new file mode 100644 index 0000000000..13a98392b4 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/assets.json @@ -0,0 +1,6 @@ +{ + "AssetsRepo": "Azure/azure-sdk-assets", + "AssetsRepoPrefixPath": "go", + "TagPrefix": "go/containers/azcontainerregistry", + "Tag": "go/containers/azcontainerregistry_cc8575d275" +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/authentication_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/authentication_client.go new file mode 100644 index 0000000000..72cf8301a1 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/authentication_client.go @@ -0,0 +1,158 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// Code generated by Microsoft (R) AutoRest Code Generator. DO NOT EDIT. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package azcontainerregistry + +import ( + "context" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming" + "net/http" + "net/url" + "strings" +) + +// authenticationClient contains the methods for the Authentication group. +// Don't use this type directly, use a constructor function instead. +type authenticationClient struct { + internal *azcore.Client + endpoint string +} + +// ExchangeAADAccessTokenForACRRefreshToken - Exchange AAD tokens for an ACR refresh Token +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-07-01 +// - grantType - Can take a value of accesstokenrefreshtoken, or accesstoken, or refresh_token +// - service - Indicates the name of your Azure container registry. +// - options - authenticationClientExchangeAADAccessTokenForACRRefreshTokenOptions contains the optional parameters for the +// authenticationClient.ExchangeAADAccessTokenForACRRefreshToken method. +func (client *authenticationClient) ExchangeAADAccessTokenForACRRefreshToken(ctx context.Context, grantType postContentSchemaGrantType, service string, options *authenticationClientExchangeAADAccessTokenForACRRefreshTokenOptions) (authenticationClientExchangeAADAccessTokenForACRRefreshTokenResponse, error) { + var err error + ctx, endSpan := runtime.StartSpan(ctx, "AuthenticationClient.ExchangeAADAccessTokenForACRRefreshToken", client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.exchangeAADAccessTokenForACRRefreshTokenCreateRequest(ctx, grantType, service, options) + if err != nil { + return authenticationClientExchangeAADAccessTokenForACRRefreshTokenResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return authenticationClientExchangeAADAccessTokenForACRRefreshTokenResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return authenticationClientExchangeAADAccessTokenForACRRefreshTokenResponse{}, err + } + resp, err := client.exchangeAADAccessTokenForACRRefreshTokenHandleResponse(httpResp) + return resp, err +} + +// exchangeAADAccessTokenForACRRefreshTokenCreateRequest creates the ExchangeAADAccessTokenForACRRefreshToken request. +func (client *authenticationClient) exchangeAADAccessTokenForACRRefreshTokenCreateRequest(ctx context.Context, grantType postContentSchemaGrantType, service string, options *authenticationClientExchangeAADAccessTokenForACRRefreshTokenOptions) (*policy.Request, error) { + urlPath := "/oauth2/exchange" + req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.endpoint, urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-07-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + formData := url.Values{} + formData.Set("grant_type", string(grantType)) + formData.Set("service", service) + if options != nil && options.Tenant != nil { + formData.Set("tenant", *options.Tenant) + } + if options != nil && options.RefreshToken != nil { + formData.Set("refresh_token", *options.RefreshToken) + } + if options != nil && options.AccessToken != nil { + formData.Set("access_token", *options.AccessToken) + } + body := streaming.NopCloser(strings.NewReader(formData.Encode())) + if err := req.SetBody(body, "application/x-www-form-urlencoded"); err != nil { + return nil, err + } + return req, nil +} + +// exchangeAADAccessTokenForACRRefreshTokenHandleResponse handles the ExchangeAADAccessTokenForACRRefreshToken response. +func (client *authenticationClient) exchangeAADAccessTokenForACRRefreshTokenHandleResponse(resp *http.Response) (authenticationClientExchangeAADAccessTokenForACRRefreshTokenResponse, error) { + result := authenticationClientExchangeAADAccessTokenForACRRefreshTokenResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.acrRefreshToken); err != nil { + return authenticationClientExchangeAADAccessTokenForACRRefreshTokenResponse{}, err + } + return result, nil +} + +// ExchangeACRRefreshTokenForACRAccessToken - Exchange ACR Refresh token for an ACR Access Token +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-07-01 +// - service - Indicates the name of your Azure container registry. +// - scope - Which is expected to be a valid scope, and can be specified more than once for multiple scope requests. You obtained +// this from the Www-Authenticate response header from the challenge. +// - refreshToken - Must be a valid ACR refresh token +// - options - authenticationClientExchangeACRRefreshTokenForACRAccessTokenOptions contains the optional parameters for the +// authenticationClient.ExchangeACRRefreshTokenForACRAccessToken method. +func (client *authenticationClient) ExchangeACRRefreshTokenForACRAccessToken(ctx context.Context, service string, scope string, refreshToken string, options *authenticationClientExchangeACRRefreshTokenForACRAccessTokenOptions) (authenticationClientExchangeACRRefreshTokenForACRAccessTokenResponse, error) { + var err error + ctx, endSpan := runtime.StartSpan(ctx, "AuthenticationClient.ExchangeACRRefreshTokenForACRAccessToken", client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.exchangeACRRefreshTokenForACRAccessTokenCreateRequest(ctx, service, scope, refreshToken, options) + if err != nil { + return authenticationClientExchangeACRRefreshTokenForACRAccessTokenResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return authenticationClientExchangeACRRefreshTokenForACRAccessTokenResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return authenticationClientExchangeACRRefreshTokenForACRAccessTokenResponse{}, err + } + resp, err := client.exchangeACRRefreshTokenForACRAccessTokenHandleResponse(httpResp) + return resp, err +} + +// exchangeACRRefreshTokenForACRAccessTokenCreateRequest creates the ExchangeACRRefreshTokenForACRAccessToken request. +func (client *authenticationClient) exchangeACRRefreshTokenForACRAccessTokenCreateRequest(ctx context.Context, service string, scope string, refreshToken string, options *authenticationClientExchangeACRRefreshTokenForACRAccessTokenOptions) (*policy.Request, error) { + urlPath := "/oauth2/token" + req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.endpoint, urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-07-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + formData := url.Values{} + formData.Set("service", service) + formData.Set("scope", scope) + formData.Set("refresh_token", refreshToken) + if options != nil && options.GrantType != nil { + formData.Set("grant_type", string(*options.GrantType)) + } + body := streaming.NopCloser(strings.NewReader(formData.Encode())) + if err := req.SetBody(body, "application/x-www-form-urlencoded"); err != nil { + return nil, err + } + return req, nil +} + +// exchangeACRRefreshTokenForACRAccessTokenHandleResponse handles the ExchangeACRRefreshTokenForACRAccessToken response. +func (client *authenticationClient) exchangeACRRefreshTokenForACRAccessTokenHandleResponse(resp *http.Response) (authenticationClientExchangeACRRefreshTokenForACRAccessTokenResponse, error) { + result := authenticationClientExchangeACRRefreshTokenForACRAccessTokenResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.acrAccessToken); err != nil { + return authenticationClientExchangeACRRefreshTokenForACRAccessTokenResponse{}, err + } + return result, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/authentication_custom_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/authentication_custom_client.go new file mode 100644 index 0000000000..f8bf0fa80b --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/authentication_custom_client.go @@ -0,0 +1,37 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package azcontainerregistry + +import ( + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" +) + +// authenticationClientOptions contains the optional parameters for the newAuthenticationClient method. +type authenticationClientOptions struct { + azcore.ClientOptions +} + +// newAuthenticationClient creates a new instance of AuthenticationClient with the specified values. +// - endpoint - Registry login URL +// - options - Client options, pass nil to accept the default values. +func newAuthenticationClient(endpoint string, options *authenticationClientOptions) (*authenticationClient, error) { + if options == nil { + options = &authenticationClientOptions{} + } + + azcoreClient, err := azcore.NewClient(moduleName, moduleVersion, runtime.PipelineOptions{}, &options.ClientOptions) + if err != nil { + return nil, err + } + + client := &authenticationClient{ + internal: azcoreClient, + endpoint: endpoint, + } + return client, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/authentication_policy.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/authentication_policy.go new file mode 100644 index 0000000000..5cf2c35704 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/authentication_policy.go @@ -0,0 +1,249 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package azcontainerregistry + +import ( + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" + "net/http" + "strings" + "sync/atomic" + "time" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/internal/temporal" +) + +const ( + headerAuthorization = "Authorization" + bearerHeader = "Bearer " +) + +type authenticationPolicyOptions struct { +} + +// authenticationPolicy is a policy to do the challenge-based authentication for container registry service. The authorization flow is as follows: +// Step 1: GET /api/v1/acr/repositories +// Return Header: 401: www-authenticate header - Bearer realm="{url}",service="{serviceName}",scope="{scope}",error="invalid_token" +// Step 2: Retrieve the serviceName, scope from the WWW-Authenticate header. +// Step 3: POST /api/oauth2/exchange +// Request Body : { service, scope, grant-type, aadToken with ARM scope } +// Response Body: { refreshToken } +// Step 4: POST /api/oauth2/token +// Request Body: { refreshToken, scope, grant-type } +// Response Body: { accessToken } +// Step 5: GET /api/v1/acr/repositories +// Request Header: { Bearer acrTokenAccess } +// Each registry service shares one refresh token, it will be cached in refreshTokenCache until expire time. +// Since the scope will be different for different API/repository/artifact, accessTokenCache will only work when continuously calling same API. +type authenticationPolicy struct { + refreshTokenCache *temporal.Resource[azcore.AccessToken, acquiringResourceState] + accessTokenCache atomic.Value + cred azcore.TokenCredential + aadScopes []string + authClient *authenticationClient +} + +func newAuthenticationPolicy(cred azcore.TokenCredential, scopes []string, authClient *authenticationClient, opts *authenticationPolicyOptions) *authenticationPolicy { + return &authenticationPolicy{ + cred: cred, + aadScopes: scopes, + authClient: authClient, + refreshTokenCache: temporal.NewResource(acquireRefreshToken), + } +} + +func (p *authenticationPolicy) Do(req *policy.Request) (*http.Response, error) { + var resp *http.Response + var err error + if req.Raw().Header.Get(headerAuthorization) != "" { + // retry request could do the request with existed token directly + resp, err = req.Next() + } else if accessToken := p.accessTokenCache.Load(); accessToken != nil && accessToken != "" { + // if there is a previous access token, then we try to use this token to do the request + req.Raw().Header.Set( + headerAuthorization, + fmt.Sprintf("%s%s", bearerHeader, accessToken), + ) + resp, err = req.Next() + } else { + // do challenge process for the initial request + var challengeReq *policy.Request + challengeReq, err = p.getChallengeRequest(*req) + if err != nil { + return nil, err + } + resp, err = challengeReq.Next() + } + if err != nil { + return nil, err + } + + // if 401 response, then try to get access token + if resp.StatusCode == http.StatusUnauthorized { + var service, scope, accessToken string + if service, scope, err = findServiceAndScope(resp); err != nil { + return nil, err + } + if accessToken, err = p.getAccessToken(req, service, scope); err != nil { + return nil, err + } + p.accessTokenCache.Store(accessToken) + req.Raw().Header.Set( + headerAuthorization, + fmt.Sprintf("%s%s", bearerHeader, accessToken), + ) + // since the request may already been used once, body should be rewound + if err = req.RewindBody(); err != nil { + return nil, err + } + return req.Next() + } + + return resp, nil +} + +func (p *authenticationPolicy) getAccessToken(req *policy.Request, service, scope string) (string, error) { + // anonymous access + if p.cred == nil { + resp, err := p.authClient.ExchangeACRRefreshTokenForACRAccessToken(req.Raw().Context(), service, scope, "", &authenticationClientExchangeACRRefreshTokenForACRAccessTokenOptions{GrantType: to.Ptr(tokenGrantTypePassword)}) + if err != nil { + return "", err + } + return *resp.acrAccessToken.AccessToken, nil + } + + // access with token + // get refresh token from cache/request + refreshToken, err := p.refreshTokenCache.Get(acquiringResourceState{ + policy: p, + req: req, + service: service, + }) + if err != nil { + return "", err + } + + // get access token from request + resp, err := p.authClient.ExchangeACRRefreshTokenForACRAccessToken(req.Raw().Context(), service, scope, refreshToken.Token, &authenticationClientExchangeACRRefreshTokenForACRAccessTokenOptions{GrantType: to.Ptr(tokenGrantTypeRefreshToken)}) + if err != nil { + return "", err + } + return *resp.acrAccessToken.AccessToken, nil +} + +func findServiceAndScope(resp *http.Response) (string, string, error) { + authHeader := resp.Header.Get("WWW-Authenticate") + if authHeader == "" { + return "", "", errors.New("response has no WWW-Authenticate header for challenge authentication") + } + + authHeader = strings.ReplaceAll(authHeader, "Bearer ", "") + parts := strings.Split(authHeader, "\",") + valuesMap := map[string]string{} + for _, part := range parts { + subParts := strings.Split(part, "=") + if len(subParts) == 2 { + valuesMap[subParts[0]] = strings.ReplaceAll(subParts[1], "\"", "") + } + } + + if _, ok := valuesMap["service"]; !ok { + return "", "", errors.New("could not find a valid service in the WWW-Authenticate header") + } + + if _, ok := valuesMap["scope"]; !ok { + return "", "", errors.New("could not find a valid scope in the WWW-Authenticate header") + } + + return valuesMap["service"], valuesMap["scope"], nil +} + +func (p authenticationPolicy) getChallengeRequest(oriReq policy.Request) (*policy.Request, error) { + copied := oriReq.Clone(oriReq.Raw().Context()) + err := copied.SetBody(nil, "") + if err != nil { + return nil, err + } + copied.Raw().Header.Del("Content-Type") + return copied, nil +} + +type acquiringResourceState struct { + req *policy.Request + policy *authenticationPolicy + service string +} + +// acquireRefreshToken acquires or updates the refresh token of ACR service; only one thread/goroutine at a time ever calls this function +func acquireRefreshToken(state acquiringResourceState) (newResource azcore.AccessToken, newExpiration time.Time, err error) { + // get AAD token from credential + aadToken, err := state.policy.cred.GetToken( + state.req.Raw().Context(), + policy.TokenRequestOptions{ + Scopes: state.policy.aadScopes, + }, + ) + if err != nil { + return azcore.AccessToken{}, time.Time{}, err + } + + // exchange refresh token with AAD token + refreshResp, err := state.policy.authClient.ExchangeAADAccessTokenForACRRefreshToken(state.req.Raw().Context(), postContentSchemaGrantTypeAccessToken, state.service, &authenticationClientExchangeAADAccessTokenForACRRefreshTokenOptions{ + AccessToken: &aadToken.Token, + }) + if err != nil { + return azcore.AccessToken{}, time.Time{}, err + } + + refreshToken := azcore.AccessToken{ + Token: *refreshResp.acrRefreshToken.RefreshToken, + } + + // get refresh token expire time + refreshToken.ExpiresOn, err = getJWTExpireTime(*refreshResp.acrRefreshToken.RefreshToken) + if err != nil { + return azcore.AccessToken{}, time.Time{}, err + } + + // return refresh token + return refreshToken, refreshToken.ExpiresOn, nil +} + +func getJWTExpireTime(token string) (time.Time, error) { + values := strings.Split(token, ".") + if len(values) > 2 { + value := values[1] + padding := len(value) % 4 + if padding > 0 { + for i := 0; i < 4-padding; i++ { + value += "=" + } + } + parsedValue, err := base64.StdEncoding.DecodeString(value) + if err != nil { + return time.Time{}, err + } + + var jsonValue *jwtOnlyWithExp + err = json.Unmarshal(parsedValue, &jsonValue) + if err != nil { + return time.Time{}, err + } + return time.Unix(jsonValue.Exp, 0), nil + } + + return time.Time{}, errors.New("could not parse refresh token expire time") +} + +type jwtOnlyWithExp struct { + Exp int64 `json:"exp"` +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/autorest.md b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/autorest.md new file mode 100644 index 0000000000..fa2c270a4c --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/autorest.md @@ -0,0 +1,486 @@ +# Autorest config for Azure Container Registry Go client + +> see https://aka.ms/autorest + +## Configuration + +```yaml +input-file: https://github.com/Azure/azure-rest-api-specs/blob/c8d9a26a2857828e095903efa72512cf3a76c15d/specification/containerregistry/data-plane/Azure.ContainerRegistry/stable/2021-07-01/containerregistry.json +license-header: MICROSOFT_MIT_NO_VERSION +go: true +clear-output-folder: false +export-clients: true +openapi-type: "data-plane" +output-folder: ../azcontainerregistry +use: "@autorest/go@4.0.0-preview.60" +honor-body-placement: true +remove-unreferenced-types: true +module-name: sdk/containers/azcontainerregistry +module: github.com/Azure/azure-sdk-for-go/$(module-name) +inject-spans: true +``` + +## Customizations + +See the [AutoRest samples](https://github.com/Azure/autorest/tree/master/Samples/3b-custom-transformations) +for more about how we're customizing things. + +### Remove response for "ContainerRegistry_DeleteRepository" operation + +so that the generated code doesn't return a response for the deleted repository operation. + +```yaml +directive: + - from: swagger-document + where: $["paths"]["/acr/v1/{name}"] + transform: > + delete $.delete["responses"]["202"].schema +``` + +### Remove response for "ContainerRegistryBlob_DeleteBlob" operation + +so that the generated code doesn't return a response for the deleted blob operation. + +```yaml +directive: + - from: swagger-document + where: $["paths"]["/v2/{name}/blobs/{digest}"] + transform: > + delete $.delete["responses"]["202"].schema +``` + +### Remove "Authentication_GetAcrAccessTokenFromLogin" operation + +as the service team discourage using username/password to authenticate. + +```yaml +directive: + - from: swagger-document + where: $["paths"]["/oauth2/token"] + transform: > + delete $.get +``` + +### Remove "ContainerRegistry_CheckDockerV2Support" operation + +```yaml +directive: + - from: swagger-document + where: $["paths"]["/v2/"] + transform: > + delete $.get +``` + +### Remove "definitions.TagAttributesBase.properties.signed" + +as we don't have customer scenario using it. + +```yaml +directive: + - from: swagger-document + where: $.definitions.TagAttributesBase + transform: > + delete $.properties.signed +``` + +### Add "definitions.ManifestAttributesBase.properties.mediaType" + +```yaml +directive: + - from: swagger-document + where: $.definitions.ManifestAttributesBase + transform: > + $.properties["mediaType"] = { + "type": "string", + "description": "Media type for this Manifest" + } +``` + +### Change "parameters.ApiVersionParameter.required" to true + +so that the API version could be removed from client parameter. + +```yaml +directive: + - from: swagger-document + where: $.parameters.ApiVersionParameter + transform: > + $.required = true +``` + +### Take stream as manifest body + +```yaml +directive: + from: swagger-document + where: $.parameters.ManifestBody + transform: > + $.schema = { + "type": "string", + "format": "binary" + } +``` + +### Change list order by param to enum + +```yaml +directive: + - from: containerregistry.json + where: $.paths["/acr/v1/{name}/_tags"].get + transform: > + $.parameters.splice(3, 1); + $.parameters.push({ + "name": "orderby", + "x-ms-client-name": "OrderBy", + "in": "query", + "required": false, + "x-ms-parameter-location": "method", + "type": "string", + "description": "Sort options for ordering tags in a collection.", + "enum": [ + "none", + "timedesc", + "timeasc" + ], + "x-ms-enum": { + "name": "ArtifactTagOrderBy", + "values": [ + { + "value": "none", + "name": "None", + "description": "Do not provide an orderby value in the request." + }, + { + "value": "timedesc", + "name": "LastUpdatedOnDescending", + "description": "Order tags by LastUpdatedOn field, from most recently updated to least recently updated." + }, + { + "value": "timeasc", + "name": "LastUpdatedOnAscending", + "description": "Order tags by LastUpdatedOn field, from least recently updated to most recently updated." + } + ] + } + }); + - from: containerregistry.json + where: $.paths["/acr/v1/{name}/_manifests"] + transform: > + $.get.parameters.splice(3, 1); + $.get.parameters.push({ + "name": "orderby", + "x-ms-client-name": "OrderBy", + "in": "query", + "required": false, + "x-ms-parameter-location": "method", + "type": "string", + "description": "Sort options for ordering manifests in a collection.", + "enum": [ + "none", + "timedesc", + "timeasc" + ], + "x-ms-enum": { + "name": "ArtifactManifestOrderBy", + "values": [ + { + "value": "none", + "name": "None", + "description": "Do not provide an orderby value in the request." + }, + { + "value": "timedesc", + "name": "LastUpdatedOnDescending", + "description": "Order manifests by LastUpdatedOn field, from most recently updated to least recently updated." + }, + { + "value": "timeasc", + "name": "LastUpdatedOnAscending", + "description": "Order manifest by LastUpdatedOn field, from least recently updated to most recently updated." + } + ] + } + }); +``` + +### Rename paged operations from Get* to List* + +```yaml +directive: + - rename-operation: + from: ContainerRegistry_GetManifests + to: ContainerRegistry_ListManifests + - rename-operation: + from: ContainerRegistry_GetRepositories + to: ContainerRegistry_ListRepositories + - rename-operation: + from: ContainerRegistry_GetTags + to: ContainerRegistry_ListTags +``` + +### Change ContainerRegistry_CreateManifest behaviour + +```yaml +directive: + from: swagger-document + where: $.paths["/v2/{name}/manifests/{reference}"].put + transform: > + $.consumes.push("application/vnd.oci.image.manifest.v1+json"); + delete $.responses["201"].schema; +``` + +### Change ContainerRegistry_GetManifest behaviour + +```yaml +directive: + from: swagger-document + where: $.paths["/v2/{name}/manifests/{reference}"].get.responses["200"] + transform: > + $.schema = { + type: "string", + format: "file" + }; + $.headers = { + "Docker-Content-Digest": { + "type": "string", + "description": "Digest of the targeted content for the request." + } + }; +``` + +### Remove generated constructors + +```yaml +directive: + - from: + - authentication_client.go + - client.go + - blob_client.go + where: $ + transform: return $.replace(/(?:\/\/.*\s)+func New.+Client.+\{\s(?:.+\s)+\}\s/, ""); +``` + +### Rename operations + +```yaml +directive: + - rename-operation: + from: ContainerRegistry_GetProperties + to: ContainerRegistry_GetRepositoryProperties + - rename-operation: + from: ContainerRegistry_UpdateProperties + to: ContainerRegistry_UpdateRepositoryProperties + - rename-operation: + from: ContainerRegistry_UpdateTagAttributes + to: ContainerRegistry_UpdateTagProperties + - rename-operation: + from: ContainerRegistry_CreateManifest + to: ContainerRegistry_UploadManifest +``` + +### Rename parameter name + +```yaml +directive: + from: swagger-document + where: $.parameters + transform: > + $.DigestReference["x-ms-client-name"] = "digest"; + $.TagReference["x-ms-client-name"] = "tag"; +``` + +### Add 202 response to ContainerRegistryBlob_MountBlob + +```yaml +directive: + from: swagger-document + where: $.paths["/v2/{name}/blobs/uploads/"] + transform: > + $.post["responses"]["202"] = $.post["responses"]["201"]; +``` + +### Extract and add endpoint for nextLink + +```yaml +directive: + - from: + - client.go + where: $ + transform: return $.replaceAll(/result\.Link = &val/g, "val = runtime.JoinPaths(client.endpoint, extractNextLink(val))\n\t\tresult.Link = &val"); +``` + +### Do not export Authentication client and related models + +```yaml +directive: + - from: + - authentication_client.go + where: $ + transform: return $.replaceAll(/ AuthenticationClient/g, " authenticationClient").replaceAll(/\*AuthenticationClient/g, "*authenticationClient").replace(/NewAuthenticationClient/, "newAuthenticationClient").replaceAll(/\(AuthenticationClient/g, "(authenticationClient"); + - from: + - authentication_client.go + where: $ + transform: return $.replace(/PostContentSchemaGrantType/, "postContentSchemaGrantType").replace(/PostContentSchemaGrantType/, "postContentSchemaGrantType"); + - from: + - authentication_client.go + where: $ + transform: return $.replace(/result\.AcrAccessToken/, "result.acrAccessToken").replace(/result\.AcrRefreshToken/, "result.acrRefreshToken"); + - from: + - response_types.go + where: $ + transform: return $.replaceAll(/AuthenticationClient/g, "authenticationClient").replace(/AcrRefreshToken\n/, "acrRefreshToken\n").replace(/AcrAccessToken\n/, "acrAccessToken\n"); + - from: + - models.go + - options.go + where: $ + transform: return $.replaceAll(/AuthenticationClient/g, "authenticationClient").replace(/AcrRefreshToken struct/, "acrRefreshToken struct").replace(/AcrAccessToken struct/, "acrAccessToken struct"); + - from: + - options.go + where: $ + transform: return $.replace(/TokenGrantType/, "tokenGrantType"); + - from: + - constants.go + where: $ + transform: return $.replaceAll(/ TokenGrantType/g, " tokenGrantType").replaceAll(/\tTokenGrantType/g, "\ttokenGrantType").replaceAll(/\]TokenGrantType/g, "]tokenGrantType").replaceAll(/PossibleTokenGrantType/g, "possibleTokenGrantType"); + - from: + - constants.go + where: $ + transform: return $.replaceAll(/ PostContentSchemaGrantType/g, " postContentSchemaGrantType").replaceAll(/\tPostContentSchemaGrantType/g, "\tpostContentSchemaGrantType").replaceAll(/\]PostContentSchemaGrantType/g, "]postContentSchemaGrantType").replaceAll(/PossiblePostContentSchemaGrantType/g, "possiblePostContentSchemaGrantType"); + - from: + - models_serde.go + where: $ + transform: return $.replaceAll(/ AcrAccessToken/g, " acrAccessToken").replace(/\*AcrAccessToken/g, "*acrAccessToken").replaceAll(/ AcrRefreshToken/g, " acrRefreshToken").replace(/\*AcrRefreshToken/g, "*acrRefreshToken"); +``` + +### Rename all Acr to ACR + +```yaml +directive: + - from: + - "*.go" + where: $ + transform: return $.replaceAll(/Acr/g, "ACR"); +``` + +### Rename TagAttributesBase, ManifestAttributesBase, TagAttributeBases, Repositories, AcrManifests and QueryNum + +```yaml +directive: + - from: containerregistry.json + where: $.definitions + transform: > + $.TagAttributesBase["x-ms-client-name"] = "TagAttributes"; + - from: containerregistry.json + where: $.definitions + transform: > + $.ManifestAttributesBase["x-ms-client-name"] = "ManifestAttributes"; + - from: containerregistry.json + where: $.definitions.TagList + transform: > + delete $.properties.tags["x-ms-client-name"]; + - from: containerregistry.json + where: $.definitions.Repositories + transform: > + $.properties.repositories["x-ms-client-name"] = "Names"; + - from: containerregistry.json + where: $.definitions + transform: > + $.AcrManifests["x-ms-client-name"] = "Manifests"; + - from: containerregistry.json + where: $.definitions.AcrManifests + transform: > + $.properties.manifests["x-ms-client-name"] = "Attributes"; + - from: containerregistry.json + where: $.parameters + transform: > + $.QueryNum["x-ms-client-name"] = "MaxNum"; +``` + +### Rename binary request param and response property + +```yaml +directive: + - from: containerregistry.json + where: $.parameters + transform: > + $.RawData["x-ms-client-name"] = "chunkData"; + $.RawDataOptional["x-ms-client-name"] = "blobData"; + $.ManifestBody["x-ms-client-name"] = "manifestData"; + - from: + - blob_client.go + where: $ + transform: return $.replace(/BlobClientGetBlobResponse\{Body/, "BlobClientGetBlobResponse{BlobData").replace(/BlobClientGetChunkResponse\{Body/, "BlobClientGetChunkResponse{ChunkData"); + - from: + - client.go + where: $ + transform: return $.replace(/ClientGetManifestResponse\{Body/, "ClientGetManifestResponse{ManifestData"); + - from: + - response_types.go + where: $ + transform: return $.replace(/Body io\.ReadCloser/, "BlobData io.ReadCloser").replace(/Body io\.ReadCloser/, "ChunkData io.ReadCloser").replace(/Body io\.ReadCloser/, "ManifestData io.ReadCloser"); +``` + +### Hide original UploadChunk and CompleteUpload method +```yaml +directive: + - from: containerregistry.json + where: $.paths["/{nextBlobUuidLink}"] + transform: > + $.put.parameters.splice(1,1); + - from: + - blob_client.go + where: $ + transform: return $.replaceAll(/ UploadChunk/g, " uploadChunk").replace(/\.UploadChunk/, ".uploadChunk").replaceAll(/ CompleteUpload/g, " completeUpload").replace(/\.CompleteUpload/, ".completeUpload"); +``` + +### Add content-range parameters to upload chunk + +```yaml +directive: + - from: swagger-document + where: $.paths["/{nextBlobUuidLink}"].patch + transform: > + $.parameters.push({ + "name": "Content-Range", + "in": "header", + "type": "string", + "description": "Range of bytes identifying the desired block of content represented by the body. Start must the end offset retrieved via status check plus one. Note that this is a non-standard use of the Content-Range header." + }); + - from: + - blob_client.go + - options.go + where: $ + transform: return $.replaceAll(/BlobClientUploadChunkOptions/g, "blobClientUploadChunkOptions").replace(/BlobClient\.UploadChunk/, "BlobClient.uploadChunk"); +``` + +### Add description for ArtifactOperatingSystem + +```yaml +directive: + - from: swagger-document + where: $.definitions + transform: > + $.ArtifactOperatingSystem.description = "The artifact platform's operating system."; +``` + +### Remove useless Marshal method + +```yaml +directive: + - from: + - models_serde.go + where: $ + transform: > + return $ + .replace(/\/\/ MarshalJSON.*TagList[^}]*}\n/g, "") + .replace(/\/\/ MarshalJSON.*TagAttributes[^}]*}\n/g, "") + .replace(/\/\/ MarshalJSON.*Repositories[^}]*}\n/g, "") + .replace(/\/\/ MarshalJSON.*Manifests[^}]*}\n/g, "") + .replace(/\/\/ MarshalJSON.*ManifestAttributes[^}]*}\n/g, "") + .replace(/\/\/ MarshalJSON.*ContainerRepositoryProperties[^}]*}\n/g, "") + .replace(/\/\/ MarshalJSON.*ArtifactTagProperties[^}]*}\n/g, "") + .replace(/\/\/ MarshalJSON.*ArtifactManifestProperties[^}]*}\n/g, "") + .replace(/\/\/ MarshalJSON.*ArtifactManifestPlatform[^}]*}\n/g, "") + .replace(/\/\/ MarshalJSON.*acrRefreshToken[^}]*}\n/g, "") + .replace(/\/\/ MarshalJSON.*acrAccessToken[^}]*}\n/g, "") +``` \ No newline at end of file diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/blob_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/blob_client.go new file mode 100644 index 0000000000..6c1d896286 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/blob_client.go @@ -0,0 +1,664 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// Code generated by Microsoft (R) AutoRest Code Generator. DO NOT EDIT. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package azcontainerregistry + +import ( + "context" + "errors" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "io" + "net/http" + "net/url" + "strconv" + "strings" +) + +// BlobClient contains the methods for the ContainerRegistryBlob group. +// Don't use this type directly, use a constructor function instead. +type BlobClient struct { + internal *azcore.Client + endpoint string +} + +// CancelUpload - Cancel outstanding upload processes, releasing associated resources. If this is not called, the unfinished +// uploads will eventually timeout. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-07-01 +// - location - Link acquired from upload start or previous chunk. Note, do not include initial / (must do substring(1) ) +// - options - BlobClientCancelUploadOptions contains the optional parameters for the BlobClient.CancelUpload method. +func (client *BlobClient) CancelUpload(ctx context.Context, location string, options *BlobClientCancelUploadOptions) (BlobClientCancelUploadResponse, error) { + var err error + ctx, endSpan := runtime.StartSpan(ctx, "BlobClient.CancelUpload", client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.cancelUploadCreateRequest(ctx, location, options) + if err != nil { + return BlobClientCancelUploadResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return BlobClientCancelUploadResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusNoContent) { + err = runtime.NewResponseError(httpResp) + return BlobClientCancelUploadResponse{}, err + } + return BlobClientCancelUploadResponse{}, nil +} + +// cancelUploadCreateRequest creates the CancelUpload request. +func (client *BlobClient) cancelUploadCreateRequest(ctx context.Context, location string, options *BlobClientCancelUploadOptions) (*policy.Request, error) { + urlPath := "/{nextBlobUuidLink}" + urlPath = strings.ReplaceAll(urlPath, "{nextBlobUuidLink}", location) + req, err := runtime.NewRequest(ctx, http.MethodDelete, runtime.JoinPaths(client.endpoint, urlPath)) + if err != nil { + return nil, err + } + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// CheckBlobExists - Same as GET, except only the headers are returned. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-07-01 +// - name - Name of the image (including the namespace) +// - digest - Digest of a BLOB +// - options - BlobClientCheckBlobExistsOptions contains the optional parameters for the BlobClient.CheckBlobExists method. +func (client *BlobClient) CheckBlobExists(ctx context.Context, name string, digest string, options *BlobClientCheckBlobExistsOptions) (BlobClientCheckBlobExistsResponse, error) { + var err error + ctx, endSpan := runtime.StartSpan(ctx, "BlobClient.CheckBlobExists", client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.checkBlobExistsCreateRequest(ctx, name, digest, options) + if err != nil { + return BlobClientCheckBlobExistsResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return BlobClientCheckBlobExistsResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return BlobClientCheckBlobExistsResponse{}, err + } + resp, err := client.checkBlobExistsHandleResponse(httpResp) + return resp, err +} + +// checkBlobExistsCreateRequest creates the CheckBlobExists request. +func (client *BlobClient) checkBlobExistsCreateRequest(ctx context.Context, name string, digest string, options *BlobClientCheckBlobExistsOptions) (*policy.Request, error) { + urlPath := "/v2/{name}/blobs/{digest}" + if name == "" { + return nil, errors.New("parameter name cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{name}", url.PathEscape(name)) + if digest == "" { + return nil, errors.New("parameter digest cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{digest}", url.PathEscape(digest)) + req, err := runtime.NewRequest(ctx, http.MethodHead, runtime.JoinPaths(client.endpoint, urlPath)) + if err != nil { + return nil, err + } + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// checkBlobExistsHandleResponse handles the CheckBlobExists response. +func (client *BlobClient) checkBlobExistsHandleResponse(resp *http.Response) (BlobClientCheckBlobExistsResponse, error) { + result := BlobClientCheckBlobExistsResponse{} + if val := resp.Header.Get("Content-Length"); val != "" { + contentLength, err := strconv.ParseInt(val, 10, 64) + if err != nil { + return BlobClientCheckBlobExistsResponse{}, err + } + result.ContentLength = &contentLength + } + if val := resp.Header.Get("Docker-Content-Digest"); val != "" { + result.DockerContentDigest = &val + } + return result, nil +} + +// CheckChunkExists - Same as GET, except only the headers are returned. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-07-01 +// - name - Name of the image (including the namespace) +// - digest - Digest of a BLOB +// - rangeParam - Format : bytes=-, HTTP Range header specifying blob chunk. +// - options - BlobClientCheckChunkExistsOptions contains the optional parameters for the BlobClient.CheckChunkExists method. +func (client *BlobClient) CheckChunkExists(ctx context.Context, name string, digest string, rangeParam string, options *BlobClientCheckChunkExistsOptions) (BlobClientCheckChunkExistsResponse, error) { + var err error + ctx, endSpan := runtime.StartSpan(ctx, "BlobClient.CheckChunkExists", client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.checkChunkExistsCreateRequest(ctx, name, digest, rangeParam, options) + if err != nil { + return BlobClientCheckChunkExistsResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return BlobClientCheckChunkExistsResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return BlobClientCheckChunkExistsResponse{}, err + } + resp, err := client.checkChunkExistsHandleResponse(httpResp) + return resp, err +} + +// checkChunkExistsCreateRequest creates the CheckChunkExists request. +func (client *BlobClient) checkChunkExistsCreateRequest(ctx context.Context, name string, digest string, rangeParam string, options *BlobClientCheckChunkExistsOptions) (*policy.Request, error) { + urlPath := "/v2/{name}/blobs/{digest}" + if name == "" { + return nil, errors.New("parameter name cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{name}", url.PathEscape(name)) + if digest == "" { + return nil, errors.New("parameter digest cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{digest}", url.PathEscape(digest)) + req, err := runtime.NewRequest(ctx, http.MethodHead, runtime.JoinPaths(client.endpoint, urlPath)) + if err != nil { + return nil, err + } + req.Raw().Header["Range"] = []string{rangeParam} + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// checkChunkExistsHandleResponse handles the CheckChunkExists response. +func (client *BlobClient) checkChunkExistsHandleResponse(resp *http.Response) (BlobClientCheckChunkExistsResponse, error) { + result := BlobClientCheckChunkExistsResponse{} + if val := resp.Header.Get("Content-Length"); val != "" { + contentLength, err := strconv.ParseInt(val, 10, 64) + if err != nil { + return BlobClientCheckChunkExistsResponse{}, err + } + result.ContentLength = &contentLength + } + if val := resp.Header.Get("Content-Range"); val != "" { + result.ContentRange = &val + } + return result, nil +} + +// completeUpload - Complete the upload, providing all the data in the body, if necessary. A request without a body will just +// complete the upload with previously uploaded content. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-07-01 +// - digest - Digest of a BLOB +// - location - Link acquired from upload start or previous chunk. Note, do not include initial / (must do substring(1) ) +// - options - BlobClientCompleteUploadOptions contains the optional parameters for the BlobClient.completeUpload method. +func (client *BlobClient) completeUpload(ctx context.Context, digest string, location string, options *BlobClientCompleteUploadOptions) (BlobClientCompleteUploadResponse, error) { + var err error + ctx, endSpan := runtime.StartSpan(ctx, "BlobClient.CompleteUpload", client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.completeUploadCreateRequest(ctx, digest, location, options) + if err != nil { + return BlobClientCompleteUploadResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return BlobClientCompleteUploadResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusCreated) { + err = runtime.NewResponseError(httpResp) + return BlobClientCompleteUploadResponse{}, err + } + resp, err := client.completeUploadHandleResponse(httpResp) + return resp, err +} + +// completeUploadCreateRequest creates the completeUpload request. +func (client *BlobClient) completeUploadCreateRequest(ctx context.Context, digest string, location string, options *BlobClientCompleteUploadOptions) (*policy.Request, error) { + urlPath := "/{nextBlobUuidLink}" + urlPath = strings.ReplaceAll(urlPath, "{nextBlobUuidLink}", location) + req, err := runtime.NewRequest(ctx, http.MethodPut, runtime.JoinPaths(client.endpoint, urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("digest", digest) + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// completeUploadHandleResponse handles the completeUpload response. +func (client *BlobClient) completeUploadHandleResponse(resp *http.Response) (BlobClientCompleteUploadResponse, error) { + result := BlobClientCompleteUploadResponse{} + if val := resp.Header.Get("Docker-Content-Digest"); val != "" { + result.DockerContentDigest = &val + } + if val := resp.Header.Get("Location"); val != "" { + result.Location = &val + } + if val := resp.Header.Get("Range"); val != "" { + result.Range = &val + } + return result, nil +} + +// DeleteBlob - Removes an already uploaded blob. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-07-01 +// - name - Name of the image (including the namespace) +// - digest - Digest of a BLOB +// - options - BlobClientDeleteBlobOptions contains the optional parameters for the BlobClient.DeleteBlob method. +func (client *BlobClient) DeleteBlob(ctx context.Context, name string, digest string, options *BlobClientDeleteBlobOptions) (BlobClientDeleteBlobResponse, error) { + var err error + ctx, endSpan := runtime.StartSpan(ctx, "BlobClient.DeleteBlob", client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.deleteBlobCreateRequest(ctx, name, digest, options) + if err != nil { + return BlobClientDeleteBlobResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return BlobClientDeleteBlobResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusAccepted) { + err = runtime.NewResponseError(httpResp) + return BlobClientDeleteBlobResponse{}, err + } + resp, err := client.deleteBlobHandleResponse(httpResp) + return resp, err +} + +// deleteBlobCreateRequest creates the DeleteBlob request. +func (client *BlobClient) deleteBlobCreateRequest(ctx context.Context, name string, digest string, options *BlobClientDeleteBlobOptions) (*policy.Request, error) { + urlPath := "/v2/{name}/blobs/{digest}" + if name == "" { + return nil, errors.New("parameter name cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{name}", url.PathEscape(name)) + if digest == "" { + return nil, errors.New("parameter digest cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{digest}", url.PathEscape(digest)) + req, err := runtime.NewRequest(ctx, http.MethodDelete, runtime.JoinPaths(client.endpoint, urlPath)) + if err != nil { + return nil, err + } + return req, nil +} + +// deleteBlobHandleResponse handles the DeleteBlob response. +func (client *BlobClient) deleteBlobHandleResponse(resp *http.Response) (BlobClientDeleteBlobResponse, error) { + result := BlobClientDeleteBlobResponse{} + if val := resp.Header.Get("Docker-Content-Digest"); val != "" { + result.DockerContentDigest = &val + } + return result, nil +} + +// GetBlob - Retrieve the blob from the registry identified by digest. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-07-01 +// - name - Name of the image (including the namespace) +// - digest - Digest of a BLOB +// - options - BlobClientGetBlobOptions contains the optional parameters for the BlobClient.GetBlob method. +func (client *BlobClient) GetBlob(ctx context.Context, name string, digest string, options *BlobClientGetBlobOptions) (BlobClientGetBlobResponse, error) { + var err error + ctx, endSpan := runtime.StartSpan(ctx, "BlobClient.GetBlob", client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.getBlobCreateRequest(ctx, name, digest, options) + if err != nil { + return BlobClientGetBlobResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return BlobClientGetBlobResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return BlobClientGetBlobResponse{}, err + } + resp, err := client.getBlobHandleResponse(httpResp) + return resp, err +} + +// getBlobCreateRequest creates the GetBlob request. +func (client *BlobClient) getBlobCreateRequest(ctx context.Context, name string, digest string, options *BlobClientGetBlobOptions) (*policy.Request, error) { + urlPath := "/v2/{name}/blobs/{digest}" + if name == "" { + return nil, errors.New("parameter name cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{name}", url.PathEscape(name)) + if digest == "" { + return nil, errors.New("parameter digest cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{digest}", url.PathEscape(digest)) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.endpoint, urlPath)) + if err != nil { + return nil, err + } + runtime.SkipBodyDownload(req) + req.Raw().Header["Accept"] = []string{"application/octet-stream"} + return req, nil +} + +// getBlobHandleResponse handles the GetBlob response. +func (client *BlobClient) getBlobHandleResponse(resp *http.Response) (BlobClientGetBlobResponse, error) { + result := BlobClientGetBlobResponse{BlobData: resp.Body} + if val := resp.Header.Get("Content-Length"); val != "" { + contentLength, err := strconv.ParseInt(val, 10, 64) + if err != nil { + return BlobClientGetBlobResponse{}, err + } + result.ContentLength = &contentLength + } + if val := resp.Header.Get("Docker-Content-Digest"); val != "" { + result.DockerContentDigest = &val + } + return result, nil +} + +// GetChunk - Retrieve the blob from the registry identified by digest. This endpoint may also support RFC7233 compliant range +// requests. Support can be detected by issuing a HEAD request. If the header +// Accept-Range: bytes is returned, range requests can be used to fetch partial content. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-07-01 +// - name - Name of the image (including the namespace) +// - digest - Digest of a BLOB +// - rangeParam - Format : bytes=-, HTTP Range header specifying blob chunk. +// - options - BlobClientGetChunkOptions contains the optional parameters for the BlobClient.GetChunk method. +func (client *BlobClient) GetChunk(ctx context.Context, name string, digest string, rangeParam string, options *BlobClientGetChunkOptions) (BlobClientGetChunkResponse, error) { + var err error + ctx, endSpan := runtime.StartSpan(ctx, "BlobClient.GetChunk", client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.getChunkCreateRequest(ctx, name, digest, rangeParam, options) + if err != nil { + return BlobClientGetChunkResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return BlobClientGetChunkResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusPartialContent) { + err = runtime.NewResponseError(httpResp) + return BlobClientGetChunkResponse{}, err + } + resp, err := client.getChunkHandleResponse(httpResp) + return resp, err +} + +// getChunkCreateRequest creates the GetChunk request. +func (client *BlobClient) getChunkCreateRequest(ctx context.Context, name string, digest string, rangeParam string, options *BlobClientGetChunkOptions) (*policy.Request, error) { + urlPath := "/v2/{name}/blobs/{digest}" + if name == "" { + return nil, errors.New("parameter name cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{name}", url.PathEscape(name)) + if digest == "" { + return nil, errors.New("parameter digest cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{digest}", url.PathEscape(digest)) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.endpoint, urlPath)) + if err != nil { + return nil, err + } + runtime.SkipBodyDownload(req) + req.Raw().Header["Range"] = []string{rangeParam} + req.Raw().Header["Accept"] = []string{"application/octet-stream"} + return req, nil +} + +// getChunkHandleResponse handles the GetChunk response. +func (client *BlobClient) getChunkHandleResponse(resp *http.Response) (BlobClientGetChunkResponse, error) { + result := BlobClientGetChunkResponse{ChunkData: resp.Body} + if val := resp.Header.Get("Content-Length"); val != "" { + contentLength, err := strconv.ParseInt(val, 10, 64) + if err != nil { + return BlobClientGetChunkResponse{}, err + } + result.ContentLength = &contentLength + } + if val := resp.Header.Get("Content-Range"); val != "" { + result.ContentRange = &val + } + return result, nil +} + +// GetUploadStatus - Retrieve status of upload identified by uuid. The primary purpose of this endpoint is to resolve the +// current status of a resumable upload. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-07-01 +// - location - Link acquired from upload start or previous chunk. Note, do not include initial / (must do substring(1) ) +// - options - BlobClientGetUploadStatusOptions contains the optional parameters for the BlobClient.GetUploadStatus method. +func (client *BlobClient) GetUploadStatus(ctx context.Context, location string, options *BlobClientGetUploadStatusOptions) (BlobClientGetUploadStatusResponse, error) { + var err error + ctx, endSpan := runtime.StartSpan(ctx, "BlobClient.GetUploadStatus", client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.getUploadStatusCreateRequest(ctx, location, options) + if err != nil { + return BlobClientGetUploadStatusResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return BlobClientGetUploadStatusResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusNoContent) { + err = runtime.NewResponseError(httpResp) + return BlobClientGetUploadStatusResponse{}, err + } + resp, err := client.getUploadStatusHandleResponse(httpResp) + return resp, err +} + +// getUploadStatusCreateRequest creates the GetUploadStatus request. +func (client *BlobClient) getUploadStatusCreateRequest(ctx context.Context, location string, options *BlobClientGetUploadStatusOptions) (*policy.Request, error) { + urlPath := "/{nextBlobUuidLink}" + urlPath = strings.ReplaceAll(urlPath, "{nextBlobUuidLink}", location) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.endpoint, urlPath)) + if err != nil { + return nil, err + } + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getUploadStatusHandleResponse handles the GetUploadStatus response. +func (client *BlobClient) getUploadStatusHandleResponse(resp *http.Response) (BlobClientGetUploadStatusResponse, error) { + result := BlobClientGetUploadStatusResponse{} + if val := resp.Header.Get("Docker-Upload-UUID"); val != "" { + result.DockerUploadUUID = &val + } + if val := resp.Header.Get("Range"); val != "" { + result.Range = &val + } + return result, nil +} + +// MountBlob - Mount a blob identified by the mount parameter from another repository. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-07-01 +// - name - Name of the image (including the namespace) +// - from - Name of the source repository. +// - mount - Digest of blob to mount from the source repository. +// - options - BlobClientMountBlobOptions contains the optional parameters for the BlobClient.MountBlob method. +func (client *BlobClient) MountBlob(ctx context.Context, name string, from string, mount string, options *BlobClientMountBlobOptions) (BlobClientMountBlobResponse, error) { + var err error + ctx, endSpan := runtime.StartSpan(ctx, "BlobClient.MountBlob", client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.mountBlobCreateRequest(ctx, name, from, mount, options) + if err != nil { + return BlobClientMountBlobResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return BlobClientMountBlobResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusCreated, http.StatusAccepted) { + err = runtime.NewResponseError(httpResp) + return BlobClientMountBlobResponse{}, err + } + resp, err := client.mountBlobHandleResponse(httpResp) + return resp, err +} + +// mountBlobCreateRequest creates the MountBlob request. +func (client *BlobClient) mountBlobCreateRequest(ctx context.Context, name string, from string, mount string, options *BlobClientMountBlobOptions) (*policy.Request, error) { + urlPath := "/v2/{name}/blobs/uploads/" + if name == "" { + return nil, errors.New("parameter name cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{name}", url.PathEscape(name)) + req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.endpoint, urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("from", from) + reqQP.Set("mount", mount) + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// mountBlobHandleResponse handles the MountBlob response. +func (client *BlobClient) mountBlobHandleResponse(resp *http.Response) (BlobClientMountBlobResponse, error) { + result := BlobClientMountBlobResponse{} + if val := resp.Header.Get("Docker-Content-Digest"); val != "" { + result.DockerContentDigest = &val + } + if val := resp.Header.Get("Docker-Upload-UUID"); val != "" { + result.DockerUploadUUID = &val + } + if val := resp.Header.Get("Location"); val != "" { + result.Location = &val + } + return result, nil +} + +// StartUpload - Initiate a resumable blob upload with an empty request body. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-07-01 +// - name - Name of the image (including the namespace) +// - options - BlobClientStartUploadOptions contains the optional parameters for the BlobClient.StartUpload method. +func (client *BlobClient) StartUpload(ctx context.Context, name string, options *BlobClientStartUploadOptions) (BlobClientStartUploadResponse, error) { + var err error + ctx, endSpan := runtime.StartSpan(ctx, "BlobClient.StartUpload", client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.startUploadCreateRequest(ctx, name, options) + if err != nil { + return BlobClientStartUploadResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return BlobClientStartUploadResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusAccepted) { + err = runtime.NewResponseError(httpResp) + return BlobClientStartUploadResponse{}, err + } + resp, err := client.startUploadHandleResponse(httpResp) + return resp, err +} + +// startUploadCreateRequest creates the StartUpload request. +func (client *BlobClient) startUploadCreateRequest(ctx context.Context, name string, options *BlobClientStartUploadOptions) (*policy.Request, error) { + urlPath := "/v2/{name}/blobs/uploads/" + if name == "" { + return nil, errors.New("parameter name cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{name}", url.PathEscape(name)) + req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.endpoint, urlPath)) + if err != nil { + return nil, err + } + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// startUploadHandleResponse handles the StartUpload response. +func (client *BlobClient) startUploadHandleResponse(resp *http.Response) (BlobClientStartUploadResponse, error) { + result := BlobClientStartUploadResponse{} + if val := resp.Header.Get("Docker-Upload-UUID"); val != "" { + result.DockerUploadUUID = &val + } + if val := resp.Header.Get("Location"); val != "" { + result.Location = &val + } + if val := resp.Header.Get("Range"); val != "" { + result.Range = &val + } + return result, nil +} + +// uploadChunk - Upload a stream of data without completing the upload. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-07-01 +// - location - Link acquired from upload start or previous chunk. Note, do not include initial / (must do substring(1) ) +// - chunkData - Raw data of blob +// - options - blobClientUploadChunkOptions contains the optional parameters for the BlobClient.uploadChunk method. +func (client *BlobClient) uploadChunk(ctx context.Context, location string, chunkData io.ReadSeekCloser, options *blobClientUploadChunkOptions) (BlobClientUploadChunkResponse, error) { + var err error + ctx, endSpan := runtime.StartSpan(ctx, "BlobClient.uploadChunk", client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.uploadChunkCreateRequest(ctx, location, chunkData, options) + if err != nil { + return BlobClientUploadChunkResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return BlobClientUploadChunkResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusAccepted) { + err = runtime.NewResponseError(httpResp) + return BlobClientUploadChunkResponse{}, err + } + resp, err := client.uploadChunkHandleResponse(httpResp) + return resp, err +} + +// uploadChunkCreateRequest creates the uploadChunk request. +func (client *BlobClient) uploadChunkCreateRequest(ctx context.Context, location string, chunkData io.ReadSeekCloser, options *blobClientUploadChunkOptions) (*policy.Request, error) { + urlPath := "/{nextBlobUuidLink}" + urlPath = strings.ReplaceAll(urlPath, "{nextBlobUuidLink}", location) + req, err := runtime.NewRequest(ctx, http.MethodPatch, runtime.JoinPaths(client.endpoint, urlPath)) + if err != nil { + return nil, err + } + if options != nil && options.ContentRange != nil { + req.Raw().Header["Content-Range"] = []string{*options.ContentRange} + } + req.Raw().Header["Accept"] = []string{"application/json"} + if err := req.SetBody(chunkData, "application/octet-stream"); err != nil { + return nil, err + } + return req, nil +} + +// uploadChunkHandleResponse handles the uploadChunk response. +func (client *BlobClient) uploadChunkHandleResponse(resp *http.Response) (BlobClientUploadChunkResponse, error) { + result := BlobClientUploadChunkResponse{} + if val := resp.Header.Get("Docker-Upload-UUID"); val != "" { + result.DockerUploadUUID = &val + } + if val := resp.Header.Get("Location"); val != "" { + result.Location = &val + } + if val := resp.Header.Get("Range"); val != "" { + result.Range = &val + } + return result, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/blob_custom_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/blob_custom_client.go new file mode 100644 index 0000000000..fc79bbe436 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/blob_custom_client.go @@ -0,0 +1,109 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package azcontainerregistry + +import ( + "context" + "errors" + "fmt" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" + "io" + "reflect" +) + +// BlobClientOptions contains the optional parameters for the NewBlobClient method. +type BlobClientOptions struct { + azcore.ClientOptions +} + +// NewBlobClient creates a new instance of BlobClient with the specified values. +// - endpoint - registry login URL +// - credential - used to authorize requests. Usually a credential from azidentity. +// - options - client options, pass nil to accept the default values. +func NewBlobClient(endpoint string, credential azcore.TokenCredential, options *BlobClientOptions) (*BlobClient, error) { + if options == nil { + options = &BlobClientOptions{} + } + + if reflect.ValueOf(options.Cloud).IsZero() { + options.Cloud = defaultCloud + } + c, ok := options.Cloud.Services[ServiceName] + if !ok || c.Audience == "" { + return nil, errors.New("provided Cloud field is missing Azure Container Registry configuration") + } + + authClient, err := newAuthenticationClient(endpoint, &authenticationClientOptions{ + options.ClientOptions, + }) + if err != nil { + return nil, err + } + + authPolicy := newAuthenticationPolicy( + credential, + []string{c.Audience + "/.default"}, + authClient, + nil, + ) + + azcoreClient, err := azcore.NewClient(moduleName, moduleVersion, runtime.PipelineOptions{PerRetry: []policy.Policy{authPolicy}}, &options.ClientOptions) + if err != nil { + return nil, err + } + + return &BlobClient{ + azcoreClient, + endpoint, + }, nil +} + +// BlobClientUploadChunkOptions contains the optional parameters for the BlobClient.UploadChunk method. +type BlobClientUploadChunkOptions struct { + // Start of range for the blob to be uploaded. + RangeStart *int32 + // End of range for the blob to be uploaded, inclusive. + RangeEnd *int32 +} + +// UploadChunk - Upload a stream of data without completing the upload. +// +// - location - Link acquired from upload start or previous chunk +// - chunkData - Raw data of blob +// - blobDigestCalculator - Calculator that help to calculate blob digest +// - options - BlobClientUploadChunkOptions contains the optional parameters for the BlobClient.UploadChunk method. +func (client *BlobClient) UploadChunk(ctx context.Context, location string, chunkData io.ReadSeeker, blobDigestCalculator *BlobDigestCalculator, options *BlobClientUploadChunkOptions) (BlobClientUploadChunkResponse, error) { + blobDigestCalculator.saveState() + reader, err := blobDigestCalculator.wrapReader(chunkData) + if err != nil { + return BlobClientUploadChunkResponse{}, err + } + wrappedChunkData := &wrappedReadSeeker{Reader: reader, Seeker: chunkData} + var requestOptions *blobClientUploadChunkOptions + if options != nil && options.RangeStart != nil && options.RangeEnd != nil { + requestOptions = &blobClientUploadChunkOptions{ContentRange: to.Ptr(fmt.Sprintf("%d-%d", *options.RangeStart, *options.RangeEnd))} + } + resp, err := client.uploadChunk(ctx, location, streaming.NopCloser(wrappedChunkData), requestOptions) + if err != nil { + blobDigestCalculator.restoreState() + } + return resp, err +} + +// CompleteUpload - Complete the upload with previously uploaded content. +// +// - digest - Digest of a BLOB +// - location - Link acquired from upload start or previous chunk +// - blobDigestCalculator - Calculator that help to calculate blob digest +// - options - BlobClientCompleteUploadOptions contains the optional parameters for the BlobClient.CompleteUpload method. +func (client *BlobClient) CompleteUpload(ctx context.Context, location string, blobDigestCalculator *BlobDigestCalculator, options *BlobClientCompleteUploadOptions) (BlobClientCompleteUploadResponse, error) { + return client.completeUpload(ctx, blobDigestCalculator.getDigest(), location, options) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/build.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/build.go new file mode 100644 index 0000000000..e62d3e4f6a --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/build.go @@ -0,0 +1,10 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +//go:generate autorest --debug ./autorest.md +//go:generate gofmt -w . + +package azcontainerregistry diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/ci.yml b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/ci.yml new file mode 100644 index 0000000000..af83077cb7 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/ci.yml @@ -0,0 +1,36 @@ +# NOTE: Please refer to https://aka.ms/azsdk/engsys/ci-yaml before editing this file. +trigger: + branches: + include: + - main + - feature/* + - hotfix/* + - release/* + paths: + include: + - sdk/containers/azcontainerregistry + +pr: + branches: + include: + - main + - feature/* + - hotfix/* + - release/* + paths: + include: + - sdk/containers/azcontainerregistry + +stages: +- template: /eng/pipelines/templates/jobs/archetype-sdk-client.yml + parameters: + ServiceDirectory: 'containers/azcontainerregistry' + RunLiveTests: true + UsePipelineProxy: false + TestRunTime: '30m' + SupportedClouds: 'Public,UsGov' + EnvVars: + AZURE_CLIENT_ID: $(AZCONTAINERREGISTRY_CLIENT_ID) + AZURE_TENANT_ID: $(AZCONTAINERREGISTRY_TENANT_ID) + AZURE_CLIENT_SECRET: $(AZCONTAINERREGISTRY_CLIENT_SECRET) + AZURE_SUBSCRIPTION_ID: $(AZCONTAINERREGISTRY_SUBSCRIPTION_ID) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/client.go new file mode 100644 index 0000000000..bcc0d067c4 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/client.go @@ -0,0 +1,850 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// Code generated by Microsoft (R) AutoRest Code Generator. DO NOT EDIT. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package azcontainerregistry + +import ( + "context" + "errors" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "io" + "net/http" + "net/url" + "strconv" + "strings" +) + +// Client contains the methods for the ContainerRegistry group. +// Don't use this type directly, use a constructor function instead. +type Client struct { + internal *azcore.Client + endpoint string +} + +// DeleteManifest - Delete the manifest identified by name and reference. Note that a manifest can only be deleted by digest. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-07-01 +// - name - Name of the image (including the namespace) +// - digest - Digest of a BLOB +// - options - ClientDeleteManifestOptions contains the optional parameters for the Client.DeleteManifest method. +func (client *Client) DeleteManifest(ctx context.Context, name string, digest string, options *ClientDeleteManifestOptions) (ClientDeleteManifestResponse, error) { + var err error + ctx, endSpan := runtime.StartSpan(ctx, "Client.DeleteManifest", client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.deleteManifestCreateRequest(ctx, name, digest, options) + if err != nil { + return ClientDeleteManifestResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return ClientDeleteManifestResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusAccepted, http.StatusNotFound) { + err = runtime.NewResponseError(httpResp) + return ClientDeleteManifestResponse{}, err + } + return ClientDeleteManifestResponse{}, nil +} + +// deleteManifestCreateRequest creates the DeleteManifest request. +func (client *Client) deleteManifestCreateRequest(ctx context.Context, name string, digest string, options *ClientDeleteManifestOptions) (*policy.Request, error) { + urlPath := "/v2/{name}/manifests/{reference}" + if name == "" { + return nil, errors.New("parameter name cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{name}", url.PathEscape(name)) + if digest == "" { + return nil, errors.New("parameter digest cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{reference}", url.PathEscape(digest)) + req, err := runtime.NewRequest(ctx, http.MethodDelete, runtime.JoinPaths(client.endpoint, urlPath)) + if err != nil { + return nil, err + } + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// DeleteRepository - Delete the repository identified by name +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-07-01 +// - name - Name of the image (including the namespace) +// - options - ClientDeleteRepositoryOptions contains the optional parameters for the Client.DeleteRepository method. +func (client *Client) DeleteRepository(ctx context.Context, name string, options *ClientDeleteRepositoryOptions) (ClientDeleteRepositoryResponse, error) { + var err error + ctx, endSpan := runtime.StartSpan(ctx, "Client.DeleteRepository", client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.deleteRepositoryCreateRequest(ctx, name, options) + if err != nil { + return ClientDeleteRepositoryResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return ClientDeleteRepositoryResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusAccepted, http.StatusNotFound) { + err = runtime.NewResponseError(httpResp) + return ClientDeleteRepositoryResponse{}, err + } + return ClientDeleteRepositoryResponse{}, nil +} + +// deleteRepositoryCreateRequest creates the DeleteRepository request. +func (client *Client) deleteRepositoryCreateRequest(ctx context.Context, name string, options *ClientDeleteRepositoryOptions) (*policy.Request, error) { + urlPath := "/acr/v1/{name}" + if name == "" { + return nil, errors.New("parameter name cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{name}", url.PathEscape(name)) + req, err := runtime.NewRequest(ctx, http.MethodDelete, runtime.JoinPaths(client.endpoint, urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-07-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// DeleteTag - Delete tag +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-07-01 +// - name - Name of the image (including the namespace) +// - tag - Tag name +// - options - ClientDeleteTagOptions contains the optional parameters for the Client.DeleteTag method. +func (client *Client) DeleteTag(ctx context.Context, name string, tag string, options *ClientDeleteTagOptions) (ClientDeleteTagResponse, error) { + var err error + ctx, endSpan := runtime.StartSpan(ctx, "Client.DeleteTag", client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.deleteTagCreateRequest(ctx, name, tag, options) + if err != nil { + return ClientDeleteTagResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return ClientDeleteTagResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusAccepted, http.StatusNotFound) { + err = runtime.NewResponseError(httpResp) + return ClientDeleteTagResponse{}, err + } + return ClientDeleteTagResponse{}, nil +} + +// deleteTagCreateRequest creates the DeleteTag request. +func (client *Client) deleteTagCreateRequest(ctx context.Context, name string, tag string, options *ClientDeleteTagOptions) (*policy.Request, error) { + urlPath := "/acr/v1/{name}/_tags/{reference}" + if name == "" { + return nil, errors.New("parameter name cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{name}", url.PathEscape(name)) + if tag == "" { + return nil, errors.New("parameter tag cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{reference}", url.PathEscape(tag)) + req, err := runtime.NewRequest(ctx, http.MethodDelete, runtime.JoinPaths(client.endpoint, urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-07-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// GetManifest - Get the manifest identified by name and reference where reference can be a tag or digest. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-07-01 +// - name - Name of the image (including the namespace) +// - reference - A tag or a digest, pointing to a specific image +// - options - ClientGetManifestOptions contains the optional parameters for the Client.GetManifest method. +func (client *Client) GetManifest(ctx context.Context, name string, reference string, options *ClientGetManifestOptions) (ClientGetManifestResponse, error) { + var err error + ctx, endSpan := runtime.StartSpan(ctx, "Client.GetManifest", client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.getManifestCreateRequest(ctx, name, reference, options) + if err != nil { + return ClientGetManifestResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return ClientGetManifestResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return ClientGetManifestResponse{}, err + } + resp, err := client.getManifestHandleResponse(httpResp) + return resp, err +} + +// getManifestCreateRequest creates the GetManifest request. +func (client *Client) getManifestCreateRequest(ctx context.Context, name string, reference string, options *ClientGetManifestOptions) (*policy.Request, error) { + urlPath := "/v2/{name}/manifests/{reference}" + if name == "" { + return nil, errors.New("parameter name cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{name}", url.PathEscape(name)) + if reference == "" { + return nil, errors.New("parameter reference cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{reference}", url.PathEscape(reference)) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.endpoint, urlPath)) + if err != nil { + return nil, err + } + runtime.SkipBodyDownload(req) + if options != nil && options.Accept != nil { + req.Raw().Header["accept"] = []string{*options.Accept} + } + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getManifestHandleResponse handles the GetManifest response. +func (client *Client) getManifestHandleResponse(resp *http.Response) (ClientGetManifestResponse, error) { + result := ClientGetManifestResponse{ManifestData: resp.Body} + if val := resp.Header.Get("Docker-Content-Digest"); val != "" { + result.DockerContentDigest = &val + } + return result, nil +} + +// GetManifestProperties - Get manifest attributes +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-07-01 +// - name - Name of the image (including the namespace) +// - digest - Digest of a BLOB +// - options - ClientGetManifestPropertiesOptions contains the optional parameters for the Client.GetManifestProperties method. +func (client *Client) GetManifestProperties(ctx context.Context, name string, digest string, options *ClientGetManifestPropertiesOptions) (ClientGetManifestPropertiesResponse, error) { + var err error + ctx, endSpan := runtime.StartSpan(ctx, "Client.GetManifestProperties", client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.getManifestPropertiesCreateRequest(ctx, name, digest, options) + if err != nil { + return ClientGetManifestPropertiesResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return ClientGetManifestPropertiesResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return ClientGetManifestPropertiesResponse{}, err + } + resp, err := client.getManifestPropertiesHandleResponse(httpResp) + return resp, err +} + +// getManifestPropertiesCreateRequest creates the GetManifestProperties request. +func (client *Client) getManifestPropertiesCreateRequest(ctx context.Context, name string, digest string, options *ClientGetManifestPropertiesOptions) (*policy.Request, error) { + urlPath := "/acr/v1/{name}/_manifests/{digest}" + if name == "" { + return nil, errors.New("parameter name cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{name}", url.PathEscape(name)) + if digest == "" { + return nil, errors.New("parameter digest cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{digest}", url.PathEscape(digest)) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.endpoint, urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-07-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getManifestPropertiesHandleResponse handles the GetManifestProperties response. +func (client *Client) getManifestPropertiesHandleResponse(resp *http.Response) (ClientGetManifestPropertiesResponse, error) { + result := ClientGetManifestPropertiesResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.ArtifactManifestProperties); err != nil { + return ClientGetManifestPropertiesResponse{}, err + } + return result, nil +} + +// GetRepositoryProperties - Get repository attributes +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-07-01 +// - name - Name of the image (including the namespace) +// - options - ClientGetRepositoryPropertiesOptions contains the optional parameters for the Client.GetRepositoryProperties +// method. +func (client *Client) GetRepositoryProperties(ctx context.Context, name string, options *ClientGetRepositoryPropertiesOptions) (ClientGetRepositoryPropertiesResponse, error) { + var err error + ctx, endSpan := runtime.StartSpan(ctx, "Client.GetRepositoryProperties", client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.getRepositoryPropertiesCreateRequest(ctx, name, options) + if err != nil { + return ClientGetRepositoryPropertiesResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return ClientGetRepositoryPropertiesResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return ClientGetRepositoryPropertiesResponse{}, err + } + resp, err := client.getRepositoryPropertiesHandleResponse(httpResp) + return resp, err +} + +// getRepositoryPropertiesCreateRequest creates the GetRepositoryProperties request. +func (client *Client) getRepositoryPropertiesCreateRequest(ctx context.Context, name string, options *ClientGetRepositoryPropertiesOptions) (*policy.Request, error) { + urlPath := "/acr/v1/{name}" + if name == "" { + return nil, errors.New("parameter name cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{name}", url.PathEscape(name)) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.endpoint, urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-07-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getRepositoryPropertiesHandleResponse handles the GetRepositoryProperties response. +func (client *Client) getRepositoryPropertiesHandleResponse(resp *http.Response) (ClientGetRepositoryPropertiesResponse, error) { + result := ClientGetRepositoryPropertiesResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.ContainerRepositoryProperties); err != nil { + return ClientGetRepositoryPropertiesResponse{}, err + } + return result, nil +} + +// GetTagProperties - Get tag attributes by tag +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-07-01 +// - name - Name of the image (including the namespace) +// - tag - Tag name +// - options - ClientGetTagPropertiesOptions contains the optional parameters for the Client.GetTagProperties method. +func (client *Client) GetTagProperties(ctx context.Context, name string, tag string, options *ClientGetTagPropertiesOptions) (ClientGetTagPropertiesResponse, error) { + var err error + ctx, endSpan := runtime.StartSpan(ctx, "Client.GetTagProperties", client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.getTagPropertiesCreateRequest(ctx, name, tag, options) + if err != nil { + return ClientGetTagPropertiesResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return ClientGetTagPropertiesResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return ClientGetTagPropertiesResponse{}, err + } + resp, err := client.getTagPropertiesHandleResponse(httpResp) + return resp, err +} + +// getTagPropertiesCreateRequest creates the GetTagProperties request. +func (client *Client) getTagPropertiesCreateRequest(ctx context.Context, name string, tag string, options *ClientGetTagPropertiesOptions) (*policy.Request, error) { + urlPath := "/acr/v1/{name}/_tags/{reference}" + if name == "" { + return nil, errors.New("parameter name cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{name}", url.PathEscape(name)) + if tag == "" { + return nil, errors.New("parameter tag cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{reference}", url.PathEscape(tag)) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.endpoint, urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-07-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getTagPropertiesHandleResponse handles the GetTagProperties response. +func (client *Client) getTagPropertiesHandleResponse(resp *http.Response) (ClientGetTagPropertiesResponse, error) { + result := ClientGetTagPropertiesResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.ArtifactTagProperties); err != nil { + return ClientGetTagPropertiesResponse{}, err + } + return result, nil +} + +// NewListManifestsPager - List manifests of a repository +// +// Generated from API version 2021-07-01 +// - name - Name of the image (including the namespace) +// - options - ClientListManifestsOptions contains the optional parameters for the Client.NewListManifestsPager method. +func (client *Client) NewListManifestsPager(name string, options *ClientListManifestsOptions) *runtime.Pager[ClientListManifestsResponse] { + return runtime.NewPager(runtime.PagingHandler[ClientListManifestsResponse]{ + More: func(page ClientListManifestsResponse) bool { + return page.Link != nil && len(*page.Link) > 0 + }, + Fetcher: func(ctx context.Context, page *ClientListManifestsResponse) (ClientListManifestsResponse, error) { + nextLink := "" + if page != nil { + nextLink = *page.Link + } + resp, err := runtime.FetcherForNextLink(ctx, client.internal.Pipeline(), nextLink, func(ctx context.Context) (*policy.Request, error) { + return client.listManifestsCreateRequest(ctx, name, options) + }, nil) + if err != nil { + return ClientListManifestsResponse{}, err + } + return client.listManifestsHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listManifestsCreateRequest creates the ListManifests request. +func (client *Client) listManifestsCreateRequest(ctx context.Context, name string, options *ClientListManifestsOptions) (*policy.Request, error) { + urlPath := "/acr/v1/{name}/_manifests" + if name == "" { + return nil, errors.New("parameter name cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{name}", url.PathEscape(name)) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.endpoint, urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + if options != nil && options.Last != nil { + reqQP.Set("last", *options.Last) + } + if options != nil && options.MaxNum != nil { + reqQP.Set("n", strconv.FormatInt(int64(*options.MaxNum), 10)) + } + reqQP.Set("api-version", "2021-07-01") + if options != nil && options.OrderBy != nil { + reqQP.Set("orderby", string(*options.OrderBy)) + } + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listManifestsHandleResponse handles the ListManifests response. +func (client *Client) listManifestsHandleResponse(resp *http.Response) (ClientListManifestsResponse, error) { + result := ClientListManifestsResponse{} + if val := resp.Header.Get("Link"); val != "" { + val = runtime.JoinPaths(client.endpoint, extractNextLink(val)) + result.Link = &val + } + if err := runtime.UnmarshalAsJSON(resp, &result.Manifests); err != nil { + return ClientListManifestsResponse{}, err + } + return result, nil +} + +// NewListRepositoriesPager - List repositories +// +// Generated from API version 2021-07-01 +// - options - ClientListRepositoriesOptions contains the optional parameters for the Client.NewListRepositoriesPager method. +func (client *Client) NewListRepositoriesPager(options *ClientListRepositoriesOptions) *runtime.Pager[ClientListRepositoriesResponse] { + return runtime.NewPager(runtime.PagingHandler[ClientListRepositoriesResponse]{ + More: func(page ClientListRepositoriesResponse) bool { + return page.Link != nil && len(*page.Link) > 0 + }, + Fetcher: func(ctx context.Context, page *ClientListRepositoriesResponse) (ClientListRepositoriesResponse, error) { + nextLink := "" + if page != nil { + nextLink = *page.Link + } + resp, err := runtime.FetcherForNextLink(ctx, client.internal.Pipeline(), nextLink, func(ctx context.Context) (*policy.Request, error) { + return client.listRepositoriesCreateRequest(ctx, options) + }, nil) + if err != nil { + return ClientListRepositoriesResponse{}, err + } + return client.listRepositoriesHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listRepositoriesCreateRequest creates the ListRepositories request. +func (client *Client) listRepositoriesCreateRequest(ctx context.Context, options *ClientListRepositoriesOptions) (*policy.Request, error) { + urlPath := "/acr/v1/_catalog" + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.endpoint, urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + if options != nil && options.Last != nil { + reqQP.Set("last", *options.Last) + } + if options != nil && options.MaxNum != nil { + reqQP.Set("n", strconv.FormatInt(int64(*options.MaxNum), 10)) + } + reqQP.Set("api-version", "2021-07-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listRepositoriesHandleResponse handles the ListRepositories response. +func (client *Client) listRepositoriesHandleResponse(resp *http.Response) (ClientListRepositoriesResponse, error) { + result := ClientListRepositoriesResponse{} + if val := resp.Header.Get("Link"); val != "" { + val = runtime.JoinPaths(client.endpoint, extractNextLink(val)) + result.Link = &val + } + if err := runtime.UnmarshalAsJSON(resp, &result.Repositories); err != nil { + return ClientListRepositoriesResponse{}, err + } + return result, nil +} + +// NewListTagsPager - List tags of a repository +// +// Generated from API version 2021-07-01 +// - name - Name of the image (including the namespace) +// - options - ClientListTagsOptions contains the optional parameters for the Client.NewListTagsPager method. +func (client *Client) NewListTagsPager(name string, options *ClientListTagsOptions) *runtime.Pager[ClientListTagsResponse] { + return runtime.NewPager(runtime.PagingHandler[ClientListTagsResponse]{ + More: func(page ClientListTagsResponse) bool { + return page.Link != nil && len(*page.Link) > 0 + }, + Fetcher: func(ctx context.Context, page *ClientListTagsResponse) (ClientListTagsResponse, error) { + nextLink := "" + if page != nil { + nextLink = *page.Link + } + resp, err := runtime.FetcherForNextLink(ctx, client.internal.Pipeline(), nextLink, func(ctx context.Context) (*policy.Request, error) { + return client.listTagsCreateRequest(ctx, name, options) + }, nil) + if err != nil { + return ClientListTagsResponse{}, err + } + return client.listTagsHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listTagsCreateRequest creates the ListTags request. +func (client *Client) listTagsCreateRequest(ctx context.Context, name string, options *ClientListTagsOptions) (*policy.Request, error) { + urlPath := "/acr/v1/{name}/_tags" + if name == "" { + return nil, errors.New("parameter name cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{name}", url.PathEscape(name)) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.endpoint, urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + if options != nil && options.Last != nil { + reqQP.Set("last", *options.Last) + } + if options != nil && options.MaxNum != nil { + reqQP.Set("n", strconv.FormatInt(int64(*options.MaxNum), 10)) + } + if options != nil && options.Digest != nil { + reqQP.Set("digest", *options.Digest) + } + reqQP.Set("api-version", "2021-07-01") + if options != nil && options.OrderBy != nil { + reqQP.Set("orderby", string(*options.OrderBy)) + } + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listTagsHandleResponse handles the ListTags response. +func (client *Client) listTagsHandleResponse(resp *http.Response) (ClientListTagsResponse, error) { + result := ClientListTagsResponse{} + if val := resp.Header.Get("Link"); val != "" { + val = runtime.JoinPaths(client.endpoint, extractNextLink(val)) + result.Link = &val + } + if err := runtime.UnmarshalAsJSON(resp, &result.TagList); err != nil { + return ClientListTagsResponse{}, err + } + return result, nil +} + +// UpdateManifestProperties - Update properties of a manifest +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-07-01 +// - name - Name of the image (including the namespace) +// - digest - Digest of a BLOB +// - options - ClientUpdateManifestPropertiesOptions contains the optional parameters for the Client.UpdateManifestProperties +// method. +func (client *Client) UpdateManifestProperties(ctx context.Context, name string, digest string, options *ClientUpdateManifestPropertiesOptions) (ClientUpdateManifestPropertiesResponse, error) { + var err error + ctx, endSpan := runtime.StartSpan(ctx, "Client.UpdateManifestProperties", client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.updateManifestPropertiesCreateRequest(ctx, name, digest, options) + if err != nil { + return ClientUpdateManifestPropertiesResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return ClientUpdateManifestPropertiesResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return ClientUpdateManifestPropertiesResponse{}, err + } + resp, err := client.updateManifestPropertiesHandleResponse(httpResp) + return resp, err +} + +// updateManifestPropertiesCreateRequest creates the UpdateManifestProperties request. +func (client *Client) updateManifestPropertiesCreateRequest(ctx context.Context, name string, digest string, options *ClientUpdateManifestPropertiesOptions) (*policy.Request, error) { + urlPath := "/acr/v1/{name}/_manifests/{digest}" + if name == "" { + return nil, errors.New("parameter name cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{name}", url.PathEscape(name)) + if digest == "" { + return nil, errors.New("parameter digest cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{digest}", url.PathEscape(digest)) + req, err := runtime.NewRequest(ctx, http.MethodPatch, runtime.JoinPaths(client.endpoint, urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-07-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if options != nil && options.Value != nil { + if err := runtime.MarshalAsJSON(req, *options.Value); err != nil { + return nil, err + } + return req, nil + } + return req, nil +} + +// updateManifestPropertiesHandleResponse handles the UpdateManifestProperties response. +func (client *Client) updateManifestPropertiesHandleResponse(resp *http.Response) (ClientUpdateManifestPropertiesResponse, error) { + result := ClientUpdateManifestPropertiesResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.ArtifactManifestProperties); err != nil { + return ClientUpdateManifestPropertiesResponse{}, err + } + return result, nil +} + +// UpdateRepositoryProperties - Update the attribute identified by name where reference is the name of the repository. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-07-01 +// - name - Name of the image (including the namespace) +// - options - ClientUpdateRepositoryPropertiesOptions contains the optional parameters for the Client.UpdateRepositoryProperties +// method. +func (client *Client) UpdateRepositoryProperties(ctx context.Context, name string, options *ClientUpdateRepositoryPropertiesOptions) (ClientUpdateRepositoryPropertiesResponse, error) { + var err error + ctx, endSpan := runtime.StartSpan(ctx, "Client.UpdateRepositoryProperties", client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.updateRepositoryPropertiesCreateRequest(ctx, name, options) + if err != nil { + return ClientUpdateRepositoryPropertiesResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return ClientUpdateRepositoryPropertiesResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return ClientUpdateRepositoryPropertiesResponse{}, err + } + resp, err := client.updateRepositoryPropertiesHandleResponse(httpResp) + return resp, err +} + +// updateRepositoryPropertiesCreateRequest creates the UpdateRepositoryProperties request. +func (client *Client) updateRepositoryPropertiesCreateRequest(ctx context.Context, name string, options *ClientUpdateRepositoryPropertiesOptions) (*policy.Request, error) { + urlPath := "/acr/v1/{name}" + if name == "" { + return nil, errors.New("parameter name cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{name}", url.PathEscape(name)) + req, err := runtime.NewRequest(ctx, http.MethodPatch, runtime.JoinPaths(client.endpoint, urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-07-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if options != nil && options.Value != nil { + if err := runtime.MarshalAsJSON(req, *options.Value); err != nil { + return nil, err + } + return req, nil + } + return req, nil +} + +// updateRepositoryPropertiesHandleResponse handles the UpdateRepositoryProperties response. +func (client *Client) updateRepositoryPropertiesHandleResponse(resp *http.Response) (ClientUpdateRepositoryPropertiesResponse, error) { + result := ClientUpdateRepositoryPropertiesResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.ContainerRepositoryProperties); err != nil { + return ClientUpdateRepositoryPropertiesResponse{}, err + } + return result, nil +} + +// UpdateTagProperties - Update tag attributes +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-07-01 +// - name - Name of the image (including the namespace) +// - tag - Tag name +// - options - ClientUpdateTagPropertiesOptions contains the optional parameters for the Client.UpdateTagProperties method. +func (client *Client) UpdateTagProperties(ctx context.Context, name string, tag string, options *ClientUpdateTagPropertiesOptions) (ClientUpdateTagPropertiesResponse, error) { + var err error + ctx, endSpan := runtime.StartSpan(ctx, "Client.UpdateTagProperties", client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.updateTagPropertiesCreateRequest(ctx, name, tag, options) + if err != nil { + return ClientUpdateTagPropertiesResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return ClientUpdateTagPropertiesResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return ClientUpdateTagPropertiesResponse{}, err + } + resp, err := client.updateTagPropertiesHandleResponse(httpResp) + return resp, err +} + +// updateTagPropertiesCreateRequest creates the UpdateTagProperties request. +func (client *Client) updateTagPropertiesCreateRequest(ctx context.Context, name string, tag string, options *ClientUpdateTagPropertiesOptions) (*policy.Request, error) { + urlPath := "/acr/v1/{name}/_tags/{reference}" + if name == "" { + return nil, errors.New("parameter name cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{name}", url.PathEscape(name)) + if tag == "" { + return nil, errors.New("parameter tag cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{reference}", url.PathEscape(tag)) + req, err := runtime.NewRequest(ctx, http.MethodPatch, runtime.JoinPaths(client.endpoint, urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-07-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if options != nil && options.Value != nil { + if err := runtime.MarshalAsJSON(req, *options.Value); err != nil { + return nil, err + } + return req, nil + } + return req, nil +} + +// updateTagPropertiesHandleResponse handles the UpdateTagProperties response. +func (client *Client) updateTagPropertiesHandleResponse(resp *http.Response) (ClientUpdateTagPropertiesResponse, error) { + result := ClientUpdateTagPropertiesResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.ArtifactTagProperties); err != nil { + return ClientUpdateTagPropertiesResponse{}, err + } + return result, nil +} + +// UploadManifest - Put the manifest identified by name and reference where reference can be a tag or digest. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-07-01 +// - name - Name of the image (including the namespace) +// - reference - A tag or a digest, pointing to a specific image +// - contentType - Upload file type +// - manifestData - Manifest body, can take v1 or v2 values depending on accept header +// - options - ClientUploadManifestOptions contains the optional parameters for the Client.UploadManifest method. +func (client *Client) UploadManifest(ctx context.Context, name string, reference string, contentType ContentType, manifestData io.ReadSeekCloser, options *ClientUploadManifestOptions) (ClientUploadManifestResponse, error) { + var err error + ctx, endSpan := runtime.StartSpan(ctx, "Client.UploadManifest", client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.uploadManifestCreateRequest(ctx, name, reference, contentType, manifestData, options) + if err != nil { + return ClientUploadManifestResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return ClientUploadManifestResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusCreated) { + err = runtime.NewResponseError(httpResp) + return ClientUploadManifestResponse{}, err + } + resp, err := client.uploadManifestHandleResponse(httpResp) + return resp, err +} + +// uploadManifestCreateRequest creates the UploadManifest request. +func (client *Client) uploadManifestCreateRequest(ctx context.Context, name string, reference string, contentType ContentType, manifestData io.ReadSeekCloser, options *ClientUploadManifestOptions) (*policy.Request, error) { + urlPath := "/v2/{name}/manifests/{reference}" + if name == "" { + return nil, errors.New("parameter name cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{name}", url.PathEscape(name)) + if reference == "" { + return nil, errors.New("parameter reference cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{reference}", url.PathEscape(reference)) + req, err := runtime.NewRequest(ctx, http.MethodPut, runtime.JoinPaths(client.endpoint, urlPath)) + if err != nil { + return nil, err + } + req.Raw().Header["Content-Type"] = []string{string(contentType)} + req.Raw().Header["Accept"] = []string{"application/json"} + if err := req.SetBody(manifestData, string(contentType)); err != nil { + return nil, err + } + return req, nil +} + +// uploadManifestHandleResponse handles the UploadManifest response. +func (client *Client) uploadManifestHandleResponse(resp *http.Response) (ClientUploadManifestResponse, error) { + result := ClientUploadManifestResponse{} + if val := resp.Header.Get("Content-Length"); val != "" { + contentLength, err := strconv.ParseInt(val, 10, 64) + if err != nil { + return ClientUploadManifestResponse{}, err + } + result.ContentLength = &contentLength + } + if val := resp.Header.Get("Docker-Content-Digest"); val != "" { + result.DockerContentDigest = &val + } + if val := resp.Header.Get("Location"); val != "" { + result.Location = &val + } + return result, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/cloud_config.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/cloud_config.go new file mode 100644 index 0000000000..45cb65905c --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/cloud_config.go @@ -0,0 +1,30 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package azcontainerregistry + +import "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud" + +const ( + // ServiceName is the cloud service name for Azure Container Registry + ServiceName cloud.ServiceName = "azcontainerregistry" +) + +func init() { + cloud.AzureChina.Services[ServiceName] = cloud.ServiceConfiguration{ + Audience: "https://management.core.chinacloudapi.cn", + } + cloud.AzureGovernment.Services[ServiceName] = cloud.ServiceConfiguration{ + Audience: "https://management.core.usgovcloudapi.net", + } + cloud.AzurePublic.Services[ServiceName] = cloud.ServiceConfiguration{ + Audience: "https://management.core.windows.net/", + } +} + +var defaultCloud = cloud.Configuration{ + Services: map[cloud.ServiceName]cloud.ServiceConfiguration{ServiceName: {Audience: defaultAudience}}, +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/constants.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/constants.go new file mode 100644 index 0000000000..8dcf5c0b1e --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/constants.go @@ -0,0 +1,198 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// Code generated by Microsoft (R) AutoRest Code Generator. DO NOT EDIT. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package azcontainerregistry + +// ArtifactArchitecture - The artifact platform's architecture. +type ArtifactArchitecture string + +const ( + // ArtifactArchitectureAmd64 - AMD64 + ArtifactArchitectureAmd64 ArtifactArchitecture = "amd64" + // ArtifactArchitectureArm - ARM + ArtifactArchitectureArm ArtifactArchitecture = "arm" + // ArtifactArchitectureArm64 - ARM64 + ArtifactArchitectureArm64 ArtifactArchitecture = "arm64" + // ArtifactArchitectureI386 - i386 + ArtifactArchitectureI386 ArtifactArchitecture = "386" + // ArtifactArchitectureMips - MIPS + ArtifactArchitectureMips ArtifactArchitecture = "mips" + // ArtifactArchitectureMips64 - MIPS64 + ArtifactArchitectureMips64 ArtifactArchitecture = "mips64" + // ArtifactArchitectureMips64Le - MIPS64LE + ArtifactArchitectureMips64Le ArtifactArchitecture = "mips64le" + // ArtifactArchitectureMipsLe - MIPSLE + ArtifactArchitectureMipsLe ArtifactArchitecture = "mipsle" + // ArtifactArchitecturePpc64 - PPC64 + ArtifactArchitecturePpc64 ArtifactArchitecture = "ppc64" + // ArtifactArchitecturePpc64Le - PPC64LE + ArtifactArchitecturePpc64Le ArtifactArchitecture = "ppc64le" + // ArtifactArchitectureRiscV64 - RISCv64 + ArtifactArchitectureRiscV64 ArtifactArchitecture = "riscv64" + // ArtifactArchitectureS390X - s390x + ArtifactArchitectureS390X ArtifactArchitecture = "s390x" + // ArtifactArchitectureWasm - Wasm + ArtifactArchitectureWasm ArtifactArchitecture = "wasm" +) + +// PossibleArtifactArchitectureValues returns the possible values for the ArtifactArchitecture const type. +func PossibleArtifactArchitectureValues() []ArtifactArchitecture { + return []ArtifactArchitecture{ + ArtifactArchitectureAmd64, + ArtifactArchitectureArm, + ArtifactArchitectureArm64, + ArtifactArchitectureI386, + ArtifactArchitectureMips, + ArtifactArchitectureMips64, + ArtifactArchitectureMips64Le, + ArtifactArchitectureMipsLe, + ArtifactArchitecturePpc64, + ArtifactArchitecturePpc64Le, + ArtifactArchitectureRiscV64, + ArtifactArchitectureS390X, + ArtifactArchitectureWasm, + } +} + +// ArtifactManifestOrderBy - Sort options for ordering manifests in a collection. +type ArtifactManifestOrderBy string + +const ( + // ArtifactManifestOrderByLastUpdatedOnAscending - Order manifest by LastUpdatedOn field, from least recently updated to most + // recently updated. + ArtifactManifestOrderByLastUpdatedOnAscending ArtifactManifestOrderBy = "timeasc" + // ArtifactManifestOrderByLastUpdatedOnDescending - Order manifests by LastUpdatedOn field, from most recently updated to + // least recently updated. + ArtifactManifestOrderByLastUpdatedOnDescending ArtifactManifestOrderBy = "timedesc" + // ArtifactManifestOrderByNone - Do not provide an orderby value in the request. + ArtifactManifestOrderByNone ArtifactManifestOrderBy = "none" +) + +// PossibleArtifactManifestOrderByValues returns the possible values for the ArtifactManifestOrderBy const type. +func PossibleArtifactManifestOrderByValues() []ArtifactManifestOrderBy { + return []ArtifactManifestOrderBy{ + ArtifactManifestOrderByLastUpdatedOnAscending, + ArtifactManifestOrderByLastUpdatedOnDescending, + ArtifactManifestOrderByNone, + } +} + +// ArtifactOperatingSystem - The artifact platform's operating system. +type ArtifactOperatingSystem string + +const ( + ArtifactOperatingSystemAix ArtifactOperatingSystem = "aix" + ArtifactOperatingSystemAndroid ArtifactOperatingSystem = "android" + ArtifactOperatingSystemDarwin ArtifactOperatingSystem = "darwin" + ArtifactOperatingSystemDragonfly ArtifactOperatingSystem = "dragonfly" + ArtifactOperatingSystemFreeBsd ArtifactOperatingSystem = "freebsd" + ArtifactOperatingSystemIOS ArtifactOperatingSystem = "ios" + ArtifactOperatingSystemIllumos ArtifactOperatingSystem = "illumos" + ArtifactOperatingSystemJS ArtifactOperatingSystem = "js" + ArtifactOperatingSystemLinux ArtifactOperatingSystem = "linux" + ArtifactOperatingSystemNetBsd ArtifactOperatingSystem = "netbsd" + ArtifactOperatingSystemOpenBsd ArtifactOperatingSystem = "openbsd" + ArtifactOperatingSystemPlan9 ArtifactOperatingSystem = "plan9" + ArtifactOperatingSystemSolaris ArtifactOperatingSystem = "solaris" + ArtifactOperatingSystemWindows ArtifactOperatingSystem = "windows" +) + +// PossibleArtifactOperatingSystemValues returns the possible values for the ArtifactOperatingSystem const type. +func PossibleArtifactOperatingSystemValues() []ArtifactOperatingSystem { + return []ArtifactOperatingSystem{ + ArtifactOperatingSystemAix, + ArtifactOperatingSystemAndroid, + ArtifactOperatingSystemDarwin, + ArtifactOperatingSystemDragonfly, + ArtifactOperatingSystemFreeBsd, + ArtifactOperatingSystemIOS, + ArtifactOperatingSystemIllumos, + ArtifactOperatingSystemJS, + ArtifactOperatingSystemLinux, + ArtifactOperatingSystemNetBsd, + ArtifactOperatingSystemOpenBsd, + ArtifactOperatingSystemPlan9, + ArtifactOperatingSystemSolaris, + ArtifactOperatingSystemWindows, + } +} + +// ArtifactTagOrderBy - Sort options for ordering tags in a collection. +type ArtifactTagOrderBy string + +const ( + // ArtifactTagOrderByLastUpdatedOnAscending - Order tags by LastUpdatedOn field, from least recently updated to most recently + // updated. + ArtifactTagOrderByLastUpdatedOnAscending ArtifactTagOrderBy = "timeasc" + // ArtifactTagOrderByLastUpdatedOnDescending - Order tags by LastUpdatedOn field, from most recently updated to least recently + // updated. + ArtifactTagOrderByLastUpdatedOnDescending ArtifactTagOrderBy = "timedesc" + // ArtifactTagOrderByNone - Do not provide an orderby value in the request. + ArtifactTagOrderByNone ArtifactTagOrderBy = "none" +) + +// PossibleArtifactTagOrderByValues returns the possible values for the ArtifactTagOrderBy const type. +func PossibleArtifactTagOrderByValues() []ArtifactTagOrderBy { + return []ArtifactTagOrderBy{ + ArtifactTagOrderByLastUpdatedOnAscending, + ArtifactTagOrderByLastUpdatedOnDescending, + ArtifactTagOrderByNone, + } +} + +// ContentType - Content type for upload +type ContentType string + +const ( + // ContentTypeApplicationVndDockerDistributionManifestV2JSON - Content Type 'application/vnd.docker.distribution.manifest.v2+json' + ContentTypeApplicationVndDockerDistributionManifestV2JSON ContentType = "application/vnd.docker.distribution.manifest.v2+json" + // ContentTypeApplicationVndOciImageManifestV1JSON - Content Type 'application/vnd.oci.image.manifest.v1+json' + ContentTypeApplicationVndOciImageManifestV1JSON ContentType = "application/vnd.oci.image.manifest.v1+json" +) + +// PossibleContentTypeValues returns the possible values for the ContentType const type. +func PossibleContentTypeValues() []ContentType { + return []ContentType{ + ContentTypeApplicationVndDockerDistributionManifestV2JSON, + ContentTypeApplicationVndOciImageManifestV1JSON, + } +} + +// postContentSchemaGrantType - Can take a value of accesstokenrefreshtoken, or accesstoken, or refresh_token +type postContentSchemaGrantType string + +const ( + postContentSchemaGrantTypeAccessToken postContentSchemaGrantType = "access_token" + postContentSchemaGrantTypeAccessTokenRefreshToken postContentSchemaGrantType = "access_token_refresh_token" + postContentSchemaGrantTypeRefreshToken postContentSchemaGrantType = "refresh_token" +) + +// possiblePostContentSchemaGrantTypeValues returns the possible values for the postContentSchemaGrantType const type. +func possiblePostContentSchemaGrantTypeValues() []postContentSchemaGrantType { + return []postContentSchemaGrantType{ + postContentSchemaGrantTypeAccessToken, + postContentSchemaGrantTypeAccessTokenRefreshToken, + postContentSchemaGrantTypeRefreshToken, + } +} + +// tokenGrantType - Grant type is expected to be refresh_token +type tokenGrantType string + +const ( + tokenGrantTypePassword tokenGrantType = "password" + tokenGrantTypeRefreshToken tokenGrantType = "refresh_token" +) + +// possibleTokenGrantTypeValues returns the possible values for the tokenGrantType const type. +func possibleTokenGrantTypeValues() []tokenGrantType { + return []tokenGrantType{ + tokenGrantTypePassword, + tokenGrantTypeRefreshToken, + } +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/custom_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/custom_client.go new file mode 100644 index 0000000000..ed9fdbad42 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/custom_client.go @@ -0,0 +1,67 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package azcontainerregistry + +import ( + "errors" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "reflect" + "strings" +) + +// ClientOptions contains the optional parameters for the NewClient method. +type ClientOptions struct { + azcore.ClientOptions +} + +// NewClient creates a new instance of Client with the specified values. +// - endpoint - registry login URL +// - credential - used to authorize requests. Usually a credential from azidentity. +// - options - client options, pass nil to accept the default values. +func NewClient(endpoint string, credential azcore.TokenCredential, options *ClientOptions) (*Client, error) { + if options == nil { + options = &ClientOptions{} + } + + if reflect.ValueOf(options.Cloud).IsZero() { + options.Cloud = defaultCloud + } + c, ok := options.Cloud.Services[ServiceName] + if !ok || c.Audience == "" { + return nil, errors.New("provided Cloud field is missing Azure Container Registry configuration") + } + + authClient, err := newAuthenticationClient(endpoint, &authenticationClientOptions{ + options.ClientOptions, + }) + if err != nil { + return nil, err + } + + authPolicy := newAuthenticationPolicy( + credential, + []string{c.Audience + "/.default"}, + authClient, + nil, + ) + + azcoreClient, err := azcore.NewClient(moduleName, moduleVersion, runtime.PipelineOptions{PerRetry: []policy.Policy{authPolicy}}, &options.ClientOptions) + if err != nil { + return nil, err + } + + return &Client{ + azcoreClient, + endpoint, + }, nil +} + +func extractNextLink(value string) string { + return value[1:strings.Index(value, ">")] +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/custom_constants.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/custom_constants.go new file mode 100644 index 0000000000..43d030b4c1 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/custom_constants.go @@ -0,0 +1,13 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package azcontainerregistry + +const ( + moduleName = "github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry" + moduleVersion = "v0.2.1" + defaultAudience = "https://containerregistry.azure.net" +) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/digest_helper.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/digest_helper.go new file mode 100644 index 0000000000..b7ff1bf986 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/digest_helper.go @@ -0,0 +1,163 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package azcontainerregistry + +import ( + "crypto/sha256" + "encoding" + "errors" + "fmt" + "hash" + "io" + "strings" +) + +var ( + validatorCtors = map[string]func() digestValidator{"sha256": newSha256Validator} + ErrMismatchedHash = errors.New("mismatched hash") + ErrDigestAlgNotSupported = errors.New("digest algorithm not supported") +) + +type digestValidator interface { + io.Writer + validate(digest string) error +} + +func parseDigestValidator(digest string) (digestValidator, error) { + i := strings.Index(digest, ":") + if i < 0 { + return nil, ErrDigestAlgNotSupported + } + alg := digest[:i] + if v, ok := validatorCtors[alg]; ok { + return v(), nil + } + return nil, ErrDigestAlgNotSupported +} + +type sha256Validator struct { + hash.Hash +} + +func newSha256Validator() digestValidator { + return &sha256Validator{sha256.New()} +} + +func (s *sha256Validator) validate(digest string) error { + if fmt.Sprintf("sha256:%x", s.Sum(nil)) != digest { + return ErrMismatchedHash + } + return nil +} + +// DigestValidationReader help to validate digest when fetching manifest or blob. +// Don't use this type directly, use NewDigestValidationReader() instead. +type DigestValidationReader struct { + digest string + digestValidator digestValidator + reader io.Reader +} + +// NewDigestValidationReader creates a new reader that help you to validate digest when you read manifest or blob data. +func NewDigestValidationReader(digest string, reader io.Reader) (*DigestValidationReader, error) { + validator, err := parseDigestValidator(digest) + if err != nil { + return nil, err + } + return &DigestValidationReader{ + digest: digest, + digestValidator: validator, + reader: reader, + }, nil +} + +// Read write to digest validator while read and validate digest when reach EOF. +func (d *DigestValidationReader) Read(p []byte) (int, error) { + n, err := d.reader.Read(p) + if err == nil || err == io.EOF { + wn, werr := d.digestValidator.Write(p[:n]) + if werr != nil { + return wn, werr + } + } + if err == io.EOF { + if err := d.digestValidator.validate(d.digest); err != nil { + return n, err + } + } + return n, err +} + +// BlobDigestCalculator help to calculate blob digest when uploading blob. +// Don't use this type directly, use NewBlobDigestCalculator() instead. +type BlobDigestCalculator struct { + h hash.Hash + state []byte +} + +// NewBlobDigestCalculator creates a new calculator to help to calculate blob digest when uploading blob. +// You should use a new BlobDigestCalculator each time you upload a blob. +func NewBlobDigestCalculator() *BlobDigestCalculator { + return &BlobDigestCalculator{ + h: sha256.New(), + } +} + +func (b *BlobDigestCalculator) saveState() { + b.state, _ = b.h.(encoding.BinaryMarshaler).MarshalBinary() +} + +func (b *BlobDigestCalculator) restoreState() { + if b.state == nil { + return + } + _ = b.h.(encoding.BinaryUnmarshaler).UnmarshalBinary(b.state) +} + +func (b *BlobDigestCalculator) getDigest() string { + return fmt.Sprintf("sha256:%x", b.h.Sum(nil)) +} + +func (b *BlobDigestCalculator) wrapReader(reader io.ReadSeeker) (io.Reader, error) { + size, err := reader.Seek(0, io.SeekEnd) // Seek to the end to get the stream's size + if err != nil { + return nil, err + } + _, err = reader.Seek(0, io.SeekStart) + if err != nil { + return nil, err + } + return newLimitTeeReader(reader, b.h, size), nil +} + +type wrappedReadSeeker struct { + io.Reader + io.Seeker +} + +// newLimitTeeReader returns a Reader that writes to w what it reads from r with n bytes limit. +func newLimitTeeReader(r io.Reader, w io.Writer, n int64) io.Reader { + return &limitTeeReader{r, w, n} +} + +type limitTeeReader struct { + r io.Reader + w io.Writer + n int64 +} + +func (lt *limitTeeReader) Read(p []byte) (int, error) { + n, err := lt.r.Read(p) + if n > 0 && lt.n > 0 { + wn, werr := lt.w.Write(p[:n]) + if werr != nil { + return wn, werr + } + lt.n -= int64(wn) + } + return n, err +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/models.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/models.go new file mode 100644 index 0000000000..cb37a1fe16 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/models.go @@ -0,0 +1,215 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// Code generated by Microsoft (R) AutoRest Code Generator. DO NOT EDIT. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package azcontainerregistry + +import "time" + +type acrAccessToken struct { + // The access token for performing authenticated requests + AccessToken *string +} + +type acrRefreshToken struct { + // The refresh token to be used for generating access tokens + RefreshToken *string +} + +// ArtifactManifestPlatform - The artifact's platform, consisting of operating system and architecture. +type ArtifactManifestPlatform struct { + // READ-ONLY; Manifest digest + Digest *string + + // READ-ONLY; CPU architecture + Architecture *ArtifactArchitecture + + // READ-ONLY; Operating system + OperatingSystem *ArtifactOperatingSystem +} + +// ArtifactManifestProperties - Manifest attributes details +type ArtifactManifestProperties struct { + // READ-ONLY; Manifest attributes + Manifest *ManifestAttributes + + // READ-ONLY; Registry login server name. This is likely to be similar to {registry-name}.azurecr.io. + RegistryLoginServer *string + + // READ-ONLY; Repository name + RepositoryName *string +} + +// ArtifactTagProperties - Tag attributes +type ArtifactTagProperties struct { + // READ-ONLY; Registry login server name. This is likely to be similar to {registry-name}.azurecr.io. + RegistryLoginServer *string + + // READ-ONLY; Image name + RepositoryName *string + + // READ-ONLY; List of tag attribute details + Tag *TagAttributes +} + +// ContainerRepositoryProperties - Properties of this repository. +type ContainerRepositoryProperties struct { + // REQUIRED; Writeable properties of the resource + ChangeableAttributes *RepositoryWriteableProperties + + // READ-ONLY; Image created time + CreatedOn *time.Time + + // READ-ONLY; Image last update time + LastUpdatedOn *time.Time + + // READ-ONLY; Number of the manifests + ManifestCount *int32 + + // READ-ONLY; Image name + Name *string + + // READ-ONLY; Registry login server name. This is likely to be similar to {registry-name}.azurecr.io. + RegistryLoginServer *string + + // READ-ONLY; Number of the tags + TagCount *int32 +} + +// ManifestAttributes - Manifest details +type ManifestAttributes struct { + // READ-ONLY; Created time + CreatedOn *time.Time + + // READ-ONLY; Manifest + Digest *string + + // READ-ONLY; Last update time + LastUpdatedOn *time.Time + + // Writeable properties of the resource + ChangeableAttributes *ManifestWriteableProperties + + // Config blob media type + ConfigMediaType *string + + // Media type for this Manifest + MediaType *string + + // READ-ONLY; CPU architecture + Architecture *ArtifactArchitecture + + // READ-ONLY; Operating system + OperatingSystem *ArtifactOperatingSystem + + // READ-ONLY; List of artifacts that are referenced by this manifest list, with information about the platform each supports. + // This list will be empty if this is a leaf manifest and not a manifest list. + RelatedArtifacts []*ArtifactManifestPlatform + + // READ-ONLY; Image size + Size *int64 + + // READ-ONLY; List of tags + Tags []*string +} + +// ManifestWriteableProperties - Changeable attributes +type ManifestWriteableProperties struct { + // Delete enabled + CanDelete *bool + + // List enabled + CanList *bool + + // Read enabled + CanRead *bool + + // Write enabled + CanWrite *bool +} + +// Manifests - Manifest attributes +type Manifests struct { + // List of manifests + Attributes []*ManifestAttributes + Link *string + + // Registry login server name. This is likely to be similar to {registry-name}.azurecr.io. + RegistryLoginServer *string + + // Image name + Repository *string +} + +// Repositories - List of repositories +type Repositories struct { + Link *string + + // Repository names + Names []*string +} + +// RepositoryWriteableProperties - Changeable attributes for Repository +type RepositoryWriteableProperties struct { + // Delete enabled + CanDelete *bool + + // List enabled + CanList *bool + + // Read enabled + CanRead *bool + + // Write enabled + CanWrite *bool +} + +// TagAttributes - Tag attribute details +type TagAttributes struct { + // REQUIRED; Writeable properties of the resource + ChangeableAttributes *TagWriteableProperties + + // READ-ONLY; Tag created time + CreatedOn *time.Time + + // READ-ONLY; Tag digest + Digest *string + + // READ-ONLY; Tag last update time + LastUpdatedOn *time.Time + + // READ-ONLY; Tag name + Name *string +} + +// TagList - List of tag details +type TagList struct { + // REQUIRED; Registry login server name. This is likely to be similar to {registry-name}.azurecr.io. + RegistryLoginServer *string + + // REQUIRED; Image name + Repository *string + + // REQUIRED; List of tag attribute details + Tags []*TagAttributes + Link *string +} + +// TagWriteableProperties - Changeable attributes +type TagWriteableProperties struct { + // Delete enabled + CanDelete *bool + + // List enabled + CanList *bool + + // Read enabled + CanRead *bool + + // Write enabled + CanWrite *bool +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/models_serde.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/models_serde.go new file mode 100644 index 0000000000..0a3ab4bc99 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/models_serde.go @@ -0,0 +1,472 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// Code generated by Microsoft (R) AutoRest Code Generator. DO NOT EDIT. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package azcontainerregistry + +import ( + "encoding/json" + "fmt" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "reflect" +) + +// UnmarshalJSON implements the json.Unmarshaller interface for type acrAccessToken. +func (a *acrAccessToken) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "access_token": + err = unpopulate(val, "AccessToken", &a.AccessToken) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + } + return nil +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type acrRefreshToken. +func (a *acrRefreshToken) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "refresh_token": + err = unpopulate(val, "RefreshToken", &a.RefreshToken) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + } + return nil +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ArtifactManifestPlatform. +func (a *ArtifactManifestPlatform) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "architecture": + err = unpopulate(val, "Architecture", &a.Architecture) + delete(rawMsg, key) + case "digest": + err = unpopulate(val, "Digest", &a.Digest) + delete(rawMsg, key) + case "os": + err = unpopulate(val, "OperatingSystem", &a.OperatingSystem) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + } + return nil +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ArtifactManifestProperties. +func (a *ArtifactManifestProperties) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "manifest": + err = unpopulate(val, "Manifest", &a.Manifest) + delete(rawMsg, key) + case "registry": + err = unpopulate(val, "RegistryLoginServer", &a.RegistryLoginServer) + delete(rawMsg, key) + case "imageName": + err = unpopulate(val, "RepositoryName", &a.RepositoryName) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + } + return nil +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ArtifactTagProperties. +func (a *ArtifactTagProperties) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "registry": + err = unpopulate(val, "RegistryLoginServer", &a.RegistryLoginServer) + delete(rawMsg, key) + case "imageName": + err = unpopulate(val, "RepositoryName", &a.RepositoryName) + delete(rawMsg, key) + case "tag": + err = unpopulate(val, "Tag", &a.Tag) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + } + return nil +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ContainerRepositoryProperties. +func (c *ContainerRepositoryProperties) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", c, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "changeableAttributes": + err = unpopulate(val, "ChangeableAttributes", &c.ChangeableAttributes) + delete(rawMsg, key) + case "createdTime": + err = unpopulateDateTimeRFC3339(val, "CreatedOn", &c.CreatedOn) + delete(rawMsg, key) + case "lastUpdateTime": + err = unpopulateDateTimeRFC3339(val, "LastUpdatedOn", &c.LastUpdatedOn) + delete(rawMsg, key) + case "manifestCount": + err = unpopulate(val, "ManifestCount", &c.ManifestCount) + delete(rawMsg, key) + case "imageName": + err = unpopulate(val, "Name", &c.Name) + delete(rawMsg, key) + case "registry": + err = unpopulate(val, "RegistryLoginServer", &c.RegistryLoginServer) + delete(rawMsg, key) + case "tagCount": + err = unpopulate(val, "TagCount", &c.TagCount) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", c, err) + } + } + return nil +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ManifestAttributes. +func (m *ManifestAttributes) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", m, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "architecture": + err = unpopulate(val, "Architecture", &m.Architecture) + delete(rawMsg, key) + case "changeableAttributes": + err = unpopulate(val, "ChangeableAttributes", &m.ChangeableAttributes) + delete(rawMsg, key) + case "configMediaType": + err = unpopulate(val, "ConfigMediaType", &m.ConfigMediaType) + delete(rawMsg, key) + case "createdTime": + err = unpopulateDateTimeRFC3339(val, "CreatedOn", &m.CreatedOn) + delete(rawMsg, key) + case "digest": + err = unpopulate(val, "Digest", &m.Digest) + delete(rawMsg, key) + case "lastUpdateTime": + err = unpopulateDateTimeRFC3339(val, "LastUpdatedOn", &m.LastUpdatedOn) + delete(rawMsg, key) + case "mediaType": + err = unpopulate(val, "MediaType", &m.MediaType) + delete(rawMsg, key) + case "os": + err = unpopulate(val, "OperatingSystem", &m.OperatingSystem) + delete(rawMsg, key) + case "references": + err = unpopulate(val, "RelatedArtifacts", &m.RelatedArtifacts) + delete(rawMsg, key) + case "imageSize": + err = unpopulate(val, "Size", &m.Size) + delete(rawMsg, key) + case "tags": + err = unpopulate(val, "Tags", &m.Tags) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", m, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ManifestWriteableProperties. +func (m ManifestWriteableProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "deleteEnabled", m.CanDelete) + populate(objectMap, "listEnabled", m.CanList) + populate(objectMap, "readEnabled", m.CanRead) + populate(objectMap, "writeEnabled", m.CanWrite) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ManifestWriteableProperties. +func (m *ManifestWriteableProperties) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", m, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "deleteEnabled": + err = unpopulate(val, "CanDelete", &m.CanDelete) + delete(rawMsg, key) + case "listEnabled": + err = unpopulate(val, "CanList", &m.CanList) + delete(rawMsg, key) + case "readEnabled": + err = unpopulate(val, "CanRead", &m.CanRead) + delete(rawMsg, key) + case "writeEnabled": + err = unpopulate(val, "CanWrite", &m.CanWrite) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", m, err) + } + } + return nil +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type Manifests. +func (m *Manifests) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", m, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "manifests": + err = unpopulate(val, "Attributes", &m.Attributes) + delete(rawMsg, key) + case "link": + err = unpopulate(val, "Link", &m.Link) + delete(rawMsg, key) + case "registry": + err = unpopulate(val, "RegistryLoginServer", &m.RegistryLoginServer) + delete(rawMsg, key) + case "imageName": + err = unpopulate(val, "Repository", &m.Repository) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", m, err) + } + } + return nil +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type Repositories. +func (r *Repositories) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "link": + err = unpopulate(val, "Link", &r.Link) + delete(rawMsg, key) + case "repositories": + err = unpopulate(val, "Names", &r.Names) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RepositoryWriteableProperties. +func (r RepositoryWriteableProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "deleteEnabled", r.CanDelete) + populate(objectMap, "listEnabled", r.CanList) + populate(objectMap, "readEnabled", r.CanRead) + populate(objectMap, "writeEnabled", r.CanWrite) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RepositoryWriteableProperties. +func (r *RepositoryWriteableProperties) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "deleteEnabled": + err = unpopulate(val, "CanDelete", &r.CanDelete) + delete(rawMsg, key) + case "listEnabled": + err = unpopulate(val, "CanList", &r.CanList) + delete(rawMsg, key) + case "readEnabled": + err = unpopulate(val, "CanRead", &r.CanRead) + delete(rawMsg, key) + case "writeEnabled": + err = unpopulate(val, "CanWrite", &r.CanWrite) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type TagAttributes. +func (t *TagAttributes) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", t, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "changeableAttributes": + err = unpopulate(val, "ChangeableAttributes", &t.ChangeableAttributes) + delete(rawMsg, key) + case "createdTime": + err = unpopulateDateTimeRFC3339(val, "CreatedOn", &t.CreatedOn) + delete(rawMsg, key) + case "digest": + err = unpopulate(val, "Digest", &t.Digest) + delete(rawMsg, key) + case "lastUpdateTime": + err = unpopulateDateTimeRFC3339(val, "LastUpdatedOn", &t.LastUpdatedOn) + delete(rawMsg, key) + case "name": + err = unpopulate(val, "Name", &t.Name) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", t, err) + } + } + return nil +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type TagList. +func (t *TagList) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", t, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "link": + err = unpopulate(val, "Link", &t.Link) + delete(rawMsg, key) + case "registry": + err = unpopulate(val, "RegistryLoginServer", &t.RegistryLoginServer) + delete(rawMsg, key) + case "imageName": + err = unpopulate(val, "Repository", &t.Repository) + delete(rawMsg, key) + case "tags": + err = unpopulate(val, "Tags", &t.Tags) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", t, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type TagWriteableProperties. +func (t TagWriteableProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "deleteEnabled", t.CanDelete) + populate(objectMap, "listEnabled", t.CanList) + populate(objectMap, "readEnabled", t.CanRead) + populate(objectMap, "writeEnabled", t.CanWrite) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type TagWriteableProperties. +func (t *TagWriteableProperties) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", t, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "deleteEnabled": + err = unpopulate(val, "CanDelete", &t.CanDelete) + delete(rawMsg, key) + case "listEnabled": + err = unpopulate(val, "CanList", &t.CanList) + delete(rawMsg, key) + case "readEnabled": + err = unpopulate(val, "CanRead", &t.CanRead) + delete(rawMsg, key) + case "writeEnabled": + err = unpopulate(val, "CanWrite", &t.CanWrite) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", t, err) + } + } + return nil +} + +func populate(m map[string]any, k string, v any) { + if v == nil { + return + } else if azcore.IsNullValue(v) { + m[k] = nil + } else if !reflect.ValueOf(v).IsNil() { + m[k] = v + } +} + +func unpopulate(data json.RawMessage, fn string, v any) error { + if data == nil { + return nil + } + if err := json.Unmarshal(data, v); err != nil { + return fmt.Errorf("struct field %s: %v", fn, err) + } + return nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/options.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/options.go new file mode 100644 index 0000000000..f1a7ebc2dc --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/options.go @@ -0,0 +1,182 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// Code generated by Microsoft (R) AutoRest Code Generator. DO NOT EDIT. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package azcontainerregistry + +// authenticationClientExchangeAADAccessTokenForACRRefreshTokenOptions contains the optional parameters for the authenticationClient.ExchangeAADAccessTokenForACRRefreshToken +// method. +type authenticationClientExchangeAADAccessTokenForACRRefreshTokenOptions struct { + // AAD access token, mandatory when granttype is accesstokenrefreshtoken or access_token. + AccessToken *string + + // AAD refresh token, mandatory when granttype is accesstokenrefreshtoken or refresh_token + RefreshToken *string + + // AAD tenant associated to the AAD credentials. + Tenant *string +} + +// authenticationClientExchangeACRRefreshTokenForACRAccessTokenOptions contains the optional parameters for the authenticationClient.ExchangeACRRefreshTokenForACRAccessToken +// method. +type authenticationClientExchangeACRRefreshTokenForACRAccessTokenOptions struct { + // Grant type is expected to be refresh_token + GrantType *tokenGrantType +} + +// BlobClientCancelUploadOptions contains the optional parameters for the BlobClient.CancelUpload method. +type BlobClientCancelUploadOptions struct { + // placeholder for future optional parameters +} + +// BlobClientCheckBlobExistsOptions contains the optional parameters for the BlobClient.CheckBlobExists method. +type BlobClientCheckBlobExistsOptions struct { + // placeholder for future optional parameters +} + +// BlobClientCheckChunkExistsOptions contains the optional parameters for the BlobClient.CheckChunkExists method. +type BlobClientCheckChunkExistsOptions struct { + // placeholder for future optional parameters +} + +// BlobClientCompleteUploadOptions contains the optional parameters for the BlobClient.CompleteUpload method. +type BlobClientCompleteUploadOptions struct { + // placeholder for future optional parameters +} + +// BlobClientDeleteBlobOptions contains the optional parameters for the BlobClient.DeleteBlob method. +type BlobClientDeleteBlobOptions struct { + // placeholder for future optional parameters +} + +// BlobClientGetBlobOptions contains the optional parameters for the BlobClient.GetBlob method. +type BlobClientGetBlobOptions struct { + // placeholder for future optional parameters +} + +// BlobClientGetChunkOptions contains the optional parameters for the BlobClient.GetChunk method. +type BlobClientGetChunkOptions struct { + // placeholder for future optional parameters +} + +// BlobClientGetUploadStatusOptions contains the optional parameters for the BlobClient.GetUploadStatus method. +type BlobClientGetUploadStatusOptions struct { + // placeholder for future optional parameters +} + +// BlobClientMountBlobOptions contains the optional parameters for the BlobClient.MountBlob method. +type BlobClientMountBlobOptions struct { + // placeholder for future optional parameters +} + +// BlobClientStartUploadOptions contains the optional parameters for the BlobClient.StartUpload method. +type BlobClientStartUploadOptions struct { + // placeholder for future optional parameters +} + +// blobClientUploadChunkOptions contains the optional parameters for the BlobClient.uploadChunk method. +type blobClientUploadChunkOptions struct { + // Range of bytes identifying the desired block of content represented by the body. Start must the end offset retrieved via + // status check plus one. Note that this is a non-standard use of the + // Content-Range header. + ContentRange *string +} + +// ClientDeleteManifestOptions contains the optional parameters for the Client.DeleteManifest method. +type ClientDeleteManifestOptions struct { + // placeholder for future optional parameters +} + +// ClientDeleteRepositoryOptions contains the optional parameters for the Client.DeleteRepository method. +type ClientDeleteRepositoryOptions struct { + // placeholder for future optional parameters +} + +// ClientDeleteTagOptions contains the optional parameters for the Client.DeleteTag method. +type ClientDeleteTagOptions struct { + // placeholder for future optional parameters +} + +// ClientGetManifestOptions contains the optional parameters for the Client.GetManifest method. +type ClientGetManifestOptions struct { + // Accept header string delimited by comma. For example, application/vnd.docker.distribution.manifest.v2+json + Accept *string +} + +// ClientGetManifestPropertiesOptions contains the optional parameters for the Client.GetManifestProperties method. +type ClientGetManifestPropertiesOptions struct { + // placeholder for future optional parameters +} + +// ClientGetRepositoryPropertiesOptions contains the optional parameters for the Client.GetRepositoryProperties method. +type ClientGetRepositoryPropertiesOptions struct { + // placeholder for future optional parameters +} + +// ClientGetTagPropertiesOptions contains the optional parameters for the Client.GetTagProperties method. +type ClientGetTagPropertiesOptions struct { + // placeholder for future optional parameters +} + +// ClientListManifestsOptions contains the optional parameters for the Client.NewListManifestsPager method. +type ClientListManifestsOptions struct { + // 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 + MaxNum *int32 + + // Sort options for ordering manifests in a collection. + OrderBy *ArtifactManifestOrderBy +} + +// ClientListRepositoriesOptions contains the optional parameters for the Client.NewListRepositoriesPager method. +type ClientListRepositoriesOptions struct { + // 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 + MaxNum *int32 +} + +// ClientListTagsOptions contains the optional parameters for the Client.NewListTagsPager method. +type ClientListTagsOptions struct { + // filter by digest + Digest *string + + // 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 + MaxNum *int32 + + // Sort options for ordering tags in a collection. + OrderBy *ArtifactTagOrderBy +} + +// ClientUpdateManifestPropertiesOptions contains the optional parameters for the Client.UpdateManifestProperties method. +type ClientUpdateManifestPropertiesOptions struct { + // Manifest attribute value + Value *ManifestWriteableProperties +} + +// ClientUpdateRepositoryPropertiesOptions contains the optional parameters for the Client.UpdateRepositoryProperties method. +type ClientUpdateRepositoryPropertiesOptions struct { + // Repository attribute value + Value *RepositoryWriteableProperties +} + +// ClientUpdateTagPropertiesOptions contains the optional parameters for the Client.UpdateTagProperties method. +type ClientUpdateTagPropertiesOptions struct { + // Tag attribute value + Value *TagWriteableProperties +} + +// ClientUploadManifestOptions contains the optional parameters for the Client.UploadManifest method. +type ClientUploadManifestOptions struct { + // placeholder for future optional parameters +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/response_types.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/response_types.go new file mode 100644 index 0000000000..ed310e0c02 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/response_types.go @@ -0,0 +1,230 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// Code generated by Microsoft (R) AutoRest Code Generator. DO NOT EDIT. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package azcontainerregistry + +import "io" + +// authenticationClientExchangeAADAccessTokenForACRRefreshTokenResponse contains the response from method authenticationClient.ExchangeAADAccessTokenForACRRefreshToken. +type authenticationClientExchangeAADAccessTokenForACRRefreshTokenResponse struct { + acrRefreshToken +} + +// authenticationClientExchangeACRRefreshTokenForACRAccessTokenResponse contains the response from method authenticationClient.ExchangeACRRefreshTokenForACRAccessToken. +type authenticationClientExchangeACRRefreshTokenForACRAccessTokenResponse struct { + acrAccessToken +} + +// BlobClientCancelUploadResponse contains the response from method BlobClient.CancelUpload. +type BlobClientCancelUploadResponse struct { + // placeholder for future response values +} + +// BlobClientCheckBlobExistsResponse contains the response from method BlobClient.CheckBlobExists. +type BlobClientCheckBlobExistsResponse struct { + // ContentLength contains the information returned from the Content-Length header response. + ContentLength *int64 + + // DockerContentDigest contains the information returned from the Docker-Content-Digest header response. + DockerContentDigest *string +} + +// BlobClientCheckChunkExistsResponse contains the response from method BlobClient.CheckChunkExists. +type BlobClientCheckChunkExistsResponse struct { + // ContentLength contains the information returned from the Content-Length header response. + ContentLength *int64 + + // ContentRange contains the information returned from the Content-Range header response. + ContentRange *string +} + +// BlobClientCompleteUploadResponse contains the response from method BlobClient.CompleteUpload. +type BlobClientCompleteUploadResponse struct { + // DockerContentDigest contains the information returned from the Docker-Content-Digest header response. + DockerContentDigest *string + + // Location contains the information returned from the Location header response. + Location *string + + // Range contains the information returned from the Range header response. + Range *string +} + +// BlobClientDeleteBlobResponse contains the response from method BlobClient.DeleteBlob. +type BlobClientDeleteBlobResponse struct { + // DockerContentDigest contains the information returned from the Docker-Content-Digest header response. + DockerContentDigest *string +} + +// BlobClientGetBlobResponse contains the response from method BlobClient.GetBlob. +type BlobClientGetBlobResponse struct { + // Body contains the streaming response. + BlobData io.ReadCloser + + // ContentLength contains the information returned from the Content-Length header response. + ContentLength *int64 + + // DockerContentDigest contains the information returned from the Docker-Content-Digest header response. + DockerContentDigest *string +} + +// BlobClientGetChunkResponse contains the response from method BlobClient.GetChunk. +type BlobClientGetChunkResponse struct { + // Body contains the streaming response. + ChunkData io.ReadCloser + + // ContentLength contains the information returned from the Content-Length header response. + ContentLength *int64 + + // ContentRange contains the information returned from the Content-Range header response. + ContentRange *string +} + +// BlobClientGetUploadStatusResponse contains the response from method BlobClient.GetUploadStatus. +type BlobClientGetUploadStatusResponse struct { + // DockerUploadUUID contains the information returned from the Docker-Upload-UUID header response. + DockerUploadUUID *string + + // Range contains the information returned from the Range header response. + Range *string +} + +// BlobClientMountBlobResponse contains the response from method BlobClient.MountBlob. +type BlobClientMountBlobResponse struct { + // DockerContentDigest contains the information returned from the Docker-Content-Digest header response. + DockerContentDigest *string + + // DockerUploadUUID contains the information returned from the Docker-Upload-UUID header response. + DockerUploadUUID *string + + // Location contains the information returned from the Location header response. + Location *string +} + +// BlobClientStartUploadResponse contains the response from method BlobClient.StartUpload. +type BlobClientStartUploadResponse struct { + // DockerUploadUUID contains the information returned from the Docker-Upload-UUID header response. + DockerUploadUUID *string + + // Location contains the information returned from the Location header response. + Location *string + + // Range contains the information returned from the Range header response. + Range *string +} + +// BlobClientUploadChunkResponse contains the response from method BlobClient.UploadChunk. +type BlobClientUploadChunkResponse struct { + // DockerUploadUUID contains the information returned from the Docker-Upload-UUID header response. + DockerUploadUUID *string + + // Location contains the information returned from the Location header response. + Location *string + + // Range contains the information returned from the Range header response. + Range *string +} + +// ClientDeleteManifestResponse contains the response from method Client.DeleteManifest. +type ClientDeleteManifestResponse struct { + // placeholder for future response values +} + +// ClientDeleteRepositoryResponse contains the response from method Client.DeleteRepository. +type ClientDeleteRepositoryResponse struct { + // placeholder for future response values +} + +// ClientDeleteTagResponse contains the response from method Client.DeleteTag. +type ClientDeleteTagResponse struct { + // placeholder for future response values +} + +// ClientGetManifestPropertiesResponse contains the response from method Client.GetManifestProperties. +type ClientGetManifestPropertiesResponse struct { + // Manifest attributes details + ArtifactManifestProperties +} + +// ClientGetManifestResponse contains the response from method Client.GetManifest. +type ClientGetManifestResponse struct { + // Body contains the streaming response. + ManifestData io.ReadCloser + + // DockerContentDigest contains the information returned from the Docker-Content-Digest header response. + DockerContentDigest *string +} + +// ClientGetRepositoryPropertiesResponse contains the response from method Client.GetRepositoryProperties. +type ClientGetRepositoryPropertiesResponse struct { + // Properties of this repository. + ContainerRepositoryProperties +} + +// ClientGetTagPropertiesResponse contains the response from method Client.GetTagProperties. +type ClientGetTagPropertiesResponse struct { + // Tag attributes + ArtifactTagProperties +} + +// ClientListManifestsResponse contains the response from method Client.NewListManifestsPager. +type ClientListManifestsResponse struct { + // Manifest attributes + Manifests + + // Link contains the information returned from the Link header response. + Link *string +} + +// ClientListRepositoriesResponse contains the response from method Client.NewListRepositoriesPager. +type ClientListRepositoriesResponse struct { + // List of repositories + Repositories + + // Link contains the information returned from the Link header response. + Link *string +} + +// ClientListTagsResponse contains the response from method Client.NewListTagsPager. +type ClientListTagsResponse struct { + // List of tag details + TagList + + // Link contains the information returned from the Link header response. + Link *string +} + +// ClientUpdateManifestPropertiesResponse contains the response from method Client.UpdateManifestProperties. +type ClientUpdateManifestPropertiesResponse struct { + // Manifest attributes details + ArtifactManifestProperties +} + +// ClientUpdateRepositoryPropertiesResponse contains the response from method Client.UpdateRepositoryProperties. +type ClientUpdateRepositoryPropertiesResponse struct { + // Properties of this repository. + ContainerRepositoryProperties +} + +// ClientUpdateTagPropertiesResponse contains the response from method Client.UpdateTagProperties. +type ClientUpdateTagPropertiesResponse struct { + // Tag attributes + ArtifactTagProperties +} + +// ClientUploadManifestResponse contains the response from method Client.UploadManifest. +type ClientUploadManifestResponse struct { + // ContentLength contains the information returned from the Content-Length header response. + ContentLength *int64 + + // DockerContentDigest contains the information returned from the Docker-Content-Digest header response. + DockerContentDigest *string + + // Location contains the information returned from the Location header response. + Location *string +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/test-resources.bicep b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/test-resources.bicep new file mode 100644 index 0000000000..4f1d819b9f --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/test-resources.bicep @@ -0,0 +1,18 @@ +param baseName string +param location string = resourceGroup().location + +resource registry 'Microsoft.ContainerRegistry/registries@2022-02-01-preview' = { + name: '${baseName}' + location: location + sku: { + name: 'Standard' + } + properties: { + publicNetworkAccess: 'Enabled' + zoneRedundancy: 'Disabled' + anonymousPullEnabled: true + } +} + +output LOGIN_SERVER string = registry.properties.loginServer +output REGISTRY_NAME string = registry.name diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/time_rfc3339.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/time_rfc3339.go new file mode 100644 index 0000000000..a594fec3aa --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry/time_rfc3339.go @@ -0,0 +1,86 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// Code generated by Microsoft (R) AutoRest Code Generator. DO NOT EDIT. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package azcontainerregistry + +import ( + "encoding/json" + "fmt" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "reflect" + "regexp" + "strings" + "time" +) + +// Azure reports time in UTC but it doesn't include the 'Z' time zone suffix in some cases. +var tzOffsetRegex = regexp.MustCompile(`(Z|z|\+|-)(\d+:\d+)*"*$`) + +const ( + utcDateTimeJSON = `"2006-01-02T15:04:05.999999999"` + utcDateTime = "2006-01-02T15:04:05.999999999" + dateTimeJSON = `"` + time.RFC3339Nano + `"` +) + +type dateTimeRFC3339 time.Time + +func (t dateTimeRFC3339) MarshalJSON() ([]byte, error) { + tt := time.Time(t) + return tt.MarshalJSON() +} + +func (t dateTimeRFC3339) MarshalText() ([]byte, error) { + tt := time.Time(t) + return tt.MarshalText() +} + +func (t *dateTimeRFC3339) UnmarshalJSON(data []byte) error { + layout := utcDateTimeJSON + if tzOffsetRegex.Match(data) { + layout = dateTimeJSON + } + return t.Parse(layout, string(data)) +} + +func (t *dateTimeRFC3339) UnmarshalText(data []byte) error { + layout := utcDateTime + if tzOffsetRegex.Match(data) { + layout = time.RFC3339Nano + } + return t.Parse(layout, string(data)) +} + +func (t *dateTimeRFC3339) Parse(layout, value string) error { + p, err := time.Parse(layout, strings.ToUpper(value)) + *t = dateTimeRFC3339(p) + return err +} + +func populateDateTimeRFC3339(m map[string]any, k string, t *time.Time) { + if t == nil { + return + } else if azcore.IsNullValue(t) { + m[k] = nil + return + } else if reflect.ValueOf(t).IsNil() { + return + } + m[k] = (*dateTimeRFC3339)(t) +} + +func unpopulateDateTimeRFC3339(data json.RawMessage, fn string, t **time.Time) error { + if data == nil || strings.EqualFold(string(data), "null") { + return nil + } + var aux dateTimeRFC3339 + if err := json.Unmarshal(data, &aux); err != nil { + return fmt.Errorf("struct field %s: %v", fn, err) + } + *t = (*time.Time)(&aux) + return nil +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 6630a3102c..42f8fa5f70 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -65,6 +65,9 @@ github.com/Azure/azure-sdk-for-go/sdk/azcore/tracing ## explicit; go 1.18 github.com/Azure/azure-sdk-for-go/sdk/azidentity github.com/Azure/azure-sdk-for-go/sdk/azidentity/internal +# github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry v0.2.1 +## explicit; go 1.18 +github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry # github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 ## explicit; go 1.18 github.com/Azure/azure-sdk-for-go/sdk/internal/diag