fix: build clean config for externalmetrics provider if address is provided

Signed-off-by: Sanskar Jaiswal <jaiswalsanskar078@gmail.com>
This commit is contained in:
Sanskar Jaiswal
2026-08-11 18:01:39 +05:30
parent b37258ccfd
commit a74eb9c9c9
2 changed files with 89 additions and 13 deletions
+24 -13
View File
@@ -47,19 +47,7 @@ func NewExternalMetricsProvider(
)
}
// clone to avoid mutating the shared config
restConfig := rest.CopyConfig(config)
// apply overrides from MetricTemplateProvider
if provider.Address != "" {
restConfig.Host = provider.Address
}
restConfig.TLSClientConfig.Insecure = provider.InsecureSkipVerify
if tokenBytes, ok := credentials["token"]; ok {
restConfig.BearerToken = string(tokenBytes)
}
restConfig.Timeout = 5 * time.Second
restConfig := externalMetricsRestConfig(provider, credentials, config)
client, err := externalmetrics_client.NewForConfig(restConfig)
if err != nil {
@@ -71,6 +59,29 @@ func NewExternalMetricsProvider(
}, nil
}
func externalMetricsRestConfig(
provider flaggerv1.MetricTemplateProvider,
credentials map[string][]byte,
config *rest.Config,
) *rest.Config {
var restConfig *rest.Config
if provider.Address == "" {
restConfig = rest.CopyConfig(config)
} else {
restConfig = &rest.Config{
Host: provider.Address,
}
}
restConfig.TLSClientConfig.Insecure = provider.InsecureSkipVerify
if tokenBytes, ok := credentials["token"]; ok {
restConfig.BearerToken = strings.TrimSpace(string(tokenBytes))
}
restConfig.Timeout = 5 * time.Second
return restConfig
}
// RunQuery retrieves the ExternalMetricValue from the External Metrics API
// at the ExternalMetricsProvider's address, using the provided query string,
// and returns the *first* result as a float64.
@@ -18,6 +18,10 @@ package providers
import (
"errors"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"strings"
"testing"
@@ -99,6 +103,67 @@ func TestExternalMetrics_NewProvider_NilConfig(t *testing.T) {
require.Error(t, err)
}
func TestExternalMetrics_CustomProviderAddressDoesNotSendInheritedAuth(t *testing.T) {
tokenFile := filepath.Join(t.TempDir(), "token")
require.NoError(t, os.WriteFile(tokenFile, []byte("operator-file-token"), 0o600))
tests := []struct {
name string
credentials map[string][]byte
wantAuthorization string
}{
{
name: "without credentials",
credentials: nil,
wantAuthorization: "",
},
{
name: "with provider token",
credentials: map[string][]byte{
"token": []byte("provider-token"),
},
wantAuthorization: "Bearer provider-token",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
authHeaders := make(chan string, 1)
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
authHeaders <- r.Header.Get("Authorization")
w.Header().Set("Content-Type", "application/json")
_, err := w.Write([]byte(`{
"kind": "ExternalMetricValueList",
"apiVersion": "external.metrics.k8s.io/v1beta1",
"metadata": {},
"items": []
}`))
require.NoError(t, err)
}))
defer ts.Close()
emp, err := NewExternalMetricsProvider(
flaggerv1.MetricTemplateProvider{
Address: ts.URL,
},
tt.credentials,
&rest.Config{
Host: "https://kubernetes.default.svc",
BearerToken: "operator-token",
BearerTokenFile: tokenFile,
},
)
require.NoError(t, err)
online, err := emp.IsOnline()
require.NoError(t, err)
assert.True(t, online)
require.Len(t, authHeaders, 1)
assert.Equal(t, tt.wantAuthorization, <-authHeaders)
})
}
}
func TestExternalMetrics_ParseQuery(t *testing.T) {
tests := []struct {
name string