Skip to content

Commit

Permalink
mcs: add option to control redirect http request
Browse files Browse the repository at this point in the history
Signed-off-by: lhy1024 <[email protected]>
  • Loading branch information
lhy1024 committed Jan 10, 2024
1 parent 8b8c78a commit 24e64d4
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 22 deletions.
3 changes: 3 additions & 0 deletions pkg/utils/apiutil/serverapi/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ func (h *redirector) matchMicroServiceRedirectRules(r *http.Request) (bool, stri
if len(h.microserviceRedirectRules) == 0 {
return false, ""
}
if r.URL.Query().Get("redirect_mcs") == "false" {
return false, ""
}
// Remove trailing '/' from the URL path
// It will be helpful when matching the redirect rules "schedulers" or "schedulers/{name}"
r.URL.Path = strings.TrimRight(r.URL.Path, "/")
Expand Down
25 changes: 18 additions & 7 deletions tests/integrations/mcs/scheduling/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/tikv/pd/pkg/schedule/handler"
"github.com/tikv/pd/pkg/schedule/labeler"
"github.com/tikv/pd/pkg/schedule/placement"
"github.com/tikv/pd/pkg/slice"
"github.com/tikv/pd/pkg/statistics"
"github.com/tikv/pd/pkg/storage"
"github.com/tikv/pd/pkg/utils/apiutil"
Expand Down Expand Up @@ -109,17 +110,17 @@ func (suite *apiTestSuite) checkAPIForward(cluster *tests.TestCluster) {

leader := cluster.GetLeaderServer().GetServer()
urlPrefix := fmt.Sprintf("%s/pd/api/v1", leader.GetAddr())
var slice []string
var respSlice []string
var resp map[string]interface{}
testutil.Eventually(re, func() bool {
return leader.GetRaftCluster().IsServiceIndependent(utils.SchedulingServiceName)
})

// Test operators
err := testutil.ReadGetJSON(re, testDialClient, fmt.Sprintf("%s/%s", urlPrefix, "operators"), &slice,
err := testutil.ReadGetJSON(re, testDialClient, fmt.Sprintf("%s/%s", urlPrefix, "operators"), &respSlice,
testutil.WithHeader(re, apiutil.ForwardToMicroServiceHeader, "true"))
re.NoError(err)
re.Empty(slice)
re.Empty(respSlice)

err = testutil.CheckPostJSON(testDialClient, fmt.Sprintf("%s/%s", urlPrefix, "operators"), []byte(``),
testutil.StatusNotOK(re), testutil.WithHeader(re, apiutil.ForwardToMicroServiceHeader, "true"))
Expand Down Expand Up @@ -167,10 +168,12 @@ func (suite *apiTestSuite) checkAPIForward(cluster *tests.TestCluster) {
// Should not redirect:
// "/schedulers", http.MethodPost
// "/schedulers/{name}", http.MethodDelete
err = testutil.ReadGetJSON(re, testDialClient, fmt.Sprintf("%s/%s", urlPrefix, "schedulers"), &slice,
testutil.WithHeader(re, apiutil.ForwardToMicroServiceHeader, "true"))
re.NoError(err)
re.Contains(slice, "balance-leader-scheduler")
testutil.Eventually(re, func() bool {
err = testutil.ReadGetJSON(re, testDialClient, fmt.Sprintf("%s/%s", urlPrefix, "schedulers"), &respSlice,
testutil.WithHeader(re, apiutil.ForwardToMicroServiceHeader, "true"))
re.NoError(err)
return slice.Contains(respSlice, "balance-leader-scheduler")
})

postScheduler := func(delay int) {
input := make(map[string]interface{})
Expand Down Expand Up @@ -361,6 +364,14 @@ func (suite *apiTestSuite) checkAPIForward(cluster *tests.TestCluster) {
err = testutil.CheckPostJSON(testDialClient, fmt.Sprintf("%s/%s", urlPrefix, "config/placement-rule/pd"), rulesArgs,
testutil.WithoutHeader(re, apiutil.ForwardToMicroServiceHeader))
re.NoError(err)

// test redirect is disabled
err = testutil.CheckGetJSON(testDialClient, fmt.Sprintf("%s/%s", urlPrefix, "config/placement-rule/pd"), nil,
testutil.WithHeader(re, apiutil.ForwardToMicroServiceHeader, "true"))
re.NoError(err)
err = testutil.CheckGetJSON(testDialClient, fmt.Sprintf("%s/%s?redirect_mcs=false", urlPrefix, "config/placement-rule/pd"), nil,
testutil.WithoutHeader(re, apiutil.ForwardToMicroServiceHeader))
re.NoError(err)
}

func (suite *apiTestSuite) TestConfig() {
Expand Down
71 changes: 56 additions & 15 deletions tools/pd-ctl/pdctl/command/config_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,21 @@ import (
"github.com/tikv/pd/server/config"
)

var (
configPrefix = "pd/api/v1/config"
schedulePrefix = "pd/api/v1/config/schedule"
replicatePrefix = "pd/api/v1/config/replicate"
labelPropertyPrefix = "pd/api/v1/config/label-property"
clusterVersionPrefix = "pd/api/v1/config/cluster-version"
rulesPrefix = "pd/api/v1/config/rules"
rulesBatchPrefix = "pd/api/v1/config/rules/batch"
rulePrefix = "pd/api/v1/config/rule"
ruleGroupPrefix = "pd/api/v1/config/rule_group"
ruleGroupsPrefix = "pd/api/v1/config/rule_groups"
replicationModePrefix = "pd/api/v1/config/replication-mode"
ruleBundlePrefix = "pd/api/v1/config/placement-rule"
pdServerPrefix = "pd/api/v1/config/pd-server"
const (
configPrefix = "pd/api/v1/config"
schedulePrefix = "pd/api/v1/config/schedule"
replicatePrefix = "pd/api/v1/config/replicate"
labelPropertyPrefix = "pd/api/v1/config/label-property"
clusterVersionPrefix = "pd/api/v1/config/cluster-version"
rulesPrefix = "pd/api/v1/config/rules"
rulesBatchPrefix = "pd/api/v1/config/rules/batch"
rulePrefix = "pd/api/v1/config/rule"
ruleGroupPrefix = "pd/api/v1/config/rule_group"
ruleGroupsPrefix = "pd/api/v1/config/rule_groups"
replicationModePrefix = "pd/api/v1/config/replication-mode"
ruleBundlePrefix = "pd/api/v1/config/placement-rule"
pdServerPrefix = "pd/api/v1/config/pd-server"
flagRedirectMicroService = "redirect_mcs"
)

// NewConfigCommand return a config subcommand of rootCmd
Expand Down Expand Up @@ -437,6 +438,7 @@ func NewPlacementRulesCommand() *cobra.Command {
show.Flags().String("id", "", "rule id")
show.Flags().String("region", "", "region id")
show.Flags().Bool("detail", false, "detailed match info for region")
show.Flags().Bool(flagRedirectMicroService, true, "allow to redirect to micro service")
load := &cobra.Command{
Use: "load",
Short: "load placement rules to a file",
Expand All @@ -446,6 +448,7 @@ func NewPlacementRulesCommand() *cobra.Command {
load.Flags().String("id", "", "rule id")
load.Flags().String("region", "", "region id")
load.Flags().String("out", "rules.json", "the filename contains rules")
load.Flags().Bool(flagRedirectMicroService, true, "allow to redirect to micro service")
save := &cobra.Command{
Use: "save",
Short: "save rules from file",
Expand All @@ -461,6 +464,7 @@ func NewPlacementRulesCommand() *cobra.Command {
Short: "show rule group configuration(s)",
Run: showRuleGroupFunc,
}
ruleGroupShow.Flags().Bool(flagRedirectMicroService, true, "allow to redirect to micro service")
ruleGroupSet := &cobra.Command{
Use: "set <id> <index> <override>",
Short: "update rule group configuration",
Expand All @@ -483,6 +487,7 @@ func NewPlacementRulesCommand() *cobra.Command {
Run: getRuleBundle,
}
ruleBundleGet.Flags().String("out", "", "the output file")
ruleBundleGet.Flags().Bool(flagRedirectMicroService, true, "allow to redirect to micro service")
ruleBundleSet := &cobra.Command{
Use: "set",
Short: "set rule group config and its rules from file",
Expand All @@ -501,6 +506,7 @@ func NewPlacementRulesCommand() *cobra.Command {
Run: loadRuleBundle,
}
ruleBundleLoad.Flags().String("out", "rules.json", "the output file")
ruleBundleLoad.Flags().Bool(flagRedirectMicroService, true, "allow to redirect to micro service")
ruleBundleSave := &cobra.Command{
Use: "save",
Short: "save all group configs and rules from file",
Expand Down Expand Up @@ -561,6 +567,15 @@ func getPlacementRulesFunc(cmd *cobra.Command, args []string) {
cmd.Println(`"region" should not be specified with "group" or "id" at the same time`)
return
}
allowRedirectMicroService, err := cmd.Flags().GetBool(flagRedirectMicroService)
if err != nil {
cmd.PrintErrln("Failed to parse flag: ", err)
return
}
if !allowRedirectMicroService {
reqPath += "?redirect_mcs=false"
}

res, err := doRequest(cmd, reqPath, http.MethodGet, http.Header{})
if err != nil {
cmd.Println(err)
Expand Down Expand Up @@ -629,6 +644,14 @@ func showRuleGroupFunc(cmd *cobra.Command, args []string) {
if len(args) > 0 {
reqPath = path.Join(ruleGroupPrefix, args[0])
}
allowRedirectMicroService, err := cmd.Flags().GetBool(flagRedirectMicroService)
if err != nil {
cmd.PrintErrln("Failed to parse flag: ", err)
return
}
if !allowRedirectMicroService {
reqPath += "?redirect_mcs=false"
}

res, err := doRequest(cmd, reqPath, http.MethodGet, http.Header{})
if err != nil {
Expand Down Expand Up @@ -671,6 +694,14 @@ func getRuleBundle(cmd *cobra.Command, args []string) {
}

reqPath := path.Join(ruleBundlePrefix, args[0])
allowRedirectMicroService, err := cmd.Flags().GetBool(flagRedirectMicroService)
if err != nil {
cmd.PrintErrln("Failed to parse flag: ", err)
return
}
if !allowRedirectMicroService {
reqPath += "?redirect_mcs=false"
}

res, err := doRequest(cmd, reqPath, http.MethodGet, http.Header{})
if err != nil {
Expand Down Expand Up @@ -747,7 +778,17 @@ func delRuleBundle(cmd *cobra.Command, args []string) {
}

func loadRuleBundle(cmd *cobra.Command, args []string) {
res, err := doRequest(cmd, ruleBundlePrefix, http.MethodGet, http.Header{})
reqPath := ruleBundlePrefix
allowRedirectMicroService, err := cmd.Flags().GetBool(flagRedirectMicroService)
if err != nil {
cmd.PrintErrln("Failed to parse flag: ", err)
return
}
if !allowRedirectMicroService {
reqPath += "?redirect_mcs=false"
}

res, err := doRequest(cmd, reqPath, http.MethodGet, http.Header{})
if err != nil {
cmd.Println(err)
return
Expand Down

0 comments on commit 24e64d4

Please sign in to comment.