Skip to content

Commit

Permalink
allow headers to be added to prometheus requests
Browse files Browse the repository at this point in the history
Signed-off-by: Nick Otter <[email protected]>
  • Loading branch information
otternq committed Jan 14, 2025
1 parent 16a6075 commit f8438ab
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 0 deletions.
7 changes: 7 additions & 0 deletions artifacts/flagger/crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1308,6 +1308,13 @@ spec:
address:
description: API address of this provider
type: string
headers:
description: Headers to add to HTTP(S) requests
type: object
additionalProperties:
type: array
items:
type: string
secretRef:
description: Kubernetes secret reference containing the provider credentials
type: object
Expand Down
7 changes: 7 additions & 0 deletions charts/flagger/crds/crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1308,6 +1308,13 @@ spec:
address:
description: API address of this provider
type: string
headers:
description: Headers to add to HTTP(S) requests
type: object
additionalProperties:
type: array
items:
type: string
secretRef:
description: Kubernetes secret reference containing the provider credentials
type: object
Expand Down
7 changes: 7 additions & 0 deletions kustomize/base/flagger/crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1308,6 +1308,13 @@ spec:
address:
description: API address of this provider
type: string
headers:
description: Headers to add to HTTP(S) requests
type: object
additionalProperties:
type: array
items:
type: string
secretRef:
description: Kubernetes secret reference containing the provider credentials
type: object
Expand Down
5 changes: 5 additions & 0 deletions pkg/apis/flagger/v1beta1/metric.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package v1beta1

import (
"net/http"
"text/template"

corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -67,6 +68,10 @@ type MetricTemplateProvider struct {
// +optional
Address string `json:"address,omitempty"`

// Headers to be supplied to HTTP(S) request of this provider
// +optional
Headers http.Header `json:"headers,omitempty"`

// Secret reference containing the provider credentials
// +optional
SecretRef *corev1.LocalObjectReference `json:"secretRef,omitempty"`
Expand Down
17 changes: 17 additions & 0 deletions pkg/apis/flagger/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions pkg/metrics/providers/prometheus.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const prometheusOnlineQuery = "vector(1)"
type PrometheusProvider struct {
timeout time.Duration
url url.URL
headers http.Header
username string
password string
token string
Expand Down Expand Up @@ -66,9 +67,16 @@ func NewPrometheusProvider(provider flaggerv1.MetricTemplateProvider, credential
return nil, fmt.Errorf("%s address %s is not a valid URL", provider.Type, provider.Address)
}

headers := http.Header{}

if provider.Headers != nil {
headers = provider.Headers
}

prom := PrometheusProvider{
timeout: 5 * time.Second,
url: *promURL,
headers: headers,
client: http.DefaultClient,
}

Expand Down Expand Up @@ -116,6 +124,8 @@ func (p *PrometheusProvider) RunQuery(query string) (float64, error) {
return 0, fmt.Errorf("http.NewRequest failed: %w", err)
}

req.Header = p.headers

if p.token != "" {
req.Header.Add("Authorization", "Bearer "+p.token)
} else if p.username != "" && p.password != "" {
Expand Down
37 changes: 37 additions & 0 deletions pkg/metrics/providers/prometheus_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,3 +307,40 @@ func TestPrometheusProvider_IsOnline(t *testing.T) {
assert.Equal(t, true, ok)
})
}

func TestPrometheusProvider_RunQueryWithProviderHeaders(t *testing.T) {
t.Run("ok", func(t *testing.T) {
expected := `sum(envoy_cluster_upstream_rq)`
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
promql := r.URL.Query()["query"][0]
assert.Equal(t, expected, promql)

assert.Equal(t, []string{"tenant1"}, r.Header.Values("X-Scope-Orgid"))

json := `{"status":"success","data":{"resultType":"vector","result":[{"metric":{},"value":[1545905245.458,"100"]}]}}`
w.Write([]byte(json))
}))
defer ts.Close()

clients := prometheusFake()

template, err := clients.flaggerClient.FlaggerV1beta1().MetricTemplates("default").Get(context.TODO(), "prometheus", metav1.GetOptions{})
require.NoError(t, err)

template.Spec.Provider.Address = ts.URL
template.Spec.Provider.Headers = http.Header{
"X-Scope-OrgID": []string{"tenant1"},
}

secret, err := clients.kubeClient.CoreV1().Secrets("default").Get(context.TODO(), "prometheus", metav1.GetOptions{})
require.NoError(t, err)

prom, err := NewPrometheusProvider(template.Spec.Provider, secret.Data)
require.NoError(t, err)

val, err := prom.RunQuery(template.Spec.Query)
require.NoError(t, err)

assert.Equal(t, float64(100), val)
})
}

0 comments on commit f8438ab

Please sign in to comment.