diff --git a/oci/auth/aws/auth.go b/oci/auth/aws/auth.go index ae2ddf22..d2086470 100644 --- a/oci/auth/aws/auth.go +++ b/oci/auth/aws/auth.go @@ -79,7 +79,7 @@ func (c *Client) WithConfig(cfg *aws.Config) { // be the case if it's running in EKS, and may need additional setup // otherwise (visit https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/ // as a starting point). -func (c *Client) getLoginAuth(ctx context.Context, awsEcrRegion string) (authn.AuthConfig, *time.Time, error) { +func (c *Client) getLoginAuth(ctx context.Context, awsEcrRegion string) (authn.AuthConfig, time.Time, error) { var authConfig authn.AuthConfig var cfg aws.Config @@ -91,7 +91,7 @@ func (c *Client) getLoginAuth(ctx context.Context, awsEcrRegion string) (authn.A cfg, err = config.LoadDefaultConfig(ctx, config.WithRegion(awsEcrRegion)) if err != nil { c.mu.Unlock() - return authConfig, nil, fmt.Errorf("failed to load default configuration: %w", err) + return authConfig, time.Time{}, fmt.Errorf("failed to load default configuration: %w", err) } c.config = &cfg } @@ -102,52 +102,56 @@ func (c *Client) getLoginAuth(ctx context.Context, awsEcrRegion string) (authn.A // pass nil input. ecrToken, err := ecrService.GetAuthorizationToken(ctx, nil) if err != nil { - return authConfig, nil, err + return authConfig, time.Time{}, err } // Validate the authorization data. if len(ecrToken.AuthorizationData) == 0 { - return authConfig, nil, errors.New("no authorization data") + return authConfig, time.Time{}, errors.New("no authorization data") } if ecrToken.AuthorizationData[0].AuthorizationToken == nil { - return authConfig, nil, fmt.Errorf("no authorization token") + return authConfig, time.Time{}, fmt.Errorf("no authorization token") } token, err := base64.StdEncoding.DecodeString(*ecrToken.AuthorizationData[0].AuthorizationToken) if err != nil { - return authConfig, nil, err + return authConfig, time.Time{}, err } tokenSplit := strings.Split(string(token), ":") // Validate the tokens. if len(tokenSplit) != 2 { - return authConfig, nil, fmt.Errorf("invalid authorization token, expected the token to have two parts separated by ':', got %d parts", len(tokenSplit)) + return authConfig, time.Time{}, fmt.Errorf("invalid authorization token, expected the token to have two parts separated by ':', got %d parts", len(tokenSplit)) } authConfig = authn.AuthConfig{ Username: tokenSplit[0], Password: tokenSplit[1], } - return authConfig, ecrToken.AuthorizationData[0].ExpiresAt, nil + expiresAt := ecrToken.AuthorizationData[0].ExpiresAt + if expiresAt == nil { + expiresAt = &time.Time{} + } + return authConfig, *expiresAt, nil } // LoginWithExpiry attempts to get the authentication material for ECR. // It returns the authentication material and the expiry time of the token. -func (c *Client) LoginWithExpiry(ctx context.Context, autoLogin bool, image string) (authn.Authenticator, *time.Time, error) { +func (c *Client) LoginWithExpiry(ctx context.Context, autoLogin bool, image string) (authn.Authenticator, time.Time, error) { if autoLogin { log.FromContext(ctx).Info("logging in to AWS ECR for " + image) _, awsEcrRegion, ok := ParseRegistry(image) if !ok { - return nil, nil, errors.New("failed to parse AWS ECR image, invalid ECR image") + return nil, time.Time{}, errors.New("failed to parse AWS ECR image, invalid ECR image") } authConfig, expiresAt, err := c.getLoginAuth(ctx, awsEcrRegion) if err != nil { - return nil, nil, err + return nil, time.Time{}, err } auth := authn.FromConfig(authConfig) return auth, expiresAt, nil } - return nil, nil, fmt.Errorf("ECR authentication failed: %w", oci.ErrUnconfiguredProvider) + return nil, time.Time{}, fmt.Errorf("ECR authentication failed: %w", oci.ErrUnconfiguredProvider) } // Login attempts to get the authentication material for ECR. @@ -156,25 +160,20 @@ func (c *Client) Login(ctx context.Context, autoLogin bool, image string) (authn return auth, err } -// OIDCLoginWithExpiry attempts to get the authentication material for ECR. -// It returns the authentication material and the expiry time of the token. -func (c *Client) OIDCLoginWithExpiry(ctx context.Context, registryURL string) (authn.Authenticator, *time.Time, error) { +// OIDCLogin attempts to get the authentication material for ECR. +// +// Deprecated: Use LoginWithExpiry instead. +func (c *Client) OIDCLogin(ctx context.Context, registryURL string) (authn.Authenticator, error) { _, awsEcrRegion, ok := ParseRegistry(registryURL) if !ok { - return nil, nil, errors.New("failed to parse AWS ECR image, invalid ECR image") + return nil, errors.New("failed to parse AWS ECR image, invalid ECR image") } - authConfig, expiresAt, err := c.getLoginAuth(ctx, awsEcrRegion) + authConfig, _, err := c.getLoginAuth(ctx, awsEcrRegion) if err != nil { - return nil, nil, err + return nil, err } auth := authn.FromConfig(authConfig) - return auth, expiresAt, nil -} - -// OIDCLogin attempts to get the authentication material for ECR. -func (c *Client) OIDCLogin(ctx context.Context, registryURL string) (authn.Authenticator, error) { - auth, _, err := c.OIDCLoginWithExpiry(ctx, registryURL) - return auth, err + return auth, nil } diff --git a/oci/auth/aws/auth_test.go b/oci/auth/aws/auth_test.go index e3f20252..d323c6b9 100644 --- a/oci/auth/aws/auth_test.go +++ b/oci/auth/aws/auth_test.go @@ -18,9 +18,11 @@ package aws import ( "context" + "fmt" "net/http" "net/http/httptest" "testing" + "time" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/credentials" @@ -99,6 +101,7 @@ func TestParseRegistry(t *testing.T) { } func TestGetLoginAuth(t *testing.T) { + authorizationData := fmt.Sprintf(`{"authorizationData": [{"authorizationToken": "c29tZS1rZXk6c29tZS1zZWNyZXQ=","expiresAt": %d}]}`, time.Now().Add(1*time.Hour).Unix()) tests := []struct { name string responseBody []byte @@ -108,15 +111,9 @@ func TestGetLoginAuth(t *testing.T) { }{ { // NOTE: The authorizationToken is base64 encoded. - name: "success", - responseBody: []byte(`{ - "authorizationData": [ - { - "authorizationToken": "c29tZS1rZXk6c29tZS1zZWNyZXQ=" - } - ] -}`), - statusCode: http.StatusOK, + name: "success", + responseBody: []byte(authorizationData), + statusCode: http.StatusOK, wantAuthConfig: authn.AuthConfig{ Username: "some-key", Password: "some-secret", @@ -183,8 +180,11 @@ func TestGetLoginAuth(t *testing.T) { cfg.Credentials = credentials.NewStaticCredentialsProvider("x", "y", "z") ec.WithConfig(cfg) - a, _, err := ec.getLoginAuth(context.TODO(), "us-east-1") + a, expiresAt, err := ec.getLoginAuth(context.TODO(), "us-east-1") g.Expect(err != nil).To(Equal(tt.wantErr)) + if !tt.wantErr { + g.Expect(expiresAt).To(BeTemporally("~", time.Now().Add(1*time.Hour), time.Second)) + } if tt.statusCode == http.StatusOK { g.Expect(a).To(Equal(tt.wantAuthConfig)) } diff --git a/oci/auth/azure/auth.go b/oci/auth/azure/auth.go index 1c569020..f6ab2ce8 100644 --- a/oci/auth/azure/auth.go +++ b/oci/auth/azure/auth.go @@ -36,7 +36,7 @@ import ( // Default cache expiration time in seconds for ACR refresh token. // TODO @souleb: This is copied from https://github.com/Azure/msi-acrpull/blob/0ca921a7740e561c7204d9c3b3b55c4e0b9bd7b9/pkg/authorizer/token_retriever.go#L21C2-L21C39 -// as it not provided by the Azure SDK. See with the Azure SDK team to see if there is a better way to get this value. +// as it is not provided by the Azure SDK. Check with the Azure SDK team to see if there is a better way to get this value. const defaultCacheExpirationInSeconds = 600 // Client is an Azure ACR client which can log into the registry and return @@ -66,7 +66,7 @@ func (c *Client) WithScheme(scheme string) *Client { // getLoginAuth returns authentication for ACR. The details needed for authentication // are gotten from environment variable so there is no need to mount a host path. // The endpoint is the registry server and will be queried for OAuth authorization token. -func (c *Client) getLoginAuth(ctx context.Context, registryURL string) (authn.AuthConfig, *time.Time, error) { +func (c *Client) getLoginAuth(ctx context.Context, registryURL string) (authn.AuthConfig, time.Time, error) { var authConfig authn.AuthConfig // Use default credentials if no token credential is provided. @@ -75,7 +75,7 @@ func (c *Client) getLoginAuth(ctx context.Context, registryURL string) (authn.Au if c.credential == nil { cred, err := azidentity.NewDefaultAzureCredential(nil) if err != nil { - return authConfig, nil, err + return authConfig, time.Time{}, err } c.credential = cred } @@ -86,14 +86,14 @@ func (c *Client) getLoginAuth(ctx context.Context, registryURL string) (authn.Au Scopes: []string{configurationEnvironment.Services[cloud.ResourceManager].Endpoint + "/" + ".default"}, }) if err != nil { - return authConfig, nil, err + return authConfig, time.Time{}, err } // Obtain ACR access token using exchanger. ex := newExchanger(registryURL) accessToken, err := ex.ExchangeACRAccessToken(string(armToken.Token)) if err != nil { - return authConfig, nil, fmt.Errorf("error exchanging token: %w", err) + return authConfig, time.Time{}, fmt.Errorf("error exchanging token: %w", err) } expiresAt := time.Now().Add(defaultCacheExpirationInSeconds * time.Second) @@ -103,7 +103,7 @@ func (c *Client) getLoginAuth(ctx context.Context, registryURL string) (authn.Au // See documentation: https://docs.microsoft.com/en-us/azure/container-registry/container-registry-authentication?tabs=azure-cli#az-acr-login-with---expose-token Username: "00000000-0000-0000-0000-000000000000", Password: accessToken, - }, &expiresAt, nil + }, expiresAt, nil } // getCloudConfiguration returns the cloud configuration based on the registry URL. @@ -133,7 +133,7 @@ func ValidHost(host string) bool { // LoginWithExpiry attempts to get the authentication material for ACR. // It returns the authentication material and the expiry time of the token. // The caller can ensure that the passed image is a valid ACR image using ValidHost(). -func (c *Client) LoginWithExpiry(ctx context.Context, autoLogin bool, image string, ref name.Reference) (authn.Authenticator, *time.Time, error) { +func (c *Client) LoginWithExpiry(ctx context.Context, autoLogin bool, image string, ref name.Reference) (authn.Authenticator, time.Time, error) { if autoLogin { log.FromContext(ctx).Info("logging in to Azure ACR for " + image) // get registry host from image @@ -142,13 +142,13 @@ func (c *Client) LoginWithExpiry(ctx context.Context, autoLogin bool, image stri authConfig, expiresAt, err := c.getLoginAuth(ctx, endpoint) if err != nil { log.FromContext(ctx).Info("error logging into ACR " + err.Error()) - return nil, nil, err + return nil, time.Time{}, err } auth := authn.FromConfig(authConfig) return auth, expiresAt, nil } - return nil, nil, fmt.Errorf("ACR authentication failed: %w", oci.ErrUnconfiguredProvider) + return nil, time.Time{}, fmt.Errorf("ACR authentication failed: %w", oci.ErrUnconfiguredProvider) } // Login attempts to get the authentication material for ACR. The caller can @@ -158,27 +158,19 @@ func (c *Client) Login(ctx context.Context, autoLogin bool, image string, ref na return auth, err } -// OIDCLoginWithExpiry attempts to get an Authenticator for the provided ACR registry URL endpoint. -// It returns the Authenticator and the expiry time of the token. +// OIDCLogin attempts to get an Authenticator for the provided ACR registry URL endpoint. // // If you want to construct an Authenticator based on an image reference, // you may want to use Login instead. -func (c *Client) OIDCLoginWithExpiry(ctx context.Context, registryUrl string) (authn.Authenticator, *time.Time, error) { - authConfig, expiresAt, err := c.getLoginAuth(ctx, registryUrl) +// +// Deprecated: Use LoginWithExpiry instead. +func (c *Client) OIDCLogin(ctx context.Context, registryUrl string) (authn.Authenticator, error) { + authConfig, _, err := c.getLoginAuth(ctx, registryUrl) if err != nil { log.FromContext(ctx).Info("error logging into ACR " + err.Error()) - return nil, nil, err + return nil, err } auth := authn.FromConfig(authConfig) - return auth, expiresAt, nil -} - -// OIDCLogin attempts to get an Authenticator for the provided ACR registry URL endpoint. -// -// If you want to construct an Authenticator based on an image reference, -// you may want to use Login instead. -func (c *Client) OIDCLogin(ctx context.Context, registryUrl string) (authn.Authenticator, error) { - auth, _, err := c.OIDCLoginWithExpiry(ctx, registryUrl) - return auth, err + return auth, nil } diff --git a/oci/auth/azure/auth_test.go b/oci/auth/azure/auth_test.go index e9ae0dfa..f1707133 100644 --- a/oci/auth/azure/auth_test.go +++ b/oci/auth/azure/auth_test.go @@ -24,6 +24,7 @@ import ( "net/url" "path" "testing" + "time" "github.com/Azure/azure-sdk-for-go/sdk/azcore" "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud" @@ -84,8 +85,11 @@ func TestGetAzureLoginAuth(t *testing.T) { WithTokenCredential(tt.tokenCredential). WithScheme("http") - auth, _, err := c.getLoginAuth(context.TODO(), srv.URL) + auth, expiresAt, err := c.getLoginAuth(context.TODO(), srv.URL) g.Expect(err != nil).To(Equal(tt.wantErr)) + if !tt.wantErr { + g.Expect(expiresAt).To(BeTemporally("~", time.Now().Add(defaultCacheExpirationInSeconds*time.Second), time.Second)) + } if tt.statusCode == http.StatusOK { g.Expect(auth).To(Equal(tt.wantAuthConfig)) } diff --git a/oci/auth/gcp/auth.go b/oci/auth/gcp/auth.go index 99cbd2ad..f5952fea 100644 --- a/oci/auth/gcp/auth.go +++ b/oci/auth/gcp/auth.go @@ -67,12 +67,12 @@ func (c *Client) WithTokenURL(url string) *Client { // on GCP. This assumes that the pod has right to pull the image which would be // the case if it is hosted on GCP. It works with both service account and // workload identity enabled clusters. -func (c *Client) getLoginAuth(ctx context.Context) (authn.AuthConfig, *time.Time, error) { +func (c *Client) getLoginAuth(ctx context.Context) (authn.AuthConfig, time.Time, error) { var authConfig authn.AuthConfig request, err := http.NewRequestWithContext(ctx, http.MethodGet, c.tokenURL, nil) if err != nil { - return authConfig, nil, err + return authConfig, time.Time{}, err } request.Header.Add("Metadata-Flavor", "Google") @@ -80,19 +80,19 @@ func (c *Client) getLoginAuth(ctx context.Context) (authn.AuthConfig, *time.Time client := &http.Client{} response, err := client.Do(request) if err != nil { - return authConfig, nil, err + return authConfig, time.Time{}, err } defer response.Body.Close() defer io.Copy(io.Discard, response.Body) if response.StatusCode != http.StatusOK { - return authConfig, nil, fmt.Errorf("unexpected status from metadata service: %s", response.Status) + return authConfig, time.Time{}, fmt.Errorf("unexpected status from metadata service: %s", response.Status) } var accessToken gceToken decoder := json.NewDecoder(response.Body) if err := decoder.Decode(&accessToken); err != nil { - return authConfig, nil, err + return authConfig, time.Time{}, err } authConfig = authn.AuthConfig{ @@ -100,28 +100,28 @@ func (c *Client) getLoginAuth(ctx context.Context) (authn.AuthConfig, *time.Time Password: accessToken.AccessToken, } - // add expires_in seconds to the current time to get the expiry time + // add expiresIn seconds to the current time to get the expiry time expiresAt := time.Now().Add(time.Duration(accessToken.ExpiresIn) * time.Second) - return authConfig, &expiresAt, nil + return authConfig, expiresAt, nil } // Login attempts to get the authentication material for GCR. // It returns the authentication material and the expiry time of the token. // The caller can ensure that the passed image is a valid GCR image using ValidHost(). -func (c *Client) LoginWithExpiry(ctx context.Context, autoLogin bool, image string, ref name.Reference) (authn.Authenticator, *time.Time, error) { +func (c *Client) LoginWithExpiry(ctx context.Context, autoLogin bool, image string, ref name.Reference) (authn.Authenticator, time.Time, error) { if autoLogin { log.FromContext(ctx).Info("logging in to GCP GCR for " + image) authConfig, expiresAt, err := c.getLoginAuth(ctx) if err != nil { log.FromContext(ctx).Info("error logging into GCP " + err.Error()) - return nil, nil, err + return nil, time.Time{}, err } auth := authn.FromConfig(authConfig) return auth, expiresAt, nil } - return nil, nil, fmt.Errorf("GCR authentication failed: %w", oci.ErrUnconfiguredProvider) + return nil, time.Time{}, fmt.Errorf("GCR authentication failed: %w", oci.ErrUnconfiguredProvider) } // Login attempts to get the authentication material for GCR. The caller can @@ -131,21 +131,16 @@ func (c *Client) Login(ctx context.Context, autoLogin bool, image string, ref na return auth, err } -// OIDCLoginWithExpiry attempts to get the authentication material for GCR from the token url set in the client. -// It returns the authentication material and the expiry time of the token. -func (c *Client) OIDCLoginWithExpiry(ctx context.Context) (authn.Authenticator, *time.Time, error) { - authConfig, expiresAt, err := c.getLoginAuth(ctx) +// OIDCLogin attempts to get the authentication material for GCR from the token url set in the client. +// +// Deprecated: Use LoginWithExpiry instead. +func (c *Client) OIDCLogin(ctx context.Context) (authn.Authenticator, error) { + authConfig, _, err := c.getLoginAuth(ctx) if err != nil { log.FromContext(ctx).Info("error logging into GCP " + err.Error()) - return nil, nil, err + return nil, err } auth := authn.FromConfig(authConfig) - return auth, expiresAt, nil -} - -// OIDCLogin attempts to get the authentication material for GCR from the token url set in the client. -func (c *Client) OIDCLogin(ctx context.Context) (authn.Authenticator, error) { - auth, _, err := c.OIDCLoginWithExpiry(ctx) - return auth, err + return auth, nil } diff --git a/oci/auth/gcp/auth_test.go b/oci/auth/gcp/auth_test.go index 25daef12..185c34f6 100644 --- a/oci/auth/gcp/auth_test.go +++ b/oci/auth/gcp/auth_test.go @@ -21,6 +21,7 @@ import ( "net/http" "net/http/httptest" "testing" + "time" "github.com/google/go-containerregistry/pkg/authn" "github.com/google/go-containerregistry/pkg/name" @@ -77,8 +78,11 @@ func TestGetLoginAuth(t *testing.T) { }) gc := NewClient().WithTokenURL(srv.URL) - a, _, err := gc.getLoginAuth(context.TODO()) + a, expiresAt, err := gc.getLoginAuth(context.TODO()) g.Expect(err != nil).To(Equal(tt.wantErr)) + if !tt.wantErr { + g.Expect(expiresAt).To(BeTemporally("~", time.Now().Add(10*time.Second), time.Second)) + } if tt.statusCode == http.StatusOK { g.Expect(a).To(Equal(tt.wantAuthConfig)) } diff --git a/oci/auth/login/cache.go b/oci/auth/login/cache.go index 7864a3cd..13180ff6 100644 --- a/oci/auth/login/cache.go +++ b/oci/auth/login/cache.go @@ -19,30 +19,26 @@ package login import ( "time" - "github.com/fluxcd/pkg/cache" "github.com/google/go-containerregistry/pkg/authn" + + "github.com/fluxcd/pkg/cache" ) -func cacheObject[T authn.Authenticator](store cache.Expirable[cache.StoreObject[T]], auth T, key string, expiresAt *time.Time) { +func cacheObject[T authn.Authenticator](store cache.Expirable[cache.StoreObject[T]], auth T, key string, expiresAt time.Time) error { obj := cache.StoreObject[T]{ Object: auth, Key: key, } - store.Set(obj) - if expiresAt == nil || expiresAt.IsZero() { - return + + err := store.Set(obj) + if err != nil { + return err } - store.SetExpiration(obj, *expiresAt) + + return store.SetExpiration(obj, expiresAt) } func getObjectFromCache[T authn.Authenticator](cache cache.Expirable[cache.StoreObject[T]], key string) (T, bool, error) { - var res T val, exists, err := cache.GetByKey(key) - if err != nil { - return res, true, err - } - if exists { - return val.Object, true, nil - } - return res, false, nil + return val.Object, exists, err } diff --git a/oci/auth/login/login.go b/oci/auth/login/login.go index 2f699ebb..72d57e79 100644 --- a/oci/auth/login/login.go +++ b/oci/auth/login/login.go @@ -112,10 +112,11 @@ func (m *Manager) WithACRClient(c *azure.Client) *Manager { // Login performs authentication against a registry and returns the Authenticator. // For generic registry provider, it is no-op. func (m *Manager) Login(ctx context.Context, url string, ref name.Reference, opts ProviderOptions) (authn.Authenticator, error) { + log := log.FromContext(ctx) if opts.Cache != nil { auth, exists, err := getObjectFromCache(opts.Cache, url) if err != nil { - return nil, err + log.Error(err, "failed to get auth object from cache") } if exists { return auth, nil @@ -129,7 +130,10 @@ func (m *Manager) Login(ctx context.Context, url string, ref name.Reference, opt return nil, err } if opts.Cache != nil { - cacheObject(opts.Cache, auth, url, expiresAt) + err := cacheObject(opts.Cache, auth, url, expiresAt) + if err != nil { + log.Error(err, "failed to cache auth object") + } } return auth, nil case oci.ProviderGCP: @@ -138,7 +142,10 @@ func (m *Manager) Login(ctx context.Context, url string, ref name.Reference, opt return nil, err } if opts.Cache != nil { - cacheObject(opts.Cache, auth, url, expiresAt) + err := cacheObject(opts.Cache, auth, url, expiresAt) + if err != nil { + log.Error(err, "failed to cache auth object") + } } return auth, nil case oci.ProviderAzure: @@ -147,7 +154,10 @@ func (m *Manager) Login(ctx context.Context, url string, ref name.Reference, opt return nil, err } if opts.Cache != nil { - cacheObject(opts.Cache, auth, url, expiresAt) + err := cacheObject(opts.Cache, auth, url, expiresAt) + if err != nil { + log.Error(err, "failed to cache auth object") + } } return auth, nil } @@ -158,63 +168,33 @@ func (m *Manager) Login(ctx context.Context, url string, ref name.Reference, opt // // If you want to construct an Authenticator based on an image reference, // you may want to use Login instead. +// +// Deprecated: Use Login instead. func (m *Manager) OIDCLogin(ctx context.Context, registryURL string, opts ProviderOptions) (authn.Authenticator, error) { u, err := url.Parse(registryURL) if err != nil { return nil, fmt.Errorf("unable to parse registry url: %w", err) } provider := ImageRegistryProvider(u.Host, nil) - cacheKey := fmt.Sprintf("%s-%d", u.Host, provider) - if opts.Cache != nil { - auth, exists, err := getObjectFromCache(opts.Cache, cacheKey) - if err != nil { - return nil, err - } - if exists { - return auth, nil - } - } - switch provider { case oci.ProviderAWS: if !opts.AwsAutoLogin { return nil, fmt.Errorf("ECR authentication failed: %w", oci.ErrUnconfiguredProvider) } log.FromContext(ctx).Info("logging in to AWS ECR for " + u.Host) - auth, expiresAt, err := m.ecr.OIDCLoginWithExpiry(ctx, u.Host) - if err != nil { - return nil, err - } - if opts.Cache != nil { - cacheObject(opts.Cache, auth, cacheKey, expiresAt) - } - return auth, nil + return m.ecr.OIDCLogin(ctx, u.Host) case oci.ProviderGCP: if !opts.GcpAutoLogin { return nil, fmt.Errorf("GCR authentication failed: %w", oci.ErrUnconfiguredProvider) } log.FromContext(ctx).Info("logging in to GCP GCR for " + u.Host) - auth, expiresAt, err := m.gcr.OIDCLoginWithExpiry(ctx) - if err != nil { - return nil, err - } - if opts.Cache != nil { - cacheObject(opts.Cache, auth, cacheKey, expiresAt) - } - return auth, nil + return m.gcr.OIDCLogin(ctx) case oci.ProviderAzure: if !opts.AzureAutoLogin { return nil, fmt.Errorf("ACR authentication failed: %w", oci.ErrUnconfiguredProvider) } log.FromContext(ctx).Info("logging in to Azure ACR for " + u.Host) - auth, expiresAt, err := m.acr.OIDCLoginWithExpiry(ctx, fmt.Sprintf("%s://%s", u.Scheme, u.Host)) - if err != nil { - return nil, err - } - if opts.Cache != nil { - cacheObject(opts.Cache, auth, cacheKey, expiresAt) - } - return auth, nil + return m.acr.OIDCLogin(ctx, fmt.Sprintf("%s://%s", u.Scheme, u.Host)) } return nil, nil } diff --git a/oci/tests/integration/go.mod b/oci/tests/integration/go.mod index dc05c844..3ec4ef63 100644 --- a/oci/tests/integration/go.mod +++ b/oci/tests/integration/go.mod @@ -2,9 +2,13 @@ module github.com/fluxcd/pkg/oci/tests/integration go 1.22.0 -replace github.com/fluxcd/pkg/oci => ../../ +replace ( + github.com/fluxcd/pkg/cache => ../../../cache + github.com/fluxcd/pkg/oci => ../../ +) require ( + github.com/fluxcd/pkg/cache v0.0.1 github.com/fluxcd/pkg/oci v0.34.0 github.com/fluxcd/test-infra/tftestenv v0.0.0-20240110132047-17651823b08c github.com/google/go-containerregistry v0.19.1 @@ -50,7 +54,6 @@ require ( github.com/emicklei/go-restful/v3 v3.11.0 // 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/cache v0.0.1 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-errors/errors v1.5.1 // indirect github.com/go-logr/logr v1.4.1 // indirect diff --git a/oci/tests/integration/go.sum b/oci/tests/integration/go.sum index 758a449e..8fc2c40d 100644 --- a/oci/tests/integration/go.sum +++ b/oci/tests/integration/go.sum @@ -100,8 +100,6 @@ 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/pkg/cache v0.0.1 h1:aeDQm4D37btj6I01p6ZKW6JNOZm3CIYN5PaVzyhHr38= -github.com/fluxcd/pkg/cache v0.0.1/go.mod h1:R3TJIK9XaohHNc3BeqfZX/UivMrx8Xz6ihGoVAjh75k= 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= diff --git a/oci/tests/integration/testapp/main.go b/oci/tests/integration/testapp/main.go index 7a0ae7b8..4ca6eb9e 100644 --- a/oci/tests/integration/testapp/main.go +++ b/oci/tests/integration/testapp/main.go @@ -30,6 +30,7 @@ import ( ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/log/zap" + "github.com/fluxcd/pkg/cache" "github.com/fluxcd/pkg/oci/auth/login" ) @@ -47,10 +48,16 @@ var ( func main() { flag.Parse() ctrl.SetLogger(zap.New(zap.UseDevMode(true))) + cache, err := cache.New(5, cache.StoreObjectKeyFunc, + cache.WithCleanupInterval[cache.StoreObject[authn.Authenticator]](1*time.Second)) + if err != nil { + panic(err) + } opts := login.ProviderOptions{ AwsAutoLogin: true, GcpAutoLogin: true, AzureAutoLogin: true, + Cache: cache, } ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() @@ -62,7 +69,6 @@ func main() { var loginURL string var auth authn.Authenticator var ref name.Reference - var err error if *registry != "" { // Registry and repository are separate.