diff --git a/server/api/config.go b/server/api/config.go index 87d1c059f96b..760bb9ff7d1e 100644 --- a/server/api/config.go +++ b/server/api/config.go @@ -150,7 +150,17 @@ func (h *confHandler) updateWithoutPrefix(w http.ResponseWriter, config *config. h.rd.JSON(w, http.StatusBadRequest, err.Error()) return } - if !found1 && !found2 && !found3 && !found4 { + found5, err := h.updateClusterVersion(data, config) + if err != nil { + h.rd.JSON(w, http.StatusBadRequest, err.Error()) + return + } + found6, err := h.updateLabelProperty(data, config) + if err != nil { + h.rd.JSON(w, http.StatusBadRequest, err.Error()) + return + } + if !found1 && !found2 && !found3 && !found4 && !found5 && !found6 { h.rd.JSON(w, http.StatusBadRequest, "config item not found") return } @@ -207,6 +217,52 @@ func (h *confHandler) updateLogLevel(data []byte, config *config.Config) (bool, return false, err } +func (h *confHandler) updateClusterVersion(data []byte, config *config.Config) (bool, error) { + cfg := make(map[string]interface{}) + err := json.Unmarshal(data, &cfg) + if err != nil { + return false, err + } + + if version, ok := cfg["cluster-version"].(string); ok { + err := h.svr.SetClusterVersion(version) + if err != nil { + return true, err + } + return true, nil + } + return false, err +} + +func (h *confHandler) updateLabelProperty(data []byte, config *config.Config) (bool, error) { + cfg := make(map[string]interface{}) + err := json.Unmarshal(data, &cfg) + if err != nil { + return false, err + } + + if lp, ok := cfg["label-property"].(string); ok { + input := make(map[string]string) + err = json.Unmarshal([]byte(lp), &input) + if err != nil { + return true, err + } + switch input["action"] { + case "set": + err = h.svr.SetLabelProperty(input["type"], input["label-key"], input["label-value"]) + case "delete": + err = h.svr.DeleteLabelProperty(input["type"], input["label-key"], input["label-value"]) + default: + err = errors.Errorf("unknown action %v", input["action"]) + } + if err != nil { + return true, err + } + return true, nil + } + return false, err +} + func (h *confHandler) mergeConfig(v interface{}, data []byte) (updated bool, found bool, err error) { old, _ := json.Marshal(v) if err := json.Unmarshal(data, v); err != nil { diff --git a/server/api/config_test.go b/server/api/config_test.go index bc3f7a96e2b7..f046bc2991b6 100644 --- a/server/api/config_test.go +++ b/server/api/config_test.go @@ -22,6 +22,7 @@ import ( . "github.com/pingcap/check" "github.com/pingcap/pd/v4/pkg/typeutil" "github.com/pingcap/pd/v4/server" + "github.com/pingcap/pd/v4/server/cluster" "github.com/pingcap/pd/v4/server/config" ) @@ -89,6 +90,8 @@ func (s *testConfigSuite) TestConfigAll(c *C) { "replication.location-labels": "idc,host", "pd-server.metric-storage": "http://127.0.0.1:1234", "log.level": "warn", + "cluster-version": "v4.0.0-beta", + "label-property": `{"type": "foo", "action": "set", "label-key": "zone", "label-value": "cn1"}`, } postData, err = json.Marshal(l) c.Assert(err, IsNil) @@ -101,8 +104,22 @@ func (s *testConfigSuite) TestConfigAll(c *C) { cfg.Replication.LocationLabels = []string{"idc", "host"} cfg.PDServerCfg.MetricStorage = "http://127.0.0.1:1234" cfg.Log.Level = "warn" + v, err := cluster.ParseVersion("v4.0.0-beta") + c.Assert(err, IsNil) + cfg.ClusterVersion = *v + cfg.LabelProperty = map[string][]config.StoreLabel{ + "foo": {{Key: "zone", Value: "cn1"}}, + } c.Assert(newCfg1, DeepEquals, cfg) + l = map[string]interface{}{ + "label-property": `{"type": "foo", "action": "delete", "label-key": "zone", "label-value": "cn1"}`, + } + postData, err = json.Marshal(l) + c.Assert(err, IsNil) + err = postJSON(addr, postData) + c.Assert(err, IsNil) + // illegal prefix l = map[string]interface{}{ "replicate.max-replicas": 1,