From aa9f394cdcb09c0690ec8cadf0a3cb8e4f062f0b Mon Sep 17 00:00:00 2001 From: gw0 Date: Tue, 1 Mar 2022 12:01:08 +0100 Subject: [PATCH] Add support for providing additional HTTP headers --- docs/index.md | 1 + grafana/provider.go | 49 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/docs/index.md b/docs/index.md index f9093adc6..ef4c3c1ca 100644 --- a/docs/index.md +++ b/docs/index.md @@ -28,6 +28,7 @@ provider "grafana" { - **ca_cert** (String) Certificate CA bundle to use to verify the Grafana server's certificate. May alternatively be set via the `GRAFANA_CA_CERT` environment variable. - **cloud_api_key** (String, Sensitive) API key for Grafana Cloud. May alternatively be set via the `GRAFANA_CLOUD_API_KEY` environment variable. - **cloud_api_url** (String) Grafana Cloud's API URL. May alternatively be set via the `GRAFANA_CLOUD_API_URL` environment variable. +- **http_headers** (Map of String, Sensitive) Optional. HTTP headers mapping keys to values used for accessing the Grafana API. May alternatively be set via the `GRAFANA_HTTP_HEADERS` environment variable in JSON format. - **insecure_skip_verify** (Boolean) Skip TLS certificate verification. May alternatively be set via the `GRAFANA_INSECURE_SKIP_VERIFY` environment variable. - **org_id** (Number) The organization id to operate on within grafana. May alternatively be set via the `GRAFANA_ORG_ID` environment variable. - **retries** (Number) The amount of retries to use for Grafana API calls. May alternatively be set via the `GRAFANA_RETRIES` environment variable. diff --git a/grafana/provider.go b/grafana/provider.go index 07fe579ab..3d7db73d4 100644 --- a/grafana/provider.go +++ b/grafana/provider.go @@ -4,9 +4,11 @@ import ( "context" "crypto/tls" "crypto/x509" + "encoding/json" "fmt" "io/ioutil" "net/url" + "os" "regexp" "strings" @@ -60,6 +62,13 @@ func Provider(version string) func() *schema.Provider { Description: "API token or basic auth username:password. May alternatively be set via the `GRAFANA_AUTH` environment variable.", AtLeastOneOf: []string{"auth", "cloud_api_key", "sm_access_token"}, }, + "http_headers": { + Type: schema.TypeMap, + Optional: true, + Sensitive: true, + DefaultFunc: JSONEnvDefaultFunc("GRAFANA_HTTP_HEADERS", nil), + Description: "Optional. HTTP headers mapping keys to values used for accessing the Grafana API. May alternatively be set via the `GRAFANA_HTTP_HEADERS` environment variable in JSON format.", + }, "retries": { Type: schema.TypeInt, Optional: true, @@ -267,6 +276,29 @@ func createGrafanaClient(d *schema.ResourceData) (string, *gapi.Config, *gapi.Cl } else { cfg.APIKey = auth[0] } + + headersMap := d.Get("http_headers").(map[string]interface{}) + if headersMap != nil && len(headersMap) == 0 { + // Workaround for a bug when DefaultFunc returns a schema.TypeMap + headersMapAbs, err := JSONEnvDefaultFunc("GRAFANA_HTTP_HEADERS", nil)() + if err != nil { + return "", nil, nil, err + } + if headersMapAbs != nil { + headersMap = headersMapAbs.(map[string]interface{}) + } + } + if headersMap != nil { + // Convert headers from map[string]interface{} to map[string]string + headers := make(map[string]string) + for k, v := range headersMap { + if v, ok := v.(string); ok { + headers[k] = v + } + } + cfg.HTTPHeaders = headers + } + gclient, err := gapi.New(apiURL, cfg) if err != nil { return "", nil, nil, err @@ -305,3 +337,20 @@ func createSMClient(d *schema.ResourceData) *smapi.Client { smURL := d.Get("sm_url").(string) return smapi.NewClient(smURL, smToken, nil) } + +// JSONEnvDefaultFunc is a helper function that parses the given environment +// variable as a JSON object, or returns the default value otherwise. +func JSONEnvDefaultFunc(k string, dv interface{}) schema.SchemaDefaultFunc { + return func() (interface{}, error) { + if valStr := os.Getenv(k); valStr != "" { + var valObj map[string]interface{} + err := json.Unmarshal([]byte(valStr), &valObj) + if err != nil { + return nil, err + } + return valObj, nil + } + + return dv, nil + } +}