From 8e7a88faffdb24e806d3f5778b48c925978783dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Labesse=20K=C3=A9vin?= Date: Mon, 6 Jul 2020 15:02:58 +0200 Subject: [PATCH] Imagestore: Fallback to application default credentials when no key file is specified for GCS (#25948) The external image storage for GCS creates the JWT Token from a credentials file, but if your Grafana server runs under a GCE instance with a service account on it, you can use that instead (you don't have to manage/secure the credentials file). Co-authored-by: Arve Knudsen Co-authored-by: Emil Tullstedt --- docs/sources/administration/configuration.md | 2 +- pkg/components/imguploader/gcsuploader.go | 35 +++++++++++++------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/docs/sources/administration/configuration.md b/docs/sources/administration/configuration.md index ff87fbd9ab0..cb39c77b4e2 100644 --- a/docs/sources/administration/configuration.md +++ b/docs/sources/administration/configuration.md @@ -1179,7 +1179,7 @@ Optional URL to send to users in notifications. If the string contains the seque ### key_file -Path to JSON key file associated with a Google service account to authenticate and authorize. +Optional path to JSON key file associated with a Google service account to authenticate and authorize. If no value is provided it tries to use the [application default credentials](https://cloud.google.com/docs/authentication/production#finding_credentials_automatically). Service Account keys can be created and downloaded from https://console.developers.google.com/permissions/serviceaccounts. Service Account should have "Storage Object Writer" role. The access control model of the bucket needs to be "Set object-level and bucket-level permissions". Grafana itself will make the images public readable. diff --git a/pkg/components/imguploader/gcsuploader.go b/pkg/components/imguploader/gcsuploader.go index f722dad8651..9aa4926961c 100644 --- a/pkg/components/imguploader/gcsuploader.go +++ b/pkg/components/imguploader/gcsuploader.go @@ -43,20 +43,31 @@ func (u *GCSUploader) Upload(ctx context.Context, imageDiskPath string) (string, fileName += pngExt key := path.Join(u.path, fileName) - u.log.Debug("Opening key file ", u.keyFile) - data, err := ioutil.ReadFile(u.keyFile) - if err != nil { - return "", err - } - - u.log.Debug("Creating JWT conf") - conf, err := google.JWTConfigFromJSON(data, tokenUrl) - if err != nil { - return "", err + var client *http.Client + + if u.keyFile != "" { + u.log.Debug("Opening key file ", u.keyFile) + data, err := ioutil.ReadFile(u.keyFile) + if err != nil { + return "", err + } + + u.log.Debug("Creating JWT conf") + conf, err := google.JWTConfigFromJSON(data, tokenUrl) + if err != nil { + return "", err + } + + u.log.Debug("Creating HTTP client") + client = conf.Client(ctx) + } else { + u.log.Debug("Key file is empty, trying to use application default credentials") + client, err = google.DefaultClient(ctx) + if err != nil { + return "", err + } } - u.log.Debug("Creating HTTP client") - client := conf.Client(ctx) err = u.uploadFile(client, imageDiskPath, key) if err != nil { return "", err