diff --git a/pkg/client/config/config.go b/pkg/client/config/config.go index 7dafa07f7..11a0f9859 100644 --- a/pkg/client/config/config.go +++ b/pkg/client/config/config.go @@ -5,7 +5,6 @@ import ( "flag" "fmt" "io" - "io/ioutil" "log" "net/http" "net/url" @@ -17,67 +16,28 @@ import ( "github.com/btwiuse/version" "k0s.io" - "k0s.io/pkg/client" ) -type config struct { - Redir string `json:"-" yaml:"redir"` - Socks string `json:"-" yaml:"socks"` - Doh string `json:"-" yaml:"doh"` - Verbose bool `json:"-" yaml:"verbose"` - Insecure bool `json:"-" yaml:"insecure"` - Record bool `json:"-" yaml:"record"` - CacheCredentials bool `json:"-" yaml:"cache_credentials"` - Credentials map[string]client.KeyStore `json:"-" yaml:"credentials"` - ConfigLocation string `json:"-" yaml:"-"` - Hub string `json:"-" yaml:"hub"` +type KeyStore map[string]string + +type Config struct { + Redir string `json:"-" yaml:"redir"` + Socks string `json:"-" yaml:"socks"` + Doh string `json:"-" yaml:"doh"` + Verbose bool `json:"-" yaml:"verbose"` + Insecure bool `json:"-" yaml:"insecure"` + Record bool `json:"-" yaml:"record"` + CacheCredentials bool `json:"-" yaml:"cache_credentials"` + Credentials map[string]KeyStore `json:"-" yaml:"credentials"` + ConfigLocation string `json:"-" yaml:"-"` + Hub string `json:"-" yaml:"hub"` uri *url.URL `json:"-"` // where server scheme, host, port, addr are defined Version *version.Version `json:"version" yaml:"-"` } -func (c *config) GetConfigLocation() string { - return c.ConfigLocation -} - -func (c *config) GetRecord() bool { - return c.Record -} - -func (c *config) GetCacheCredentials() bool { - return c.CacheCredentials -} - -func (c *config) GetCredentials() map[string]client.KeyStore { - return c.Credentials -} - -func (c *config) GetSocks() string { - return c.Socks -} - -func (c *config) GetRedir() string { - return c.Redir -} - -func (c *config) GetDoh() string { - return c.Doh -} - -func (c *config) GetVersion() *version.Version { - return c.Version -} - -func (c *config) GetVerbose() bool { - return c.Verbose -} - -func (c *config) GetInsecure() bool { - return c.Insecure -} - -func (c *config) GetPort() string { +func (c *Config) GetPort() string { if c.uri.Port() == "" { switch c.uri.Scheme { case "http": @@ -89,7 +49,7 @@ func (c *config) GetPort() string { return c.uri.Port() } -func (c *config) GetAddr() string { +func (c *Config) GetAddr() string { var ( scheme = c.GetScheme() host = c.GetHost() @@ -106,7 +66,7 @@ func (c *config) GetAddr() string { } } -func (c *config) GetSchemeWS() string { +func (c *Config) GetSchemeWS() string { switch c.GetScheme() { case "https": return "wss" @@ -115,84 +75,14 @@ func (c *config) GetSchemeWS() string { } } -func (c *config) GetScheme() string { +func (c *Config) GetScheme() string { if c.uri.Scheme == "http" && c.uri.Hostname() == "" && c.uri.Port() == "443" { return "https" } return c.uri.Scheme } -type Opt func(c *config) - -func SetCacheCredentials(cc bool) Opt { - return func(c *config) { - c.CacheCredentials = cc - } -} - -func SetHub(h string) Opt { - return func(c *config) { - c.Hub = h - } -} - -func SetRedir(h string) Opt { - return func(c *config) { - c.Redir = h - } -} - -func SetSocks(h string) Opt { - return func(c *config) { - c.Socks = h - } -} - -func SetDoh(h string) Opt { - return func(c *config) { - c.Doh = h - } -} - -func SetRecord(h bool) Opt { - return func(c *config) { - c.Record = h - } -} - -func SetInsecure(h bool) Opt { - return func(c *config) { - c.Insecure = h - } -} - -func SetURI() Opt { - return func(c *config) { - var hubapi = c.Hub - // prepend host 127.0.0.1 to port without an explicit host :8000 - if strings.HasPrefix(hubapi, ":") { - hubapi = "127.0.0.1" + hubapi - } - // default to http - if !(strings.HasPrefix(hubapi, "http://") || strings.HasPrefix(hubapi, "https://")) { - hubapi = "http://" + hubapi - } - - uri, err := url.Parse(hubapi) - if err != nil { - log.Fatalln(err) - } - c.uri = uri - } -} - -func SetVerbose(v bool) Opt { - return func(c *config) { - c.Verbose = v - } -} - -func (c *config) GetHost() string { +func (c *Config) GetHost() string { host := c.uri.Hostname() if host == "" { return "127.0.0.1" @@ -223,8 +113,8 @@ func probeConfigFile() string { return "" } -func loadConfigFile(file string) *config { - c := &config{ +func loadConfigFile(file string) *Config { + c := &Config{ Hub: k0s.DEFAULT_HUB_ADDRESS, Version: version.Info, ConfigLocation: file, @@ -245,12 +135,10 @@ func loadConfigFile(file string) *config { return c } -func Parse(args []string) client.Config { +func Parse(args []string) *Config { var ( fset = flag.NewFlagSet("client", flag.ExitOnError) - opts = []Opt{} - hubapi *string = fset.String("hub", k0s.DEFAULT_HUB_ADDRESS, "Hub address.") redir *string = fset.String("redir", k0s.REDIR_PROXY_PORT, "Redir port.") socks *string = fset.String("socks", k0s.SOCKS5_PROXY_PORT, "Socks port.") @@ -259,7 +147,7 @@ func Parse(args []string) client.Config { version *bool = fset.Bool("version", false, "Show agent/hub version info.") insecure *bool = fset.Bool("insecure", false, "Allow insecure server connections when using SSL.") record *bool = fset.Bool("record", false, "Record terminal events to a log file.") - // cc *bool = fset.Bool("cc", false, "Cache credentials.") + // cc *bool = fset.Bool("cc", false, "Cache credentials.") c *string = fset.String("c", probeConfigFile(), "Config file location.") ) @@ -268,47 +156,39 @@ func Parse(args []string) client.Config { log.Fatalln(err) } + baseConfig := loadConfigFile(*c) + + // Apply flags if they were set fset.Visit(func(f *flag.Flag) { + switch f.Name { /* - if f.Name == "cc" { - opts = append(opts, SetCacheCredentials(*cc)) - } + case "cc": + baseConfig.WithCacheCredentials(*cc) */ - if f.Name == "hub" { - opts = append(opts, SetHub(*hubapi)) - } - if f.Name == "redir" { - opts = append(opts, SetRedir(*redir)) - } - if f.Name == "socks" { - opts = append(opts, SetSocks(*socks)) - } - if f.Name == "doh" { - opts = append(opts, SetDoh(*doh)) - } - if f.Name == "verbose" { - opts = append(opts, SetVerbose(*verbose)) - } - if f.Name == "record" { - opts = append(opts, SetRecord(*record)) - } - if f.Name == "insecure" { - opts = append(opts, SetInsecure(*insecure)) + case "hub": + baseConfig.WithHub(*hubapi) + case "redir": + baseConfig.WithRedir(*redir) + case "socks": + baseConfig.WithSocks(*socks) + case "doh": + baseConfig.WithDoh(*doh) + case "verbose": + baseConfig.WithVerbose(*verbose) + case "record": + baseConfig.WithRecord(*record) + case "insecure": + baseConfig.WithInsecure(*insecure) } }) - // The 1st positional argument is used if you leave out the -hub part. + // Handle positional hub argument if len(fset.Args()) != 0 { - opts = append(opts, SetHub(fset.Args()[0])) + baseConfig.WithHub(fset.Args()[0]) } - opts = append(opts, SetURI()) - - baseConfig := loadConfigFile(*c) - - for _, opt := range opts { - opt(baseConfig) - } + // Set URI + baseConfig.WithURI() if *version { printClientVersion(baseConfig) @@ -319,6 +199,66 @@ func Parse(args []string) client.Config { return baseConfig } +// Replace Opt functions with With* methods on Config +func (c *Config) WithCacheCredentials(cc bool) *Config { + c.CacheCredentials = cc + return c +} + +func (c *Config) WithHub(h string) *Config { + c.Hub = h + return c +} + +func (c *Config) WithRedir(h string) *Config { + c.Redir = h + return c +} + +func (c *Config) WithSocks(h string) *Config { + c.Socks = h + return c +} + +func (c *Config) WithDoh(h string) *Config { + c.Doh = h + return c +} + +func (c *Config) WithRecord(h bool) *Config { + c.Record = h + return c +} + +func (c *Config) WithInsecure(h bool) *Config { + c.Insecure = h + return c +} + +func (c *Config) WithURI() *Config { + var hubapi = c.Hub + // prepend host 127.0.0.1 to port without an explicit host :8000 + if strings.HasPrefix(hubapi, ":") { + hubapi = "127.0.0.1" + hubapi + } + // default to http + if !(strings.HasPrefix(hubapi, "http://") || strings.HasPrefix(hubapi, "https://")) { + hubapi = "http://" + hubapi + } + + uri, err := url.Parse(hubapi) + if err != nil { + log.Fatalln(err) + } + c.uri = uri + return c +} + +func (c *Config) WithVerbose(v bool) *Config { + c.Verbose = v + return c +} + type clientVersion struct { Client *version.Version } @@ -327,12 +267,12 @@ type hubVersion struct { Hub *version.Version } -func printClientVersion(c client.Config) { - av := &clientVersion{c.GetVersion()} +func printClientVersion(c *Config) { + av := &clientVersion{c.Version} fmt.Println(pretty.YAMLString(av)) } -func printHubVersion(c client.Config) { +func printHubVersion(c *Config) { var ( ub = &url.URL{ Scheme: c.GetScheme(), @@ -346,7 +286,7 @@ func printHubVersion(c client.Config) { t = &http.Client{ Transport: &http.Transport{ TLSClientConfig: &tls.Config{ - InsecureSkipVerify: c.GetInsecure(), + InsecureSkipVerify: c.Insecure, }, }, } @@ -356,7 +296,7 @@ func printHubVersion(c client.Config) { log.Fatalln(err) } - buf, err := ioutil.ReadAll(resp.Body) + buf, err := io.ReadAll(resp.Body) if err != nil { log.Fatalln(err) } @@ -372,7 +312,7 @@ func printHubVersion(c client.Config) { fmt.Print(pretty.YAMLString(hv)) } -func (c *config) String() string { +func (c *Config) String() string { return pretty.JsonStringLine(c) } diff --git a/pkg/client/impl/client.go b/pkg/client/impl/client.go index db86d7efc..d9df45989 100644 --- a/pkg/client/impl/client.go +++ b/pkg/client/impl/client.go @@ -25,6 +25,7 @@ import ( "golang.org/x/crypto/ssh/terminal" "k0s.io" "k0s.io/pkg/client" + "k0s.io/pkg/client/config" "k0s.io/pkg/hub/agent/info" ) @@ -33,9 +34,9 @@ var ( idd string ) -func NewClient(c client.Config) client.Client { +func NewClient(c *config.Config) client.Client { cl := &clientImpl{ - Config: c, + config: c, sl: ishell.New(), dialer: &dialer{c}, } @@ -44,14 +45,18 @@ func NewClient(c client.Config) client.Client { type clientImpl struct { *dialer - client.Config + config *config.Config userinfo *url.Userinfo sl *ishell.Shell } +func (cl *clientImpl) Config() *config.Config { + return cl.config +} + func (cl *clientImpl) ListAgents() (agis []*info.Info, err error) { var ( - c = cl.Config + c = cl.config ub = &url.URL{ Scheme: c.GetScheme(), Host: c.GetAddr(), @@ -66,7 +71,7 @@ func (cl *clientImpl) ListAgents() (agis []*info.Info, err error) { t = &http.Client{ Transport: &http.Transport{ TLSClientConfig: &tls.Config{ - InsecureSkipVerify: c.GetInsecure(), + InsecureSkipVerify: c.Insecure, }, }, } @@ -261,7 +266,7 @@ func (cl *clientImpl) runFzf() string { func (cl *clientImpl) runLogin(idd string) error { var ( - c = cl.Config + c = cl.config user string pass string ) @@ -275,11 +280,11 @@ func (cl *clientImpl) runLogin(idd string) error { if *ag.Auth { var ( name = ag.Name - creds = c.GetCredentials() + creds = c.Credentials ) ks, ok := creds[name] if ok && len(ks) > 0 { - log.Println("loading cached credentials from", c.GetConfigLocation()) + log.Println("loading cached credentials from", c.ConfigLocation) // load first entry in map for k, v := range ks { user = k @@ -331,7 +336,7 @@ func (cl *clientImpl) runLogin(idd string) error { } } - if conf := c.GetConfigLocation(); conf != "" && c.GetCacheCredentials() { + if conf := c.ConfigLocation; conf != "" && c.CacheCredentials { // log.Println("yes") set(conf, fmt.Sprintf("credentials.%s.%s: %s", ag.Name, user, pass)) } @@ -343,13 +348,13 @@ func (cl *clientImpl) runLogin(idd string) error { } } - if len(cl.GetRedir()) > 0 { + if len(cl.config.Redir) > 0 { go cl.RunRedir() } - if len(cl.GetSocks()) > 0 { + if len(cl.config.Socks) > 0 { go cl.RunSocks() } - if len(cl.GetDoh()) > 0 { + if len(cl.config.Doh) > 0 { go cl.RunDoh() } @@ -362,8 +367,8 @@ func (cl *clientImpl) RunRedir() error { log.Println("dial", ep) addr := k0s.REDIR_PROXY_PORT - if cl.GetRedir() != "" { - addr = cl.GetRedir() + if cl.config.Redir != "" { + addr = cl.config.Redir } log.Println("redir listening on", addr) ln, err := net.Listen("tcp", addr) @@ -396,8 +401,8 @@ func (cl *clientImpl) RunSocks() error { log.Println("dial", ep) addr := k0s.SOCKS5_PROXY_PORT - if cl.GetSocks() != "" { - addr = cl.GetSocks() + if cl.config.Socks != "" { + addr = cl.config.Socks } log.Println("socks5 listening on", addr) ln, err := net.Listen("tcp", addr) @@ -430,8 +435,8 @@ func (cl *clientImpl) RunDoh() error { log.Println("dial", ep) addr := k0s.DOH_PROXY_PORT - if cl.GetDoh() != "" { - addr = cl.GetDoh() + if cl.config.Doh != "" { + addr = cl.config.Doh } log.Println("doh listening on", addr) ln, err := net.Listen("udp", addr) diff --git a/pkg/client/impl/dialer.go b/pkg/client/impl/dialer.go index 5e401b966..fd7cef94c 100644 --- a/pkg/client/impl/dialer.go +++ b/pkg/client/impl/dialer.go @@ -5,11 +5,11 @@ import ( "net/url" "github.com/btwiuse/wsdial" - "k0s.io/pkg/client" + "k0s.io/pkg/client/config" ) type dialer struct { - c client.Config + c *config.Config } func (d *dialer) Dial(p string, userinfo *url.Userinfo) (conn net.Conn, err error) { diff --git a/pkg/client/impl/terminal_unix.go b/pkg/client/impl/terminal_unix.go index 69ea824df..41e5e035f 100644 --- a/pkg/client/impl/terminal_unix.go +++ b/pkg/client/impl/terminal_unix.go @@ -20,7 +20,7 @@ func (cl *clientImpl) terminalConnect(endpoint string, userinfo *url.Userinfo) { log.Println("Press ESC twice to exit. (Some terminals don't supported it)") var ( - c = cl.Config + c = cl.Config() conn net.Conn err error ) @@ -50,7 +50,7 @@ func (cl *clientImpl) terminalConnect(endpoint string, userinfo *url.Userinfo) { asciitransport.WithWriter(os.Stdout), } - if c.GetRecord() { + if c.Record { logname := rng.NewUUID() + ".log" logfile, err := os.Create(logname) if err != nil { diff --git a/pkg/client/impl/terminal_windows.go b/pkg/client/impl/terminal_windows.go index 391962d4e..977b1bf86 100644 --- a/pkg/client/impl/terminal_windows.go +++ b/pkg/client/impl/terminal_windows.go @@ -16,7 +16,7 @@ func (cl *clientImpl) terminalConnect(endpoint string, userinfo *url.Userinfo) { log.Println("Press ESC twice to exit.") var ( - c = cl.Config + c = cl.Config() conn net.Conn err error ) @@ -46,7 +46,7 @@ func (cl *clientImpl) terminalConnect(endpoint string, userinfo *url.Userinfo) { asciitransport.WithWriter(os.Stdout), } - if c.GetRecord() { + if c.Record { logname := rng.NewUUID() + ".log" logfile, err := os.Create(logname) if err != nil { diff --git a/pkg/client/types.go b/pkg/client/types.go index 59afcb393..cd1b6187f 100644 --- a/pkg/client/types.go +++ b/pkg/client/types.go @@ -1,12 +1,12 @@ package client import ( - "github.com/btwiuse/version" + "k0s.io/pkg/client/config" "k0s.io/pkg/hub/agent/info" ) type Client interface { - Config + Config() *config.Config RunRedir() error RunSocks() error @@ -15,24 +15,3 @@ type Client interface { MiniRun() error ListAgents() ([]*info.Info, error) } - -type Config interface { - GetHost() string - GetPort() string - GetAddr() string - GetScheme() string - GetSchemeWS() string - - GetRedir() string - GetSocks() string - GetDoh() string - GetCacheCredentials() bool - GetCredentials() map[string]KeyStore - GetConfigLocation() string - - GetVersion() *version.Version - GetInsecure() bool - GetRecord() bool -} - -type KeyStore map[string]string