From bd38cb5ae8a043e9965bd569a5a1930d2a306a4f Mon Sep 17 00:00:00 2001 From: hsinhoyeh Date: Fri, 20 May 2022 11:44:23 +0800 Subject: [PATCH] fix(backend): fixes healthz response by adding json content type. Fixes #7525 (#7532) --- backend/src/apiserver/main.go | 1 + .../client/api_server/healthz_client.go | 52 +++++++++++++++ backend/test/integration/healthz_api_test.go | 64 +++++++++++++++++++ 3 files changed, 117 insertions(+) create mode 100644 backend/src/common/client/api_server/healthz_client.go create mode 100644 backend/test/integration/healthz_api_test.go diff --git a/backend/src/apiserver/main.go b/backend/src/apiserver/main.go index c36303cbe18..e6c1cbffc5e 100644 --- a/backend/src/apiserver/main.go +++ b/backend/src/apiserver/main.go @@ -144,6 +144,7 @@ func startHttpProxy(resourceManager *resource.ResourceManager) { topMux.HandleFunc("/apis/v1beta1/pipelines/upload", pipelineUploadServer.UploadPipeline) topMux.HandleFunc("/apis/v1beta1/pipelines/upload_version", pipelineUploadServer.UploadPipelineVersion) topMux.HandleFunc("/apis/v1beta1/healthz", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") io.WriteString(w, `{"commit_sha":"`+common.GetStringConfigWithDefault("COMMIT_SHA", "unknown")+`", "tag_name":"`+common.GetStringConfigWithDefault("TAG_NAME", "unknown")+`", "multi_user":`+strconv.FormatBool(common.IsMultiUserMode())+`}`) }) diff --git a/backend/src/common/client/api_server/healthz_client.go b/backend/src/common/client/api_server/healthz_client.go new file mode 100644 index 00000000000..c18e3a1810f --- /dev/null +++ b/backend/src/common/client/api_server/healthz_client.go @@ -0,0 +1,52 @@ +package api_server + +import ( + "fmt" + + "github.com/go-openapi/strfmt" + apiclient "github.com/kubeflow/pipelines/backend/api/go_http_client/healthz_client" + params "github.com/kubeflow/pipelines/backend/api/go_http_client/healthz_client/healthz_service" + model "github.com/kubeflow/pipelines/backend/api/go_http_client/healthz_model" + "github.com/kubeflow/pipelines/backend/src/common/util" + "k8s.io/client-go/tools/clientcmd" +) + +type HealthzInterface interface { + GetHealthz() (*params.GetHealthzOK, error) +} + +type HealthzClient struct { + apiClient *apiclient.Healthz +} + +func NewHealthzClient(clientConfig clientcmd.ClientConfig, debug bool) (*HealthzClient, error) { + runtime, err := NewHTTPRuntime(clientConfig, debug) + if err != nil { + return nil, err + } + + apiClient := apiclient.New(runtime, strfmt.Default) + + // Creating upload client + return &HealthzClient{ + apiClient: apiClient, + }, nil +} + +func (c *HealthzClient) GetHealthz() (*model.APIGetHealthzResponse, error) { + parameters := params.NewGetHealthzParamsWithTimeout(apiServerDefaultTimeout) + response, err := c.apiClient.HealthzService.GetHealthz(parameters, PassThroughAuth) + if err != nil { + if defaultError, ok := err.(*params.GetHealthzDefault); ok { + err = CreateErrorFromAPIStatus(defaultError.Payload.Error, defaultError.Payload.Code) + } else { + err = CreateErrorCouldNotRecoverAPIStatus(err) + } + + return nil, util.NewUserError(err, + fmt.Sprintf("Failed to get Healthz. Params: '%+v'", parameters), + fmt.Sprintf("Failed to get Healthz. Params: '%+v'", parameters)) + + } + return response.Payload, nil +} diff --git a/backend/test/integration/healthz_api_test.go b/backend/test/integration/healthz_api_test.go new file mode 100644 index 00000000000..7b259d49fbf --- /dev/null +++ b/backend/test/integration/healthz_api_test.go @@ -0,0 +1,64 @@ +package integration + +import ( + "testing" + + "github.com/golang/glog" + "github.com/kubeflow/pipelines/backend/src/common/client/api_server" + "github.com/kubeflow/pipelines/backend/test" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" +) + +type HealthzApiTest struct { + suite.Suite + namespace string + healthzClient *api_server.HealthzClient +} + +// Check the namespace have ML job installed and ready +func (s *HealthzApiTest) SetupTest() { + if !*runIntegrationTests { + s.T().SkipNow() + return + } + + if !*isDevMode { + err := test.WaitForReady(*namespace, *initializeTimeout) + if err != nil { + glog.Exitf("Failed to initialize test. Error: %v", err) + } + } + s.namespace = *namespace + clientConfig := test.GetClientConfig(*namespace) + var err error + s.healthzClient, err = api_server.NewHealthzClient(clientConfig, false) + if err != nil { + glog.Exitf("Failed to get healthz client. Error: %v", err) + } + s.cleanUp() +} + +func (s *HealthzApiTest) TearDownSuite() { + if *runIntegrationTests { + if !*isDevMode { + s.cleanUp() + } + } +} + +func (s *HealthzApiTest) cleanUp() { +} + +func (s *HealthzApiTest) TestHealthzAPI() { + t := s.T() + + /* ---------- Verify healthz response ---------- */ + healthzResp, err := s.healthzClient.GetHealthz() + assert.Nil(t, err) + assert.NotNil(t, healthzResp) +} + +func TestHealthzAPI(t *testing.T) { + suite.Run(t, new(HealthzApiTest)) +}