From 95e4df86d7cee81049aab572ec28e7970a57f913 Mon Sep 17 00:00:00 2001 From: glorv Date: Thu, 4 Aug 2022 18:08:06 +0800 Subject: [PATCH] server: add a http interface to change labels (#36845) ref pingcap/tidb#35926 --- server/http_handler.go | 32 ++++++++++++++++++++++++++++++++ server/http_handler_test.go | 33 +++++++++++++++++++++++++++++++++ server/http_status.go | 1 + 3 files changed, 66 insertions(+) diff --git a/server/http_handler.go b/server/http_handler.go index d73d357dc1d87..f06e701902de8 100644 --- a/server/http_handler.go +++ b/server/http_handler.go @@ -392,6 +392,9 @@ type ddlHookHandler struct { type valueHandler struct { } +// labelHandler is the handler for set labels +type labelHandler struct{} + const ( opTableRegions = "regions" opTableRanges = "ranges" @@ -2158,3 +2161,32 @@ func (h ddlHookHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { ctx := req.Context() logutil.Logger(ctx).Info("change ddl hook success", zap.String("to_ddl_hook", req.FormValue("ddl_hook"))) } + +// ServeHTTP handles request of set server labels. +func (h labelHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { + if req.Method != http.MethodPost { + writeError(w, errors.Errorf("This api only support POST method")) + return + } + + labels := make(map[string]string) + err := json.NewDecoder(req.Body).Decode(&labels) + if err != nil { + writeError(w, err) + return + } + + if len(labels) > 0 { + cfg := *config.GetGlobalConfig() + if cfg.Labels == nil { + cfg.Labels = make(map[string]string, len(labels)) + } + for k, v := range labels { + cfg.Labels[k] = v + } + config.StoreGlobalConfig(&cfg) + logutil.BgLogger().Info("update server labels", zap.Any("labels", cfg.Labels)) + } + + writeData(w, config.GetGlobalConfig().Labels) +} diff --git a/server/http_handler_test.go b/server/http_handler_test.go index b60a8f989dc6c..e75760303197b 100644 --- a/server/http_handler_test.go +++ b/server/http_handler_test.go @@ -1127,3 +1127,36 @@ func TestWriteDBTablesData(t *testing.T) { require.Equal(t, ti[0].Name.String(), tbs[0].Meta().Name.String()) require.Equal(t, ti[1].Name.String(), tbs[1].Meta().Name.String()) } + +func TestSetLabels(t *testing.T) { + ts := createBasicHTTPHandlerTestSuite() + + ts.startServer(t) + defer ts.stopServer(t) + + testUpdateLabels := func(labels, expected map[string]string) { + buffer := bytes.NewBuffer([]byte{}) + require.Nil(t, json.NewEncoder(buffer).Encode(labels)) + resp, err := ts.postStatus("/labels", "application/json", buffer) + require.NoError(t, err) + require.NotNil(t, resp) + require.Equal(t, http.StatusOK, resp.StatusCode) + newLabels := config.GetGlobalConfig().Labels + require.Equal(t, newLabels, expected) + } + + labels := map[string]string{ + "zone": "us-west-1", + "test": "123", + } + testUpdateLabels(labels, labels) + + updated := map[string]string{ + "zone": "bj-1", + } + labels["zone"] = "bj-1" + testUpdateLabels(updated, labels) + + // reset the global variable + config.GetGlobalConfig().Labels = map[string]string{} +} diff --git a/server/http_status.go b/server/http_status.go index 0ed6dd07543a8..5c815b8ed1886 100644 --- a/server/http_status.go +++ b/server/http_status.go @@ -225,6 +225,7 @@ func (s *Server) startHTTPServer() { router.Handle("/config", fn.Wrap(func() (*config.Config, error) { return config.GetGlobalConfig(), nil })) + router.Handle("/labels", labelHandler{}).Name("Labels") // HTTP path for get server info. router.Handle("/info", serverInfoHandler{tikvHandlerTool}).Name("Info")