fix(setting): Add default scheme to handle k8s api errors (#115177)

This commit is contained in:
Andres Torres
2025-12-11 20:12:25 +00:00
committed by GitHub
parent c35642b04d
commit 652b4f2fab
2 changed files with 81 additions and 1 deletions
+5 -1
View File
@@ -13,6 +13,7 @@ import (
"go.opentelemetry.io/otel/trace"
"gopkg.in/ini.v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apiserver/pkg/endpoints/request"
@@ -397,6 +398,9 @@ func getRestClient(config Config, log logging.Logger) (*rest.RESTClient, error)
burst = config.Burst
}
// Add a default scheme to handle K8s API error responses
scheme := runtime.NewScheme()
restConfig := &rest.Config{
Host: config.URL,
TLSClientConfig: config.TLSClientConfig,
@@ -407,7 +411,7 @@ func getRestClient(config Config, log logging.Logger) (*rest.RESTClient, error)
APIPath: "/apis",
ContentConfig: rest.ContentConfig{
GroupVersion: &settingGroupVersion,
NegotiatedSerializer: serializer.NewCodecFactory(nil).WithoutConversion(),
NegotiatedSerializer: serializer.NewCodecFactory(scheme).WithoutConversion(),
},
}
+76
View File
@@ -148,6 +148,82 @@ func TestRemoteSettingService_List(t *testing.T) {
require.Error(t, err)
assert.Nil(t, result)
})
t.Run("should handle API errors", func(t *testing.T) {
statusResponse := `{
"apiVersion": "v1",
"kind": "Status",
"metadata": {},
"status": "Failure",
"message": "settings.setting.grafana.app \"test\" not found",
"reason": "NotFound",
"details": {
"name": "test",
"group": "setting.grafana.app",
"kind": "settings"
},
"code": 404
}`
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusNotFound)
_, _ = w.Write([]byte(statusResponse))
}))
defer server.Close()
client := newTestClient(t, server.URL, 500)
ctx := request.WithNamespace(context.Background(), "test-namespace")
result, err := client.List(ctx, metav1.LabelSelector{})
require.Error(t, err)
assert.Nil(t, result)
assert.Contains(t, err.Error(), "could not find the requested resource")
})
t.Run("should handle 500 internal server error", func(t *testing.T) {
statusResponse := `{
"apiVersion": "v1",
"kind": "Status",
"metadata": {},
"status": "Failure",
"message": "Internal error occurred: database connection failed",
"reason": "InternalError",
"code": 500
}`
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write([]byte(statusResponse))
}))
defer server.Close()
client := newTestClient(t, server.URL, 500)
ctx := request.WithNamespace(context.Background(), "test-namespace")
result, err := client.List(ctx, metav1.LabelSelector{})
require.Error(t, err)
assert.Nil(t, result)
assert.Contains(t, err.Error(), "error on the server")
})
t.Run("should handle connection errors", func(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))
serverURL := server.URL
server.Close()
client := newTestClient(t, serverURL, 500)
ctx := request.WithNamespace(context.Background(), "test-namespace")
result, err := client.List(ctx, metav1.LabelSelector{})
require.Error(t, err)
assert.Nil(t, result)
assert.Contains(t, err.Error(), "connection refused")
})
}
func TestParseSettingList(t *testing.T) {