diff --git a/main.go b/main.go index 356715a..aa8b2e2 100644 --- a/main.go +++ b/main.go @@ -8,6 +8,7 @@ import ( "net/url" "os" "strings" + "time" "github.com/CloudyKit/jet" "github.com/labstack/echo" @@ -109,31 +110,7 @@ func main() { } // Get authorization token for AWS ECR. if a.config.AWSRegion != "" { - sess, err := session.NewSession(&aws.Config{ - Region: aws.String(a.config.AWSRegion), - }) - if err != nil { - panic(err) - } - // Get authorization token - input := &ecr.GetAuthorizationTokenInput{ - RegistryIds: []*string{ - aws.String(a.config.AWSRegistryID), - }, - } - svc := ecr.New(sess) - authTokenOutput, err := svc.GetAuthorizationToken(input) - if err != nil { - panic(err) - } - authToken := *authTokenOutput.AuthorizationData[0].AuthorizationToken - decodedToken, err := base64.StdEncoding.DecodeString(authToken) - if err != nil { - panic(err) - } - // Override username and password with the ones found in token - a.config.Username = strings.Split(string(decodedToken), ":")[0] - a.config.Password = strings.Split(string(decodedToken), ":")[1] + a.setAWSCredentials() } // Init registry API client. @@ -142,6 +119,17 @@ func main() { panic(fmt.Errorf("cannot initialize api client or unsupported auth method")) } + // When using AWS ECR, renew AWS credentials + if a.config.AWSRegion != "" { + go func() { + for { + time.Sleep(time.Hour * 8) + a.setAWSCredentials() + a.client.RenewBasicAuth(a.config.Username, a.config.Password) + } + }() + } + // Execute CLI task and exit. if purgeTags { a.purgeOldTags(purgeDryRun) @@ -198,6 +186,34 @@ func main() { e.Logger.Fatal(e.Start(a.config.ListenAddr)) } +func (a *apiClient) setAWSCredentials() { + sess, err := session.NewSession(&aws.Config{ + Region: aws.String(a.config.AWSRegion), + }) + if err != nil { + panic(err) + } + // Get authorization token + input := &ecr.GetAuthorizationTokenInput{ + RegistryIds: []*string{ + aws.String(a.config.AWSRegistryID), + }, + } + svc := ecr.New(sess) + authTokenOutput, err := svc.GetAuthorizationToken(input) + if err != nil { + panic(err) + } + authToken := *authTokenOutput.AuthorizationData[0].AuthorizationToken + decodedToken, err := base64.StdEncoding.DecodeString(authToken) + if err != nil { + panic(err) + } + // Override username and password with the ones found in token + a.config.Username = strings.Split(string(decodedToken), ":")[0] + a.config.Password = strings.Split(string(decodedToken), ":")[1] +} + func (a *apiClient) viewRepositories(c echo.Context) error { namespace := c.Param("namespace") if namespace == "" { diff --git a/registry/client.go b/registry/client.go index ff53994..488a201 100644 --- a/registry/client.go +++ b/registry/client.go @@ -78,6 +78,12 @@ func NewClient(url string, verifyTLS bool, username, password string) *Client { return c } +// RenewBasicAuth sets the basic auth credentials. +func (c *Client) RenewBasicAuth(username, password string) { + c.request = c.request.SetBasicAuth(username, password) + c.logger.Info("Renewed basic auth credentials") +} + // getToken get existing or new auth token. func (c *Client) getToken(scope string) string { // Check if we have already a token and it's not expired.