From bae0b4d7c00837743766808bc4f02e93a8313f39 Mon Sep 17 00:00:00 2001 From: fatedier Date: Fri, 15 Sep 2023 10:33:32 +0800 Subject: [PATCH] optimize the code of the command line (#3614) --- Release.md | 5 + cmd/frpc/sub/admin.go | 117 ++++++++++++++++ cmd/frpc/sub/flags.go | 125 ++++++++++++++++++ cmd/frpc/sub/http.go | 96 -------------- cmd/frpc/sub/https.go | 88 ------------ cmd/frpc/sub/nathole.go | 2 - cmd/frpc/sub/proxy.go | 121 +++++++++++++++++ cmd/frpc/sub/reload.go | 86 ------------ cmd/frpc/sub/root.go | 90 ------------- cmd/frpc/sub/status.go | 108 --------------- cmd/frpc/sub/stcp.go | 114 ---------------- cmd/frpc/sub/stop.go | 86 ------------ cmd/frpc/sub/sudp.go | 113 ---------------- cmd/frpc/sub/tcp.go | 84 ------------ cmd/frpc/sub/tcpmux.go | 90 ------------- cmd/frpc/sub/udp.go | 85 ------------ cmd/frpc/sub/xtcp.go | 116 ---------------- cmd/frps/flags.go | 110 +++++++++++++++ cmd/frps/root.go | 102 +------------- pkg/config/types/types.go | 3 + pkg/config/v1/validation/client.go | 12 +- pkg/config/v1/validation/common.go | 4 +- pkg/config/v1/validation/server.go | 12 +- pkg/config/v1/validation/validation.go | 10 +- pkg/config/v1/validation/visitor.go | 6 +- {test/e2e/pkg => pkg}/sdk/client/client.go | 20 ++- pkg/util/util/http.go | 5 + test/e2e/legacy/basic/client.go | 2 +- test/e2e/legacy/basic/cmd.go | 7 +- test/e2e/legacy/basic/server.go | 2 +- test/e2e/legacy/features/bandwidth_limit.go | 4 +- test/e2e/legacy/plugin/server.go | 17 +-- .../plugin/utils.go => pkg/plugin/plugin.go} | 0 test/e2e/pkg/request/request.go | 4 +- test/e2e/pkg/utils/utils.go | 10 -- test/e2e/v1/basic/client.go | 2 +- test/e2e/v1/basic/cmd.go | 7 +- test/e2e/v1/basic/server.go | 2 +- test/e2e/v1/features/bandwidth_limit.go | 4 +- test/e2e/v1/plugin/server.go | 17 +-- test/e2e/v1/plugin/utils.go | 41 ------ 41 files changed, 566 insertions(+), 1363 deletions(-) create mode 100644 cmd/frpc/sub/admin.go create mode 100644 cmd/frpc/sub/flags.go delete mode 100644 cmd/frpc/sub/http.go delete mode 100644 cmd/frpc/sub/https.go create mode 100644 cmd/frpc/sub/proxy.go delete mode 100644 cmd/frpc/sub/reload.go delete mode 100644 cmd/frpc/sub/status.go delete mode 100644 cmd/frpc/sub/stcp.go delete mode 100644 cmd/frpc/sub/stop.go delete mode 100644 cmd/frpc/sub/sudp.go delete mode 100644 cmd/frpc/sub/tcp.go delete mode 100644 cmd/frpc/sub/tcpmux.go delete mode 100644 cmd/frpc/sub/udp.go delete mode 100644 cmd/frpc/sub/xtcp.go create mode 100644 cmd/frps/flags.go rename {test/e2e/pkg => pkg}/sdk/client/client.go (79%) rename test/e2e/{legacy/plugin/utils.go => pkg/plugin/plugin.go} (100%) delete mode 100644 test/e2e/pkg/utils/utils.go delete mode 100644 test/e2e/v1/plugin/utils.go diff --git a/Release.md b/Release.md index 7f01bee..a25902c 100644 --- a/Release.md +++ b/Release.md @@ -1,3 +1,8 @@ ### Features * Configuration: We now support TOML, YAML, and JSON for configuration. Please note that INI is deprecated and will be removed in future releases. New features will only be available in TOML, YAML, or JSON. Users wanting these new features should switch their configuration format accordingly. #2521 + +### Breaking Changes + +* Change the way to start the visitor through the command line from `frpc stcp --role=visitor xxx` to `frpc stcp visitor xxx`. +* Modified the semantics of the `server_addr` in the command line, no longer including the port. Added the `server_port` parameter to configure the port. diff --git a/cmd/frpc/sub/admin.go b/cmd/frpc/sub/admin.go new file mode 100644 index 0000000..c5514bc --- /dev/null +++ b/cmd/frpc/sub/admin.go @@ -0,0 +1,117 @@ +// Copyright 2023 The frp Authors +// +// 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 sub + +import ( + "fmt" + "os" + "strings" + + "github.com/rodaine/table" + "github.com/spf13/cobra" + + "github.com/fatedier/frp/pkg/config" + v1 "github.com/fatedier/frp/pkg/config/v1" + clientsdk "github.com/fatedier/frp/pkg/sdk/client" +) + +func init() { + rootCmd.AddCommand(NewAdminCommand( + "reload", + "Hot-Reload frpc configuration", + ReloadHandler, + )) + + rootCmd.AddCommand(NewAdminCommand( + "status", + "Overview of all proxies status", + StatusHandler, + )) + + rootCmd.AddCommand(NewAdminCommand( + "stop", + "Stop the running frpc", + StopHandler, + )) +} + +func NewAdminCommand(name, short string, handler func(*v1.ClientCommonConfig) error) *cobra.Command { + return &cobra.Command{ + Use: name, + Short: short, + Run: func(cmd *cobra.Command, args []string) { + cfg, _, _, _, err := config.LoadClientConfig(cfgFile) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + if cfg.WebServer.Port <= 0 { + fmt.Println("web server port should be set if you want to use this feature") + os.Exit(1) + } + + if err := handler(cfg); err != nil { + fmt.Println(err) + os.Exit(1) + } + }, + } +} + +func ReloadHandler(clientCfg *v1.ClientCommonConfig) error { + client := clientsdk.New(clientCfg.WebServer.Addr, clientCfg.WebServer.Port) + client.SetAuth(clientCfg.WebServer.User, clientCfg.WebServer.Password) + if err := client.Reload(); err != nil { + return err + } + fmt.Println("reload success") + return nil +} + +func StatusHandler(clientCfg *v1.ClientCommonConfig) error { + client := clientsdk.New(clientCfg.WebServer.Addr, clientCfg.WebServer.Port) + client.SetAuth(clientCfg.WebServer.User, clientCfg.WebServer.Password) + res, err := client.GetAllProxyStatus() + if err != nil { + return err + } + + fmt.Printf("Proxy Status...\n\n") + for _, typ := range proxyTypes { + arrs := res[typ] + if len(arrs) == 0 { + continue + } + + fmt.Println(strings.ToUpper(typ)) + tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error") + for _, ps := range arrs { + tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err) + } + tbl.Print() + fmt.Println("") + } + return nil +} + +func StopHandler(clientCfg *v1.ClientCommonConfig) error { + client := clientsdk.New(clientCfg.WebServer.Addr, clientCfg.WebServer.Port) + client.SetAuth(clientCfg.WebServer.User, clientCfg.WebServer.Password) + if err := client.Stop(); err != nil { + return err + } + fmt.Println("stop success") + return nil +} diff --git a/cmd/frpc/sub/flags.go b/cmd/frpc/sub/flags.go new file mode 100644 index 0000000..eb3cc01 --- /dev/null +++ b/cmd/frpc/sub/flags.go @@ -0,0 +1,125 @@ +// Copyright 2023 The frp Authors +// +// 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 sub + +import ( + "fmt" + + "github.com/spf13/cobra" + + "github.com/fatedier/frp/pkg/config/types" + v1 "github.com/fatedier/frp/pkg/config/v1" + "github.com/fatedier/frp/pkg/config/v1/validation" +) + +type BandwidthQuantityFlag struct { + V *types.BandwidthQuantity +} + +func (f *BandwidthQuantityFlag) Set(s string) error { + return f.V.UnmarshalString(s) +} + +func (f *BandwidthQuantityFlag) String() string { + return f.V.String() +} + +func (f *BandwidthQuantityFlag) Type() string { + return "string" +} + +func RegisterProxyFlags(cmd *cobra.Command, c v1.ProxyConfigurer) { + registerProxyBaseConfigFlags(cmd, c.GetBaseConfig()) + switch cc := c.(type) { + case *v1.TCPProxyConfig: + cmd.Flags().IntVarP(&cc.RemotePort, "remote_port", "r", 0, "remote port") + case *v1.UDPProxyConfig: + cmd.Flags().IntVarP(&cc.RemotePort, "remote_port", "r", 0, "remote port") + case *v1.HTTPProxyConfig: + registerProxyDomainConfigFlags(cmd, &cc.DomainConfig) + cmd.Flags().StringSliceVarP(&cc.Locations, "locations", "", []string{}, "locations") + cmd.Flags().StringVarP(&cc.HTTPUser, "http_user", "", "", "http auth user") + cmd.Flags().StringVarP(&cc.HTTPPassword, "http_pwd", "", "", "http auth password") + cmd.Flags().StringVarP(&cc.HostHeaderRewrite, "host_header_rewrite", "", "", "host header rewrite") + case *v1.HTTPSProxyConfig: + registerProxyDomainConfigFlags(cmd, &cc.DomainConfig) + case *v1.TCPMuxProxyConfig: + registerProxyDomainConfigFlags(cmd, &cc.DomainConfig) + cmd.Flags().StringVarP(&cc.Multiplexer, "mux", "", "", "multiplexer") + case *v1.STCPProxyConfig: + cmd.Flags().StringVarP(&cc.Secretkey, "sk", "", "", "secret key") + case *v1.SUDPProxyConfig: + cmd.Flags().StringVarP(&cc.Secretkey, "sk", "", "", "secret key") + case *v1.XTCPProxyConfig: + cmd.Flags().StringVarP(&cc.Secretkey, "sk", "", "", "secret key") + } +} + +func registerProxyBaseConfigFlags(cmd *cobra.Command, c *v1.ProxyBaseConfig) { + if c == nil { + return + } + cmd.Flags().StringVarP(&c.Name, "proxy_name", "n", "", "proxy name") + cmd.Flags().StringVarP(&c.LocalIP, "local_ip", "i", "127.0.0.1", "local ip") + cmd.Flags().IntVarP(&c.LocalPort, "local_port", "l", 0, "local port") + cmd.Flags().BoolVarP(&c.Transport.UseEncryption, "ue", "", false, "use encryption") + cmd.Flags().BoolVarP(&c.Transport.UseCompression, "uc", "", false, "use compression") + cmd.Flags().StringVarP(&c.Transport.BandwidthLimitMode, "bandwidth_limit_mode", "", types.BandwidthLimitModeClient, "bandwidth limit mode") + cmd.Flags().VarP(&BandwidthQuantityFlag{V: &c.Transport.BandwidthLimit}, "bandwidth_limit", "", "bandwidth limit (e.g. 100KB or 1MB)") +} + +func registerProxyDomainConfigFlags(cmd *cobra.Command, c *v1.DomainConfig) { + if c == nil { + return + } + cmd.Flags().StringSliceVarP(&c.CustomDomains, "custom_domain", "d", []string{}, "custom domains") + cmd.Flags().StringVarP(&c.SubDomain, "sd", "", "", "sub domain") +} + +func RegisterVisitorFlags(cmd *cobra.Command, c v1.VisitorConfigurer) { + registerVisitorBaseConfigFlags(cmd, c.GetBaseConfig()) + + // add visitor flags if exist +} + +func registerVisitorBaseConfigFlags(cmd *cobra.Command, c *v1.VisitorBaseConfig) { + if c == nil { + return + } + cmd.Flags().StringVarP(&c.Name, "visitor_name", "n", "", "visitor name") + cmd.Flags().BoolVarP(&c.Transport.UseEncryption, "ue", "", false, "use encryption") + cmd.Flags().BoolVarP(&c.Transport.UseCompression, "uc", "", false, "use compression") + cmd.Flags().StringVarP(&c.SecretKey, "sk", "", "", "secret key") + cmd.Flags().StringVarP(&c.ServerName, "server_name", "", "", "server name") + cmd.Flags().StringVarP(&c.BindAddr, "bind_addr", "", "", "bind addr") + cmd.Flags().IntVarP(&c.BindPort, "bind_port", "", 0, "bind port") +} + +func RegisterClientCommonConfigFlags(cmd *cobra.Command, c *v1.ClientCommonConfig) { + cmd.PersistentFlags().StringVarP(&c.ServerAddr, "server_addr", "s", "127.0.0.1", "frp server's address") + cmd.PersistentFlags().IntVarP(&c.ServerPort, "server_port", "P", 7000, "frp server's port") + cmd.PersistentFlags().StringVarP(&c.User, "user", "u", "", "user") + cmd.PersistentFlags().StringVarP(&c.Transport.Protocol, "protocol", "p", "tcp", + fmt.Sprintf("optional values are %v", validation.SupportedTransportProtocols)) + cmd.PersistentFlags().StringVarP(&c.Auth.Token, "token", "t", "", "auth token") + cmd.PersistentFlags().StringVarP(&c.Log.Level, "log_level", "", "info", "log level") + cmd.PersistentFlags().StringVarP(&c.Log.To, "log_file", "", "console", "console or file path") + cmd.PersistentFlags().Int64VarP(&c.Log.MaxDays, "log_max_days", "", 3, "log file reversed days") + cmd.PersistentFlags().BoolVarP(&c.Log.DisablePrintColor, "disable_log_color", "", false, "disable log color in console") + cmd.PersistentFlags().StringVarP(&c.Transport.TLS.ServerName, "tls_server_name", "", "", "specify the custom server name of tls certificate") + cmd.PersistentFlags().StringVarP(&c.DNSServer, "dns_server", "", "", "specify dns server instead of using system default one") + + c.Transport.TLS.Enable = cmd.PersistentFlags().BoolP("tls_enable", "", true, "enable frpc tls") +} diff --git a/cmd/frpc/sub/http.go b/cmd/frpc/sub/http.go deleted file mode 100644 index 55c45b7..0000000 --- a/cmd/frpc/sub/http.go +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright 2018 fatedier, fatedier@gmail.com -// -// 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 sub - -import ( - "fmt" - "os" - "strings" - - "github.com/spf13/cobra" - - "github.com/fatedier/frp/pkg/config/types" - v1 "github.com/fatedier/frp/pkg/config/v1" - "github.com/fatedier/frp/pkg/config/v1/validation" - "github.com/fatedier/frp/pkg/consts" -) - -func init() { - RegisterCommonFlags(httpCmd) - - httpCmd.PersistentFlags().StringVarP(&proxyName, "proxy_name", "n", "", "proxy name") - httpCmd.PersistentFlags().StringVarP(&localIP, "local_ip", "i", "127.0.0.1", "local ip") - httpCmd.PersistentFlags().IntVarP(&localPort, "local_port", "l", 0, "local port") - httpCmd.PersistentFlags().StringVarP(&customDomains, "custom_domain", "d", "", "custom domain") - httpCmd.PersistentFlags().StringVarP(&subDomain, "sd", "", "", "sub domain") - httpCmd.PersistentFlags().StringVarP(&locations, "locations", "", "", "locations") - httpCmd.PersistentFlags().StringVarP(&httpUser, "http_user", "", "", "http auth user") - httpCmd.PersistentFlags().StringVarP(&httpPwd, "http_pwd", "", "", "http auth password") - httpCmd.PersistentFlags().StringVarP(&hostHeaderRewrite, "host_header_rewrite", "", "", "host header rewrite") - httpCmd.PersistentFlags().BoolVarP(&useEncryption, "ue", "", false, "use encryption") - httpCmd.PersistentFlags().BoolVarP(&useCompression, "uc", "", false, "use compression") - httpCmd.PersistentFlags().StringVarP(&bandwidthLimit, "bandwidth_limit", "", "", "bandwidth limit") - httpCmd.PersistentFlags().StringVarP(&bandwidthLimitMode, "bandwidth_limit_mode", "", types.BandwidthLimitModeClient, "bandwidth limit mode") - - rootCmd.AddCommand(httpCmd) -} - -var httpCmd = &cobra.Command{ - Use: "http", - Short: "Run frpc with a single http proxy", - RunE: func(cmd *cobra.Command, args []string) error { - clientCfg, err := parseClientCommonCfgFromCmd() - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - cfg := &v1.HTTPProxyConfig{} - var prefix string - if user != "" { - prefix = user + "." - } - cfg.Name = prefix + proxyName - cfg.Type = consts.HTTPProxy - cfg.LocalIP = localIP - cfg.LocalPort = localPort - cfg.CustomDomains = strings.Split(customDomains, ",") - cfg.SubDomain = subDomain - cfg.Locations = strings.Split(locations, ",") - cfg.HTTPUser = httpUser - cfg.HTTPPassword = httpPwd - cfg.HostHeaderRewrite = hostHeaderRewrite - cfg.Transport.UseEncryption = useEncryption - cfg.Transport.UseCompression = useCompression - cfg.Transport.BandwidthLimit, err = types.NewBandwidthQuantity(bandwidthLimit) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - cfg.Transport.BandwidthLimitMode = bandwidthLimitMode - - if err := validation.ValidateProxyConfigurerForClient(cfg); err != nil { - fmt.Println(err) - os.Exit(1) - } - - err = startService(clientCfg, []v1.ProxyConfigurer{cfg}, nil, "") - if err != nil { - fmt.Println(err) - os.Exit(1) - } - return nil - }, -} diff --git a/cmd/frpc/sub/https.go b/cmd/frpc/sub/https.go deleted file mode 100644 index d6bf4a6..0000000 --- a/cmd/frpc/sub/https.go +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright 2018 fatedier, fatedier@gmail.com -// -// 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 sub - -import ( - "fmt" - "os" - "strings" - - "github.com/spf13/cobra" - - "github.com/fatedier/frp/pkg/config/types" - v1 "github.com/fatedier/frp/pkg/config/v1" - "github.com/fatedier/frp/pkg/config/v1/validation" - "github.com/fatedier/frp/pkg/consts" -) - -func init() { - RegisterCommonFlags(httpsCmd) - - httpsCmd.PersistentFlags().StringVarP(&proxyName, "proxy_name", "n", "", "proxy name") - httpsCmd.PersistentFlags().StringVarP(&localIP, "local_ip", "i", "127.0.0.1", "local ip") - httpsCmd.PersistentFlags().IntVarP(&localPort, "local_port", "l", 0, "local port") - httpsCmd.PersistentFlags().StringVarP(&customDomains, "custom_domain", "d", "", "custom domain") - httpsCmd.PersistentFlags().StringVarP(&subDomain, "sd", "", "", "sub domain") - httpsCmd.PersistentFlags().BoolVarP(&useEncryption, "ue", "", false, "use encryption") - httpsCmd.PersistentFlags().BoolVarP(&useCompression, "uc", "", false, "use compression") - httpsCmd.PersistentFlags().StringVarP(&bandwidthLimit, "bandwidth_limit", "", "", "bandwidth limit") - httpsCmd.PersistentFlags().StringVarP(&bandwidthLimitMode, "bandwidth_limit_mode", "", types.BandwidthLimitModeClient, "bandwidth limit mode") - - rootCmd.AddCommand(httpsCmd) -} - -var httpsCmd = &cobra.Command{ - Use: "https", - Short: "Run frpc with a single https proxy", - RunE: func(cmd *cobra.Command, args []string) error { - clientCfg, err := parseClientCommonCfgFromCmd() - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - cfg := &v1.HTTPSProxyConfig{} - var prefix string - if user != "" { - prefix = user + "." - } - cfg.Name = prefix + proxyName - cfg.Type = consts.HTTPSProxy - cfg.LocalIP = localIP - cfg.LocalPort = localPort - cfg.CustomDomains = strings.Split(customDomains, ",") - cfg.SubDomain = subDomain - cfg.Transport.UseEncryption = useEncryption - cfg.Transport.UseCompression = useCompression - cfg.Transport.BandwidthLimit, err = types.NewBandwidthQuantity(bandwidthLimit) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - cfg.Transport.BandwidthLimitMode = bandwidthLimitMode - - if err := validation.ValidateProxyConfigurerForClient(cfg); err != nil { - fmt.Println(err) - os.Exit(1) - } - - err = startService(clientCfg, []v1.ProxyConfigurer{cfg}, nil, "") - if err != nil { - fmt.Println(err) - os.Exit(1) - } - return nil - }, -} diff --git a/cmd/frpc/sub/nathole.go b/cmd/frpc/sub/nathole.go index 92977cd..72b635f 100644 --- a/cmd/frpc/sub/nathole.go +++ b/cmd/frpc/sub/nathole.go @@ -31,8 +31,6 @@ var ( ) func init() { - RegisterCommonFlags(natholeCmd) - rootCmd.AddCommand(natholeCmd) natholeCmd.AddCommand(natholeDiscoveryCmd) diff --git a/cmd/frpc/sub/proxy.go b/cmd/frpc/sub/proxy.go new file mode 100644 index 0000000..d27d3fa --- /dev/null +++ b/cmd/frpc/sub/proxy.go @@ -0,0 +1,121 @@ +// Copyright 2023 The frp Authors +// +// 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 sub + +import ( + "fmt" + "os" + + "github.com/samber/lo" + "github.com/spf13/cobra" + + v1 "github.com/fatedier/frp/pkg/config/v1" + "github.com/fatedier/frp/pkg/config/v1/validation" + "github.com/fatedier/frp/pkg/consts" +) + +var proxyTypes = []string{ + consts.TCPProxy, + consts.UDPProxy, + consts.TCPMuxProxy, + consts.HTTPProxy, + consts.HTTPSProxy, + consts.STCPProxy, + consts.SUDPProxy, + consts.XTCPProxy, +} + +var visitorTypes = []string{ + consts.STCPProxy, + consts.SUDPProxy, + consts.XTCPProxy, +} + +func init() { + for _, typ := range proxyTypes { + c := v1.NewProxyConfigurerByType(typ) + if c == nil { + panic("proxy type: " + typ + " not support") + } + clientCfg := v1.ClientCommonConfig{} + cmd := NewProxyCommand(typ, c, &clientCfg) + RegisterClientCommonConfigFlags(cmd, &clientCfg) + RegisterProxyFlags(cmd, c) + + // add sub command for visitor + if lo.Contains(visitorTypes, typ) { + vc := v1.NewVisitorConfigurerByType(typ) + if vc == nil { + panic("visitor type: " + typ + " not support") + } + visitorCmd := NewVisitorCommand(typ, vc, &clientCfg) + RegisterVisitorFlags(visitorCmd, vc) + cmd.AddCommand(visitorCmd) + } + rootCmd.AddCommand(cmd) + } +} + +func NewProxyCommand(name string, c v1.ProxyConfigurer, clientCfg *v1.ClientCommonConfig) *cobra.Command { + return &cobra.Command{ + Use: name, + Short: fmt.Sprintf("Run frpc with a single %s proxy", name), + Run: func(cmd *cobra.Command, args []string) { + clientCfg.Complete() + if _, err := validation.ValidateClientCommonConfig(clientCfg); err != nil { + fmt.Println(err) + os.Exit(1) + } + + c.Complete(clientCfg.User) + c.GetBaseConfig().Type = name + if err := validation.ValidateProxyConfigurerForClient(c); err != nil { + fmt.Println(err) + os.Exit(1) + } + err := startService(clientCfg, []v1.ProxyConfigurer{c}, nil, "") + if err != nil { + fmt.Println(err) + os.Exit(1) + } + }, + } +} + +func NewVisitorCommand(name string, c v1.VisitorConfigurer, clientCfg *v1.ClientCommonConfig) *cobra.Command { + return &cobra.Command{ + Use: "visitor", + Short: fmt.Sprintf("Run frpc with a single %s visitor", name), + Run: func(cmd *cobra.Command, args []string) { + clientCfg.Complete() + if _, err := validation.ValidateClientCommonConfig(clientCfg); err != nil { + fmt.Println(err) + os.Exit(1) + } + + c.Complete(clientCfg) + c.GetBaseConfig().Type = name + if err := validation.ValidateVisitorConfigurer(c); err != nil { + fmt.Println(err) + os.Exit(1) + } + err := startService(clientCfg, nil, []v1.VisitorConfigurer{c}, "") + if err != nil { + fmt.Println(err) + os.Exit(1) + } + }, + } +} diff --git a/cmd/frpc/sub/reload.go b/cmd/frpc/sub/reload.go deleted file mode 100644 index a01a34f..0000000 --- a/cmd/frpc/sub/reload.go +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2018 fatedier, fatedier@gmail.com -// -// 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 sub - -import ( - "encoding/base64" - "fmt" - "io" - "net/http" - "os" - "strings" - - "github.com/spf13/cobra" - - "github.com/fatedier/frp/pkg/config" - v1 "github.com/fatedier/frp/pkg/config/v1" -) - -func init() { - rootCmd.AddCommand(reloadCmd) -} - -var reloadCmd = &cobra.Command{ - Use: "reload", - Short: "Hot-Reload frpc configuration", - RunE: func(cmd *cobra.Command, args []string) error { - cfg, _, _, _, err := config.LoadClientConfig(cfgFile) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - err = reload(cfg) - if err != nil { - fmt.Printf("frpc reload error: %v\n", err) - os.Exit(1) - } - fmt.Printf("reload success\n") - return nil - }, -} - -func reload(clientCfg *v1.ClientCommonConfig) error { - if clientCfg.WebServer.Port == 0 { - return fmt.Errorf("the port of web server shoud be set if you want to use reload feature") - } - - req, err := http.NewRequest("GET", "http://"+ - clientCfg.WebServer.Addr+":"+ - fmt.Sprintf("%d", clientCfg.WebServer.Port)+"/api/reload", nil) - if err != nil { - return err - } - - authStr := "Basic " + base64.StdEncoding.EncodeToString( - []byte(clientCfg.WebServer.User+":"+clientCfg.WebServer.Password)) - - req.Header.Add("Authorization", authStr) - resp, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - if resp.StatusCode == 200 { - return nil - } - - body, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - return fmt.Errorf("code [%d], %s", resp.StatusCode, strings.TrimSpace(string(body))) -} diff --git a/cmd/frpc/sub/root.go b/cmd/frpc/sub/root.go index 878114b..915e6b3 100644 --- a/cmd/frpc/sub/root.go +++ b/cmd/frpc/sub/root.go @@ -18,16 +18,13 @@ import ( "context" "fmt" "io/fs" - "net" "os" "os/signal" "path/filepath" - "strconv" "sync" "syscall" "time" - "github.com/samber/lo" "github.com/spf13/cobra" "github.com/fatedier/frp/client" @@ -42,40 +39,6 @@ var ( cfgFile string cfgDir string showVersion bool - - serverAddr string - user string - protocol string - token string - logLevel string - logFile string - logMaxDays int - disableLogColor bool - dnsServer string - - proxyName string - localIP string - localPort int - remotePort int - useEncryption bool - useCompression bool - bandwidthLimit string - bandwidthLimitMode string - customDomains string - subDomain string - httpUser string - httpPwd string - locations string - hostHeaderRewrite string - role string - sk string - multiplexer string - serverName string - bindAddr string - bindPort int - - tlsEnable bool - tlsServerName string ) func init() { @@ -84,20 +47,6 @@ func init() { rootCmd.PersistentFlags().BoolVarP(&showVersion, "version", "v", false, "version of frpc") } -func RegisterCommonFlags(cmd *cobra.Command) { - cmd.PersistentFlags().StringVarP(&serverAddr, "server_addr", "s", "127.0.0.1:7000", "frp server's address") - cmd.PersistentFlags().StringVarP(&user, "user", "u", "", "user") - cmd.PersistentFlags().StringVarP(&protocol, "protocol", "p", "tcp", "tcp, kcp, quic, websocket, wss") - cmd.PersistentFlags().StringVarP(&token, "token", "t", "", "auth token") - cmd.PersistentFlags().StringVarP(&logLevel, "log_level", "", "info", "log level") - cmd.PersistentFlags().StringVarP(&logFile, "log_file", "", "console", "console or file path") - cmd.PersistentFlags().IntVarP(&logMaxDays, "log_max_days", "", 3, "log file reversed days") - cmd.PersistentFlags().BoolVarP(&disableLogColor, "disable_log_color", "", false, "disable log color in console") - cmd.PersistentFlags().BoolVarP(&tlsEnable, "tls_enable", "", true, "enable frpc tls") - cmd.PersistentFlags().StringVarP(&tlsServerName, "tls_server_name", "", "", "specify the custom server name of tls certificate") - cmd.PersistentFlags().StringVarP(&dnsServer, "dns_server", "", "", "specify dns server instead of using system default one") -} - var rootCmd = &cobra.Command{ Use: "frpc", Short: "frpc is the client of frp (https://github.com/fatedier/frp)", @@ -158,45 +107,6 @@ func handleTermSignal(svr *client.Service) { svr.GracefulClose(500 * time.Millisecond) } -func parseClientCommonCfgFromCmd() (*v1.ClientCommonConfig, error) { - cfg := &v1.ClientCommonConfig{} - - ipStr, portStr, err := net.SplitHostPort(serverAddr) - if err != nil { - return nil, fmt.Errorf("invalid server_addr: %v", err) - } - - cfg.ServerAddr = ipStr - cfg.ServerPort, err = strconv.Atoi(portStr) - if err != nil { - return nil, fmt.Errorf("invalid server_addr: %v", err) - } - - cfg.User = user - cfg.Transport.Protocol = protocol - cfg.Log.Level = logLevel - cfg.Log.To = logFile - cfg.Log.MaxDays = int64(logMaxDays) - cfg.Log.DisablePrintColor = disableLogColor - cfg.DNSServer = dnsServer - - // Only token authentication is supported in cmd mode - cfg.Auth.Token = token - cfg.Transport.TLS.Enable = lo.ToPtr(tlsEnable) - cfg.Transport.TLS.ServerName = tlsServerName - - cfg.Complete() - - warning, err := validation.ValidateClientCommonConfig(cfg) - if warning != nil { - fmt.Printf("WARNING: %v\n", warning) - } - if err != nil { - return nil, fmt.Errorf("parse config error: %v", err) - } - return cfg, nil -} - func runClient(cfgFilePath string) error { cfg, pxyCfgs, visitorCfgs, isLegacyFormat, err := config.LoadClientConfig(cfgFilePath) if err != nil { diff --git a/cmd/frpc/sub/status.go b/cmd/frpc/sub/status.go deleted file mode 100644 index 1db4a95..0000000 --- a/cmd/frpc/sub/status.go +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright 2018 fatedier, fatedier@gmail.com -// -// 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 sub - -import ( - "encoding/base64" - "encoding/json" - "fmt" - "io" - "net/http" - "os" - "strings" - - "github.com/rodaine/table" - "github.com/spf13/cobra" - - "github.com/fatedier/frp/client" - "github.com/fatedier/frp/pkg/config" - v1 "github.com/fatedier/frp/pkg/config/v1" -) - -func init() { - rootCmd.AddCommand(statusCmd) -} - -var statusCmd = &cobra.Command{ - Use: "status", - Short: "Overview of all proxies status", - RunE: func(cmd *cobra.Command, args []string) error { - cfg, _, _, _, err := config.LoadClientConfig(cfgFile) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - if err = status(cfg); err != nil { - fmt.Printf("frpc get status error: %v\n", err) - os.Exit(1) - } - return nil - }, -} - -func status(clientCfg *v1.ClientCommonConfig) error { - if clientCfg.WebServer.Port == 0 { - return fmt.Errorf("the port of web server shoud be set if you want to get proxy status") - } - - req, err := http.NewRequest("GET", "http://"+ - clientCfg.WebServer.Addr+":"+fmt.Sprintf("%d", clientCfg.WebServer.Port)+"/api/status", nil) - if err != nil { - return err - } - - authStr := "Basic " + base64.StdEncoding.EncodeToString( - []byte(clientCfg.WebServer.User+":"+clientCfg.WebServer.Password)) - - req.Header.Add("Authorization", authStr) - resp, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - if resp.StatusCode != 200 { - return fmt.Errorf("admin api status code [%d]", resp.StatusCode) - } - - body, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - res := make(client.StatusResp) - err = json.Unmarshal(body, &res) - if err != nil { - return fmt.Errorf("unmarshal http response error: %s", strings.TrimSpace(string(body))) - } - - fmt.Println("Proxy Status...") - types := []string{"tcp", "udp", "tcpmux", "http", "https", "stcp", "sudp", "xtcp"} - for _, pxyType := range types { - arrs := res[pxyType] - if len(arrs) == 0 { - continue - } - - fmt.Println(strings.ToUpper(pxyType)) - tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error") - for _, ps := range arrs { - tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err) - } - tbl.Print() - fmt.Println("") - } - return nil -} diff --git a/cmd/frpc/sub/stcp.go b/cmd/frpc/sub/stcp.go deleted file mode 100644 index 47ad362..0000000 --- a/cmd/frpc/sub/stcp.go +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright 2018 fatedier, fatedier@gmail.com -// -// 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 sub - -import ( - "fmt" - "os" - - "github.com/spf13/cobra" - - "github.com/fatedier/frp/pkg/config/types" - v1 "github.com/fatedier/frp/pkg/config/v1" - "github.com/fatedier/frp/pkg/config/v1/validation" - "github.com/fatedier/frp/pkg/consts" -) - -func init() { - RegisterCommonFlags(stcpCmd) - - stcpCmd.PersistentFlags().StringVarP(&proxyName, "proxy_name", "n", "", "proxy name") - stcpCmd.PersistentFlags().StringVarP(&role, "role", "", "server", "role") - stcpCmd.PersistentFlags().StringVarP(&sk, "sk", "", "", "secret key") - stcpCmd.PersistentFlags().StringVarP(&serverName, "server_name", "", "", "server name") - stcpCmd.PersistentFlags().StringVarP(&localIP, "local_ip", "i", "127.0.0.1", "local ip") - stcpCmd.PersistentFlags().IntVarP(&localPort, "local_port", "l", 0, "local port") - stcpCmd.PersistentFlags().StringVarP(&bindAddr, "bind_addr", "", "", "bind addr") - stcpCmd.PersistentFlags().IntVarP(&bindPort, "bind_port", "", 0, "bind port") - stcpCmd.PersistentFlags().BoolVarP(&useEncryption, "ue", "", false, "use encryption") - stcpCmd.PersistentFlags().BoolVarP(&useCompression, "uc", "", false, "use compression") - stcpCmd.PersistentFlags().StringVarP(&bandwidthLimit, "bandwidth_limit", "", "", "bandwidth limit") - stcpCmd.PersistentFlags().StringVarP(&bandwidthLimitMode, "bandwidth_limit_mode", "", types.BandwidthLimitModeClient, "bandwidth limit mode") - - rootCmd.AddCommand(stcpCmd) -} - -var stcpCmd = &cobra.Command{ - Use: "stcp", - Short: "Run frpc with a single stcp proxy", - RunE: func(cmd *cobra.Command, args []string) error { - clientCfg, err := parseClientCommonCfgFromCmd() - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - pxyCfgs := make([]v1.ProxyConfigurer, 0) - visitorCfgs := make([]v1.VisitorConfigurer, 0) - - var prefix string - if user != "" { - prefix = user + "." - } - - switch role { - case "server": - cfg := &v1.STCPProxyConfig{} - cfg.Name = prefix + proxyName - cfg.Type = consts.STCPProxy - cfg.Transport.UseEncryption = useEncryption - cfg.Transport.UseCompression = useCompression - cfg.Secretkey = sk - cfg.LocalIP = localIP - cfg.LocalPort = localPort - cfg.Transport.BandwidthLimit, err = types.NewBandwidthQuantity(bandwidthLimit) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - cfg.Transport.BandwidthLimitMode = bandwidthLimitMode - if err := validation.ValidateProxyConfigurerForClient(cfg); err != nil { - fmt.Println(err) - os.Exit(1) - } - pxyCfgs = append(pxyCfgs, cfg) - case "visitor": - cfg := &v1.STCPVisitorConfig{} - cfg.Name = prefix + proxyName - cfg.Type = consts.STCPProxy - cfg.Transport.UseEncryption = useEncryption - cfg.Transport.UseCompression = useCompression - cfg.SecretKey = sk - cfg.ServerName = serverName - cfg.BindAddr = bindAddr - cfg.BindPort = bindPort - if err := validation.ValidateVisitorConfigurer(cfg); err != nil { - fmt.Println(err) - os.Exit(1) - } - visitorCfgs = append(visitorCfgs, cfg) - default: - fmt.Println("invalid role") - os.Exit(1) - } - - err = startService(clientCfg, pxyCfgs, visitorCfgs, "") - if err != nil { - fmt.Println(err) - os.Exit(1) - } - return nil - }, -} diff --git a/cmd/frpc/sub/stop.go b/cmd/frpc/sub/stop.go deleted file mode 100644 index c0ec5da..0000000 --- a/cmd/frpc/sub/stop.go +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2023 The frp Authors -// -// 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 sub - -import ( - "encoding/base64" - "fmt" - "io" - "net/http" - "os" - "strings" - - "github.com/spf13/cobra" - - "github.com/fatedier/frp/pkg/config" - v1 "github.com/fatedier/frp/pkg/config/v1" -) - -func init() { - rootCmd.AddCommand(stopCmd) -} - -var stopCmd = &cobra.Command{ - Use: "stop", - Short: "Stop the running frpc", - RunE: func(cmd *cobra.Command, args []string) error { - cfg, _, _, _, err := config.LoadClientConfig(cfgFile) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - err = stopClient(cfg) - if err != nil { - fmt.Printf("frpc stop error: %v\n", err) - os.Exit(1) - } - fmt.Printf("stop success\n") - return nil - }, -} - -func stopClient(clientCfg *v1.ClientCommonConfig) error { - if clientCfg.WebServer.Port == 0 { - return fmt.Errorf("the port of web server shoud be set if you want to use stop feature") - } - - req, err := http.NewRequest("POST", "http://"+ - clientCfg.WebServer.Addr+":"+ - fmt.Sprintf("%d", clientCfg.WebServer.Port)+"/api/stop", nil) - if err != nil { - return err - } - - authStr := "Basic " + base64.StdEncoding.EncodeToString( - []byte(clientCfg.WebServer.User+":"+clientCfg.WebServer.Password)) - - req.Header.Add("Authorization", authStr) - resp, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - if resp.StatusCode == 200 { - return nil - } - - body, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - return fmt.Errorf("code [%d], %s", resp.StatusCode, strings.TrimSpace(string(body))) -} diff --git a/cmd/frpc/sub/sudp.go b/cmd/frpc/sub/sudp.go deleted file mode 100644 index 28f17ee..0000000 --- a/cmd/frpc/sub/sudp.go +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright 2018 fatedier, fatedier@gmail.com -// -// 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 sub - -import ( - "fmt" - "os" - - "github.com/spf13/cobra" - - "github.com/fatedier/frp/pkg/config/types" - v1 "github.com/fatedier/frp/pkg/config/v1" - "github.com/fatedier/frp/pkg/config/v1/validation" - "github.com/fatedier/frp/pkg/consts" -) - -func init() { - RegisterCommonFlags(sudpCmd) - - sudpCmd.PersistentFlags().StringVarP(&proxyName, "proxy_name", "n", "", "proxy name") - sudpCmd.PersistentFlags().StringVarP(&role, "role", "", "server", "role") - sudpCmd.PersistentFlags().StringVarP(&sk, "sk", "", "", "secret key") - sudpCmd.PersistentFlags().StringVarP(&serverName, "server_name", "", "", "server name") - sudpCmd.PersistentFlags().StringVarP(&localIP, "local_ip", "i", "127.0.0.1", "local ip") - sudpCmd.PersistentFlags().IntVarP(&localPort, "local_port", "l", 0, "local port") - sudpCmd.PersistentFlags().StringVarP(&bindAddr, "bind_addr", "", "", "bind addr") - sudpCmd.PersistentFlags().IntVarP(&bindPort, "bind_port", "", 0, "bind port") - sudpCmd.PersistentFlags().BoolVarP(&useEncryption, "ue", "", false, "use encryption") - sudpCmd.PersistentFlags().BoolVarP(&useCompression, "uc", "", false, "use compression") - sudpCmd.PersistentFlags().StringVarP(&bandwidthLimit, "bandwidth_limit", "", "", "bandwidth limit") - sudpCmd.PersistentFlags().StringVarP(&bandwidthLimitMode, "bandwidth_limit_mode", "", types.BandwidthLimitModeClient, "bandwidth limit mode") - - rootCmd.AddCommand(sudpCmd) -} - -var sudpCmd = &cobra.Command{ - Use: "sudp", - Short: "Run frpc with a single sudp proxy", - RunE: func(cmd *cobra.Command, args []string) error { - clientCfg, err := parseClientCommonCfgFromCmd() - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - pxyCfgs := make([]v1.ProxyConfigurer, 0) - visitorCfgs := make([]v1.VisitorConfigurer, 0) - - var prefix string - if user != "" { - prefix = user + "." - } - - switch role { - case "server": - cfg := &v1.SUDPProxyConfig{} - cfg.Name = prefix + proxyName - cfg.Type = consts.SUDPProxy - cfg.Transport.UseEncryption = useEncryption - cfg.Transport.UseCompression = useCompression - cfg.Secretkey = sk - cfg.LocalIP = localIP - cfg.LocalPort = localPort - cfg.Transport.BandwidthLimit, err = types.NewBandwidthQuantity(bandwidthLimit) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - cfg.Transport.BandwidthLimitMode = bandwidthLimitMode - if err := validation.ValidateProxyConfigurerForClient(cfg); err != nil { - fmt.Println(err) - os.Exit(1) - } - pxyCfgs = append(pxyCfgs, cfg) - case "visitor": - cfg := &v1.SUDPVisitorConfig{} - cfg.Name = prefix + proxyName - cfg.Type = consts.SUDPProxy - cfg.Transport.UseEncryption = useEncryption - cfg.Transport.UseCompression = useCompression - cfg.SecretKey = sk - cfg.ServerName = serverName - cfg.BindAddr = bindAddr - cfg.BindPort = bindPort - if err := validation.ValidateVisitorConfigurer(cfg); err != nil { - fmt.Println(err) - os.Exit(1) - } - visitorCfgs = append(visitorCfgs, cfg) - default: - fmt.Println("invalid role") - os.Exit(1) - } - - err = startService(clientCfg, pxyCfgs, visitorCfgs, "") - if err != nil { - os.Exit(1) - } - return nil - }, -} diff --git a/cmd/frpc/sub/tcp.go b/cmd/frpc/sub/tcp.go deleted file mode 100644 index 1a65a2a..0000000 --- a/cmd/frpc/sub/tcp.go +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright 2018 fatedier, fatedier@gmail.com -// -// 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 sub - -import ( - "fmt" - "os" - - "github.com/spf13/cobra" - - "github.com/fatedier/frp/pkg/config/types" - v1 "github.com/fatedier/frp/pkg/config/v1" - "github.com/fatedier/frp/pkg/config/v1/validation" - "github.com/fatedier/frp/pkg/consts" -) - -func init() { - RegisterCommonFlags(tcpCmd) - - tcpCmd.PersistentFlags().StringVarP(&proxyName, "proxy_name", "n", "", "proxy name") - tcpCmd.PersistentFlags().StringVarP(&localIP, "local_ip", "i", "127.0.0.1", "local ip") - tcpCmd.PersistentFlags().IntVarP(&localPort, "local_port", "l", 0, "local port") - tcpCmd.PersistentFlags().IntVarP(&remotePort, "remote_port", "r", 0, "remote port") - tcpCmd.PersistentFlags().BoolVarP(&useEncryption, "ue", "", false, "use encryption") - tcpCmd.PersistentFlags().BoolVarP(&useCompression, "uc", "", false, "use compression") - tcpCmd.PersistentFlags().StringVarP(&bandwidthLimit, "bandwidth_limit", "", "", "bandwidth limit") - tcpCmd.PersistentFlags().StringVarP(&bandwidthLimitMode, "bandwidth_limit_mode", "", types.BandwidthLimitModeClient, "bandwidth limit mode") - - rootCmd.AddCommand(tcpCmd) -} - -var tcpCmd = &cobra.Command{ - Use: "tcp", - Short: "Run frpc with a single tcp proxy", - RunE: func(cmd *cobra.Command, args []string) error { - clientCfg, err := parseClientCommonCfgFromCmd() - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - cfg := &v1.TCPProxyConfig{} - var prefix string - if user != "" { - prefix = user + "." - } - cfg.Name = prefix + proxyName - cfg.Type = consts.TCPProxy - cfg.LocalIP = localIP - cfg.LocalPort = localPort - cfg.RemotePort = remotePort - cfg.Transport.UseEncryption = useEncryption - cfg.Transport.UseCompression = useCompression - cfg.Transport.BandwidthLimit, err = types.NewBandwidthQuantity(bandwidthLimit) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - cfg.Transport.BandwidthLimitMode = bandwidthLimitMode - - if err := validation.ValidateProxyConfigurerForClient(cfg); err != nil { - fmt.Println(err) - os.Exit(1) - } - err = startService(clientCfg, []v1.ProxyConfigurer{cfg}, nil, "") - if err != nil { - fmt.Println(err) - os.Exit(1) - } - return nil - }, -} diff --git a/cmd/frpc/sub/tcpmux.go b/cmd/frpc/sub/tcpmux.go deleted file mode 100644 index a217591..0000000 --- a/cmd/frpc/sub/tcpmux.go +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright 2020 guylewin, guy@lewin.co.il -// -// 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 sub - -import ( - "fmt" - "os" - "strings" - - "github.com/spf13/cobra" - - "github.com/fatedier/frp/pkg/config/types" - v1 "github.com/fatedier/frp/pkg/config/v1" - "github.com/fatedier/frp/pkg/config/v1/validation" - "github.com/fatedier/frp/pkg/consts" -) - -func init() { - RegisterCommonFlags(tcpMuxCmd) - - tcpMuxCmd.PersistentFlags().StringVarP(&proxyName, "proxy_name", "n", "", "proxy name") - tcpMuxCmd.PersistentFlags().StringVarP(&localIP, "local_ip", "i", "127.0.0.1", "local ip") - tcpMuxCmd.PersistentFlags().IntVarP(&localPort, "local_port", "l", 0, "local port") - tcpMuxCmd.PersistentFlags().StringVarP(&customDomains, "custom_domain", "d", "", "custom domain") - tcpMuxCmd.PersistentFlags().StringVarP(&subDomain, "sd", "", "", "sub domain") - tcpMuxCmd.PersistentFlags().StringVarP(&multiplexer, "mux", "", "", "multiplexer") - tcpMuxCmd.PersistentFlags().BoolVarP(&useEncryption, "ue", "", false, "use encryption") - tcpMuxCmd.PersistentFlags().BoolVarP(&useCompression, "uc", "", false, "use compression") - tcpMuxCmd.PersistentFlags().StringVarP(&bandwidthLimit, "bandwidth_limit", "", "", "bandwidth limit") - tcpMuxCmd.PersistentFlags().StringVarP(&bandwidthLimitMode, "bandwidth_limit_mode", "", types.BandwidthLimitModeClient, "bandwidth limit mode") - - rootCmd.AddCommand(tcpMuxCmd) -} - -var tcpMuxCmd = &cobra.Command{ - Use: "tcpmux", - Short: "Run frpc with a single tcpmux proxy", - RunE: func(cmd *cobra.Command, args []string) error { - clientCfg, err := parseClientCommonCfgFromCmd() - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - cfg := &v1.TCPMuxProxyConfig{} - var prefix string - if user != "" { - prefix = user + "." - } - cfg.Name = prefix + proxyName - cfg.Type = consts.TCPMuxProxy - cfg.LocalIP = localIP - cfg.LocalPort = localPort - cfg.CustomDomains = strings.Split(customDomains, ",") - cfg.SubDomain = subDomain - cfg.Multiplexer = multiplexer - cfg.Transport.UseEncryption = useEncryption - cfg.Transport.UseCompression = useCompression - cfg.Transport.BandwidthLimit, err = types.NewBandwidthQuantity(bandwidthLimit) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - cfg.Transport.BandwidthLimitMode = bandwidthLimitMode - - if err := validation.ValidateProxyConfigurerForClient(cfg); err != nil { - fmt.Println(err) - os.Exit(1) - } - - err = startService(clientCfg, []v1.ProxyConfigurer{cfg}, nil, "") - if err != nil { - fmt.Println(err) - os.Exit(1) - } - return nil - }, -} diff --git a/cmd/frpc/sub/udp.go b/cmd/frpc/sub/udp.go deleted file mode 100644 index e617070..0000000 --- a/cmd/frpc/sub/udp.go +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2018 fatedier, fatedier@gmail.com -// -// 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 sub - -import ( - "fmt" - "os" - - "github.com/spf13/cobra" - - "github.com/fatedier/frp/pkg/config/types" - v1 "github.com/fatedier/frp/pkg/config/v1" - "github.com/fatedier/frp/pkg/config/v1/validation" - "github.com/fatedier/frp/pkg/consts" -) - -func init() { - RegisterCommonFlags(udpCmd) - - udpCmd.PersistentFlags().StringVarP(&proxyName, "proxy_name", "n", "", "proxy name") - udpCmd.PersistentFlags().StringVarP(&localIP, "local_ip", "i", "127.0.0.1", "local ip") - udpCmd.PersistentFlags().IntVarP(&localPort, "local_port", "l", 0, "local port") - udpCmd.PersistentFlags().IntVarP(&remotePort, "remote_port", "r", 0, "remote port") - udpCmd.PersistentFlags().BoolVarP(&useEncryption, "ue", "", false, "use encryption") - udpCmd.PersistentFlags().BoolVarP(&useCompression, "uc", "", false, "use compression") - udpCmd.PersistentFlags().StringVarP(&bandwidthLimit, "bandwidth_limit", "", "", "bandwidth limit") - udpCmd.PersistentFlags().StringVarP(&bandwidthLimitMode, "bandwidth_limit_mode", "", types.BandwidthLimitModeClient, "bandwidth limit mode") - - rootCmd.AddCommand(udpCmd) -} - -var udpCmd = &cobra.Command{ - Use: "udp", - Short: "Run frpc with a single udp proxy", - RunE: func(cmd *cobra.Command, args []string) error { - clientCfg, err := parseClientCommonCfgFromCmd() - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - cfg := &v1.UDPProxyConfig{} - var prefix string - if user != "" { - prefix = user + "." - } - cfg.Name = prefix + proxyName - cfg.Type = consts.UDPProxy - cfg.LocalIP = localIP - cfg.LocalPort = localPort - cfg.RemotePort = remotePort - cfg.Transport.UseEncryption = useEncryption - cfg.Transport.UseCompression = useCompression - cfg.Transport.BandwidthLimit, err = types.NewBandwidthQuantity(bandwidthLimit) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - cfg.Transport.BandwidthLimitMode = bandwidthLimitMode - - if err := validation.ValidateProxyConfigurerForClient(cfg); err != nil { - fmt.Println(err) - os.Exit(1) - } - - err = startService(clientCfg, []v1.ProxyConfigurer{cfg}, nil, "") - if err != nil { - fmt.Println(err) - os.Exit(1) - } - return nil - }, -} diff --git a/cmd/frpc/sub/xtcp.go b/cmd/frpc/sub/xtcp.go deleted file mode 100644 index a4bdd80..0000000 --- a/cmd/frpc/sub/xtcp.go +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright 2018 fatedier, fatedier@gmail.com -// -// 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 sub - -import ( - "fmt" - "os" - - "github.com/spf13/cobra" - - "github.com/fatedier/frp/pkg/config/types" - v1 "github.com/fatedier/frp/pkg/config/v1" - "github.com/fatedier/frp/pkg/config/v1/validation" - "github.com/fatedier/frp/pkg/consts" -) - -func init() { - RegisterCommonFlags(xtcpCmd) - - xtcpCmd.PersistentFlags().StringVarP(&proxyName, "proxy_name", "n", "", "proxy name") - xtcpCmd.PersistentFlags().StringVarP(&role, "role", "", "server", "role") - xtcpCmd.PersistentFlags().StringVarP(&sk, "sk", "", "", "secret key") - xtcpCmd.PersistentFlags().StringVarP(&serverName, "server_name", "", "", "server name") - xtcpCmd.PersistentFlags().StringVarP(&localIP, "local_ip", "i", "127.0.0.1", "local ip") - xtcpCmd.PersistentFlags().IntVarP(&localPort, "local_port", "l", 0, "local port") - xtcpCmd.PersistentFlags().StringVarP(&bindAddr, "bind_addr", "", "", "bind addr") - xtcpCmd.PersistentFlags().IntVarP(&bindPort, "bind_port", "", 0, "bind port") - xtcpCmd.PersistentFlags().BoolVarP(&useEncryption, "ue", "", false, "use encryption") - xtcpCmd.PersistentFlags().BoolVarP(&useCompression, "uc", "", false, "use compression") - xtcpCmd.PersistentFlags().StringVarP(&bandwidthLimit, "bandwidth_limit", "", "", "bandwidth limit") - xtcpCmd.PersistentFlags().StringVarP(&bandwidthLimitMode, "bandwidth_limit_mode", "", types.BandwidthLimitModeClient, "bandwidth limit mode") - - rootCmd.AddCommand(xtcpCmd) -} - -var xtcpCmd = &cobra.Command{ - Use: "xtcp", - Short: "Run frpc with a single xtcp proxy", - RunE: func(cmd *cobra.Command, args []string) error { - clientCfg, err := parseClientCommonCfgFromCmd() - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - pxyCfgs := make([]v1.ProxyConfigurer, 0) - visitorCfgs := make([]v1.VisitorConfigurer, 0) - - var prefix string - if user != "" { - prefix = user + "." - } - - switch role { - case "server": - cfg := &v1.XTCPProxyConfig{} - cfg.Name = prefix + proxyName - cfg.Type = consts.XTCPProxy - cfg.Transport.UseEncryption = useEncryption - cfg.Transport.UseCompression = useCompression - cfg.Secretkey = sk - cfg.LocalIP = localIP - cfg.LocalPort = localPort - cfg.Transport.BandwidthLimit, err = types.NewBandwidthQuantity(bandwidthLimit) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - cfg.Transport.BandwidthLimitMode = bandwidthLimitMode - - if err := validation.ValidateProxyConfigurerForClient(cfg); err != nil { - fmt.Println(err) - os.Exit(1) - } - pxyCfgs = append(pxyCfgs, cfg) - case "visitor": - cfg := &v1.XTCPVisitorConfig{} - cfg.Name = prefix + proxyName - cfg.Type = consts.XTCPProxy - cfg.Transport.UseEncryption = useEncryption - cfg.Transport.UseCompression = useCompression - cfg.SecretKey = sk - cfg.ServerName = serverName - cfg.BindAddr = bindAddr - cfg.BindPort = bindPort - - if err := validation.ValidateVisitorConfigurer(cfg); err != nil { - fmt.Println(err) - os.Exit(1) - } - visitorCfgs = append(visitorCfgs, cfg) - default: - fmt.Println("invalid role") - os.Exit(1) - } - - err = startService(clientCfg, pxyCfgs, visitorCfgs, "") - if err != nil { - fmt.Println(err) - os.Exit(1) - } - return nil - }, -} diff --git a/cmd/frps/flags.go b/cmd/frps/flags.go new file mode 100644 index 0000000..5017068 --- /dev/null +++ b/cmd/frps/flags.go @@ -0,0 +1,110 @@ +// Copyright 2023 The frp Authors +// +// 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 ( + "strconv" + + "github.com/spf13/cobra" + + "github.com/fatedier/frp/pkg/config/types" + v1 "github.com/fatedier/frp/pkg/config/v1" +) + +type PortsRangeSliceFlag struct { + V *[]types.PortsRange +} + +func (f *PortsRangeSliceFlag) String() string { + if f.V == nil { + return "" + } + return types.PortsRangeSlice(*f.V).String() +} + +func (f *PortsRangeSliceFlag) Set(s string) error { + slice, err := types.NewPortsRangeSliceFromString(s) + if err != nil { + return err + } + *f.V = slice + return nil +} + +func (f *PortsRangeSliceFlag) Type() string { + return "string" +} + +type BoolFuncFlag struct { + TrueFunc func() + FalseFunc func() + + v bool +} + +func (f *BoolFuncFlag) String() string { + return strconv.FormatBool(f.v) +} + +func (f *BoolFuncFlag) Set(s string) error { + f.v = strconv.FormatBool(f.v) == "true" + + if !f.v { + if f.FalseFunc != nil { + f.FalseFunc() + } + return nil + } + + if f.TrueFunc != nil { + f.TrueFunc() + } + return nil +} + +func (f *BoolFuncFlag) Type() string { + return "bool" +} + +func RegisterServerConfigFlags(cmd *cobra.Command, c *v1.ServerConfig) { + cmd.PersistentFlags().StringVarP(&c.BindAddr, "bind_addr", "", "0.0.0.0", "bind address") + cmd.PersistentFlags().IntVarP(&c.BindPort, "bind_port", "p", 7000, "bind port") + cmd.PersistentFlags().IntVarP(&c.KCPBindPort, "kcp_bind_port", "", 0, "kcp bind udp port") + cmd.PersistentFlags().StringVarP(&c.ProxyBindAddr, "proxy_bind_addr", "", "0.0.0.0", "proxy bind address") + cmd.PersistentFlags().IntVarP(&c.VhostHTTPPort, "vhost_http_port", "", 0, "vhost http port") + cmd.PersistentFlags().IntVarP(&c.VhostHTTPSPort, "vhost_https_port", "", 0, "vhost https port") + cmd.PersistentFlags().Int64VarP(&c.VhostHTTPTimeout, "vhost_http_timeout", "", 60, "vhost http response header timeout") + cmd.PersistentFlags().StringVarP(&c.WebServer.Addr, "dashboard_addr", "", "0.0.0.0", "dashboard address") + cmd.PersistentFlags().IntVarP(&c.WebServer.Port, "dashboard_port", "", 0, "dashboard port") + cmd.PersistentFlags().StringVarP(&c.WebServer.User, "dashboard_user", "", "admin", "dashboard user") + cmd.PersistentFlags().StringVarP(&c.WebServer.Password, "dashboard_pwd", "", "admin", "dashboard password") + cmd.PersistentFlags().BoolVarP(&c.EnablePrometheus, "enable_prometheus", "", false, "enable prometheus dashboard") + cmd.PersistentFlags().StringVarP(&c.Log.To, "log_file", "", "console", "log file") + cmd.PersistentFlags().StringVarP(&c.Log.Level, "log_level", "", "info", "log level") + cmd.PersistentFlags().Int64VarP(&c.Log.MaxDays, "log_max_days", "", 3, "log max days") + cmd.PersistentFlags().BoolVarP(&c.Log.DisablePrintColor, "disable_log_color", "", false, "disable log color in console") + cmd.PersistentFlags().StringVarP(&c.Auth.Token, "token", "t", "", "auth token") + cmd.PersistentFlags().StringVarP(&c.SubDomainHost, "subdomain_host", "", "", "subdomain host") + cmd.PersistentFlags().VarP(&PortsRangeSliceFlag{V: &c.AllowPorts}, "allow_ports", "", "allow ports") + cmd.PersistentFlags().Int64VarP(&c.MaxPortsPerClient, "max_ports_per_client", "", 0, "max ports per client") + cmd.PersistentFlags().BoolVarP(&c.Transport.TLS.Force, "tls_only", "", false, "frps tls only") + + webServerTLS := v1.TLSConfig{} + cmd.PersistentFlags().StringVarP(&webServerTLS.CertFile, "dashboard_tls_cert_file", "", "", "dashboard tls cert file") + cmd.PersistentFlags().StringVarP(&webServerTLS.KeyFile, "dashboard_tls_key_file", "", "", "dashboard tls key file") + cmd.PersistentFlags().VarP(&BoolFuncFlag{ + TrueFunc: func() { c.WebServer.TLS = &webServerTLS }, + }, "dashboard_tls_mode", "", "if enable dashboard tls mode") +} diff --git a/cmd/frps/root.go b/cmd/frps/root.go index 601e068..4a6f011 100644 --- a/cmd/frps/root.go +++ b/cmd/frps/root.go @@ -22,7 +22,6 @@ import ( "github.com/spf13/cobra" "github.com/fatedier/frp/pkg/config" - "github.com/fatedier/frp/pkg/config/types" v1 "github.com/fatedier/frp/pkg/config/v1" "github.com/fatedier/frp/pkg/config/v1/validation" "github.com/fatedier/frp/pkg/util/log" @@ -34,61 +33,14 @@ var ( cfgFile string showVersion bool - bindAddr string - bindPort int - kcpBindPort int - proxyBindAddr string - vhostHTTPPort int - vhostHTTPSPort int - vhostHTTPTimeout int64 - dashboardAddr string - dashboardPort int - dashboardUser string - dashboardPwd string - enablePrometheus bool - logFile string - logLevel string - logMaxDays int64 - disableLogColor bool - token string - subDomainHost string - allowPorts string - maxPortsPerClient int64 - tlsOnly bool - dashboardTLSMode bool - dashboardTLSCertFile string - dashboardTLSKeyFile string + serverCfg v1.ServerConfig ) func init() { rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "config file of frps") rootCmd.PersistentFlags().BoolVarP(&showVersion, "version", "v", false, "version of frps") - rootCmd.PersistentFlags().StringVarP(&bindAddr, "bind_addr", "", "0.0.0.0", "bind address") - rootCmd.PersistentFlags().IntVarP(&bindPort, "bind_port", "p", 7000, "bind port") - rootCmd.PersistentFlags().IntVarP(&kcpBindPort, "kcp_bind_port", "", 0, "kcp bind udp port") - rootCmd.PersistentFlags().StringVarP(&proxyBindAddr, "proxy_bind_addr", "", "0.0.0.0", "proxy bind address") - rootCmd.PersistentFlags().IntVarP(&vhostHTTPPort, "vhost_http_port", "", 0, "vhost http port") - rootCmd.PersistentFlags().IntVarP(&vhostHTTPSPort, "vhost_https_port", "", 0, "vhost https port") - rootCmd.PersistentFlags().Int64VarP(&vhostHTTPTimeout, "vhost_http_timeout", "", 60, "vhost http response header timeout") - rootCmd.PersistentFlags().StringVarP(&dashboardAddr, "dashboard_addr", "", "0.0.0.0", "dashboard address") - rootCmd.PersistentFlags().IntVarP(&dashboardPort, "dashboard_port", "", 0, "dashboard port") - rootCmd.PersistentFlags().StringVarP(&dashboardUser, "dashboard_user", "", "admin", "dashboard user") - rootCmd.PersistentFlags().StringVarP(&dashboardPwd, "dashboard_pwd", "", "admin", "dashboard password") - rootCmd.PersistentFlags().BoolVarP(&enablePrometheus, "enable_prometheus", "", false, "enable prometheus dashboard") - rootCmd.PersistentFlags().StringVarP(&logFile, "log_file", "", "console", "log file") - rootCmd.PersistentFlags().StringVarP(&logLevel, "log_level", "", "info", "log level") - rootCmd.PersistentFlags().Int64VarP(&logMaxDays, "log_max_days", "", 3, "log max days") - rootCmd.PersistentFlags().BoolVarP(&disableLogColor, "disable_log_color", "", false, "disable log color in console") - - rootCmd.PersistentFlags().StringVarP(&token, "token", "t", "", "auth token") - rootCmd.PersistentFlags().StringVarP(&subDomainHost, "subdomain_host", "", "", "subdomain host") - rootCmd.PersistentFlags().StringVarP(&allowPorts, "allow_ports", "", "", "allow ports") - rootCmd.PersistentFlags().Int64VarP(&maxPortsPerClient, "max_ports_per_client", "", 0, "max ports per client") - rootCmd.PersistentFlags().BoolVarP(&tlsOnly, "tls_only", "", false, "frps tls only") - rootCmd.PersistentFlags().BoolVarP(&dashboardTLSMode, "dashboard_tls_mode", "", false, "dashboard tls mode") - rootCmd.PersistentFlags().StringVarP(&dashboardTLSCertFile, "dashboard_tls_cert_file", "", "", "dashboard tls cert file") - rootCmd.PersistentFlags().StringVarP(&dashboardTLSKeyFile, "dashboard_tls_key_file", "", "", "dashboard tls key file") + RegisterServerConfigFlags(rootCmd, &serverCfg) } var rootCmd = &cobra.Command{ @@ -116,10 +68,8 @@ var rootCmd = &cobra.Command{ "please use yaml/json/toml format instead!\n") } } else { - if svrCfg, err = parseServerConfigFromCmd(); err != nil { - fmt.Println(err) - os.Exit(1) - } + serverCfg.Complete() + svrCfg = &serverCfg } warning, err := validation.ValidateServerConfig(svrCfg) @@ -145,50 +95,6 @@ func Execute() { } } -func parseServerConfigFromCmd() (*v1.ServerConfig, error) { - cfg := &v1.ServerConfig{} - - cfg.BindAddr = bindAddr - cfg.BindPort = bindPort - cfg.KCPBindPort = kcpBindPort - cfg.ProxyBindAddr = proxyBindAddr - cfg.VhostHTTPPort = vhostHTTPPort - cfg.VhostHTTPSPort = vhostHTTPSPort - cfg.VhostHTTPTimeout = vhostHTTPTimeout - cfg.WebServer.Addr = dashboardAddr - cfg.WebServer.Port = dashboardPort - cfg.WebServer.User = dashboardUser - cfg.WebServer.Password = dashboardPwd - cfg.EnablePrometheus = enablePrometheus - if dashboardTLSMode { - cfg.WebServer.TLS = &v1.TLSConfig{ - CertFile: dashboardTLSCertFile, - KeyFile: dashboardTLSKeyFile, - } - } - cfg.Log.To = logFile - cfg.Log.Level = logLevel - cfg.Log.MaxDays = logMaxDays - cfg.Log.DisablePrintColor = disableLogColor - cfg.SubDomainHost = subDomainHost - cfg.Transport.TLS.Force = tlsOnly - cfg.MaxPortsPerClient = maxPortsPerClient - - // Only token authentication is supported in cmd mode - cfg.Auth.Token = token - - if len(allowPorts) > 0 { - portsRanges, err := types.NewPortsRangeSliceFromString(allowPorts) - if err != nil { - return cfg, fmt.Errorf("allow_ports format error: %v", err) - } - cfg.AllowPorts = portsRanges - } - - cfg.Complete() - return cfg, nil -} - func runServer(cfg *v1.ServerConfig) (err error) { log.InitLog(cfg.Log.To, cfg.Log.Level, cfg.Log.MaxDays, cfg.Log.DisablePrintColor) diff --git a/pkg/config/types/types.go b/pkg/config/types/types.go index b6fb7a8..fac29d7 100644 --- a/pkg/config/types/types.go +++ b/pkg/config/types/types.go @@ -134,6 +134,9 @@ type PortsRange struct { type PortsRangeSlice []PortsRange func (p PortsRangeSlice) String() string { + if len(p) == 0 { + return "" + } strs := []string{} for _, v := range p { if v.Single > 0 { diff --git a/pkg/config/v1/validation/client.go b/pkg/config/v1/validation/client.go index 00214dd..3812394 100644 --- a/pkg/config/v1/validation/client.go +++ b/pkg/config/v1/validation/client.go @@ -29,11 +29,11 @@ func ValidateClientCommonConfig(c *v1.ClientCommonConfig) (Warning, error) { warnings Warning errs error ) - if !lo.Contains(supportedAuthMethods, c.Auth.Method) { - errs = AppendError(errs, fmt.Errorf("invalid auth method, optional values are %v", supportedAuthMethods)) + if !lo.Contains(SupportedAuthMethods, c.Auth.Method) { + errs = AppendError(errs, fmt.Errorf("invalid auth method, optional values are %v", SupportedAuthMethods)) } - if !lo.Every(supportedAuthAdditionalScopes, c.Auth.AdditionalScopes) { - errs = AppendError(errs, fmt.Errorf("invalid auth additional scopes, optional values are %v", supportedAuthAdditionalScopes)) + if !lo.Every(SupportedAuthAdditionalScopes, c.Auth.AdditionalScopes) { + errs = AppendError(errs, fmt.Errorf("invalid auth additional scopes, optional values are %v", SupportedAuthAdditionalScopes)) } if err := validateLogConfig(&c.Log); err != nil { @@ -63,8 +63,8 @@ func ValidateClientCommonConfig(c *v1.ClientCommonConfig) (Warning, error) { warnings = AppendError(warnings, checkTLSConfig("transport.tls.trustedCaFile", c.Transport.TLS.TrustedCaFile)) } - if !lo.Contains(supportedTransportProtocols, c.Transport.Protocol) { - errs = AppendError(errs, fmt.Errorf("invalid transport.protocol, optional values are %v", supportedTransportProtocols)) + if !lo.Contains(SupportedTransportProtocols, c.Transport.Protocol) { + errs = AppendError(errs, fmt.Errorf("invalid transport.protocol, optional values are %v", SupportedTransportProtocols)) } for _, f := range c.IncludeConfigFiles { diff --git a/pkg/config/v1/validation/common.go b/pkg/config/v1/validation/common.go index 3409a9d..c159e27 100644 --- a/pkg/config/v1/validation/common.go +++ b/pkg/config/v1/validation/common.go @@ -44,8 +44,8 @@ func ValidatePort(port int, fieldPath string) error { } func validateLogConfig(c *v1.LogConfig) error { - if !lo.Contains(supportedLogLevels, c.Level) { - return fmt.Errorf("invalid log level, optional values are %v", supportedLogLevels) + if !lo.Contains(SupportedLogLevels, c.Level) { + return fmt.Errorf("invalid log level, optional values are %v", SupportedLogLevels) } return nil } diff --git a/pkg/config/v1/validation/server.go b/pkg/config/v1/validation/server.go index d8b222f..5f17d6c 100644 --- a/pkg/config/v1/validation/server.go +++ b/pkg/config/v1/validation/server.go @@ -27,11 +27,11 @@ func ValidateServerConfig(c *v1.ServerConfig) (Warning, error) { warnings Warning errs error ) - if !lo.Contains(supportedAuthMethods, c.Auth.Method) { - errs = AppendError(errs, fmt.Errorf("invalid auth method, optional values are %v", supportedAuthMethods)) + if !lo.Contains(SupportedAuthMethods, c.Auth.Method) { + errs = AppendError(errs, fmt.Errorf("invalid auth method, optional values are %v", SupportedAuthMethods)) } - if !lo.Every(supportedAuthAdditionalScopes, c.Auth.AdditionalScopes) { - errs = AppendError(errs, fmt.Errorf("invalid auth additional scopes, optional values are %v", supportedAuthAdditionalScopes)) + if !lo.Every(SupportedAuthAdditionalScopes, c.Auth.AdditionalScopes) { + errs = AppendError(errs, fmt.Errorf("invalid auth additional scopes, optional values are %v", SupportedAuthAdditionalScopes)) } if err := validateLogConfig(&c.Log); err != nil { @@ -50,8 +50,8 @@ func ValidateServerConfig(c *v1.ServerConfig) (Warning, error) { errs = AppendError(errs, ValidatePort(c.TCPMuxHTTPConnectPort, "tcpMuxHTTPConnectPort")) for _, p := range c.HTTPPlugins { - if !lo.Every(supportedHTTPPluginOps, p.Ops) { - errs = AppendError(errs, fmt.Errorf("invalid http plugin ops, optional values are %v", supportedHTTPPluginOps)) + if !lo.Every(SupportedHTTPPluginOps, p.Ops) { + errs = AppendError(errs, fmt.Errorf("invalid http plugin ops, optional values are %v", SupportedHTTPPluginOps)) } } return warnings, errs diff --git a/pkg/config/v1/validation/validation.go b/pkg/config/v1/validation/validation.go index bc25272..dcce5f7 100644 --- a/pkg/config/v1/validation/validation.go +++ b/pkg/config/v1/validation/validation.go @@ -22,7 +22,7 @@ import ( ) var ( - supportedTransportProtocols = []string{ + SupportedTransportProtocols = []string{ "tcp", "kcp", "quic", @@ -30,17 +30,17 @@ var ( "wss", } - supportedAuthMethods = []string{ + SupportedAuthMethods = []string{ "token", "oidc", } - supportedAuthAdditionalScopes = []v1.AuthScope{ + SupportedAuthAdditionalScopes = []v1.AuthScope{ "HeartBeats", "NewWorkConns", } - supportedLogLevels = []string{ + SupportedLogLevels = []string{ "trace", "debug", "info", @@ -48,7 +48,7 @@ var ( "error", } - supportedHTTPPluginOps = []string{ + SupportedHTTPPluginOps = []string{ splugin.OpLogin, splugin.OpNewProxy, splugin.OpCloseProxy, diff --git a/pkg/config/v1/validation/visitor.go b/pkg/config/v1/validation/visitor.go index c478b49..5307dc9 100644 --- a/pkg/config/v1/validation/visitor.go +++ b/pkg/config/v1/validation/visitor.go @@ -42,7 +42,11 @@ func ValidateVisitorConfigurer(c v1.VisitorConfigurer) error { func validateVisitorBaseConfig(c *v1.VisitorBaseConfig) error { if c.Name == "" { - return errors.New("name should not be empty") + return errors.New("name is required") + } + + if c.ServerName == "" { + return errors.New("server name is required") } if c.BindPort == 0 { diff --git a/test/e2e/pkg/sdk/client/client.go b/pkg/sdk/client/client.go similarity index 79% rename from test/e2e/pkg/sdk/client/client.go rename to pkg/sdk/client/client.go index 3d15707..c965790 100644 --- a/test/e2e/pkg/sdk/client/client.go +++ b/pkg/sdk/client/client.go @@ -10,7 +10,7 @@ import ( "strings" "github.com/fatedier/frp/client" - "github.com/fatedier/frp/test/e2e/pkg/utils" + "github.com/fatedier/frp/pkg/util/util" ) type Client struct { @@ -53,6 +53,22 @@ func (c *Client) GetProxyStatus(name string) (*client.ProxyStatusResp, error) { return nil, fmt.Errorf("no proxy status found") } +func (c *Client) GetAllProxyStatus() (client.StatusResp, error) { + req, err := http.NewRequest("GET", "http://"+c.address+"/api/status", nil) + if err != nil { + return nil, err + } + content, err := c.do(req) + if err != nil { + return nil, err + } + allStatus := make(client.StatusResp) + if err = json.Unmarshal([]byte(content), &allStatus); err != nil { + return nil, fmt.Errorf("unmarshal http response error: %s", strings.TrimSpace(content)) + } + return allStatus, nil +} + func (c *Client) Reload() error { req, err := http.NewRequest("GET", "http://"+c.address+"/api/reload", nil) if err != nil { @@ -90,7 +106,7 @@ func (c *Client) UpdateConfig(content string) error { func (c *Client) setAuthHeader(req *http.Request) { if c.authUser != "" || c.authPwd != "" { - req.Header.Set("Authorization", utils.BasicAuth(c.authUser, c.authPwd)) + req.Header.Set("Authorization", util.BasicAuth(c.authUser, c.authPwd)) } } diff --git a/pkg/util/util/http.go b/pkg/util/util/http.go index 7d6200a..a6a25a4 100644 --- a/pkg/util/util/http.go +++ b/pkg/util/util/http.go @@ -95,3 +95,8 @@ func ParseBasicAuth(auth string) (username, password string, ok bool) { } return cs[:s], cs[s+1:], true } + +func BasicAuth(username, passwd string) string { + auth := username + ":" + passwd + return "Basic " + base64.StdEncoding.EncodeToString([]byte(auth)) +} diff --git a/test/e2e/legacy/basic/client.go b/test/e2e/legacy/basic/client.go index b2e462b..da23db9 100644 --- a/test/e2e/legacy/basic/client.go +++ b/test/e2e/legacy/basic/client.go @@ -8,10 +8,10 @@ import ( "github.com/onsi/ginkgo/v2" + clientsdk "github.com/fatedier/frp/pkg/sdk/client" "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/framework/consts" "github.com/fatedier/frp/test/e2e/pkg/request" - clientsdk "github.com/fatedier/frp/test/e2e/pkg/sdk/client" ) var _ = ginkgo.Describe("[Feature: ClientManage]", func() { diff --git a/test/e2e/legacy/basic/cmd.go b/test/e2e/legacy/basic/cmd.go index 89f2435..7d86233 100644 --- a/test/e2e/legacy/basic/cmd.go +++ b/test/e2e/legacy/basic/cmd.go @@ -1,7 +1,6 @@ package basic import ( - "fmt" "strconv" "strings" @@ -70,7 +69,7 @@ var _ = ginkgo.Describe("[Feature: Cmd]", func() { localPort := f.PortByName(framework.TCPEchoServerPort) remotePort := f.AllocPort() - _, _, err = f.RunFrpc("tcp", "-s", fmt.Sprintf("127.0.0.1:%d", serverPort), "-t", "123", "-u", "test", + _, _, err = f.RunFrpc("tcp", "-s", "127.0.0.1", "-P", strconv.Itoa(serverPort), "-t", "123", "-u", "test", "-l", strconv.Itoa(localPort), "-r", strconv.Itoa(remotePort), "-n", "tcp_test") framework.ExpectNoError(err) @@ -84,7 +83,7 @@ var _ = ginkgo.Describe("[Feature: Cmd]", func() { localPort := f.PortByName(framework.UDPEchoServerPort) remotePort := f.AllocPort() - _, _, err = f.RunFrpc("udp", "-s", fmt.Sprintf("127.0.0.1:%d", serverPort), "-t", "123", "-u", "test", + _, _, err = f.RunFrpc("udp", "-s", "127.0.0.1", "-P", strconv.Itoa(serverPort), "-t", "123", "-u", "test", "-l", strconv.Itoa(localPort), "-r", strconv.Itoa(remotePort), "-n", "udp_test") framework.ExpectNoError(err) @@ -98,7 +97,7 @@ var _ = ginkgo.Describe("[Feature: Cmd]", func() { _, _, err := f.RunFrps("-t", "123", "-p", strconv.Itoa(serverPort), "--vhost_http_port", strconv.Itoa(vhostHTTPPort)) framework.ExpectNoError(err) - _, _, err = f.RunFrpc("http", "-s", "127.0.0.1:"+strconv.Itoa(serverPort), "-t", "123", "-u", "test", + _, _, err = f.RunFrpc("http", "-s", "127.0.0.1", "-P", strconv.Itoa(serverPort), "-t", "123", "-u", "test", "-n", "udp_test", "-l", strconv.Itoa(f.PortByName(framework.HTTPSimpleServerPort)), "--custom_domain", "test.example.com") framework.ExpectNoError(err) diff --git a/test/e2e/legacy/basic/server.go b/test/e2e/legacy/basic/server.go index 08bc6b2..f3c2a22 100644 --- a/test/e2e/legacy/basic/server.go +++ b/test/e2e/legacy/basic/server.go @@ -7,11 +7,11 @@ import ( "github.com/onsi/ginkgo/v2" + clientsdk "github.com/fatedier/frp/pkg/sdk/client" "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/framework/consts" "github.com/fatedier/frp/test/e2e/pkg/port" "github.com/fatedier/frp/test/e2e/pkg/request" - clientsdk "github.com/fatedier/frp/test/e2e/pkg/sdk/client" ) var _ = ginkgo.Describe("[Feature: Server Manager]", func() { diff --git a/test/e2e/legacy/features/bandwidth_limit.go b/test/e2e/legacy/features/bandwidth_limit.go index cbc6e92..c94e473 100644 --- a/test/e2e/legacy/features/bandwidth_limit.go +++ b/test/e2e/legacy/features/bandwidth_limit.go @@ -10,8 +10,8 @@ import ( plugin "github.com/fatedier/frp/pkg/plugin/server" "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/framework/consts" - plugintest "github.com/fatedier/frp/test/e2e/legacy/plugin" "github.com/fatedier/frp/test/e2e/mock/server/streamserver" + pluginpkg "github.com/fatedier/frp/test/e2e/pkg/plugin" "github.com/fatedier/frp/test/e2e/pkg/request" ) @@ -65,7 +65,7 @@ var _ = ginkgo.Describe("[Feature: Bandwidth Limit]", func() { ret.Content = content return &ret } - pluginServer := plugintest.NewHTTPPluginServer(pluginPort, newFunc, handler, nil) + pluginServer := pluginpkg.NewHTTPPluginServer(pluginPort, newFunc, handler, nil) f.RunServer("", pluginServer) diff --git a/test/e2e/legacy/plugin/server.go b/test/e2e/legacy/plugin/server.go index 0011b1b..3f14a42 100644 --- a/test/e2e/legacy/plugin/server.go +++ b/test/e2e/legacy/plugin/server.go @@ -10,6 +10,7 @@ import ( "github.com/fatedier/frp/pkg/transport" "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/framework/consts" + pluginpkg "github.com/fatedier/frp/test/e2e/pkg/plugin" ) var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { @@ -40,7 +41,7 @@ var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { } return &ret } - pluginServer := NewHTTPPluginServer(localPort, newFunc, handler, nil) + pluginServer := pluginpkg.NewHTTPPluginServer(localPort, newFunc, handler, nil) f.RunServer("", pluginServer) @@ -98,7 +99,7 @@ var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { } return &ret } - pluginServer := NewHTTPPluginServer(localPort, newFunc, handler, nil) + pluginServer := pluginpkg.NewHTTPPluginServer(localPort, newFunc, handler, nil) f.RunServer("", pluginServer) @@ -133,7 +134,7 @@ var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { ret.Content = content return &ret } - pluginServer := NewHTTPPluginServer(localPort, newFunc, handler, nil) + pluginServer := pluginpkg.NewHTTPPluginServer(localPort, newFunc, handler, nil) f.RunServer("", pluginServer) @@ -174,7 +175,7 @@ var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { recordProxyName = content.ProxyName return &ret } - pluginServer := NewHTTPPluginServer(localPort, newFunc, handler, nil) + pluginServer := pluginpkg.NewHTTPPluginServer(localPort, newFunc, handler, nil) f.RunServer("", pluginServer) @@ -226,7 +227,7 @@ var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { ret.Unchange = true return &ret } - pluginServer := NewHTTPPluginServer(localPort, newFunc, handler, nil) + pluginServer := pluginpkg.NewHTTPPluginServer(localPort, newFunc, handler, nil) f.RunServer("", pluginServer) @@ -276,7 +277,7 @@ var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { ret.Unchange = true return &ret } - pluginServer := NewHTTPPluginServer(localPort, newFunc, handler, nil) + pluginServer := pluginpkg.NewHTTPPluginServer(localPort, newFunc, handler, nil) f.RunServer("", pluginServer) @@ -321,7 +322,7 @@ var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { ret.Unchange = true return &ret } - pluginServer := NewHTTPPluginServer(localPort, newFunc, handler, nil) + pluginServer := pluginpkg.NewHTTPPluginServer(localPort, newFunc, handler, nil) f.RunServer("", pluginServer) @@ -368,7 +369,7 @@ var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { } tlsConfig, err := transport.NewServerTLSConfig("", "", "") framework.ExpectNoError(err) - pluginServer := NewHTTPPluginServer(localPort, newFunc, handler, tlsConfig) + pluginServer := pluginpkg.NewHTTPPluginServer(localPort, newFunc, handler, tlsConfig) f.RunServer("", pluginServer) diff --git a/test/e2e/legacy/plugin/utils.go b/test/e2e/pkg/plugin/plugin.go similarity index 100% rename from test/e2e/legacy/plugin/utils.go rename to test/e2e/pkg/plugin/plugin.go diff --git a/test/e2e/pkg/request/request.go b/test/e2e/pkg/request/request.go index 44bc0d0..50deb3b 100644 --- a/test/e2e/pkg/request/request.go +++ b/test/e2e/pkg/request/request.go @@ -14,8 +14,8 @@ import ( libdial "github.com/fatedier/golib/net/dial" + "github.com/fatedier/frp/pkg/util/util" "github.com/fatedier/frp/test/e2e/pkg/rpc" - "github.com/fatedier/frp/test/e2e/pkg/utils" ) type Request struct { @@ -115,7 +115,7 @@ func (r *Request) HTTPHeaders(headers map[string]string) *Request { } func (r *Request) HTTPAuth(user, password string) *Request { - r.authValue = utils.BasicAuth(user, password) + r.authValue = util.BasicAuth(user, password) return r } diff --git a/test/e2e/pkg/utils/utils.go b/test/e2e/pkg/utils/utils.go deleted file mode 100644 index 7b177e1..0000000 --- a/test/e2e/pkg/utils/utils.go +++ /dev/null @@ -1,10 +0,0 @@ -package utils - -import ( - "encoding/base64" -) - -func BasicAuth(username, passwd string) string { - auth := username + ":" + passwd - return "Basic " + base64.StdEncoding.EncodeToString([]byte(auth)) -} diff --git a/test/e2e/v1/basic/client.go b/test/e2e/v1/basic/client.go index 111a238..25b9942 100644 --- a/test/e2e/v1/basic/client.go +++ b/test/e2e/v1/basic/client.go @@ -8,10 +8,10 @@ import ( "github.com/onsi/ginkgo/v2" + clientsdk "github.com/fatedier/frp/pkg/sdk/client" "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/framework/consts" "github.com/fatedier/frp/test/e2e/pkg/request" - clientsdk "github.com/fatedier/frp/test/e2e/pkg/sdk/client" ) var _ = ginkgo.Describe("[Feature: ClientManage]", func() { diff --git a/test/e2e/v1/basic/cmd.go b/test/e2e/v1/basic/cmd.go index 9d3120f..08a9ea9 100644 --- a/test/e2e/v1/basic/cmd.go +++ b/test/e2e/v1/basic/cmd.go @@ -1,7 +1,6 @@ package basic import ( - "fmt" "strconv" "strings" @@ -66,7 +65,7 @@ var _ = ginkgo.Describe("[Feature: Cmd]", func() { localPort := f.PortByName(framework.TCPEchoServerPort) remotePort := f.AllocPort() - _, _, err = f.RunFrpc("tcp", "-s", fmt.Sprintf("127.0.0.1:%d", serverPort), "-t", "123", "-u", "test", + _, _, err = f.RunFrpc("tcp", "-s", "127.0.0.1", "-P", strconv.Itoa(serverPort), "-t", "123", "-u", "test", "-l", strconv.Itoa(localPort), "-r", strconv.Itoa(remotePort), "-n", "tcp_test") framework.ExpectNoError(err) @@ -80,7 +79,7 @@ var _ = ginkgo.Describe("[Feature: Cmd]", func() { localPort := f.PortByName(framework.UDPEchoServerPort) remotePort := f.AllocPort() - _, _, err = f.RunFrpc("udp", "-s", fmt.Sprintf("127.0.0.1:%d", serverPort), "-t", "123", "-u", "test", + _, _, err = f.RunFrpc("udp", "-s", "127.0.0.1", "-P", strconv.Itoa(serverPort), "-t", "123", "-u", "test", "-l", strconv.Itoa(localPort), "-r", strconv.Itoa(remotePort), "-n", "udp_test") framework.ExpectNoError(err) @@ -94,7 +93,7 @@ var _ = ginkgo.Describe("[Feature: Cmd]", func() { _, _, err := f.RunFrps("-t", "123", "-p", strconv.Itoa(serverPort), "--vhost_http_port", strconv.Itoa(vhostHTTPPort)) framework.ExpectNoError(err) - _, _, err = f.RunFrpc("http", "-s", "127.0.0.1:"+strconv.Itoa(serverPort), "-t", "123", "-u", "test", + _, _, err = f.RunFrpc("http", "-s", "127.0.0.1", "-P", strconv.Itoa(serverPort), "-t", "123", "-u", "test", "-n", "udp_test", "-l", strconv.Itoa(f.PortByName(framework.HTTPSimpleServerPort)), "--custom_domain", "test.example.com") framework.ExpectNoError(err) diff --git a/test/e2e/v1/basic/server.go b/test/e2e/v1/basic/server.go index ff1225b..eed1dda 100644 --- a/test/e2e/v1/basic/server.go +++ b/test/e2e/v1/basic/server.go @@ -7,11 +7,11 @@ import ( "github.com/onsi/ginkgo/v2" + clientsdk "github.com/fatedier/frp/pkg/sdk/client" "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/framework/consts" "github.com/fatedier/frp/test/e2e/pkg/port" "github.com/fatedier/frp/test/e2e/pkg/request" - clientsdk "github.com/fatedier/frp/test/e2e/pkg/sdk/client" ) var _ = ginkgo.Describe("[Feature: Server Manager]", func() { diff --git a/test/e2e/v1/features/bandwidth_limit.go b/test/e2e/v1/features/bandwidth_limit.go index 5bf1c79..efcf38e 100644 --- a/test/e2e/v1/features/bandwidth_limit.go +++ b/test/e2e/v1/features/bandwidth_limit.go @@ -10,8 +10,8 @@ import ( plugin "github.com/fatedier/frp/pkg/plugin/server" "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/framework/consts" - plugintest "github.com/fatedier/frp/test/e2e/legacy/plugin" "github.com/fatedier/frp/test/e2e/mock/server/streamserver" + pluginpkg "github.com/fatedier/frp/test/e2e/pkg/plugin" "github.com/fatedier/frp/test/e2e/pkg/request" ) @@ -66,7 +66,7 @@ var _ = ginkgo.Describe("[Feature: Bandwidth Limit]", func() { ret.Content = content return &ret } - pluginServer := plugintest.NewHTTPPluginServer(pluginPort, newFunc, handler, nil) + pluginServer := pluginpkg.NewHTTPPluginServer(pluginPort, newFunc, handler, nil) f.RunServer("", pluginServer) diff --git a/test/e2e/v1/plugin/server.go b/test/e2e/v1/plugin/server.go index 02e8469..66456f5 100644 --- a/test/e2e/v1/plugin/server.go +++ b/test/e2e/v1/plugin/server.go @@ -10,6 +10,7 @@ import ( "github.com/fatedier/frp/pkg/transport" "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/framework/consts" + pluginpkg "github.com/fatedier/frp/test/e2e/pkg/plugin" ) var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { @@ -40,7 +41,7 @@ var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { } return &ret } - pluginServer := NewHTTPPluginServer(localPort, newFunc, handler, nil) + pluginServer := pluginpkg.NewHTTPPluginServer(localPort, newFunc, handler, nil) f.RunServer("", pluginServer) @@ -101,7 +102,7 @@ var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { } return &ret } - pluginServer := NewHTTPPluginServer(localPort, newFunc, handler, nil) + pluginServer := pluginpkg.NewHTTPPluginServer(localPort, newFunc, handler, nil) f.RunServer("", pluginServer) @@ -138,7 +139,7 @@ var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { ret.Content = content return &ret } - pluginServer := NewHTTPPluginServer(localPort, newFunc, handler, nil) + pluginServer := pluginpkg.NewHTTPPluginServer(localPort, newFunc, handler, nil) f.RunServer("", pluginServer) @@ -181,7 +182,7 @@ var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { recordProxyName = content.ProxyName return &ret } - pluginServer := NewHTTPPluginServer(localPort, newFunc, handler, nil) + pluginServer := pluginpkg.NewHTTPPluginServer(localPort, newFunc, handler, nil) f.RunServer("", pluginServer) @@ -235,7 +236,7 @@ var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { ret.Unchange = true return &ret } - pluginServer := NewHTTPPluginServer(localPort, newFunc, handler, nil) + pluginServer := pluginpkg.NewHTTPPluginServer(localPort, newFunc, handler, nil) f.RunServer("", pluginServer) @@ -287,7 +288,7 @@ var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { ret.Unchange = true return &ret } - pluginServer := NewHTTPPluginServer(localPort, newFunc, handler, nil) + pluginServer := pluginpkg.NewHTTPPluginServer(localPort, newFunc, handler, nil) f.RunServer("", pluginServer) @@ -334,7 +335,7 @@ var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { ret.Unchange = true return &ret } - pluginServer := NewHTTPPluginServer(localPort, newFunc, handler, nil) + pluginServer := pluginpkg.NewHTTPPluginServer(localPort, newFunc, handler, nil) f.RunServer("", pluginServer) @@ -383,7 +384,7 @@ var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { } tlsConfig, err := transport.NewServerTLSConfig("", "", "") framework.ExpectNoError(err) - pluginServer := NewHTTPPluginServer(localPort, newFunc, handler, tlsConfig) + pluginServer := pluginpkg.NewHTTPPluginServer(localPort, newFunc, handler, tlsConfig) f.RunServer("", pluginServer) diff --git a/test/e2e/v1/plugin/utils.go b/test/e2e/v1/plugin/utils.go deleted file mode 100644 index 51de01d..0000000 --- a/test/e2e/v1/plugin/utils.go +++ /dev/null @@ -1,41 +0,0 @@ -package plugin - -import ( - "crypto/tls" - "encoding/json" - "io" - "net/http" - - plugin "github.com/fatedier/frp/pkg/plugin/server" - "github.com/fatedier/frp/pkg/util/log" - "github.com/fatedier/frp/test/e2e/mock/server/httpserver" -) - -type Handler func(req *plugin.Request) *plugin.Response - -type NewPluginRequest func() *plugin.Request - -func NewHTTPPluginServer(port int, newFunc NewPluginRequest, handler Handler, tlsConfig *tls.Config) *httpserver.Server { - return httpserver.New( - httpserver.WithBindPort(port), - httpserver.WithTLSConfig(tlsConfig), - httpserver.WithHandler(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { - r := newFunc() - buf, err := io.ReadAll(req.Body) - if err != nil { - w.WriteHeader(500) - return - } - log.Trace("plugin request: %s", string(buf)) - err = json.Unmarshal(buf, &r) - if err != nil { - w.WriteHeader(500) - return - } - resp := handler(r) - buf, _ = json.Marshal(resp) - log.Trace("plugin response: %s", string(buf)) - _, _ = w.Write(buf) - })), - ) -}