From 042adeb5d0e4cc1771da05a56e8b868292d7c037 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Mon, 9 Oct 2017 12:48:42 -0700 Subject: [PATCH] Refactor credentials management to support multiple mechanisms. This PR adds the ability of chaining the credentials provider, such that restic as a tool attempts to honor credentials from multiple different ways. Currently supported mechanisms are - static (user-provided) - IAM profile (only valid inside configured ec2 instances) - Standard AWS envs (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) - Standard Minio envs (MINIO_ACCESS_KEY, MINIO_SECRET_KEY) Refer https://github.com/restic/restic/issues/1341 --- internal/backend/s3/s3.go | 43 +++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/internal/backend/s3/s3.go b/internal/backend/s3/s3.go index 416f290ee..6c4850b64 100644 --- a/internal/backend/s3/s3.go +++ b/internal/backend/s3/s3.go @@ -40,24 +40,31 @@ func open(cfg Config, rt http.RoundTripper) (*Backend, error) { minio.MaxRetry = int(cfg.MaxRetries) } - var client *minio.Client - var err error - - if cfg.KeyID == "" || cfg.Secret == "" { - debug.Log("key/secret not found, trying to get them from IAM") - creds := credentials.NewIAM("") - client, err = minio.NewWithCredentials(cfg.Endpoint, creds, !cfg.UseHTTP, "") - - if err != nil { - return nil, errors.Wrap(err, "minio.NewWithCredentials") - } - } else { - debug.Log("key/secret found") - client, err = minio.New(cfg.Endpoint, cfg.KeyID, cfg.Secret, !cfg.UseHTTP) - - if err != nil { - return nil, errors.Wrap(err, "minio.New") - } + // Chains all credential types, starting with + // Static credentials provided by user. + // IAM profile based credentials. (performs an HTTP + // call to a pre-defined endpoint, only valid inside + // configured ec2 instances) + // AWS env variables such as AWS_ACCESS_KEY_ID + // Minio env variables such as MINIO_ACCESS_KEY + creds := credentials.NewChainCredentials([]credentials.Provider{ + &credentials.Static{ + Value: credentials.Value{ + AccessKeyID: cfg.KeyID, + SecretAccessKey: cfg.Secret, + }, + }, + &credentials.IAM{ + Client: &http.Client{ + Transport: http.DefaultTransport, + }, + }, + &credentials.EnvAWS{}, + &credentials.EnvMinio{}, + }) + client, err := minio.NewWithCredentials(cfg.Endpoint, creds, !cfg.UseHTTP, "") + if err != nil { + return nil, errors.Wrap(err, "minio.NewWithCredentials") } sem, err := backend.NewSemaphore(cfg.Connections)