From 7e61b3384952e5759af04d3261bb1faf2ffd2f53 Mon Sep 17 00:00:00 2001 From: Dipti Pai Date: Tue, 9 Jul 2024 11:29:09 -0700 Subject: [PATCH 1/5] Add packages auth, azure and git to get authentication credentials for azure provider Signed-off-by: Dipti Pai --- auth/azure/fake_credential.go | 51 +++++++++++++++++++ auth/azure/token_provider.go | 83 ++++++++++++++++++++++++++++++ auth/azure/token_provider_test.go | 81 +++++++++++++++++++++++++++++ auth/git/credentials.go | 66 ++++++++++++++++++++++++ auth/git/credentials_test.go | 84 +++++++++++++++++++++++++++++++ auth/go.mod | 25 +++++++++ auth/go.sum | 58 +++++++++++++++++++++ auth/options.go | 37 ++++++++++++++ 8 files changed, 485 insertions(+) create mode 100644 auth/azure/fake_credential.go create mode 100644 auth/azure/token_provider.go create mode 100644 auth/azure/token_provider_test.go create mode 100644 auth/git/credentials.go create mode 100644 auth/git/credentials_test.go create mode 100644 auth/go.mod create mode 100644 auth/go.sum create mode 100644 auth/options.go diff --git a/auth/azure/fake_credential.go b/auth/azure/fake_credential.go new file mode 100644 index 00000000..d09c77e9 --- /dev/null +++ b/auth/azure/fake_credential.go @@ -0,0 +1,51 @@ +/* +Copyright 2023 The Flux authors Licensed under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with the +License. + +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed +under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. +*/ + +package azure + +import ( + "context" + "fmt" + "time" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" +) + +// FakeTokenCredential is a fake Azure credential provider. +type FakeTokenCredential struct { + Token string + + ExpiresOn time.Time + Err error +} + +var _ azcore.TokenCredential = &FakeTokenCredential{} + +func (tc *FakeTokenCredential) GetToken(ctx context.Context, options policy.TokenRequestOptions) (azcore.AccessToken, error) { + if tc.Err != nil { + return azcore.AccessToken{}, tc.Err + } + + // Embed the scope inside the context to verify that the desired scope was + // specified while fetching the token. + val, ok := ctx.Value("scope").(*string) + if ok { + *val = options.Scopes[0] + } else { + return azcore.AccessToken{}, fmt.Errorf("unable to get scope") + } + + return azcore.AccessToken{Token: tc.Token, ExpiresOn: tc.ExpiresOn}, nil +} diff --git a/auth/azure/token_provider.go b/auth/azure/token_provider.go new file mode 100644 index 00000000..7d3815cc --- /dev/null +++ b/auth/azure/token_provider.go @@ -0,0 +1,83 @@ +/* +Copyright 2024 The Flux authors Licensed under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with the +License. + +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed +under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. +*/ + +package azure + +import ( + "context" + "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/azidentity" +) + +const ( + AzureDevOpsRestApiScope = "499b84ac-1321-427f-aa17-267ca6975798/.default" +) + +// Provider is an authentication provider for Azure. +type Provider struct { + credential azcore.TokenCredential + scopes []string +} + +// ProviderOptFunc enables specifying options for the provider. +type ProviderOptFunc func(*Provider) + +// NewProvider returns a new authentication provider for Azure. +func NewProvider(opts ...ProviderOptFunc) *Provider { + p := &Provider{} + for _, opt := range opts { + opt(p) + } + return p +} + +// WithCredential configures the credential to use to fetch the resource manager +// token. +func WithCredential(cred azcore.TokenCredential) ProviderOptFunc { + return func(p *Provider) { + p.credential = cred + } +} + +func WithAzureDevOpsScope() ProviderOptFunc { + return func(p *Provider) { + p.scopes = []string{AzureDevOpsRestApiScope} + } +} + +func (p *Provider) GetToken(ctx context.Context) (*azcore.AccessToken, error) { + if len(p.scopes) == 0 { + return nil, fmt.Errorf("error scopes must be specified") + } + + if p.credential == nil { + cred, err := azidentity.NewDefaultAzureCredential(nil) + if err != nil { + return nil, err + } + p.credential = cred + } + + accessToken, err := p.credential.GetToken(ctx, policy.TokenRequestOptions{ + Scopes: p.scopes, + }) + if err != nil { + return nil, err + } + + return &accessToken, nil +} diff --git a/auth/azure/token_provider_test.go b/auth/azure/token_provider_test.go new file mode 100644 index 00000000..887bf179 --- /dev/null +++ b/auth/azure/token_provider_test.go @@ -0,0 +1,81 @@ +/* +Copyright 2023 The Flux authors Licensed under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with the +License. + +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed +under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. +*/ + +package azure + +import ( + "context" + "errors" + "testing" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + . "github.com/onsi/gomega" + "k8s.io/utils/pointer" +) + +func TestGetProviderToken(t *testing.T) { + tests := []struct { + name string + tokenCred azcore.TokenCredential + opts []ProviderOptFunc + wantToken string + wantScope string + wantErr error + }{ + { + name: "custom scope", + tokenCred: &FakeTokenCredential{ + Token: "foo", + }, + opts: []ProviderOptFunc{WithAzureDevOpsScope()}, + wantScope: "499b84ac-1321-427f-aa17-267ca6975798/.default", + wantToken: "foo", + }, + { + name: "no scope specified", + tokenCred: &FakeTokenCredential{ + Token: "foo", + }, + wantErr: errors.New("error scopes must be specified"), + }, + { + name: "error", + tokenCred: &FakeTokenCredential{ + Err: errors.New("oh no!"), + }, + opts: []ProviderOptFunc{WithAzureDevOpsScope()}, + wantErr: errors.New("oh no!"), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + g := NewWithT(t) + provider := NewProvider(tt.opts...) + provider.credential = tt.tokenCred + ctx := context.WithValue(context.TODO(), "scope", pointer.String("")) + token, err := provider.GetToken(ctx) + + if tt.wantErr != nil { + g.Expect(err).To(HaveOccurred()) + g.Expect(err).To(Equal(tt.wantErr)) + } else { + g.Expect(err).ToNot(HaveOccurred()) + g.Expect(token.Token).To(Equal(tt.wantToken)) + scope := ctx.Value("scope").(*string) + g.Expect(*scope).To(Equal(tt.wantScope)) + } + }) + } +} diff --git a/auth/git/credentials.go b/auth/git/credentials.go new file mode 100644 index 00000000..740f1ea7 --- /dev/null +++ b/auth/git/credentials.go @@ -0,0 +1,66 @@ +/* +Copyright 2024 The Flux authors Licensed under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with the +License. + +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed +under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. +*/ + +package git + +import ( + "context" + + "github.com/fluxcd/pkg/auth" + "github.com/fluxcd/pkg/auth/azure" +) + +// Credentials contains authentication data needed in order to access a Git +// repository. +type Credentials struct { + BearerToken string `json:"bearerToken,omitempty"` +} + +// ToSecretData returns the Credentials object in the format of the data found +// in Kubernetes Generic Secret. +func (c *Credentials) ToSecretData() map[string][]byte { + var data map[string][]byte = make(map[string][]byte) + + if c.BearerToken != "" { + data["bearerToken"] = []byte(c.BearerToken) + } + + return data +} + +// GetCredentials returns authentication credentials for accessing the provided +// Git repository. +func GetCredentials(ctx context.Context, provider string, authOpts *auth.AuthOptions) (*Credentials, error) { + var creds Credentials + + switch provider { + case auth.ProviderAzure: + var opts []azure.ProviderOptFunc + if authOpts != nil { + opts = authOpts.ProviderOptions.AzureOpts + } + azureProvider := azure.NewProvider(opts...) + accessToken, err := azureProvider.GetToken(ctx) + if err != nil { + return nil, err + } + creds = Credentials{ + BearerToken: accessToken.Token, + } + default: + return nil, nil + } + + return &creds, nil +} diff --git a/auth/git/credentials_test.go b/auth/git/credentials_test.go new file mode 100644 index 00000000..a9cf2b74 --- /dev/null +++ b/auth/git/credentials_test.go @@ -0,0 +1,84 @@ +/* +Copyright 2023 The Flux authors + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed +under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. +*/ + +package git + +import ( + "context" + "testing" + "time" + + . "github.com/onsi/gomega" + "k8s.io/utils/pointer" + + "github.com/fluxcd/pkg/auth" + "github.com/fluxcd/pkg/auth/azure" +) + +func TestGetCredentials(t *testing.T) { + expiresAt := time.Now().UTC().Add(time.Hour) + + tests := []struct { + name string + authOpts *auth.AuthOptions + provider string + wantCredentials *Credentials + wantScope string + }{ + { + name: "get credentials from azure", + provider: auth.ProviderAzure, + authOpts: &auth.AuthOptions{ + ProviderOptions: auth.ProviderOptions{ + AzureOpts: []azure.ProviderOptFunc{ + azure.WithCredential(&azure.FakeTokenCredential{ + Token: "ado-token", + ExpiresOn: expiresAt, + }), + azure.WithAzureDevOpsScope(), + }, + }, + }, + wantCredentials: &Credentials{ + BearerToken: "ado-token", + }, + wantScope: "499b84ac-1321-427f-aa17-267ca6975798/.default", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + g := NewWithT(t) + ctx := context.WithValue(context.TODO(), "scope", pointer.String("")) + creds, err := GetCredentials(ctx, tt.provider, tt.authOpts) + g.Expect(err).ToNot(HaveOccurred()) + + if tt.wantCredentials != nil { + g.Expect(*creds).To(Equal(*tt.wantCredentials)) + val := ctx.Value("scope").(*string) + g.Expect(*val).ToNot(BeEmpty()) + g.Expect(*val).To(Equal((tt.wantScope))) + + data := creds.ToSecretData() + g.Expect(data).ToNot((BeNil())) + g.Expect(data).To(HaveKey("bearerToken")) + credBytes := []byte(tt.wantCredentials.BearerToken) + g.Expect(data["bearerToken"]).To(Equal(credBytes)) + } else { + g.Expect(creds).To(BeNil()) + } + }) + } +} diff --git a/auth/go.mod b/auth/go.mod new file mode 100644 index 00000000..ea43181b --- /dev/null +++ b/auth/go.mod @@ -0,0 +1,25 @@ +module github.com/fluxcd/pkg/auth + +go 1.22.4 + +require ( + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.12.0 + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 + github.com/onsi/gomega v1.33.1 + k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 +) + +require ( + github.com/Azure/azure-sdk-for-go/sdk/internal v1.9.0 // indirect + github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect + github.com/golang-jwt/jwt/v5 v5.2.1 // indirect + github.com/google/go-cmp v0.6.0 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/kylelemons/godebug v1.1.0 // indirect + github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect + golang.org/x/crypto v0.24.0 // indirect + golang.org/x/net v0.26.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/text v0.16.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/auth/go.sum b/auth/go.sum new file mode 100644 index 00000000..7eecaa19 --- /dev/null +++ b/auth/go.sum @@ -0,0 +1,58 @@ +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.12.0 h1:1nGuui+4POelzDwI7RG56yfQJHCnKvwfMoU7VsEp+Zg= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.12.0/go.mod h1:99EvauvlcJ1U06amZiksfYz/3aFGyIhWGHVyiZXtBAI= +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/internal v1.9.0 h1:H+U3Gk9zY56G3u872L82bk4thcsy2Gghb9ExT4Zvm1o= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.9.0/go.mod h1:mgrmMSgaLp9hmax62XQTd0N4aAqSE5E0DulSpVYK7vc= +github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 h1:XHOnouVk1mxXfQidrMEnLlPk9UMeRtyBTnEFtxkV0kU= +github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= +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/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= +github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= +github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/onsi/ginkgo/v2 v2.17.2 h1:7eMhcy3GimbsA3hEnVKdw/PQM9XN9krpKVXsZdph0/g= +github.com/onsi/ginkgo/v2 v2.17.2/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/PRJ1eCc= +github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= +github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 h1:jgGTlFYnhF1PM1Ax/lAlxUPE+KfCIXHaathvJg1C3ak= +k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= diff --git a/auth/options.go b/auth/options.go new file mode 100644 index 00000000..b17a9792 --- /dev/null +++ b/auth/options.go @@ -0,0 +1,37 @@ +/* +Copyright 2024 The Flux authors + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. + +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed +under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. +*/ + +package auth + +import ( + "github.com/fluxcd/pkg/auth/azure" +) + +const ( + ProviderAzure = "azure" +) + +// AuthOptions contains options that can be used for authentication. +type AuthOptions struct { + // ProviderOptions specifies the options to configure various authentication + // providers. + ProviderOptions ProviderOptions +} + +// ProviderOptions contains options to configure various authentication +// providers. +type ProviderOptions struct { + AzureOpts []azure.ProviderOptFunc +} From dd8c5b4b6697038adae842531055083c2b2e3df1 Mon Sep 17 00:00:00 2001 From: Dipti Pai Date: Wed, 10 Jul 2024 12:58:41 -0700 Subject: [PATCH 2/5] Add Credential cache and cache git credentials Signed-off-by: Dipti Pai --- auth/constants.go | 19 +++ auth/git/cache.go | 41 ++++++ auth/git/credentials.go | 41 +++++- auth/git/credentials_test.go | 73 ++++++++-- auth/go.mod | 51 +++++++ auth/go.sum | 264 ++++++++++++++++++++++++++++++++++- auth/options.go | 37 ----- 7 files changed, 478 insertions(+), 48 deletions(-) create mode 100644 auth/constants.go create mode 100644 auth/git/cache.go delete mode 100644 auth/options.go diff --git a/auth/constants.go b/auth/constants.go new file mode 100644 index 00000000..5d223ac3 --- /dev/null +++ b/auth/constants.go @@ -0,0 +1,19 @@ +/* +Copyright 2024 The Flux authors Licensed under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with the +License. + +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed +under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. +*/ + +package auth + +const ( + ProviderAzure = "azure" +) diff --git a/auth/git/cache.go b/auth/git/cache.go new file mode 100644 index 00000000..0c099771 --- /dev/null +++ b/auth/git/cache.go @@ -0,0 +1,41 @@ +/* +Copyright 2024 The Flux authors + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed +under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. +*/ + +package git + +import ( + "time" + + "github.com/fluxcd/pkg/cache" +) + +func cacheObject[T Credentials](store cache.Expirable[cache.StoreObject[T]], auth T, key string, expiresAt time.Time) error { + obj := cache.StoreObject[T]{ + Object: auth, + Key: key, + } + + err := store.Set(obj) + if err != nil { + return err + } + + return store.SetExpiration(obj, expiresAt) +} + +func getObjectFromCache[T Credentials](cache cache.Expirable[cache.StoreObject[T]], key string) (T, bool, error) { + val, exists, err := cache.GetByKey(key) + return val.Object, exists, err +} diff --git a/auth/git/credentials.go b/auth/git/credentials.go index 740f1ea7..615708bf 100644 --- a/auth/git/credentials.go +++ b/auth/git/credentials.go @@ -19,8 +19,30 @@ import ( "github.com/fluxcd/pkg/auth" "github.com/fluxcd/pkg/auth/azure" + "github.com/fluxcd/pkg/cache" + "sigs.k8s.io/controller-runtime/pkg/log" ) +const ( + ProviderAzure = "azure" +) + +// AuthOptions contains options that can be used for authentication. +type AuthOptions struct { + // ProviderOptions specifies the options to configure various authentication + // providers. + ProviderOptions ProviderOptions + + // Cache is a cache for storing auth configurations. + Cache cache.Expirable[cache.StoreObject[Credentials]] +} + +// ProviderOptions contains options to configure various authentication +// providers. +type ProviderOptions struct { + AzureOpts []azure.ProviderOptFunc +} + // Credentials contains authentication data needed in order to access a Git // repository. type Credentials struct { @@ -41,8 +63,19 @@ func (c *Credentials) ToSecretData() map[string][]byte { // GetCredentials returns authentication credentials for accessing the provided // Git repository. -func GetCredentials(ctx context.Context, provider string, authOpts *auth.AuthOptions) (*Credentials, error) { +func GetCredentials(ctx context.Context, url string, provider string, authOpts *AuthOptions) (*Credentials, error) { var creds Credentials + log := log.FromContext(ctx) + + if authOpts.Cache != nil { + creds, exists, err := getObjectFromCache(authOpts.Cache, url) + if err != nil { + log.Error(err, "failed to get credential object from cache") + } + if exists { + return &creds, nil + } + } switch provider { case auth.ProviderAzure: @@ -58,6 +91,12 @@ func GetCredentials(ctx context.Context, provider string, authOpts *auth.AuthOpt creds = Credentials{ BearerToken: accessToken.Token, } + if authOpts.Cache != nil { + err := cacheObject(authOpts.Cache, creds, url, accessToken.ExpiresOn) + if err != nil { + log.Error(err, "failed to cache auth object") + } + } default: return nil, nil } diff --git a/auth/git/credentials_test.go b/auth/git/credentials_test.go index a9cf2b74..7d325c73 100644 --- a/auth/git/credentials_test.go +++ b/auth/git/credentials_test.go @@ -25,27 +25,27 @@ import ( "github.com/fluxcd/pkg/auth" "github.com/fluxcd/pkg/auth/azure" + "github.com/fluxcd/pkg/cache" ) func TestGetCredentials(t *testing.T) { - expiresAt := time.Now().UTC().Add(time.Hour) - tests := []struct { name string - authOpts *auth.AuthOptions + url string + authOpts *AuthOptions provider string wantCredentials *Credentials wantScope string }{ { name: "get credentials from azure", + url: "https://dev.azure.com/foo/bar/_git/baz", provider: auth.ProviderAzure, - authOpts: &auth.AuthOptions{ - ProviderOptions: auth.ProviderOptions{ + authOpts: &AuthOptions{ + ProviderOptions: ProviderOptions{ AzureOpts: []azure.ProviderOptFunc{ azure.WithCredential(&azure.FakeTokenCredential{ - Token: "ado-token", - ExpiresOn: expiresAt, + Token: "ado-token", }), azure.WithAzureDevOpsScope(), }, @@ -62,7 +62,7 @@ func TestGetCredentials(t *testing.T) { t.Run(tt.name, func(t *testing.T) { g := NewWithT(t) ctx := context.WithValue(context.TODO(), "scope", pointer.String("")) - creds, err := GetCredentials(ctx, tt.provider, tt.authOpts) + creds, err := GetCredentials(ctx, tt.url, tt.provider, tt.authOpts) g.Expect(err).ToNot(HaveOccurred()) if tt.wantCredentials != nil { @@ -82,3 +82,60 @@ func TestGetCredentials(t *testing.T) { }) } } + +func TestGetCredentialsWithCache(t *testing.T) { + expiresOn := time.Now().Add(10 * time.Second) + tests := []struct { + name string + url string + authOpts *AuthOptions + provider string + wantCredentials *Credentials + wantScope string + }{ + { + name: "get credentials from azure", + url: "https://dev.azure.com/foo/bar/_git/baz", + provider: auth.ProviderAzure, + authOpts: &AuthOptions{ + ProviderOptions: ProviderOptions{ + AzureOpts: []azure.ProviderOptFunc{ + azure.WithCredential(&azure.FakeTokenCredential{ + Token: "ado-token", + ExpiresOn: expiresOn, + }), + azure.WithAzureDevOpsScope(), + }, + }, + }, + wantCredentials: &Credentials{ + BearerToken: "ado-token", + }, + wantScope: "499b84ac-1321-427f-aa17-267ca6975798/.default", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + g := NewWithT(t) + cache, err := cache.New(5, cache.StoreObjectKeyFunc, + cache.WithCleanupInterval[cache.StoreObject[Credentials]](1*time.Second)) + g.Expect(err).ToNot(HaveOccurred()) + tt.authOpts.Cache = cache + + ctx := context.WithValue(context.TODO(), "scope", pointer.String("")) + _, err = GetCredentials(ctx, tt.url, tt.provider, tt.authOpts) + g.Expect(err).ToNot(HaveOccurred()) + creds, exists, err := getObjectFromCache(cache, tt.url) + g.Expect(err).ToNot(HaveOccurred()) + g.Expect(exists).To(BeTrue()) + g.Expect(creds).ToNot(BeNil()) + obj, _, err := cache.GetByKey(tt.url) + g.Expect(err).ToNot(HaveOccurred()) + expiration, err := cache.GetExpiration(obj) + g.Expect(err).ToNot(HaveOccurred()) + g.Expect(expiration).ToNot(BeZero()) + g.Expect(expiration).To(BeTemporally("~", expiresOn, 1*time.Second)) + }) + } +} diff --git a/auth/go.mod b/auth/go.mod index ea43181b..5e0e327f 100644 --- a/auth/go.mod +++ b/auth/go.mod @@ -5,21 +5,72 @@ go 1.22.4 require ( github.com/Azure/azure-sdk-for-go/sdk/azcore v1.12.0 github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 + github.com/fluxcd/pkg/cache v0.0.1 github.com/onsi/gomega v1.33.1 k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 + sigs.k8s.io/controller-runtime v0.18.0 ) require ( github.com/Azure/azure-sdk-for-go/sdk/internal v1.9.0 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/blang/semver/v4 v4.0.0 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/fluxcd/cli-utils v0.36.0-flux.7 // indirect + github.com/go-errors/errors v1.5.1 // indirect + github.com/go-logr/logr v1.4.1 // indirect + github.com/go-openapi/jsonpointer v0.19.6 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/swag v0.22.4 // indirect + github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v5 v5.2.1 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.6.0 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.6.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect github.com/kylelemons/godebug v1.1.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/prometheus/client_golang v1.19.0 // indirect + github.com/prometheus/client_model v0.5.0 // indirect + github.com/prometheus/common v0.48.0 // indirect + github.com/prometheus/procfs v0.12.0 // indirect + github.com/xlab/treeprint v1.2.0 // indirect + go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect golang.org/x/crypto v0.24.0 // indirect golang.org/x/net v0.26.0 // indirect + golang.org/x/oauth2 v0.19.0 // indirect + golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.21.0 // indirect + golang.org/x/term v0.21.0 // indirect golang.org/x/text v0.16.0 // indirect + golang.org/x/time v0.5.0 // indirect + google.golang.org/protobuf v1.33.0 // indirect + gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/api v0.30.0 // indirect + k8s.io/apimachinery v0.30.0 // indirect + k8s.io/cli-runtime v0.30.0 // indirect + k8s.io/client-go v0.30.0 // indirect + k8s.io/klog/v2 v2.120.1 // indirect + k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/kustomize/api v0.17.1 // indirect + sigs.k8s.io/kustomize/kyaml v0.17.0 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect + sigs.k8s.io/yaml v1.4.0 // indirect ) diff --git a/auth/go.sum b/auth/go.sum index 7eecaa19..74f5ff7d 100644 --- a/auth/go.sum +++ b/auth/go.sum @@ -1,58 +1,318 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.12.0 h1:1nGuui+4POelzDwI7RG56yfQJHCnKvwfMoU7VsEp+Zg= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.12.0/go.mod h1:99EvauvlcJ1U06amZiksfYz/3aFGyIhWGHVyiZXtBAI= 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/internal v1.9.0 h1:H+U3Gk9zY56G3u872L82bk4thcsy2Gghb9ExT4Zvm1o= github.com/Azure/azure-sdk-for-go/sdk/internal v1.9.0/go.mod h1:mgrmMSgaLp9hmax62XQTd0N4aAqSE5E0DulSpVYK7vc= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 h1:XHOnouVk1mxXfQidrMEnLlPk9UMeRtyBTnEFtxkV0kU= github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= +github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= +github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk= +github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= +github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI= +github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM= +github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= +github.com/fluxcd/cli-utils v0.36.0-flux.7 h1:81zEo/LNmIRWMgtsZy/8L13TMUZHmmJib4gHRvKwVE8= +github.com/fluxcd/cli-utils v0.36.0-flux.7/go.mod h1:TcfLhvBjtQnqxYMsHQUAEB2c5WJRVuibtas2Izz5ZTs= +github.com/fluxcd/pkg/cache v0.0.1 h1:aeDQm4D37btj6I01p6ZKW6JNOZm3CIYN5PaVzyhHr38= +github.com/fluxcd/pkg/cache v0.0.1/go.mod h1:R3TJIK9XaohHNc3BeqfZX/UivMrx8Xz6ihGoVAjh75k= +github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk= +github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= +github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= +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/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= +github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg= github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= +github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= +github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= +github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= +github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= +github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= +github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= +github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0= +github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/onsi/ginkgo/v2 v2.17.2 h1:7eMhcy3GimbsA3hEnVKdw/PQM9XN9krpKVXsZdph0/g= github.com/onsi/ginkgo/v2 v2.17.2/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/PRJ1eCc= github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= +github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= +github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= +github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE= +github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= +github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= +github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= +github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY= +go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +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.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +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.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg= +golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +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-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= +golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= +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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= +gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +k8s.io/api v0.30.0 h1:siWhRq7cNjy2iHssOB9SCGNCl2spiF1dO3dABqZ8niA= +k8s.io/api v0.30.0/go.mod h1:OPlaYhoHs8EQ1ql0R/TsUgaRPhpKNxIMrKQfWUp8QSE= +k8s.io/apimachinery v0.30.0 h1:qxVPsyDM5XS96NIh9Oj6LavoVFYff/Pon9cZeDIkHHA= +k8s.io/apimachinery v0.30.0/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc= +k8s.io/cli-runtime v0.30.0 h1:0vn6/XhOvn1RJ2KJOC6IRR2CGqrpT6QQF4+8pYpWQ48= +k8s.io/cli-runtime v0.30.0/go.mod h1:vATpDMATVTMA79sZ0YUCzlMelf6rUjoBzlp+RnoM+cg= +k8s.io/client-go v0.30.0 h1:sB1AGGlhY/o7KCyCEQ0bPWzYDL0pwOZO4vAtTSh/gJQ= +k8s.io/client-go v0.30.0/go.mod h1:g7li5O5256qe6TYdAMyX/otJqMhIiGgTapdLchhmOaY= +k8s.io/component-base v0.30.0 h1:cj6bp38g0ainlfYtaOQuRELh5KSYjhKxM+io7AUIk4o= +k8s.io/component-base v0.30.0/go.mod h1:V9x/0ePFNaKeKYA3bOvIbrNoluTSG+fSJKjLdjOoeXQ= +k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= +k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= +k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= +k8s.io/kubectl v0.30.0 h1:xbPvzagbJ6RNYVMVuiHArC1grrV5vSmmIcSZuCdzRyk= +k8s.io/kubectl v0.30.0/go.mod h1:zgolRw2MQXLPwmic2l/+iHs239L49fhSeICuMhQQXTI= k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 h1:jgGTlFYnhF1PM1Ax/lAlxUPE+KfCIXHaathvJg1C3ak= k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/controller-runtime v0.18.0 h1:Z7jKuX784TQSUL1TIyeuF7j8KXZ4RtSX0YgtjKcSTME= +sigs.k8s.io/controller-runtime v0.18.0/go.mod h1:tuAt1+wbVsXIT8lPtk5RURxqAnq7xkpv2Mhttslg7Hw= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/kustomize/api v0.17.1 h1:MYJBOP/yQ3/5tp4/sf6HiiMfNNyO97LmtnirH9SLNr4= +sigs.k8s.io/kustomize/api v0.17.1/go.mod h1:ffn5491s2EiNrJSmgqcWGzQUVhc/pB0OKNI0HsT/0tA= +sigs.k8s.io/kustomize/kyaml v0.17.0 h1:G2bWs03V9Ur2PinHLzTUJ8Ded+30SzXZKiO92SRDs3c= +sigs.k8s.io/kustomize/kyaml v0.17.0/go.mod h1:6lxkYF1Cv9Ic8g/N7I86cvxNc5iinUo/P2vKsHNmpyE= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= +sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= +sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/auth/options.go b/auth/options.go deleted file mode 100644 index b17a9792..00000000 --- a/auth/options.go +++ /dev/null @@ -1,37 +0,0 @@ -/* -Copyright 2024 The Flux authors - -Licensed under the Apache License, Version 2.0 (the "License"); you may not use -this file except in compliance with the License. - -You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software distributed -under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -CONDITIONS OF ANY KIND, either express or implied. See the License for the -specific language governing permissions and limitations under the License. -*/ - -package auth - -import ( - "github.com/fluxcd/pkg/auth/azure" -) - -const ( - ProviderAzure = "azure" -) - -// AuthOptions contains options that can be used for authentication. -type AuthOptions struct { - // ProviderOptions specifies the options to configure various authentication - // providers. - ProviderOptions ProviderOptions -} - -// ProviderOptions contains options to configure various authentication -// providers. -type ProviderOptions struct { - AzureOpts []azure.ProviderOptFunc -} From b7425e149afdd4e5cc6ea923906f4e02a06ba002 Mon Sep 17 00:00:00 2001 From: Dipti Pai Date: Fri, 12 Jul 2024 12:57:48 -0700 Subject: [PATCH 3/5] Add cache credentials function Signed-off-by: Dipti Pai --- auth/git/credentials.go | 23 +++++++++++++---------- auth/git/credentials_test.go | 8 +++++--- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/auth/git/credentials.go b/auth/git/credentials.go index 615708bf..8d4da269 100644 --- a/auth/git/credentials.go +++ b/auth/git/credentials.go @@ -16,6 +16,7 @@ package git import ( "context" + "time" "github.com/fluxcd/pkg/auth" "github.com/fluxcd/pkg/auth/azure" @@ -23,10 +24,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log" ) -const ( - ProviderAzure = "azure" -) - // AuthOptions contains options that can be used for authentication. type AuthOptions struct { // ProviderOptions specifies the options to configure various authentication @@ -47,6 +44,7 @@ type ProviderOptions struct { // repository. type Credentials struct { BearerToken string `json:"bearerToken,omitempty"` + ExpiresOn time.Time } // ToSecretData returns the Credentials object in the format of the data found @@ -61,6 +59,16 @@ func (c *Credentials) ToSecretData() map[string][]byte { return data } +func CacheCredentials(ctx context.Context, url string, authOpts *AuthOptions, creds *Credentials) { + log := log.FromContext(ctx) + if authOpts.Cache != nil { + err := cacheObject(authOpts.Cache, *creds, url, creds.ExpiresOn) + if err != nil { + log.Error(err, "failed to cache credentials") + } + } +} + // GetCredentials returns authentication credentials for accessing the provided // Git repository. func GetCredentials(ctx context.Context, url string, provider string, authOpts *AuthOptions) (*Credentials, error) { @@ -90,12 +98,7 @@ func GetCredentials(ctx context.Context, url string, provider string, authOpts * } creds = Credentials{ BearerToken: accessToken.Token, - } - if authOpts.Cache != nil { - err := cacheObject(authOpts.Cache, creds, url, accessToken.ExpiresOn) - if err != nil { - log.Error(err, "failed to cache auth object") - } + ExpiresOn: accessToken.ExpiresOn, } default: return nil, nil diff --git a/auth/git/credentials_test.go b/auth/git/credentials_test.go index 7d325c73..1b77307a 100644 --- a/auth/git/credentials_test.go +++ b/auth/git/credentials_test.go @@ -124,12 +124,14 @@ func TestGetCredentialsWithCache(t *testing.T) { tt.authOpts.Cache = cache ctx := context.WithValue(context.TODO(), "scope", pointer.String("")) - _, err = GetCredentials(ctx, tt.url, tt.provider, tt.authOpts) + creds, err := GetCredentials(ctx, tt.url, tt.provider, tt.authOpts) g.Expect(err).ToNot(HaveOccurred()) - creds, exists, err := getObjectFromCache(cache, tt.url) + g.Expect(creds).ToNot(BeNil()) + CacheCredentials(ctx, tt.url, tt.authOpts, creds) + cachedCreds, exists, err := getObjectFromCache(cache, tt.url) g.Expect(err).ToNot(HaveOccurred()) g.Expect(exists).To(BeTrue()) - g.Expect(creds).ToNot(BeNil()) + g.Expect(cachedCreds).ToNot(BeNil()) obj, _, err := cache.GetByKey(tt.url) g.Expect(err).ToNot(HaveOccurred()) expiration, err := cache.GetExpiration(obj) From d96622d5076666ead4570477275e0c8c348193f9 Mon Sep 17 00:00:00 2001 From: Dipti Pai Date: Fri, 19 Jul 2024 13:37:47 -0700 Subject: [PATCH 4/5] If applied, this commit creates a new category of git integration tests. - testapp is modified to accept category git and test cloning azure devops git repository using workload identity. - Azure terraform files are separated into oci and git. Azure terraform files for git require an organization and PAT and create ADO project and repository - suite_test.go is modified to add new git category and setup provider specific test configuration and permissions on git repository - azure_test.go has new functions to return test configuration based on the git terraform file output and API to give the workload identity access to the ADO repository. - repo_list_test.go has a new test to validate Azure OIDC for ADO repository. - util_test.go is a new utility with functions to get the gogit client to clone, commit and push changes to a git repository. Signed-off-by: Dipti Pai --- oci/tests/integration/.env.sample | 2 + oci/tests/integration/Makefile | 14 +- oci/tests/integration/README.md | 37 +++- oci/tests/integration/aws_test.go | 8 + oci/tests/integration/azure_test.go | 163 +++++++++++++- oci/tests/integration/gcp_test.go | 8 + oci/tests/integration/go.mod | 49 +++-- oci/tests/integration/go.sum | 107 +++++++--- oci/tests/integration/repo_list_test.go | 56 ++++- oci/tests/integration/suite_test.go | 202 ++++++++++++++---- .../integration/terraform/azure/git/main.tf | 70 ++++++ .../terraform/azure/git/outputs.tf | 37 ++++ .../terraform/azure/git/variables.tf | 37 ++++ .../terraform/azure/{ => oci}/main.tf | 0 .../terraform/azure/{ => oci}/outputs.tf | 4 + .../terraform/azure/{ => oci}/variables.tf | 2 +- oci/tests/integration/testapp/main.go | 107 +++++++++- oci/tests/integration/util_test.go | 123 +++++++++++ 18 files changed, 907 insertions(+), 119 deletions(-) create mode 100644 oci/tests/integration/terraform/azure/git/main.tf create mode 100644 oci/tests/integration/terraform/azure/git/outputs.tf create mode 100644 oci/tests/integration/terraform/azure/git/variables.tf rename oci/tests/integration/terraform/azure/{ => oci}/main.tf (100%) rename oci/tests/integration/terraform/azure/{ => oci}/outputs.tf (72%) rename oci/tests/integration/terraform/azure/{ => oci}/variables.tf (99%) create mode 100644 oci/tests/integration/util_test.go diff --git a/oci/tests/integration/.env.sample b/oci/tests/integration/.env.sample index e50eb0c1..0aa2cb14 100644 --- a/oci/tests/integration/.env.sample +++ b/oci/tests/integration/.env.sample @@ -18,6 +18,8 @@ # export ARM_CLIENT_SECRET= # export ARM_SUBSCRIPTION_ID= # export ARM_TENANT_ID= +# export TF_VAR_devops_org = +# export TF_VAR_pat = ## GCP # export TF_VAR_gcp_project_id= diff --git a/oci/tests/integration/Makefile b/oci/tests/integration/Makefile index 2183bfd6..69f0934d 100644 --- a/oci/tests/integration/Makefile +++ b/oci/tests/integration/Makefile @@ -20,8 +20,11 @@ test: test-aws: $(MAKE) test PROVIDER_ARG="-provider aws" -test-azure: - $(MAKE) test PROVIDER_ARG="-provider azure" +test-azure-oci: + $(MAKE) test PROVIDER_ARG="-provider azure -category oci" + +test-azure-git: + $(MAKE) test PROVIDER_ARG="-provider azure -category git" test-gcp: $(MAKE) test PROVIDER_ARG="-provider gcp" @@ -32,8 +35,11 @@ destroy: destroy-aws: $(MAKE) destroy PROVIDER_ARG="-provider aws" -destroy-azure: - $(MAKE) destroy PROVIDER_ARG="-provider azure" +destroy-azure-oci: + $(MAKE) destroy PROVIDER_ARG="-provider azure -category oci" + +destroy-azure-git: + $(MAKE) destroy PROVIDER_ARG="-provider azure -category git" destroy-gcp: $(MAKE) destroy PROVIDER_ARG="-provider gcp" diff --git a/oci/tests/integration/README.md b/oci/tests/integration/README.md index 3fc14ce3..9a390c79 100644 --- a/oci/tests/integration/README.md +++ b/oci/tests/integration/README.md @@ -1,7 +1,7 @@ -# OCI integration test +# Integration tests -OCI integration test uses a test application(`testapp/`) to test the -oci package against each of the supported cloud providers. +Integration tests uses a test application(`testapp/`) to test the +oci and git package against each of the supported cloud providers. **NOTE:** Tests in this package aren't run automatically by the `test-*` make target at the root of `fluxcd/pkg` repo. These tests are more complicated than @@ -16,7 +16,7 @@ runs the test app as a batch job which tries to log in and list tags from the test registry repository. A successful job indicates successful test. If the job fails, the test fails. -Logs of a successful job run: +Logs of a successful job run for oci: ```console $ kubectl logs test-job-93tbl-4jp2r 2022/07/28 21:59:06 repo: xxx.dkr.ecr.us-east-2.amazonaws.com/test-repo-flux-test-heroic-ram @@ -25,6 +25,17 @@ $ kubectl logs test-job-93tbl-4jp2r 2022/07/28 21:59:06 tags: [v0.1.4 v0.1.3 v0.1.0 v0.1.2] ``` +Logs of a successful job run for git: +```console +$ kubectl logs test-job-dzful-jrcqw +2024/07/19 19:04:06 Validating git oidc by cloning repo https://dev.azure.com/xxx/fluxProjtoughowerewolf/_git/fluxRepotoughowerewolf +2024/07/19 19:04:07 Successfully cloned repository +2024/07/19 19:04:07 apiVersion: v1 +kind: ConfigMap +metadata: + name: foobar +``` + ## Requirements ### Amazon Web Services @@ -42,6 +53,11 @@ $ kubectl logs test-job-93tbl-4jp2r workloads to access ACR. - Azure CLI, need to be logged in using `az login` as a User (not a Service Principal). +- (To run the git integration tests) An Azure DevOps organization, personal access token for accessing repositories within the organization. The scope required for the personal access token is: + - Project and Team - read, write and manage access + - Member Entitlement Management (Read & Write) + - Code - Full + - Please take a look at the [terraform provider](https://registry.terraform.io/providers/microsoft/azuredevops/latest/docs/guides/authenticating_using_the_personal_access_token#create-a-personal-access-token) for more explanation. **NOTE:** To use Service Principal (for example in CI environment), set the `ARM-*` variables in `.env`, source it and authenticate Azure CLI with: @@ -243,12 +259,14 @@ Run the test with `make test-*`, setting the test app image with variable `fluxcd/testapp:test`, will be used. ```console -$ make test-azure -make test PROVIDER_ARG="-provider azure" +$ make test-azure-oci +make test PROVIDER_ARG="-provider azure -category oci" docker image inspect fluxcd/testapp:test >/dev/null -TEST_IMG=fluxcd/testapp:test go test -timeout 30m -v ./ -verbose -retain -provider azure --tags=integration -2022/07/29 02:06:51 Terraform binary: /usr/bin/terraform -2022/07/29 02:06:51 Init Terraform +TEST_IMG=fluxcd/testapp:test go test -timeout 30m -v ./ -provider azure -category oci --tags=integration +2024/07/19 13:07:14 Terraform binary: /snap/bin/terraform +2024/07/19 13:07:14 Init Terraform +2024/07/19 13:07:18 Checking for an empty Terraform state +2024/07/19 13:07:18 Applying Terraform ... ``` @@ -273,6 +291,7 @@ export TF_VAR_enable_wi= They have been included in the `.env.sample` and you can simply uncomment it. +The git integration tests require workload identity to be enabled. ## Debugging the tests For debugging environment provisioning, enable verbose output with `-verbose` diff --git a/oci/tests/integration/aws_test.go b/oci/tests/integration/aws_test.go index 640a514b..d48a8751 100644 --- a/oci/tests/integration/aws_test.go +++ b/oci/tests/integration/aws_test.go @@ -98,3 +98,11 @@ func getWISAAnnotationsAWS(output map[string]*tfjson.StateOutput) (map[string]st eksRoleArnAnnotation: iamARN, }, nil } + +func getTestConfigAWS(outputs map[string]*tfjson.StateOutput) (*testConfig, error) { + return nil, fmt.Errorf("NotImplemented for AWS") +} + +func givePermissionsToRepositoryAWS(output map[string]*tfjson.StateOutput) error { + return fmt.Errorf("NotImplemented for AWS") +} diff --git a/oci/tests/integration/azure_test.go b/oci/tests/integration/azure_test.go index 104ca721..d0df2d22 100644 --- a/oci/tests/integration/azure_test.go +++ b/oci/tests/integration/azure_test.go @@ -20,12 +20,20 @@ limitations under the License. package integration import ( + "bytes" "context" + "encoding/base64" + "encoding/json" "fmt" + "io/ioutil" + "log" + "net/http" + "strings" + "time" - tfjson "github.com/hashicorp/terraform-json" - + "github.com/fluxcd/pkg/git" "github.com/fluxcd/test-infra/tftestenv" + tfjson "github.com/hashicorp/terraform-json" ) const ( @@ -81,3 +89,154 @@ func getWISAAnnotationsAzure(output map[string]*tfjson.StateOutput) (map[string] azureWIClientIdAnnotation: clientID, }, nil } + +// Give managed identity permissions on the azure devops project using +// ServicePrincipalEntitlement REST API +// https://learn.microsoft.com/en-us/rest/api/azure/devops/memberentitlementmanagement/service-principal-entitlements/add?view=azure-devops-rest-7.1&tabs=HTTP +// This can be moved to terraform if/when this PR completes - +// https://github.com/microsoft/terraform-provider-azuredevops/pull/1028 +type ServicePrincipalEntitlement struct { + AccessLevel struct { + AccountLicenseType string `json:"accountLicenseType"` + } `json:"accessLevel"` + ProjectEntitlements []struct { + Group struct { + GroupType string `json:"groupType"` + } `json:"group"` + ProjectRef struct { + ID string `json:"id"` + } `json:"projectRef"` + } `json:"projectEntitlements"` + ServicePrincipal struct { + Origin string `json:"origin"` + OriginID string `json:"originId"` + SubjectKind string `json:"subjectKind"` + } `json:"servicePrincipal"` +} + +func givePermissionsToRepositoryAzure(outputs map[string]*tfjson.StateOutput) error { + // Organization, PAT, Project ID and WI ID are availble as terraform output + organization := outputs["azure_devops_organization"].Value.(string) + project_id := outputs["azure_devops_project_id"].Value.(string) + pat := outputs["azure_devops_access_token"].Value.(string) + wi_object_id := outputs["workload_identity_object_id"].Value.(string) + + encodedPat := base64.StdEncoding.EncodeToString([]byte(":" + pat)) + apiURL := fmt.Sprintf("https://vsaex.dev.azure.com/%s/_apis/serviceprincipalentitlements?api-version=7.1-preview.1", organization) + + // Set up the request payload + payload := ServicePrincipalEntitlement{ + AccessLevel: struct { + AccountLicenseType string `json:"accountLicenseType"` + }{ + AccountLicenseType: "express", + }, + ProjectEntitlements: []struct { + Group struct { + GroupType string `json:"groupType"` + } `json:"group"` + ProjectRef struct { + ID string `json:"id"` + } `json:"projectRef"` + }{ + { + Group: struct { + GroupType string `json:"groupType"` + }{ + GroupType: "projectContributor", + }, + ProjectRef: struct { + ID string `json:"id"` + }{ + ID: project_id, + }, + }, + }, + ServicePrincipal: struct { + Origin string `json:"origin"` + OriginID string `json:"originId"` + SubjectKind string `json:"subjectKind"` + }{ + Origin: "aad", + OriginID: wi_object_id, + SubjectKind: "servicePrincipal", + }, + } + + // Marshal the payload into JSON + jsonPayload, err := json.Marshal(payload) + if err != nil { + log.Printf("Error marshalling the payload:%v", err) + return err + } + + // First request to add user always fails, second request succeeds, add a + // retry + retryAttempts := 3 + retryDelay := 5 * time.Second // 5 seconds delay + attempts := 0 + + for attempts < retryAttempts { + attempts++ + // Create a new request + req, err := http.NewRequest("POST", apiURL, bytes.NewBuffer(jsonPayload)) + if err != nil { + log.Printf("Error creating the request: %v", err) + return err + } + + // Set the authorization header to use the PAT + req.Header.Set("Authorization", "Basic "+strings.TrimSpace(encodedPat)) + req.Header.Set("Content-Type", "application/json") + + // Send the request + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + log.Printf("Error sending the request: %v", err) + return err + } + defer resp.Body.Close() + + // Read the response body + body, err := ioutil.ReadAll(resp.Body) + if err != nil || strings.Contains(string(body), "VS403283: Could not add user") { + log.Printf("Encountered error : %v, retrying..", err) + time.Sleep(retryDelay) + continue + } + + log.Printf("Added managed identity to organization:") + break + } + return nil +} + +// getTestConfigAzure returns the test config used to setup the git repository +func getTestConfigAzure(outputs map[string]*tfjson.StateOutput) (*testConfig, error) { + config := &testConfig{ + defaultGitTransport: git.HTTP, + gitUsername: git.DefaultPublicKeyAuthUser, + gitPat: outputs["azure_devops_access_token"].Value.(string), + applicationRepository: outputs["git_repo_url"].Value.(string), + } + + opts, err := getAuthOpts(config.applicationRepository, map[string][]byte{ + "password": []byte(config.gitPat), + "username": []byte(git.DefaultPublicKeyAuthUser), + }) + if err != nil { + return nil, err + } + config.defaultAuthOpts = opts + + parts := strings.Split(config.applicationRepository, "@") + // Check if the URL contains the "@" symbol + if len(parts) > 1 { + // Reconstruct the URL without the username + config.applicationRepositoryWithoutUser = "https://" + parts[1] + } + + fmt.Println("URL without username:", config.applicationRepositoryWithoutUser) + return config, nil +} diff --git a/oci/tests/integration/gcp_test.go b/oci/tests/integration/gcp_test.go index a92b5791..5f47b796 100644 --- a/oci/tests/integration/gcp_test.go +++ b/oci/tests/integration/gcp_test.go @@ -90,3 +90,11 @@ func getWISAAnnotationsGCP(output map[string]*tfjson.StateOutput) (map[string]st gcpIAMAnnotation: saEmail, }, nil } + +func getTestConfigGCP(outputs map[string]*tfjson.StateOutput) (*testConfig, error) { + return nil, fmt.Errorf("NotImplemented for GCP") +} + +func givePermissionsToRepositoryGCP(output map[string]*tfjson.StateOutput) error { + return fmt.Errorf("NotImplemented for GCP") +} diff --git a/oci/tests/integration/go.mod b/oci/tests/integration/go.mod index 3ec4ef63..2018212a 100644 --- a/oci/tests/integration/go.mod +++ b/oci/tests/integration/go.mod @@ -1,6 +1,8 @@ module github.com/fluxcd/pkg/oci/tests/integration -go 1.22.0 +go 1.22.4 + +toolchain go1.22.5 replace ( github.com/fluxcd/pkg/cache => ../../../cache @@ -8,9 +10,13 @@ replace ( ) require ( + github.com/fluxcd/pkg/auth v0.0.0-00010101000000-000000000000 github.com/fluxcd/pkg/cache v0.0.1 + github.com/fluxcd/pkg/git v0.19.0 + github.com/fluxcd/pkg/git/gogit v0.19.0 github.com/fluxcd/pkg/oci v0.34.0 github.com/fluxcd/test-infra/tftestenv v0.0.0-20240110132047-17651823b08c + github.com/go-git/go-git/v5 v5.12.0 github.com/google/go-containerregistry v0.19.1 github.com/hashicorp/terraform-exec v0.20.0 github.com/hashicorp/terraform-json v0.19.0 @@ -21,11 +27,14 @@ require ( ) require ( - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1 // indirect - github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.2 // indirect - github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 // indirect + dario.cat/mergo v1.0.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.12.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/internal v1.9.0 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect - github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect + github.com/Masterminds/semver/v3 v3.2.1 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/ProtonMail/go-crypto v1.0.0 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/aws/aws-sdk-go-v2 v1.26.1 // indirect github.com/aws/aws-sdk-go-v2/config v1.27.11 // indirect @@ -46,16 +55,22 @@ require ( github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cloudflare/circl v1.3.7 // indirect github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect + github.com/cyphar/filepath-securejoin v0.2.4 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/docker/cli v24.0.9+incompatible // indirect github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/docker v24.0.9+incompatible // indirect github.com/docker/docker-credential-helpers v0.7.0 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/emirpasic/gods v1.18.1 // indirect github.com/evanphx/json-patch/v5 v5.9.0 // indirect github.com/fluxcd/cli-utils v0.36.0-flux.7 // indirect + github.com/fluxcd/pkg/ssh v0.13.0 // indirect + github.com/fluxcd/pkg/version v0.4.0 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-errors/errors v1.5.1 // indirect + github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect + github.com/go-git/go-billy/v5 v5.5.0 // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/zapr v1.3.0 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect @@ -76,9 +91,11 @@ require ( github.com/hashicorp/go-version v1.6.0 // indirect github.com/hashicorp/hc-install v0.6.2 // indirect github.com/imdario/mergo v0.3.15 // indirect + github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/klauspost/compress v1.17.4 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect @@ -89,34 +106,40 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0-rc3 // indirect + github.com/pjbgf/sha1cd v0.3.0 // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pkg/errors v0.9.1 // indirect github.com/prometheus/client_golang v1.19.0 // indirect github.com/prometheus/client_model v0.5.0 // indirect github.com/prometheus/common v0.48.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect + github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/sirupsen/logrus v1.9.3 // indirect + github.com/skeema/knownhosts v1.2.2 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/vbatts/tar-split v0.11.3 // indirect + github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xlab/treeprint v1.2.0 // indirect github.com/zclconf/go-cty v1.14.1 // indirect go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect - golang.org/x/crypto v0.22.0 // indirect + golang.org/x/crypto v0.24.0 // indirect golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect - golang.org/x/mod v0.15.0 // indirect - golang.org/x/net v0.24.0 // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/net v0.26.0 // indirect golang.org/x/oauth2 v0.19.0 // indirect golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.19.0 // indirect - golang.org/x/term v0.19.0 // indirect - golang.org/x/text v0.14.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/term v0.21.0 // indirect + golang.org/x/text v0.16.0 // indirect golang.org/x/time v0.5.0 // indirect + golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/protobuf v1.33.0 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/apiextensions-apiserver v0.30.0 // indirect @@ -124,10 +147,12 @@ require ( k8s.io/client-go v0.30.0 // indirect k8s.io/klog/v2 v2.120.1 // indirect k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect - k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect + k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/kustomize/api v0.17.1 // indirect sigs.k8s.io/kustomize/kyaml v0.17.0 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.4.0 // indirect ) + +replace github.com/fluxcd/pkg/auth => github.com/dipti-pai/pkg/auth v0.0.0-20240712195748-b7425e149afd diff --git a/oci/tests/integration/go.sum b/oci/tests/integration/go.sum index 8fc2c40d..3322f565 100644 --- a/oci/tests/integration/go.sum +++ b/oci/tests/integration/go.sum @@ -1,12 +1,12 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1 h1:E+OJmp2tPvt1W+amx48v1eqbjDYsgN+RzP4q16yV5eM= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1/go.mod h1:a6xsAQUZg+VsS3TJ05SRp524Hs4pZ/AeFSr5ENf0Yjo= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.2 h1:FDif4R1+UUR+00q6wquyX90K7A8dN+R5E8GEadoP7sU= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.2/go.mod h1:aiYBYui4BJ/BJCAIKs92XiPyQfTaBWqvHujDwKb6CBU= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 h1:LqbJ/WzJUwBf8UiaSzgX7aMclParm9/5Vgp+TY51uBQ= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2/go.mod h1:yInRyqWXAuaPrgI7p70+lDDgh3mlBohis29jGMISnmc= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.12.0 h1:1nGuui+4POelzDwI7RG56yfQJHCnKvwfMoU7VsEp+Zg= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.12.0/go.mod h1:99EvauvlcJ1U06amZiksfYz/3aFGyIhWGHVyiZXtBAI= +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/internal v1.9.0 h1:H+U3Gk9zY56G3u872L82bk4thcsy2Gghb9ExT4Zvm1o= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.9.0/go.mod h1:mgrmMSgaLp9hmax62XQTd0N4aAqSE5E0DulSpVYK7vc= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 h1:XHOnouVk1mxXfQidrMEnLlPk9UMeRtyBTnEFtxkV0kU= @@ -15,12 +15,19 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= +github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= +github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg= -github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= +github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78= +github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/aws/aws-sdk-go-v2 v1.26.1 h1:5554eUqIYVWpU0YmeeYZ0wU64H2VLBs8TlhRB2L+EkA= github.com/aws/aws-sdk-go-v2 v1.26.1/go.mod h1:ffIFB97e2yNsv4aTSGkqtHnppsIJzw7G7BReUZ3jCXM= github.com/aws/aws-sdk-go-v2/config v1.27.11 h1:f47rANd2LQEYHda2ddSCKYId18/8BhSRM4BULGmfgNA= @@ -76,8 +83,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= -github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= +github.com/dipti-pai/pkg/auth v0.0.0-20240712195748-b7425e149afd h1:E1ZHKeQiL57c73F6EpAhLTXVdGWBoJEZ4Kmzz/l6ucI= +github.com/dipti-pai/pkg/auth v0.0.0-20240712195748-b7425e149afd/go.mod h1:dkgECFjmpiIoSghxTJP97LERCVN7NfwjwMJrGOnqQ90= github.com/docker/cli v24.0.9+incompatible h1:OxbimnP/z+qVjDLpq9wbeFU3Nc30XhSe+LkwYQisD50= github.com/docker/cli v24.0.9+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= @@ -86,6 +93,8 @@ github.com/docker/docker v24.0.9+incompatible h1:HPGzNmwfLZWdxHqK9/II92pyi1EpYKs github.com/docker/docker v24.0.9+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= +github.com/elazarl/goproxy v0.0.0-20231117061959-7cc037d33fb5 h1:m62nsMU279qRD9PQSWD1l66kmkXzuYcnVJqL4XLeV2M= +github.com/elazarl/goproxy v0.0.0-20231117061959-7cc037d33fb5/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= @@ -100,18 +109,34 @@ github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwC github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= github.com/fluxcd/cli-utils v0.36.0-flux.7 h1:81zEo/LNmIRWMgtsZy/8L13TMUZHmmJib4gHRvKwVE8= github.com/fluxcd/cli-utils v0.36.0-flux.7/go.mod h1:TcfLhvBjtQnqxYMsHQUAEB2c5WJRVuibtas2Izz5ZTs= +github.com/fluxcd/gitkit v0.6.0 h1:iNg5LTx6ePo+Pl0ZwqHTAkhbUHxGVSY3YCxCdw7VIFg= +github.com/fluxcd/gitkit v0.6.0/go.mod h1:svOHuKi0fO9HoawdK4HfHAJJseZDHHjk7I3ihnCIqNo= +github.com/fluxcd/pkg/git v0.19.0 h1:zIv+GAT0ieIUpnGBVi3Bhax/qq4Rr28BW7Jv4DTt6zE= +github.com/fluxcd/pkg/git v0.19.0/go.mod h1:wkqUOSrTjtsVVk/gC6/7RxVpi9GcqAA+7O5HVJF5S14= +github.com/fluxcd/pkg/git/gogit v0.19.0 h1:SdoNAmC/HTPXniQjp609X59rCsBiA+Sdq1Hv8SnYC6I= +github.com/fluxcd/pkg/git/gogit v0.19.0/go.mod h1:8kOmrNMjq8daQTVLhp6klhuoY8+s81gydM0MozDjaHM= +github.com/fluxcd/pkg/gittestserver v0.12.0 h1:QGbIVyje9U6urSAeDw3diKb/5wdA+Cnw1YJN+3Zflaw= +github.com/fluxcd/pkg/gittestserver v0.12.0/go.mod h1:Eh82e+kzKdhpafnUwR5oCBmxqAqhF5QuCn290AFntPM= +github.com/fluxcd/pkg/ssh v0.13.0 h1:lPU1Gst8XIz7AU2dhdqVFaaOWd54/O1LZu62vH4JB/s= +github.com/fluxcd/pkg/ssh v0.13.0/go.mod h1:J9eyirMd4s++tWG4euRRhmcthKX203GPHpzFpH++TP8= +github.com/fluxcd/pkg/version v0.4.0 h1:3F6oeIZ+ug/f7pALIBhcUhfURel37EPPOn7nsGfsnOg= +github.com/fluxcd/pkg/version v0.4.0/go.mod h1:izVsSDxac81qWRmpOL9qcxZYx+zAN1ajoP5SidGP6PA= github.com/fluxcd/test-infra/tftestenv v0.0.0-20240110132047-17651823b08c h1:Cz+NgW2Y0rNODbwanioXO79dUgm9mzGBfQyp5COvNz4= github.com/fluxcd/test-infra/tftestenv v0.0.0-20240110132047-17651823b08c/go.mod h1:liFlLEXgambGVdWSJ4JzbIHf1Vjpp1HwUyPazPIVZug= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE= +github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8= github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk= github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= -github.com/go-git/go-git/v5 v5.11.0 h1:XIZc1p+8YzypNr34itUfSvYJcv+eYdTnTvOZ2vD3cA4= -github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lKqXmCUiUCY= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= +github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= +github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= @@ -126,6 +151,8 @@ github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+ github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= +github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= +github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= 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/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= @@ -206,6 +233,7 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -266,18 +294,19 @@ github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSz github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= -github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ= -github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= +github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= +github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -287,7 +316,9 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= @@ -318,10 +349,11 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk 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-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= -golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= @@ -332,8 +364,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= -golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -343,12 +375,13 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL 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.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= -golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg= golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8= @@ -364,8 +397,11 @@ golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 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-20191026070338-33540a1f6037/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-20210124154548-22da62e12c0c/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-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -376,24 +412,25 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/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.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.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.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= -golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= +golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= +golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= 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.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -406,8 +443,8 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= -golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -433,6 +470,7 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= @@ -441,6 +479,7 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= @@ -469,8 +508,8 @@ k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7F k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= k8s.io/kubectl v0.30.0 h1:xbPvzagbJ6RNYVMVuiHArC1grrV5vSmmIcSZuCdzRyk= k8s.io/kubectl v0.30.0/go.mod h1:zgolRw2MQXLPwmic2l/+iHs239L49fhSeICuMhQQXTI= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 h1:jgGTlFYnhF1PM1Ax/lAlxUPE+KfCIXHaathvJg1C3ak= +k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= sigs.k8s.io/controller-runtime v0.18.1 h1:RpWbigmuiylbxOCLy0tGnq1cU1qWPwNIQzoJk+QeJx4= sigs.k8s.io/controller-runtime v0.18.1/go.mod h1:tuAt1+wbVsXIT8lPtk5RURxqAnq7xkpv2Mhttslg7Hw= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= diff --git a/oci/tests/integration/repo_list_test.go b/oci/tests/integration/repo_list_test.go index 459cf566..7eba84b8 100644 --- a/oci/tests/integration/repo_list_test.go +++ b/oci/tests/integration/repo_list_test.go @@ -32,51 +32,89 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" ) -func TestImageRepositoryListTags(t *testing.T) { +func TestOciImageRepositoryListTags(t *testing.T) { + if !enableOci { + t.Skip("Skipping oci feature tests, specify -category oci to enable") + } + for name, repo := range testRepos { t.Run(name, func(t *testing.T) { - args := []string{fmt.Sprintf("-repo=%s", repo)} - testImageRepositoryListTags(t, args) + args := []string{ + "-category=oci", + fmt.Sprintf("-repo=%s", repo), + } + testjobExecutionWithArgs(t, args) }) } } -func TestRepositoryRootLoginListTags(t *testing.T) { +func TestOciRepositoryRootLoginListTags(t *testing.T) { + if !enableOci { + t.Skip("Skipping oci feature tests, specify -category oci to enable") + } + for name, repo := range testRepos { t.Run(name, func(t *testing.T) { parts := strings.SplitN(repo, "/", 2) args := []string{ + "-category=oci", fmt.Sprintf("-registry=%s", parts[0]), fmt.Sprintf("-repo=%s", parts[1]), } - testImageRepositoryListTags(t, args) + testjobExecutionWithArgs(t, args) }) } } -func TestOIDCLoginListTags(t *testing.T) { +func TestOciOIDCLoginListTags(t *testing.T) { + if !enableOci { + t.Skip("Skipping oci feature tests, specify -category oci to enable") + } + for name, repo := range testRepos { t.Run(name, func(t *testing.T) { // Registry only. parts := strings.SplitN(repo, "/", 2) args := []string{ + "-category=oci", "-oidc-login=true", fmt.Sprintf("-registry=%s", parts[0]), fmt.Sprintf("-repo=%s", parts[1]), } - testImageRepositoryListTags(t, args) + testjobExecutionWithArgs(t, args) // Registry + repo. args = []string{ + "-category=oci", "-oidc-login=true", fmt.Sprintf("-repo=%s", repo), } - testImageRepositoryListTags(t, args) + testjobExecutionWithArgs(t, args) }) } } -func testImageRepositoryListTags(t *testing.T, args []string) { +func TestGitCloneUsingProvider(t *testing.T) { + if !enableGit { + t.Skip("Skipping git feature tests, specify -category git to enable") + } + + ctx := context.TODO() + tmpDir := t.TempDir() + + setupGitRepository(ctx, tmpDir) + t.Run("Git oidc credential test", func(t *testing.T) { + args := []string{ + "-category=git", + "-oidc-login=true", + fmt.Sprintf("-provider=%s", *targetProvider), + fmt.Sprintf("-repo=%s", cfg.applicationRepositoryWithoutUser), + } + testjobExecutionWithArgs(t, args) + }) +} + +func testjobExecutionWithArgs(t *testing.T, args []string) { g := NewWithT(t) ctx := context.TODO() diff --git a/oci/tests/integration/suite_test.go b/oci/tests/integration/suite_test.go index 2ddc566e..62bff561 100644 --- a/oci/tests/integration/suite_test.go +++ b/oci/tests/integration/suite_test.go @@ -37,6 +37,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + "github.com/fluxcd/pkg/git" "github.com/fluxcd/test-infra/tftestenv" ) @@ -46,7 +47,9 @@ const ( terraformPathAWS = "./terraform/aws" // terraformPathAzure is the path to the terraform working directory // containing the azure terraform configurations. - terraformPathAzure = "./terraform/azure" + terraformPathAzureOci = "./terraform/azure/oci" + terraformPathAzureGit = "./terraform/azure/git" + // terraformPathGCP is the path to the terraform working directory // containing the gcp terraform configurations. terraformPathGCP = "./terraform/gcp" @@ -66,11 +69,26 @@ const ( ) var ( + // supportedCategories are the test categories that can be run. + supportedCategories = []string{"oci", "git"} + + // supportedOciProviders are the providers supported by the test. + supportedOciProviders = []string{"aws", "azure", "gcp"} + // supportedProviders are the providers supported by the test. - supportedProviders = []string{"aws", "azure", "gcp"} + supportedGitProviders = []string{"azure"} // targetProvider is the name of the kubernetes provider to test against. - targetProvider = flag.String("provider", "", fmt.Sprintf("name of the provider %v", supportedProviders)) + targetProvider = flag.String("provider", "", fmt.Sprintf("name of the provider %v for oci, %v for git", supportedOciProviders, supportedGitProviders)) + + // category is the name of the kubernetes provider to test against. + category = flag.String("category", "", fmt.Sprintf("name of the category %v", supportedCategories)) + + // enableOci is set to true when a supported provider is specified for category oci + enableOci bool + + // enableGit is set to true when a supported provider is specified for category git + enableGit bool // retain flag to prevent destroy and retaining the created infrastructure. retain = flag.Bool("retain", false, "retain the infrastructure for debugging purposes") @@ -106,8 +124,11 @@ var ( // identity. It is set from the terraform variable (`TF_VAR_k8s_serviceaccount_name`) wiServiceAccount string - // enableWI is set to true when the TF_vAR_enable_wi is set to "true", so the tests run for Workload Identtty + // enableWI is set to true when the TF_VAR_enable_wi is set to "true", so the tests run for Workload Identtty enableWI bool + + // cfg is a struct containing different variables needed for the test. + cfg *testConfig ) // registryLoginFunc is used to perform registry login against a provider based @@ -126,6 +147,23 @@ type pushTestImages func(ctx context.Context, localImgs map[string]string, outpu // service account when workload identity is used on the cluster. type getWISAAnnotations func(output map[string]*tfjson.StateOutput) (map[string]string, error) +// givePermissionsToRepository calls provider specific API to add additional permissions to the git repository/project +type givePermissionsToRepository func(output map[string]*tfjson.StateOutput) error + +// getTestConfig gets the configuration for the tests +type getTestConfig func(output map[string]*tfjson.StateOutput) (*testConfig, error) + +// testConfig hold different variable that will be needed by the different test functions. +type testConfig struct { + // authentication info for git repositories + gitPat string + gitUsername string + defaultGitTransport git.TransportType + defaultAuthOpts *git.AuthOptions + applicationRepository string + applicationRepositoryWithoutUser string +} + // ProviderConfig is the test configuration of a supported cloud provider to run // the tests against. type ProviderConfig struct { @@ -141,6 +179,10 @@ type ProviderConfig struct { // getWISAAnnotations is used to return the provider specific annotations // for the service account when using workload identity. getWISAAnnotations getWISAAnnotations + // givePermissionsToRepository is used to give the identity access to the Git repository + givePermissionsToRepository givePermissionsToRepository + // getTestConfig is used to return provider specific test configuration + getTestConfig getTestConfig } var letterRunes = []rune("abcdefghijklmnopqrstuvwxyz1234567890") @@ -157,6 +199,30 @@ func TestMain(m *testing.M) { flag.Parse() ctx := context.TODO() + // Validate the test category. + if *category == "" { + log.Fatalf("-category flag must be set to one of %v", supportedCategories) + } + + var supportedCategory bool + for _, p := range supportedCategories { + if p == *category { + supportedCategory = true + } + } + if !supportedCategory { + log.Fatalf("Unsupported category %q, must be one of %v", *category, supportedCategories) + } + + var supportedProviders []string + if *category == "oci" { + supportedProviders = supportedOciProviders + enableOci = true + } else if *category == "git" { + supportedProviders = supportedOciProviders + enableGit = true + } + // Validate the provider. if *targetProvider == "" { log.Fatalf("-provider flag must be set to one of %v", supportedProviders) @@ -171,6 +237,11 @@ func TestMain(m *testing.M) { log.Fatalf("Unsupported provider %q, must be one of %v", *targetProvider, supportedProviders) } + enableWI = os.Getenv("TF_VAR_enable_wi") == "true" + if enableGit && !enableWI { + log.Fatalf("Workload identity must be enabled to run git tests") + } + providerCfg := getProviderConfig(*targetProvider) if providerCfg == nil { log.Fatalf("Failed to get provider config for %q", *targetProvider) @@ -249,40 +320,31 @@ func TestMain(m *testing.M) { panic(fmt.Sprintf("Failed to get the terraform state output: %v", err)) } - testRepos, err = providerCfg.registryLogin(ctx, output) - if err != nil { - panic(fmt.Sprintf("Failed to log into registry: %v", err)) - } - - pushedImages, err := providerCfg.pushAppTestImages(ctx, localImgs, output) - if err != nil { - panic(fmt.Sprintf("Failed to push test images: %v", err)) - } - - if len(pushedImages) != 1 { - panic(fmt.Sprintf("Unexpected number of app images pushed: %d", len(pushedImages))) + if enableOci { + log.Println("OCI is enabled, push oci app and test images") + pushAppAndTestImagesOci(ctx, providerCfg, output, localImgs) } - if appImg, ok := pushedImages["app"]; !ok { - panic(fmt.Sprintf("Could not find pushed app image in %v", pushedImages)) - } else { - testAppImage = appImg + if enableGit { + log.Println("Git is enabled, push git app image and get test config") + pushAppImageGit(ctx, providerCfg, output, localImgs) + cfg, err = providerCfg.getTestConfig(output) } - // Create and push test images. - if err := tftestenv.CreateAndPushImages(testRepos, testImageTags); err != nil { - panic(fmt.Sprintf("Failed to create and push images: %v", err)) - } - - enableWI = os.Getenv("TF_VAR_enable_wi") == "true" if enableWI { - log.Println("Running tests with workload identity enabled") + if enableGit { + // Call provider specific API to configure permisions for the git repository + log.Println("Giving permissions to workload identity to access repository") + providerCfg.givePermissionsToRepository(output) + } + + log.Println("Workload identity is enabled, initializing service account with annotations") annotations, err := providerCfg.getWISAAnnotations(output) if err != nil { panic(fmt.Sprintf("Failed to get service account func for workload identity: %v", err)) } - if err := creatWorkloadIDServiceAccount(ctx, annotations); err != nil { + if err := createWorkloadIDServiceAccount(ctx, annotations); err != nil { panic(err) } } @@ -295,37 +357,87 @@ func getProviderConfig(provider string) *ProviderConfig { switch provider { case "aws": return &ProviderConfig{ - terraformPath: terraformPathAWS, - registryLogin: registryLoginECR, - pushAppTestImages: pushAppTestImagesECR, - createKubeconfig: createKubeconfigEKS, - getWISAAnnotations: getWISAAnnotationsAWS, + terraformPath: terraformPathAWS, + registryLogin: registryLoginECR, + pushAppTestImages: pushAppTestImagesECR, + createKubeconfig: createKubeconfigEKS, + getWISAAnnotations: getWISAAnnotationsAWS, + givePermissionsToRepository: givePermissionsToRepositoryAWS, + getTestConfig: getTestConfigAWS, } case "azure": - return &ProviderConfig{ - terraformPath: terraformPathAzure, - registryLogin: registryLoginACR, - pushAppTestImages: pushAppTestImagesACR, - createKubeconfig: createKubeConfigAKS, - getWISAAnnotations: getWISAAnnotationsAzure, + providerCfg := &ProviderConfig{ + registryLogin: registryLoginACR, + pushAppTestImages: pushAppTestImagesACR, + createKubeconfig: createKubeConfigAKS, + getWISAAnnotations: getWISAAnnotationsAzure, + givePermissionsToRepository: givePermissionsToRepositoryAzure, + getTestConfig: getTestConfigAzure, + } + if enableOci { + providerCfg.terraformPath = terraformPathAzureOci + } else if enableGit { + providerCfg.terraformPath = terraformPathAzureGit + } else { + panic("Invalid configuration") } + return providerCfg case "gcp": return &ProviderConfig{ - terraformPath: terraformPathGCP, - registryLogin: registryLoginGCR, - pushAppTestImages: pushAppTestImagesGCR, - createKubeconfig: createKubeconfigGKE, - getWISAAnnotations: getWISAAnnotationsGCP, + terraformPath: terraformPathGCP, + registryLogin: registryLoginGCR, + pushAppTestImages: pushAppTestImagesGCR, + createKubeconfig: createKubeconfigGKE, + getWISAAnnotations: getWISAAnnotationsGCP, + givePermissionsToRepository: givePermissionsToRepositoryGCP, + getTestConfig: getTestConfigGCP, } } return nil } +func pushAppImage(ctx context.Context, providerCfg *ProviderConfig, tfOutput map[string]*tfjson.StateOutput, localImgs map[string]string) { + pushedImages, err := providerCfg.pushAppTestImages(ctx, localImgs, tfOutput) + if err != nil { + panic(fmt.Sprintf("Failed to push test images: %v", err)) + } + + if len(pushedImages) != 1 { + panic(fmt.Sprintf("Unexpected number of app images pushed: %d", len(pushedImages))) + } + + if appImg, ok := pushedImages["app"]; !ok { + panic(fmt.Sprintf("Could not find pushed app image in %v", pushedImages)) + } else { + testAppImage = appImg + } +} + +func pushAppAndTestImagesOci(ctx context.Context, providerCfg *ProviderConfig, tfOutput map[string]*tfjson.StateOutput, localImgs map[string]string) { + testRepos, err := providerCfg.registryLogin(ctx, tfOutput) + if err != nil { + panic(fmt.Sprintf("Failed to log into registry: %v", err)) + } + pushAppImage(ctx, providerCfg, tfOutput, localImgs) + // Create and push test images. + if err := tftestenv.CreateAndPushImages(testRepos, testImageTags); err != nil { + panic(fmt.Sprintf("Failed to create and push images: %v", err)) + } +} + +func pushAppImageGit(ctx context.Context, providerCfg *ProviderConfig, tfOutput map[string]*tfjson.StateOutput, localImgs map[string]string) { + _, err := providerCfg.registryLogin(ctx, tfOutput) + if err != nil { + panic(fmt.Sprintf("Failed to log into registry: %v", err)) + } + pushAppImage(ctx, providerCfg, tfOutput, localImgs) +} + // creatWorkloadIDServiceAccount creates the service account (name and namespace specified in the terraform // variables) with the annotations passed into the function. // // TODO: move creation of serviceaccount to terraform -func creatWorkloadIDServiceAccount(ctx context.Context, annotations map[string]string) error { +func createWorkloadIDServiceAccount(ctx context.Context, annotations map[string]string) error { wiServiceAccount = os.Getenv(envVarWISAName) wiSANamespace := os.Getenv(envVarWISANamespace) if wiServiceAccount == "" || wiSANamespace == "" { diff --git a/oci/tests/integration/terraform/azure/git/main.tf b/oci/tests/integration/terraform/azure/git/main.tf new file mode 100644 index 00000000..2050c571 --- /dev/null +++ b/oci/tests/integration/terraform/azure/git/main.tf @@ -0,0 +1,70 @@ +provider "azurerm" { + features {} +} + +resource "random_pet" "suffix" { + // Since azurerm doesn't allow "-" in registry name, use an alphabet as a + // separator. + separator = "o" +} + +locals { + name = "fluxTest${random_pet.suffix.id}" + project_name = "fluxProj${random_pet.suffix.id}" + repo_name = "fluxRepo${random_pet.suffix.id}" +} + +module "devops" { + // TODO: replace source with fluxcd path once PR https://github.com/fluxcd/test-infra/pull/44 is merged + source = "git::https://github.com/dipti-pai/test-infra.git//tf-modules/azure/devops" + + organization = var.devops_org + pat_token = var.pat + project_name = local.project_name + repository_name = local.repo_name + tags = var.tags +} + +module "aks" { + source = "git::https://github.com/fluxcd/test-infra.git//tf-modules/azure/aks" + + name = local.name + location = var.azure_location + tags = var.tags + enable_wi = var.enable_wi +} + +resource "azurerm_user_assigned_identity" "wi-id" { + count = var.enable_wi ? 1 : 0 + location = var.azure_location + name = local.name + resource_group_name = module.aks.resource_group + tags = var.tags +} + +resource "azurerm_federated_identity_credential" "federated-identity2" { + count = var.enable_wi ? 1 : 0 + name = local.name + resource_group_name = module.aks.resource_group + audience = ["api://AzureADTokenExchange"] + issuer = module.aks.cluster_oidc_url + parent_id = azurerm_user_assigned_identity.wi-id[count.index].id + subject = "system:serviceaccount:${var.wi_k8s_sa_ns}:${var.wi_k8s_sa_name}" + + depends_on = [module.aks] +} + +module "acr" { + source = "git::https://github.com/fluxcd/test-infra.git//tf-modules/azure/acr" + + name = local.name + location = var.azure_location + // By default, azure nodes have no access to ACR. We have to pass the AKS principal id to the modules + // Additionally, when workload identity is enabled, we also want to give permissions to managed identity. + aks_principal_id = var.enable_wi ? [module.aks.principal_id, azurerm_user_assigned_identity.wi-id[0].principal_id] : [module.aks.principal_id] + resource_group = module.aks.resource_group + admin_enabled = true + tags = var.tags + + depends_on = [module.aks] +} \ No newline at end of file diff --git a/oci/tests/integration/terraform/azure/git/outputs.tf b/oci/tests/integration/terraform/azure/git/outputs.tf new file mode 100644 index 00000000..2297a128 --- /dev/null +++ b/oci/tests/integration/terraform/azure/git/outputs.tf @@ -0,0 +1,37 @@ +output "git_repo_url" { + value = module.devops.repo_url +} + +output azure_devops_project_id { + value = module.devops.project_id +} + +output "azure_devops_organization" { + value = var.devops_org +} + +output "azure_devops_access_token" { + sensitive = true + value = var.pat +} + +output "aks_kubeconfig" { + value = module.aks.kubeconfig + sensitive = true +} + +output "workload_identity_client_id" { + value = var.enable_wi ? azurerm_user_assigned_identity.wi-id[0].client_id : "" +} + +output "workload_identity_object_id" { + value = var.enable_wi ? azurerm_user_assigned_identity.wi-id[0].principal_id : "" +} + +output "acr_registry_url" { + value = module.acr.registry_url +} + +output "acr_registry_id" { + value = module.acr.registry_id +} \ No newline at end of file diff --git a/oci/tests/integration/terraform/azure/git/variables.tf b/oci/tests/integration/terraform/azure/git/variables.tf new file mode 100644 index 00000000..a51e91a1 --- /dev/null +++ b/oci/tests/integration/terraform/azure/git/variables.tf @@ -0,0 +1,37 @@ +variable "azure_location" { + type = string + default = "eastus" +} + +variable "tags" { + type = map(string) + default = {} +} + +variable "devops_org" { + type = string + description = "Azure Devops organization to create project and git repository" +} + +variable "pat" { + type = string + description = "Personal access token to create project and repository in azure devops" +} + +variable "wi_k8s_sa_name" { + type = string + default = "test" + description = "Name of kubernetes service account to establish federated identity with (For workload identity)" +} + +variable "wi_k8s_sa_ns" { + type = string + default = "default" + description = "Namespace of kubernetes service account to establish federated identity with (For workload identity)" +} + +variable "enable_wi" { + type = bool + default = false + description = "Enable workload identity on cluster and create federated identity" +} \ No newline at end of file diff --git a/oci/tests/integration/terraform/azure/main.tf b/oci/tests/integration/terraform/azure/oci/main.tf similarity index 100% rename from oci/tests/integration/terraform/azure/main.tf rename to oci/tests/integration/terraform/azure/oci/main.tf diff --git a/oci/tests/integration/terraform/azure/outputs.tf b/oci/tests/integration/terraform/azure/oci/outputs.tf similarity index 72% rename from oci/tests/integration/terraform/azure/outputs.tf rename to oci/tests/integration/terraform/azure/oci/outputs.tf index 02822208..cc70f429 100644 --- a/oci/tests/integration/terraform/azure/outputs.tf +++ b/oci/tests/integration/terraform/azure/oci/outputs.tf @@ -14,3 +14,7 @@ output "acr_registry_id" { output "workload_identity_client_id" { value = var.enable_wi ? azurerm_user_assigned_identity.wi-id[0].client_id : "" } + +output "workload_identity_object_id" { + value = var.enable_wi ? azurerm_user_assigned_identity.wi-id[0].principal_id : "" +} diff --git a/oci/tests/integration/terraform/azure/variables.tf b/oci/tests/integration/terraform/azure/oci/variables.tf similarity index 99% rename from oci/tests/integration/terraform/azure/variables.tf rename to oci/tests/integration/terraform/azure/oci/variables.tf index e2a1f205..801b6c5a 100644 --- a/oci/tests/integration/terraform/azure/variables.tf +++ b/oci/tests/integration/terraform/azure/oci/variables.tf @@ -24,4 +24,4 @@ variable "enable_wi" { type = bool default = false description = "Enable workload identity on cluster and create federated identity" -} +} \ No newline at end of file diff --git a/oci/tests/integration/testapp/main.go b/oci/tests/integration/testapp/main.go index 4ca6eb9e..071ad291 100644 --- a/oci/tests/integration/testapp/main.go +++ b/oci/tests/integration/testapp/main.go @@ -21,6 +21,9 @@ import ( "flag" "fmt" "log" + "net/url" + "os" + "path/filepath" "strings" "time" @@ -31,7 +34,14 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log/zap" "github.com/fluxcd/pkg/cache" + "github.com/fluxcd/pkg/git" + "github.com/fluxcd/pkg/git/gogit" + "github.com/fluxcd/pkg/git/repository" "github.com/fluxcd/pkg/oci/auth/login" + + "github.com/fluxcd/pkg/auth" + "github.com/fluxcd/pkg/auth/azure" + gitAuth "github.com/fluxcd/pkg/auth/git" ) // registry and repo flags are to facilitate testing of two login scenarios: @@ -41,12 +51,27 @@ import ( // is provided separately, e.g. registry: foo.azurecr.io, repo: bar. var ( registry = flag.String("registry", "", "registry of the repository") - repo = flag.String("repo", "", "repository to list") + repo = flag.String("repo", "", "git/oci repository to list") oidcLogin = flag.Bool("oidc-login", false, "login with OIDCLogin function") + category = flag.String("category", "", "Test category to run - oci/git") + provider = flag.String("provider", "", "Supported oidc provider - azure") ) func main() { flag.Parse() + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + if *category == "oci" { + checkOci(ctx) + } else if *category == "git" { + checkGit(ctx) + } else { + panic("unsupported category") + } +} + +func checkOci(ctx context.Context) { ctrl.SetLogger(zap.New(zap.UseDevMode(true))) cache, err := cache.New(5, cache.StoreObjectKeyFunc, cache.WithCleanupInterval[cache.StoreObject[authn.Authenticator]](1*time.Second)) @@ -59,8 +84,6 @@ func main() { AzureAutoLogin: true, Cache: cache, } - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() if *repo == "" { panic("must provide -repo value") @@ -106,3 +129,81 @@ func main() { } log.Println("tags:", tags) } + +func checkGit(ctx context.Context) { + log.Println("Validating git oidc by cloning repo ", *repo) + providerCreds, err := getProviderCreds(ctx, *repo, *provider) + if err != nil { + panic(err) + } + + authData := providerCreds.ToSecretData() + u, err := url.Parse(*repo) + if err != nil { + panic(err) + } + + authOpts, err := git.NewAuthOptions(*u, authData) + if err != nil { + panic(err) + } + + cloneDir, err := os.MkdirTemp("", "test-clone-") + if err != nil { + panic(err) + } + defer os.RemoveAll(cloneDir) + c, err := gogit.NewClient(cloneDir, authOpts, gogit.WithSingleBranch(false), gogit.WithDiskStorage()) + if err != nil { + panic(err) + } + + _, err = c.Clone(ctx, *repo, repository.CloneConfig{ + CheckoutStrategy: repository.CheckoutStrategy{ + Branch: "main", + }, + }) + if err != nil { + panic(err) + } + + log.Println("Successfully cloned repository ") + // Check file from clone. + fPath := filepath.Join(cloneDir, "configmap.yaml") + if _, err := os.Stat(fPath); os.IsNotExist(err) { + panic("expected artifact configmap.yaml to exist in clone dir") + } + + // read the whole file at once + contents, err := os.ReadFile(fPath) + if err != nil { + panic(err) + } + log.Println(string(contents)) +} + +func getProviderCreds(ctx context.Context, url, provider string) (*gitAuth.Credentials, error) { + var providerCreds *gitAuth.Credentials + switch provider { + case auth.ProviderAzure: + authOpts := &gitAuth.AuthOptions{} + authOpts.ProviderOptions = gitAuth.ProviderOptions{ + AzureOpts: []azure.ProviderOptFunc{ + azure.WithAzureDevOpsScope(), + }, + } + c, err := cache.New(10, cache.StoreObjectKeyFunc, + cache.WithCleanupInterval[cache.StoreObject[gitAuth.Credentials]](5*time.Second)) + if err != nil { + return nil, err + } + authOpts.Cache = c + providerCreds, err = gitAuth.GetCredentials(ctx, url, provider, authOpts) + if err != nil { + return nil, err + } + // Add other providers here + } + + return providerCreds, nil +} diff --git a/oci/tests/integration/util_test.go b/oci/tests/integration/util_test.go new file mode 100644 index 00000000..2799ab03 --- /dev/null +++ b/oci/tests/integration/util_test.go @@ -0,0 +1,123 @@ +//go:build integration +// +build integration + +/* +Copyright 2024 The Flux authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package integration + +import ( + "context" + "errors" + "fmt" + "io" + "net/url" + "strings" + "time" + + "github.com/fluxcd/pkg/git" + "github.com/fluxcd/pkg/git/gogit" + "github.com/fluxcd/pkg/git/repository" + "github.com/go-git/go-git/v5/plumbing" +) + +const ( + // default branch to be used when cloning git repositories + defaultBranch = "main" +) + +// Clones the git repository specified in the test config and commits a config +// map yaml into the repository +func setupGitRepository(ctx context.Context, tmpDir string) { + c, err := getRepository(ctx, tmpDir, cfg.applicationRepository, defaultBranch, cfg.defaultAuthOpts) + + if err != nil { + panic(err) + } + + manifest := `apiVersion: v1 +kind: ConfigMap +metadata: + name: foobar` + branchName := defaultBranch + + files := make(map[string]io.Reader) + files["configmap.yaml"] = strings.NewReader(manifest) + err = commitAndPushAll(ctx, c, files, branchName) + + if err != nil { + panic(err) + } +} + +// Uses git package to get auth options +func getAuthOpts(repoURL string, authData map[string][]byte) (*git.AuthOptions, error) { + u, err := url.Parse(repoURL) + if err != nil { + return nil, err + } + + return git.NewAuthOptions(*u, authData) +} + +// getRepository clones the specified branch of the git repository +func getRepository(ctx context.Context, dir, repoURL, branchName string, authOpts *git.AuthOptions) (*gogit.Client, error) { + c, err := gogit.NewClient(dir, authOpts, gogit.WithSingleBranch(false), gogit.WithDiskStorage()) + if err != nil { + return nil, err + } + + _, err = c.Clone(ctx, repoURL, repository.CloneConfig{ + CheckoutStrategy: repository.CheckoutStrategy{ + Branch: branchName, + }, + }) + if err != nil { + return nil, err + } + + return c, nil +} + +// commitAndPushAll creates a commit and pushes the changes using gogit client +func commitAndPushAll(ctx context.Context, client *gogit.Client, files map[string]io.Reader, branchName string) error { + err := client.SwitchBranch(ctx, branchName) + if err != nil && !errors.Is(err, plumbing.ErrReferenceNotFound) { + return err + } + + _, err = client.Commit(git.Commit{ + Author: git.Signature{ + Name: git.DefaultPublicKeyAuthUser, + Email: "test@example.com", + When: time.Now(), + }, + }, repository.WithFiles(files)) + if err != nil { + if errors.Is(err, git.ErrNoStagedFiles) { + return nil + } + + return err + } + + err = client.Push(ctx, repository.PushConfig{}) + if err != nil { + return fmt.Errorf("unable to push: %s", err) + } + + return nil +} From 4635eced2659427fe72ee34336234eb6c5fc1761 Mon Sep 17 00:00:00 2001 From: Dipti Pai Date: Fri, 19 Jul 2024 14:03:09 -0700 Subject: [PATCH 5/5] Fix copyright Signed-off-by: Dipti Pai --- auth/azure/fake_credential.go | 7 ++++--- auth/azure/token_provider.go | 7 ++++--- auth/azure/token_provider_test.go | 7 ++++--- auth/constants.go | 7 ++++--- auth/git/credentials.go | 7 ++++--- auth/git/credentials_test.go | 2 +- 6 files changed, 21 insertions(+), 16 deletions(-) diff --git a/auth/azure/fake_credential.go b/auth/azure/fake_credential.go index d09c77e9..d3d25705 100644 --- a/auth/azure/fake_credential.go +++ b/auth/azure/fake_credential.go @@ -1,7 +1,8 @@ /* -Copyright 2023 The Flux authors Licensed under the Apache License, Version 2.0 -(the "License"); you may not use this file except in compliance with the -License. +Copyright 2024 The Flux authors + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 diff --git a/auth/azure/token_provider.go b/auth/azure/token_provider.go index 7d3815cc..4a2f8ae6 100644 --- a/auth/azure/token_provider.go +++ b/auth/azure/token_provider.go @@ -1,7 +1,8 @@ /* -Copyright 2024 The Flux authors Licensed under the Apache License, Version 2.0 -(the "License"); you may not use this file except in compliance with the -License. +Copyright 2024 The Flux authors + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 diff --git a/auth/azure/token_provider_test.go b/auth/azure/token_provider_test.go index 887bf179..2f8c3d78 100644 --- a/auth/azure/token_provider_test.go +++ b/auth/azure/token_provider_test.go @@ -1,7 +1,8 @@ /* -Copyright 2023 The Flux authors Licensed under the Apache License, Version 2.0 -(the "License"); you may not use this file except in compliance with the -License. +Copyright 2024 The Flux authors + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 diff --git a/auth/constants.go b/auth/constants.go index 5d223ac3..0a62b2ca 100644 --- a/auth/constants.go +++ b/auth/constants.go @@ -1,7 +1,8 @@ /* -Copyright 2024 The Flux authors Licensed under the Apache License, Version 2.0 -(the "License"); you may not use this file except in compliance with the -License. +Copyright 2024 The Flux authors + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 diff --git a/auth/git/credentials.go b/auth/git/credentials.go index 8d4da269..ddfeebc7 100644 --- a/auth/git/credentials.go +++ b/auth/git/credentials.go @@ -1,7 +1,8 @@ /* -Copyright 2024 The Flux authors Licensed under the Apache License, Version 2.0 -(the "License"); you may not use this file except in compliance with the -License. +Copyright 2024 The Flux authors + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 diff --git a/auth/git/credentials_test.go b/auth/git/credentials_test.go index 1b77307a..d592ecd6 100644 --- a/auth/git/credentials_test.go +++ b/auth/git/credentials_test.go @@ -1,5 +1,5 @@ /* -Copyright 2023 The Flux authors +Copyright 2024 The Flux authors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the