Skip to content

Commit

Permalink
config: dynamic proxy config (#56)
Browse files Browse the repository at this point in the history
  • Loading branch information
xhebox authored Aug 26, 2022
1 parent 64e87f0 commit bacaced
Show file tree
Hide file tree
Showing 22 changed files with 503 additions and 117 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ bin
*.swp
.DS_Store
vendor
work
.vscode/
.coverage*
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ cmd: $(EXECUTABLE_TARGETS)
build: cmd
go build $(GOFLAGS) ./...

cmd_%: OUTPUT=$(patsubst cmd_%,bin/%,$@)
cmd_%: SOURCE=$(patsubst cmd_%,cmd/%/main.go,$@)
cmd_%: OUTPUT=$(patsubst cmd_%,./bin/%,$@)
cmd_%: SOURCE=$(patsubst cmd_%,./cmd/%,$@)
cmd_%:
go build $(GOFLAGS) -o $(OUTPUT) $(SOURCE)

Expand Down
66 changes: 66 additions & 0 deletions cmd/weirctl/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright 2022 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
"fmt"
"io"
"net/http"
"os"

"github.com/spf13/cobra"
)

const (
configPrefix = "/api/admin/config"
)

func GetConfigCmd(ctx *Context) *cobra.Command {
rootCmd := &cobra.Command{
Use: "config",
Short: "",
}

// config proxy
{
configProxy := &cobra.Command{
Use: "proxy",
}
input := configProxy.Flags().String("input", "", "specify the input json file for proxy config")
configProxy.RunE = func(cmd *cobra.Command, args []string) error {
var b io.Reader
if *input != "" {
f, err := os.Open(*input)
if err != nil {
return err
}
defer f.Close()
} else {
b = os.Stdin
}

resp, err := doRequest(cmd.Context(), ctx, http.MethodPut, fmt.Sprintf("%s/proxy", configPrefix), b)
if err != nil {
return err
}

cmd.Println(resp)
return nil
}
rootCmd.AddCommand(configProxy)
}

return rootCmd
}
9 changes: 4 additions & 5 deletions cmd/weirctl/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ package main
import (
"net/http"

"github.com/pingcap/TiProxy/cmd/weirctl/namespace"
"github.com/pingcap/TiProxy/cmd/weirctl/util"
"github.com/pingcap/TiProxy/pkg/util/cmd"
"github.com/spf13/cobra"
"go.uber.org/zap"
Expand All @@ -30,9 +28,9 @@ func main() {
Short: "cli",
}

ctx := &util.Context{}
ctx := &Context{}

curls := rootCmd.PersistentFlags().StringArray("curls", []string{"localhost:2379"}, "API gateway addresses")
curls := rootCmd.PersistentFlags().StringArray("curls", []string{"localhost:3080"}, "API gateway addresses")
logEncoder := rootCmd.PersistentFlags().String("log_encoder", "tidb", "log in format of tidb, console, or json")
logLevel := rootCmd.PersistentFlags().String("log_level", "info", "log level")
rootCmd.PersistentFlags().Bool("indent", true, "whether indent the returned json")
Expand All @@ -52,6 +50,7 @@ func main() {
return nil
}

rootCmd.AddCommand(namespace.GetRootCommand(ctx))
rootCmd.AddCommand(GetNamespaceCmd(ctx))
rootCmd.AddCommand(GetConfigCmd(ctx))
cmd.RunRootCommand(rootCmd)
}
27 changes: 13 additions & 14 deletions cmd/weirctl/namespace/main.go → cmd/weirctl/namespace.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,22 @@
// See the License for the specific language governing permissions and
// limitations under the License.

package namespace
package main

import (
"fmt"
"net/http"
"os"
"strings"

"github.com/pingcap/TiProxy/cmd/weirctl/util"
"github.com/spf13/cobra"
)

const (
prefix = "/api/admin/namespace"
namespacePrefix = "/api/admin/namespace"
)

func GetRootCommand(ctx *util.Context) *cobra.Command {
func GetNamespaceCmd(ctx *Context) *cobra.Command {
rootCmd := &cobra.Command{
Use: "namespace",
Short: "",
Expand All @@ -39,12 +38,12 @@ func GetRootCommand(ctx *util.Context) *cobra.Command {
&cobra.Command{
Use: "list",
RunE: func(cmd *cobra.Command, args []string) error {
resp, err := util.DoRequest(cmd.Context(), ctx, http.MethodGet, prefix, nil)
resp, err := doRequest(cmd.Context(), ctx, http.MethodGet, namespacePrefix, nil)
if err != nil {
return err
}

fmt.Print(resp)
cmd.Println(resp)
return nil
},
},
Expand All @@ -56,12 +55,12 @@ func GetRootCommand(ctx *util.Context) *cobra.Command {
Use: "commit",
}
commitNamespaces.RunE = func(cmd *cobra.Command, args []string) error {
resp, err := util.DoRequest(cmd.Context(), ctx, http.MethodPost, fmt.Sprintf("%s/commit?namespaces=%s", prefix, strings.Join(args, ",")), nil)
resp, err := doRequest(cmd.Context(), ctx, http.MethodPost, fmt.Sprintf("%s/commit?namespaces=%s", namespacePrefix, strings.Join(args, ",")), nil)
if err != nil {
return err
}

fmt.Print(resp)
cmd.Println(resp)
return nil
}
rootCmd.AddCommand(commitNamespaces)
Expand All @@ -77,12 +76,12 @@ func GetRootCommand(ctx *util.Context) *cobra.Command {
return cmd.Help()
}

resp, err := util.DoRequest(cmd.Context(), ctx, http.MethodGet, fmt.Sprintf("%s/%s", prefix, args[0]), nil)
resp, err := doRequest(cmd.Context(), ctx, http.MethodGet, fmt.Sprintf("%s/%s", namespacePrefix, args[0]), nil)
if err != nil {
return err
}

fmt.Print(resp)
cmd.Println(resp)
return nil
}
rootCmd.AddCommand(getNamespace)
Expand All @@ -109,12 +108,12 @@ func GetRootCommand(ctx *util.Context) *cobra.Command {
in = f
}

resp, err := util.DoRequest(cmd.Context(), ctx, http.MethodPut, fmt.Sprintf("%s/%s", prefix, args[0]), in)
resp, err := doRequest(cmd.Context(), ctx, http.MethodPut, fmt.Sprintf("%s/%s", namespacePrefix, args[0]), in)
if err != nil {
return err
}

fmt.Print(resp)
cmd.Println(resp)
return nil
}
rootCmd.AddCommand(putNamespace)
Expand All @@ -130,12 +129,12 @@ func GetRootCommand(ctx *util.Context) *cobra.Command {
return cmd.Help()
}

resp, err := util.DoRequest(cmd.Context(), ctx, http.MethodDelete, fmt.Sprintf("%s/%s", prefix, args[0]), nil)
resp, err := doRequest(cmd.Context(), ctx, http.MethodDelete, fmt.Sprintf("%s/%s", namespacePrefix, args[0]), nil)
if err != nil {
return err
}

fmt.Print(resp)
cmd.Println(resp)
return nil
}
rootCmd.AddCommand(delNamespace)
Expand Down
13 changes: 8 additions & 5 deletions cmd/weirctl/util/util.go → cmd/weirctl/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

package util
package main

import (
"context"
Expand All @@ -31,7 +31,7 @@ type Context struct {
Client *http.Client
}

func DoRequest(ctx context.Context, bctx *Context, method string, url string, rd io.Reader) (string, error) {
func doRequest(ctx context.Context, bctx *Context, method string, url string, rd io.Reader) (string, error) {
var sep string
if len(url) > 0 && url[0] != '/' {
sep = "/"
Expand All @@ -43,7 +43,7 @@ func DoRequest(ctx context.Context, bctx *Context, method string, url string, rd
}

var rete string
for i := range rand.Perm(len(bctx.CUrls)) {
for _, i := range rand.Perm(len(bctx.CUrls)) {
req.URL.Host = bctx.CUrls[i]

res, err := bctx.Client.Do(req)
Expand All @@ -56,11 +56,14 @@ func DoRequest(ctx context.Context, bctx *Context, method string, url string, rd
switch res.StatusCode {
case http.StatusOK:
return string(resb), nil
case http.StatusBadRequest:
return fmt.Sprintf("bad request: %s", string(resb)), nil
case http.StatusInternalServerError:
rete = fmt.Sprintf("internal error: %s", string(resb))
continue
case http.StatusBadRequest:
return string(resb), fmt.Errorf("bad request")
default:
rete = fmt.Sprintf("%s: %s", res.Status, string(resb))
continue
}
}

Expand Down
81 changes: 43 additions & 38 deletions pkg/config/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,64 +28,69 @@ const (
)

type Config struct {
Workdir string `yaml:"workdir"`
Workdir string `yaml:"workdir" toml:"workdir" json:"workdir"`

LCUrlsI []string `yaml:"listen-urls"`
ACUrlsI []string `yaml:"advertise-urls"`
LPUrlsI []string `yaml:"listen-peer-urls"`
APUrlsI []string `yaml:"advertise-peer-urls"`
LCUrls []url.URL `yaml:"-"`
ACUrls []url.URL `yaml:"-"`
LPUrls []url.URL `yaml:"-"`
APUrls []url.URL `yaml:"-"`
LCUrlsI []string `yaml:"listen-urls" toml:"listen-urls" json:"listen-urls"`
ACUrlsI []string `yaml:"advertise-urls" toml:"advertise-urls" json:"advertise-urls"`
LPUrlsI []string `yaml:"listen-peer-urls" toml:"listen-peer-urls" json:"listen-peer-urls"`
APUrlsI []string `yaml:"advertise-peer-urls" toml:"advertise-peer-urls" json:"advertise-peer-urls"`
LCUrls []url.URL `yaml:"-" toml:"-" json:"-"`
ACUrls []url.URL `yaml:"-" toml:"-" json:"-"`
LPUrls []url.URL `yaml:"-" toml:"-" json:"-"`
APUrls []url.URL `yaml:"-" toml:"-" json:"-"`

Config ConfigManager `yaml:"config"`
Proxy ProxyServer `yaml:"proxy"`
API API `yaml:"api"`
Metrics Metrics `yaml:"metrics"`
Log Log `yaml:"log"`
Security Security `yaml:"security"`
Config ConfigManager `yaml:"config" toml:"config" json:"config"`
Proxy ProxyServer `yaml:"proxy" toml:"proxy" json:"proxy"`
API API `yaml:"api" toml:"api" json:"api"`
Metrics Metrics `yaml:"metrics" toml:"metrics" json:"metrics"`
Log Log `yaml:"log" toml:"log" json:"log"`
Security Security `yaml:"security" toml:"security" json:"security"`
}

type Metrics struct {
PromCluster string `yaml:"prom_cluster"`
PromCluster string `yaml:"prom_cluster" toml:"prom_cluster" json:"prom_cluster"`
}

type ConfigManager struct {
IgnoreWrongNamespace bool `yaml:"ignore_wrong_namespace"`
IgnoreWrongNamespace bool `yaml:"ignore_wrong_namespace" toml:"ignore_wrong_namespace" json:"ignore_wrong_namespace"`
WatchInterval string `yaml:"watch_interval" toml:"watch_interval" json:"watch_interval"`
}

type ProxyServerOnline struct {
MaxConnections uint64 `yaml:"max_connections" toml:"max_connections" json:"max_connections"`
TCPKeepAlive bool `yaml:"tcp_keep_alive" toml:"tcp_keep_alive" json:"tcp_keep_alive"`
}

type ProxyServer struct {
Addr string `yaml:"addr"`
MaxConnections uint64 `yaml:"max_connections"`
TCPKeepAlive bool `yaml:"tcp_keep_alive"`
PDAddrs string `yaml:"pd_addrs"`
ProxyProtocol string `yaml:"proxy_protocol"`
ProxyServerOnline
Addr string `yaml:"addr" toml:"addr" json:"addr"`
PDAddrs string `yaml:"pd_addrs" toml:"pd_addrs" json:"pd_addrs"`
ProxyProtocol string `yaml:"proxy_protocol" toml:"proxy_protocol" json:"proxy_protocol"`
}

type API struct {
EnableBasicAuth bool `yaml:"enable_basic_auth"`
User string `yaml:"user"`
Password string `yaml:"password"`
EnableBasicAuth bool `yaml:"enable_basic_auth" toml:"enable_basic_auth" json:"enable_basic_auth"`
User string `yaml:"user" toml:"user" json:"user"`
Password string `yaml:"password" toml:"password" json:"password"`
}

type Log struct {
Level string `yaml:"level"`
Encoder string `yaml:"encoder"`
LogFile LogFile `yaml:"log_file"`
Level string `yaml:"level" toml:"level" json:"level"`
Encoder string `yaml:"encoder" toml:"encoder" json:"encoder"`
LogFile LogFile `yaml:"log_file" toml:"log_file" json:"log_file"`
}

type LogFile struct {
Filename string `yaml:"filename"`
MaxSize int `yaml:"max_size"`
MaxDays int `yaml:"max_days"`
MaxBackups int `yaml:"max_backups"`
Filename string `yaml:"filename" toml:"filename" json:"filename"`
MaxSize int `yaml:"max_size" toml:"max_size" json:"max_size"`
MaxDays int `yaml:"max_days" toml:"max_days" json:"max_days"`
MaxBackups int `yaml:"max_backups" toml:"max_backups" json:"max_backups"`
}

type TLSCert struct {
CA string `toml:"ca" json:"ca"`
Cert string `toml:"cert" json:"cert"`
Key string `toml:"key" json:"key"`
CA string `yaml:"ca" toml:"ca" json:"ca"`
Cert string `yaml:"cert" toml:"cert" json:"cert"`
Key string `yaml:"key" toml:"key" json:"key"`
}

func (c TLSCert) HasCert() bool {
Expand All @@ -97,9 +102,9 @@ func (c TLSCert) HasCA() bool {
}

type Security struct {
RSAKeySize int `toml:"rsa-key-size" json:"rsa-key-size"`
Server TLSCert `toml:"server" json:"server"`
Cluster TLSCert `toml:"cluster" json:"cluster"`
RSAKeySize int `yaml:"rsa-key-size" toml:"rsa-key-size" json:"rsa-key-size"`
Server TLSCert `yaml:"server" toml:"server" json:"server"`
Cluster TLSCert `yaml:"cluster" toml:"cluster" json:"cluster"`
}

func NewConfig(data []byte) (*Config, error) {
Expand Down
10 changes: 6 additions & 4 deletions pkg/config/proxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ var testProxyConfig = Config{
IgnoreWrongNamespace: true,
},
Proxy: ProxyServer{
Addr: "0.0.0.0:4000",
MaxConnections: 1,
TCPKeepAlive: true,
PDAddrs: "127.0.0.1:4089",
Addr: "0.0.0.0:4000",
PDAddrs: "127.0.0.1:4089",
ProxyServerOnline: ProxyServerOnline{
MaxConnections: 1,
TCPKeepAlive: true,
},
},
API: API{
EnableBasicAuth: false,
Expand Down
Loading

0 comments on commit bacaced

Please sign in to comment.