From 8ac58af82ad136b6a35b5dae6499e25c636f8417 Mon Sep 17 00:00:00 2001 From: Paul Laffitte Date: Thu, 24 Oct 2024 15:57:57 +0200 Subject: [PATCH 1/4] feat: add support for GCR credential helper --- go.mod | 5 +++-- go.sum | 6 ++++-- internal/registry/keychain.go | 2 ++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 3dfab548..ecc3d4a1 100644 --- a/go.mod +++ b/go.mod @@ -27,6 +27,7 @@ require ( ) require ( + cloud.google.com/go/compute/metadata v0.5.2 // indirect github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/aws/aws-sdk-go-v2 v1.26.1 // indirect @@ -72,7 +73,7 @@ require ( github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.20.0 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect - github.com/goccy/go-json v0.10.2 // indirect + github.com/goccy/go-json v0.10.2 // indirect; indirect PR github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect @@ -120,7 +121,7 @@ require ( golang.org/x/net v0.28.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.24.0 // indirect + golang.org/x/sys v0.25.0 // indirect golang.org/x/term v0.23.0 // indirect golang.org/x/text v0.17.0 // indirect golang.org/x/time v0.3.0 // indirect diff --git a/go.sum b/go.sum index b3055b39..9423e151 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,6 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go/compute/metadata v0.5.2 h1:UxK4uu/Tn+I3p2dYWTfiX4wva7aYlKixAHn3fyqngqo= +cloud.google.com/go/compute/metadata v0.5.2/go.mod h1:C66sj2AluDcIqakBq/M8lw8/ybHgOZqin2obFxa/E5k= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= @@ -361,8 +363,8 @@ golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220906165534-d0df966e6959/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/internal/registry/keychain.go b/internal/registry/keychain.go index 6a7226a9..dc0f5dda 100644 --- a/internal/registry/keychain.go +++ b/internal/registry/keychain.go @@ -7,6 +7,7 @@ import ( ecrLogin "github.com/awslabs/amazon-ecr-credential-helper/ecr-login" "github.com/distribution/reference" "github.com/google/go-containerregistry/pkg/authn" + "github.com/google/go-containerregistry/pkg/v1/google" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/types" @@ -52,6 +53,7 @@ func GetKeychains(repositoryName string, pullSecrets []corev1.Secret) ([]authn.K } keychains = append(keychains, authn.NewKeychainFromHelper(ecrLogin.NewECRHelper())) + keychains = append(keychains, google.Keychain) return keychains, nil } From 3920235b8b6b350274bb2899fc2a532c6ba82d69 Mon Sep 17 00:00:00 2001 From: Paul Laffitte Date: Fri, 25 Oct 2024 18:09:12 +0200 Subject: [PATCH 2/4] fix: don't show error when pulling an image that doesn't come from ECR --- internal/registry/keychain.go | 5 +++- internal/registry/keychain_test.go | 44 ++++++++++++++++++------------ 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/internal/registry/keychain.go b/internal/registry/keychain.go index dc0f5dda..cebd7cf0 100644 --- a/internal/registry/keychain.go +++ b/internal/registry/keychain.go @@ -5,6 +5,7 @@ import ( "fmt" ecrLogin "github.com/awslabs/amazon-ecr-credential-helper/ecr-login" + "github.com/awslabs/amazon-ecr-credential-helper/ecr-login/api" "github.com/distribution/reference" "github.com/google/go-containerregistry/pkg/authn" "github.com/google/go-containerregistry/pkg/v1/google" @@ -52,7 +53,9 @@ func GetKeychains(repositoryName string, pullSecrets []corev1.Secret) ([]authn.K }) } - keychains = append(keychains, authn.NewKeychainFromHelper(ecrLogin.NewECRHelper())) + if _, err := api.ExtractRegistry(repositoryName); err == nil { + keychains = append(keychains, authn.NewKeychainFromHelper(ecrLogin.NewECRHelper())) + } keychains = append(keychains, google.Keychain) return keychains, nil diff --git a/internal/registry/keychain_test.go b/internal/registry/keychain_test.go index 85c8d103..6d4d6dc8 100644 --- a/internal/registry/keychain_test.go +++ b/internal/registry/keychain_test.go @@ -8,8 +8,10 @@ import ( "testing" ecrLogin "github.com/awslabs/amazon-ecr-credential-helper/ecr-login" + "github.com/chrismellard/docker-credential-acr-env/pkg/credhelper" "github.com/docker/cli/cli/config" "github.com/google/go-containerregistry/pkg/authn" + "github.com/google/go-containerregistry/pkg/v1/google" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -118,28 +120,22 @@ func TestResolve(t *testing.T) { } func TestGetKeychains(t *testing.T) { - ecrHelper := authn.NewKeychainFromHelper(ecrLogin.NewECRHelper()) defaultKeychains := []authn.Keychain{ - ecrHelper, + google.Keychain, + authn.NewKeychainFromHelper(credhelper.NewACRCredentialsHelper()), } - dockerHubKeychains := []authn.Keychain{ - ecrHelper, - &authConfigKeychain{ - AuthConfig: authn.AuthConfig{ - Username: "login", - Password: "password", - }, + dockerHubKeychains := append(defaultKeychains, &authConfigKeychain{ + AuthConfig: authn.AuthConfig{ + Username: "login", + Password: "password", }, - } - localKeychains := []authn.Keychain{ - ecrHelper, - &authConfigKeychain{ - AuthConfig: authn.AuthConfig{ - Username: "locallogin", - Password: "localpassword", - }, + }) + localKeychains := append(defaultKeychains, &authConfigKeychain{ + AuthConfig: authn.AuthConfig{ + Username: "locallogin", + Password: "localpassword", }, - } + }) tests := []struct { name string @@ -256,6 +252,18 @@ func TestGetKeychains(t *testing.T) { } }) } + + t.Run("Not from Amazon ECR", func(t *testing.T) { + keychains, err := GetKeychains("alpine", []corev1.Secret{}) + g.Expect(err).To(BeNil()) + g.Expect(keychains).ToNot(ContainElement(authn.NewKeychainFromHelper(ecrLogin.NewECRHelper()))) + }) + + t.Run("From Amazon ECR", func(t *testing.T) { + keychains, err := GetKeychains("000000000000.dkr.ecr.eu-west-1.amazonaws.com/some-image", []corev1.Secret{}) + g.Expect(err).To(BeNil()) + g.Expect(keychains).To(ContainElement(authn.NewKeychainFromHelper(ecrLogin.NewECRHelper()))) + }) } func TestGetPullSecrets(t *testing.T) { From 878b3eb30694a8a8ef8e3b31d7895551155aba9a Mon Sep 17 00:00:00 2001 From: Paul Laffitte Date: Wed, 30 Oct 2024 11:15:41 +0100 Subject: [PATCH 3/4] feat: add support for ACR credential helper --- go.mod | 15 +++++++++++++ go.sum | 41 +++++++++++++++++++++++++++++++++++ internal/registry/keychain.go | 2 ++ 3 files changed, 58 insertions(+) diff --git a/go.mod b/go.mod index ecc3d4a1..6eb41f13 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.22 require ( github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20230519004202-7f2db5bd753e + github.com/chrismellard/docker-credential-acr-env v0.0.0-20230304212654-82a0ddb27589 github.com/distribution/reference v0.6.0 github.com/docker/cli v27.3.1+incompatible github.com/docker/docker v27.3.1+incompatible @@ -26,6 +27,20 @@ require ( sigs.k8s.io/controller-runtime v0.15.0 ) +require ( + github.com/Azure/azure-sdk-for-go v55.0.0+incompatible // indirect + github.com/Azure/go-autorest v14.2.0+incompatible // indirect + github.com/Azure/go-autorest/autorest v0.11.28 // indirect + github.com/Azure/go-autorest/autorest/adal v0.9.21 // indirect + github.com/Azure/go-autorest/autorest/azure/auth v0.5.11 // indirect + github.com/Azure/go-autorest/autorest/azure/cli v0.4.5 // indirect + github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect + github.com/Azure/go-autorest/logger v0.2.1 // indirect + github.com/Azure/go-autorest/tracing v0.6.0 // indirect + github.com/dimchansky/utfbom v1.1.1 // indirect + github.com/golang-jwt/jwt/v4 v4.4.2 // indirect +) + require ( cloud.google.com/go/compute/metadata v0.5.2 // indirect github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect diff --git a/go.sum b/go.sum index 9423e151..cbeeabd5 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,31 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go/compute/metadata v0.5.2 h1:UxK4uu/Tn+I3p2dYWTfiX4wva7aYlKixAHn3fyqngqo= cloud.google.com/go/compute/metadata v0.5.2/go.mod h1:C66sj2AluDcIqakBq/M8lw8/ybHgOZqin2obFxa/E5k= +github.com/Azure/azure-sdk-for-go v55.0.0+incompatible h1:L4/vUGbg1Xkw5L20LZD+hJI5I+ibWSytqQ68lTCfLwY= +github.com/Azure/azure-sdk-for-go v55.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= +github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest/autorest v0.11.24/go.mod h1:G6kyRlFnTuSbEYkQGawPfsCswgme4iYf6rfSKUDzbCc= +github.com/Azure/go-autorest/autorest v0.11.28 h1:ndAExarwr5Y+GaHE6VCaY1kyS/HwwGGyuimVhWsHOEM= +github.com/Azure/go-autorest/autorest v0.11.28/go.mod h1:MrkzG3Y3AH668QyF9KRk5neJnGgmhQ6krbhR8Q5eMvA= +github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= +github.com/Azure/go-autorest/autorest/adal v0.9.21 h1:jjQnVFXPfekaqb8vIsv2G1lxshoW+oGv4MDlhRtnYZk= +github.com/Azure/go-autorest/autorest/adal v0.9.21/go.mod h1:zua7mBUaCc5YnSLKYgGJR/w5ePdMDA6H56upLsHzA9U= +github.com/Azure/go-autorest/autorest/azure/auth v0.5.11 h1:P6bYXFoao05z5uhOQzbC3Qd8JqF3jUoocoTeIxkp2cA= +github.com/Azure/go-autorest/autorest/azure/auth v0.5.11/go.mod h1:84w/uV8E37feW2NCJ08uT9VBfjfUHpgLVnG2InYD6cg= +github.com/Azure/go-autorest/autorest/azure/cli v0.4.5 h1:0W/yGmFdTIT77fvdlGZ0LMISoLHFJ7Tx4U0yeB+uFs4= +github.com/Azure/go-autorest/autorest/azure/cli v0.4.5/go.mod h1:ADQAXrkgm7acgWVUNamOgh8YNrv4p27l3Wc55oVfpzg= +github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= +github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= +github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/mocks v0.4.2 h1:PGN4EDXnuQbojHbU0UWoNvmu9AGVwYHG9/fkDYhtAfw= +github.com/Azure/go-autorest/autorest/mocks v0.4.2/go.mod h1:Vy7OitM9Kei0i1Oj+LvyAWMXJHeKH1MVlzFugfVrmyU= +github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg= +github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= +github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= @@ -66,6 +89,8 @@ github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyY github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chrismellard/docker-credential-acr-env v0.0.0-20230304212654-82a0ddb27589 h1:krfRl01rzPzxSxyLyrChD+U+MzsBXbm0OwYYB67uF+4= +github.com/chrismellard/docker-credential-acr-env v0.0.0-20230304212654-82a0ddb27589/go.mod h1:OuDyvmLnMCwa2ep4Jkm6nyA0ocJuZlGyk2gGseVzERM= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= @@ -81,6 +106,8 @@ github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnG github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U= +github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/docker/cli v27.3.1+incompatible h1:qEGdFBF3Xu6SCvCYhc7CzaQTlBmqDuzxPDpigSyeKQQ= @@ -142,6 +169,10 @@ github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= +github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= +github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs= +github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -320,6 +351,9 @@ golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -340,6 +374,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -356,6 +392,9 @@ golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -365,10 +404,12 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= diff --git a/internal/registry/keychain.go b/internal/registry/keychain.go index cebd7cf0..c499016c 100644 --- a/internal/registry/keychain.go +++ b/internal/registry/keychain.go @@ -6,6 +6,7 @@ import ( ecrLogin "github.com/awslabs/amazon-ecr-credential-helper/ecr-login" "github.com/awslabs/amazon-ecr-credential-helper/ecr-login/api" + "github.com/chrismellard/docker-credential-acr-env/pkg/credhelper" "github.com/distribution/reference" "github.com/google/go-containerregistry/pkg/authn" "github.com/google/go-containerregistry/pkg/v1/google" @@ -57,6 +58,7 @@ func GetKeychains(repositoryName string, pullSecrets []corev1.Secret) ([]authn.K keychains = append(keychains, authn.NewKeychainFromHelper(ecrLogin.NewECRHelper())) } keychains = append(keychains, google.Keychain) + keychains = append(keychains, authn.NewKeychainFromHelper(credhelper.NewACRCredentialsHelper())) return keychains, nil } From f5456ab4dfd24de5ae32e5c46f8a9479c6489d49 Mon Sep 17 00:00:00 2001 From: Paul Laffitte Date: Wed, 30 Oct 2024 16:23:19 +0100 Subject: [PATCH 4/4] feat(storage): add azure support --- docs/high-availability.md | 24 ++++++++++++++++- helm/kube-image-keeper/templates/_helpers.tpl | 2 +- .../templates/registry-deployment.yaml | 27 ++++++++++++++++--- helm/kube-image-keeper/values.yaml | 5 +++- 4 files changed, 52 insertions(+), 6 deletions(-) diff --git a/docs/high-availability.md b/docs/high-availability.md index 61dfb57b..b125ad86 100644 --- a/docs/high-availability.md +++ b/docs/high-availability.md @@ -16,6 +16,7 @@ The registry supports various storage solutions, some of which enable high avail | MinIO | Yes | `minio.enabled=true` | | S3-compatible | Yes | `registry.persistence.s3=...` | | GCS | Yes | `registry.persistence.gcs=...` | +| Azure | Yes | `registry.persistence.azure=...` | HA-compatible backends uses a deployment whereas other backends relies on a statefulset. @@ -95,6 +96,28 @@ kubectl create secret generic secret-name \ --from-literal=credentials.json=${GCS_KEY} ``` +### Azure + +Microsoft Azure can also be used as a storage backend for the registry. Here is an example of values to use Azure: + +```yaml +registry: + persistence: + azureExistingSecret: secret-name + azure: + container: registry +``` + +Please refer to the [Docker registry documentation](https://distribution.github.io/distribution/about/configuration/) for more details. + +Note that you will need to create a Secret holding the associated service account secret: + +``` +kubectl create secret generic secret-name \ + --from-literal=accountname=${ACCOUNTNAME} \ + --from-literal=accountkey=${ACCOUNTKEY} +``` + ## MinIO The kuik Helm chart has an optional dependency on the [bitnami MinIO chart](https://artifacthub.io/packages/helm/bitnami/minio). The subchart can be enabled by setting `minio.enabled` to `true`, and it can be configured by passing values under the `minio.*` path; for instance, with the following values YAML: @@ -126,4 +149,3 @@ kubectl create secret generic minio-root-auth \ It is NOT necessary to set `registry.persistence.enabled` to `true` to enable persistence through MinIO. It is NOT necessary to configure the S3 endpoint when using this solution as it will be configured automatically by the chart. - diff --git a/helm/kube-image-keeper/templates/_helpers.tpl b/helm/kube-image-keeper/templates/_helpers.tpl index 6f0314c2..a67df7b1 100644 --- a/helm/kube-image-keeper/templates/_helpers.tpl +++ b/helm/kube-image-keeper/templates/_helpers.tpl @@ -110,5 +110,5 @@ Create the name of the service account to use {{- end }} {{- define "kube-image-keeper.registry-stateless-mode" -}} -{{- ternary "true" "false" (or .Values.minio.enabled (not (empty .Values.registry.persistence.s3)) (not (empty .Values.registry.persistence.gcs))) }} +{{- ternary "true" "false" (or .Values.minio.enabled (not (empty .Values.registry.persistence.s3)) (not (empty .Values.registry.persistence.gcs)) (not (empty .Values.registry.persistence.azure))) }} {{- end }} diff --git a/helm/kube-image-keeper/templates/registry-deployment.yaml b/helm/kube-image-keeper/templates/registry-deployment.yaml index 11833d62..0be71993 100644 --- a/helm/kube-image-keeper/templates/registry-deployment.yaml +++ b/helm/kube-image-keeper/templates/registry-deployment.yaml @@ -48,16 +48,20 @@ spec: key: secret - name: REGISTRY_STORAGE_DELETE_ENABLED value: "true" - {{- if (not (empty .Values.registry.persistence.s3))}} + {{- if (not (empty .Values.registry.persistence.s3)) }} - name: REGISTRY_STORAGE value: s3 {{- end}} - {{- if (not (empty .Values.registry.persistence.gcs))}} + {{- if (not (empty .Values.registry.persistence.gcs)) }} - name: REGISTRY_STORAGE value: gcs - name: REGISTRY_STORAGE_GCS_KEYFILE value: "/etc/registry/keys/credentials.json" {{- end}} + {{- if (not (empty .Values.registry.persistence.azure)) }} + - name: REGISTRY_STORAGE + value: azure + {{- end}} {{- if .Values.registry.serviceMonitor.create }} - name: REGISTRY_HTTP_DEBUG_ADDR value: 0.0.0.0:5001 @@ -78,10 +82,14 @@ spec: - name: {{ printf "%s_%s" "REGISTRY_STORAGE_S3" ($k | upper) }} value: {{ $v | quote }} {{- end }} - {{- range $k, $v := omit .Values.registry.persistence.gcs }} + {{- range $k, $v := .Values.registry.persistence.gcs }} - name: {{ printf "%s_%s" "REGISTRY_STORAGE_GCS" ($k | upper) }} value: {{ $v | quote }} {{- end }} + {{- range $k, $v := omit .Values.registry.persistence.azure "accountname" "accountkey" }} + - name: {{ printf "%s_%s" "REGISTRY_STORAGE_AZURE" ($k | upper) }} + value: {{ $v | quote }} + {{- end }} {{- if .Values.registry.persistence.disableS3Redirections }} - name: REGISTRY_STORAGE_REDIRECT_DISABLE value: "true" @@ -100,6 +108,19 @@ spec: name: {{ $s3KeysSecretName }} key: secretKey {{- end }} + {{- if (not (empty .Values.registry.persistence.azureExistingSecret)) }} + {{ $azureKeysSecretName := .Values.registry.persistence.azureExistingSecret | default "kube-image-keeper-s3-registry-keys" }} + - name: REGISTRY_STORAGE_AZURE_ACCOUNTNAME + valueFrom: + secretKeyRef: + name: {{ $azureKeysSecretName }} + key: accountname + - name: REGISTRY_STORAGE_AZURE_ACCOUNTKEY + valueFrom: + secretKeyRef: + name: {{ $azureKeysSecretName }} + key: accountkey + {{- end }} {{- range .Values.registry.env }} - name: {{ .name }} value: {{ .value | quote }} diff --git a/helm/kube-image-keeper/values.yaml b/helm/kube-image-keeper/values.yaml index a3da0ed6..1a14b4c0 100644 --- a/helm/kube-image-keeper/values.yaml +++ b/helm/kube-image-keeper/values.yaml @@ -220,7 +220,7 @@ registry: storageClass: null # -- Registry persistent volume size size: 20Gi - # -- External S3 configuration (needed only if you don't enable minio) (see https://github.com/docker/docs/blob/main/registry/storage-drivers/s3.md) + # -- External S3 configuration (needed only if you don't enable minio) (see https://github.com/distribution/distribution/blob/main/docs/content/storage-drivers/s3.md) s3: {} s3ExistingSecret: "" # -- Disable blobs redirection to S3 bucket (useful if your S3 instance is not accessible from kubelet) @@ -229,6 +229,9 @@ registry: gcs: {} # use service account secret in JSON format gcsExistingSecret: "" + # -- Azure configuration (see https://github.com/distribution/distribution/blob/main/docs/content/storage-drivers/azure.md) + azure: {} + azureExistingSecret: "" garbageCollection: # -- Garbage collector cron schedule. Use standard crontab format. schedule: "0 0 * * 0"