From ac38633c7192d31a4e1665d7aba16447de3aa1cb Mon Sep 17 00:00:00 2001 From: Derek Nola Date: Wed, 12 Mar 2025 09:02:45 -0700 Subject: [PATCH] Migrate to UrfaveCLI v2 (#11831) * Bump rootlesskit tov 1.1.1, last of the v1 line * Migrate to urfavecli v2 * Disable StringSlice seperattion Signed-off-by: Derek Nola --- cmd/agent/main.go | 5 +- cmd/cert/main.go | 4 +- cmd/completion/main.go | 4 +- cmd/encrypt/main.go | 4 +- cmd/etcdsnapshot/main.go | 4 +- cmd/k3s/main.go | 7 +- cmd/server/main.go | 5 +- cmd/token/main.go | 4 +- go.mod | 7 +- go.sum | 15 +-- main.go | 5 +- pkg/agent/config/config.go | 20 ++-- pkg/agent/run.go | 4 +- pkg/cli/agent/agent.go | 6 +- pkg/cli/cert/cert.go | 22 ++-- pkg/cli/cmds/agent.go | 84 +++++++------- pkg/cli/cmds/certs.go | 37 +++--- pkg/cli/cmds/check-config.go | 7 +- pkg/cli/cmds/completion.go | 6 +- pkg/cli/cmds/config.go | 11 +- pkg/cli/cmds/crictl.go | 7 +- pkg/cli/cmds/ctr.go | 7 +- pkg/cli/cmds/etcd_snapshot.go | 81 +++++++------ pkg/cli/cmds/kubectl.go | 7 +- pkg/cli/cmds/log.go | 5 +- pkg/cli/cmds/root.go | 4 +- pkg/cli/cmds/secrets_encrypt.go | 83 +++++++------ pkg/cli/cmds/server.go | 135 +++++++++++----------- pkg/cli/cmds/token.go | 43 ++++--- pkg/cli/completion/completion.go | 4 +- pkg/cli/crictl/crictl.go | 2 +- pkg/cli/ctr/ctr.go | 2 +- pkg/cli/etcdsnapshot/etcd_snapshot.go | 10 +- pkg/cli/kubectl/kubectl.go | 2 +- pkg/cli/secretsencrypt/secrets_encrypt.go | 2 +- pkg/cli/server/server.go | 46 ++++---- pkg/cli/token/token.go | 10 +- pkg/configfilearg/defaultparser.go | 2 +- pkg/configfilearg/parser.go | 4 +- pkg/kubeadm/token.go | 11 +- pkg/util/client.go | 5 +- pkg/util/client_test.go | 12 +- pkg/util/net.go | 7 +- pkg/util/net_test.go | 18 ++- 44 files changed, 391 insertions(+), 379 deletions(-) diff --git a/cmd/agent/main.go b/cmd/agent/main.go index 97053f2ab0d..e8c3b3a9049 100644 --- a/cmd/agent/main.go +++ b/cmd/agent/main.go @@ -9,12 +9,13 @@ import ( "github.com/k3s-io/k3s/pkg/cli/cmds" "github.com/k3s-io/k3s/pkg/configfilearg" "github.com/sirupsen/logrus" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) func main() { app := cmds.NewApp() - app.Commands = []cli.Command{ + app.DisableSliceFlagSeparator = true + app.Commands = []*cli.Command{ cmds.NewAgentCommand(agent.Run), } diff --git a/cmd/cert/main.go b/cmd/cert/main.go index d0dbf759567..81fba81abb8 100644 --- a/cmd/cert/main.go +++ b/cmd/cert/main.go @@ -9,12 +9,12 @@ import ( "github.com/k3s-io/k3s/pkg/cli/cmds" "github.com/k3s-io/k3s/pkg/configfilearg" "github.com/sirupsen/logrus" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) func main() { app := cmds.NewApp() - app.Commands = []cli.Command{ + app.Commands = []*cli.Command{ cmds.NewCertCommands( cert.Check, cert.Rotate, diff --git a/cmd/completion/main.go b/cmd/completion/main.go index a49107c308a..43e72a07286 100644 --- a/cmd/completion/main.go +++ b/cmd/completion/main.go @@ -8,12 +8,12 @@ import ( "github.com/k3s-io/k3s/pkg/cli/cmds" "github.com/k3s-io/k3s/pkg/cli/completion" "github.com/sirupsen/logrus" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) func main() { app := cmds.NewApp() - app.Commands = []cli.Command{ + app.Commands = []*cli.Command{ cmds.NewCompletionCommand(completion.Run), } diff --git a/cmd/encrypt/main.go b/cmd/encrypt/main.go index 52d02029a91..f60f6afe9f9 100644 --- a/cmd/encrypt/main.go +++ b/cmd/encrypt/main.go @@ -9,12 +9,12 @@ import ( "github.com/k3s-io/k3s/pkg/cli/secretsencrypt" "github.com/k3s-io/k3s/pkg/configfilearg" "github.com/sirupsen/logrus" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) func main() { app := cmds.NewApp() - app.Commands = []cli.Command{ + app.Commands = []*cli.Command{ cmds.NewSecretsEncryptCommands( secretsencrypt.Status, secretsencrypt.Enable, diff --git a/cmd/etcdsnapshot/main.go b/cmd/etcdsnapshot/main.go index d6f8cb3a60c..7e342330182 100644 --- a/cmd/etcdsnapshot/main.go +++ b/cmd/etcdsnapshot/main.go @@ -9,12 +9,12 @@ import ( "github.com/k3s-io/k3s/pkg/cli/etcdsnapshot" "github.com/k3s-io/k3s/pkg/configfilearg" "github.com/sirupsen/logrus" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) func main() { app := cmds.NewApp() - app.Commands = []cli.Command{ + app.Commands = []*cli.Command{ cmds.NewEtcdSnapshotCommands( etcdsnapshot.Delete, etcdsnapshot.List, diff --git a/cmd/k3s/main.go b/cmd/k3s/main.go index 5d78d21afbe..3f243d91fa4 100644 --- a/cmd/k3s/main.go +++ b/cmd/k3s/main.go @@ -25,7 +25,7 @@ import ( "github.com/rancher/wrangler/v3/pkg/resolvehome" "github.com/sirupsen/logrus" "github.com/spf13/pflag" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) var criDefaultConfigPath = "/etc/crictl.yaml" @@ -52,7 +52,8 @@ func main() { // Handle subcommand invocation (k3s server, k3s crictl, etc) app := cmds.NewApp() app.EnableBashCompletion = true - app.Commands = []cli.Command{ + app.DisableSliceFlagSeparator = true + app.Commands = []*cli.Command{ cmds.NewServerCommand(internalCLIAction(version.Program+"-server"+programPostfix, dataDir, os.Args)), cmds.NewAgentCommand(internalCLIAction(version.Program+"-agent"+programPostfix, dataDir, os.Args)), cmds.NewKubectlCommand(externalCLIAction("kubectl", dataDir)), @@ -173,7 +174,7 @@ func runCLIs(dataDir string) bool { // externalCLIAction returns a function that will call an external binary, be used as the Action of a cli.Command. func externalCLIAction(cmd, dataDir string) func(cli *cli.Context) error { return func(cli *cli.Context) error { - return externalCLI(cmd, dataDir, cli.Args()) + return externalCLI(cmd, dataDir, cli.Args().Slice()) } } diff --git a/cmd/server/main.go b/cmd/server/main.go index 193cdc0fd45..ed6b1d66659 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -23,7 +23,7 @@ import ( ctr2 "github.com/k3s-io/k3s/pkg/ctr" kubectl2 "github.com/k3s-io/k3s/pkg/kubectl" "github.com/sirupsen/logrus" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" crictl2 "sigs.k8s.io/cri-tools/cmd/crictl" ) @@ -43,7 +43,8 @@ func main() { os.Args[0] = cmd app := cmds.NewApp() - app.Commands = []cli.Command{ + app.DisableSliceFlagSeparator = true + app.Commands = []*cli.Command{ cmds.NewServerCommand(server.Run), cmds.NewAgentCommand(agent.Run), cmds.NewKubectlCommand(kubectl.Run), diff --git a/cmd/token/main.go b/cmd/token/main.go index 3edaf99fb47..9d980ca96e3 100644 --- a/cmd/token/main.go +++ b/cmd/token/main.go @@ -9,12 +9,12 @@ import ( "github.com/k3s-io/k3s/pkg/cli/token" "github.com/k3s-io/k3s/pkg/configfilearg" "github.com/sirupsen/logrus" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) func main() { app := cmds.NewApp() - app.Commands = []cli.Command{ + app.Commands = []*cli.Command{ cmds.NewTokenCommands( token.Create, token.Delete, diff --git a/go.mod b/go.mod index 001a9963c80..ecd77ba3ab4 100644 --- a/go.mod +++ b/go.mod @@ -131,16 +131,15 @@ require ( github.com/rancher/lasso v0.0.0-20250109193533-00757eec2dbd github.com/rancher/permissions v0.0.0-20240523180510-4001d3d637f7 github.com/rancher/remotedialer v0.4.1 - github.com/rancher/wharfie v0.6.7 + github.com/rancher/wharfie v0.6.9 github.com/rancher/wrangler/v3 v3.2.0-rc.1 github.com/robfig/cron/v3 v3.0.1 - github.com/rootless-containers/rootlesskit v1.0.1 + github.com/rootless-containers/rootlesskit v1.1.1 github.com/sirupsen/logrus v1.9.3 github.com/spegel-org/spegel v1.0.18 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.10.0 - github.com/urfave/cli v1.22.15 - github.com/urfave/cli/v2 v2.27.5 + github.com/urfave/cli/v2 v2.27.6 github.com/vishvananda/netlink v1.3.1-0.20240905180732-b1ce50cfa9be github.com/yl2chen/cidranger v1.0.2 go.etcd.io/etcd/api/v3 v3.5.19 diff --git a/go.sum b/go.sum index 88962f75220..aafa72d6d6a 100644 --- a/go.sum +++ b/go.sum @@ -233,7 +233,6 @@ github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOv github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= @@ -1208,8 +1207,8 @@ github.com/rancher/permissions v0.0.0-20240523180510-4001d3d637f7 h1:0Kg2SGoMeU1 github.com/rancher/permissions v0.0.0-20240523180510-4001d3d637f7/go.mod h1:fsbs0YOsGn1ofPD5p+BuI4qDhbMbSJtTegKt6Ucna+c= github.com/rancher/remotedialer v0.4.1 h1:jwOf2kPRjBBpSFofv1OuZHWaYHeC9Eb6/XgDvbkoTgc= github.com/rancher/remotedialer v0.4.1/go.mod h1:Ys004RpJuTLSm+k4aYUCoFiOOad37ubYev3TkOFg/5w= -github.com/rancher/wharfie v0.6.7 h1:BhbBVJSLoDQMkZb+zVTLEKckUbq4sc3ZmEYqGakggSY= -github.com/rancher/wharfie v0.6.7/go.mod h1:ew49A9PzRsTngdzXIkgakfhMq3mHMA650HS1OVQpaNA= +github.com/rancher/wharfie v0.6.9 h1:w0xf8F/LqjuXBYYJRMWTcHWIF8p4zVKmFOOEqz74VhQ= +github.com/rancher/wharfie v0.6.9/go.mod h1:PpyuDiBgnFVd56kKtNfSS3cMDTVcRJZVYfNwxcqv50I= github.com/rancher/wrangler/v3 v3.2.0-rc.1 h1:c0r5aBVUwWUqfeVFP9S4JGalsLra5zHZtvyteSuKHtI= github.com/rancher/wrangler/v3 v3.2.0-rc.1/go.mod h1:8DV2nXOOiUrsoRviL3WmzjELR5B6AS8CtMGEP34E0DE= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= @@ -1224,8 +1223,8 @@ github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/f github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= -github.com/rootless-containers/rootlesskit v1.0.1 h1:jepqW1txFSowKSMAEkVhWH3Oa1TCY9S400MVYe/6Iro= -github.com/rootless-containers/rootlesskit v1.0.1/go.mod h1:t2UAiYagxrJ+wmpFAUIZPcqsm4k2B7ve6g7lILKbloc= +github.com/rootless-containers/rootlesskit v1.1.1 h1:F5psKWoWY9/VjZ3ifVcaosjvFZJOagX85U22M0/EQZE= +github.com/rootless-containers/rootlesskit v1.1.1/go.mod h1:UD5GoA3dqKCJrnvnhVgQQnweMF2qZnf9KLw8EewcMZI= github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= @@ -1330,10 +1329,8 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1 github.com/urfave/cli v1.19.1/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.15 h1:nuqt+pdC/KqswQKhETJjo7pvn/k4xMUxgW6liI7XpnM= -github.com/urfave/cli v1.22.15/go.mod h1:wSan1hmo5zeyLGBjRJbzRTNk8gwoYa2B9n4q9dmRIc0= -github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w= -github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ= +github.com/urfave/cli/v2 v2.27.6 h1:VdRdS98FNhKZ8/Az8B7MTyGQmpIr36O1EHybx/LaZ4g= +github.com/urfave/cli/v2 v2.27.6/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ= github.com/vbatts/tar-split v0.11.6 h1:4SjTW5+PU11n6fZenf2IPoV8/tz3AaYHMWjf23envGs= github.com/vbatts/tar-split v0.11.6/go.mod h1:dqKNtesIOr2j2Qv3W/cHjnvk9I8+G7oAkFDFN6TCBEI= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= diff --git a/main.go b/main.go index 78ac760b997..f000ad6a6ee 100644 --- a/main.go +++ b/main.go @@ -20,12 +20,13 @@ import ( "github.com/k3s-io/k3s/pkg/cli/server" "github.com/k3s-io/k3s/pkg/configfilearg" "github.com/sirupsen/logrus" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) func main() { app := cmds.NewApp() - app.Commands = []cli.Command{ + app.DisableSliceFlagSeparator = true + app.Commands = []*cli.Command{ cmds.NewServerCommand(server.Run), cmds.NewAgentCommand(agent.Run), cmds.NewKubectlCommand(kubectl.Run), diff --git a/pkg/agent/config/config.go b/pkg/agent/config/config.go index a259c296dc1..14e92fa2f1a 100644 --- a/pkg/agent/config/config.go +++ b/pkg/agent/config/config.go @@ -442,7 +442,7 @@ func get(ctx context.Context, envInfo *cmds.Agent, proxy proxy.Proxy) (*config.N } // If the supervisor and externally-facing apiserver are not on the same port, tell the proxy where to find the apiserver. if controlConfig.SupervisorPort != controlConfig.HTTPSPort { - isIPv6 := utilsnet.IsIPv6(net.ParseIP(util.GetFirstValidIPString(envInfo.NodeIP))) + isIPv6 := utilsnet.IsIPv6(net.ParseIP(util.GetFirstValidIPString(envInfo.NodeIP.Value()))) if err := proxy.SetAPIServerPort(controlConfig.HTTPSPort, isIPv6); err != nil { return nil, pkgerrors.WithMessagef(err, "failed to set apiserver port to %d", controlConfig.HTTPSPort) } @@ -483,7 +483,7 @@ func get(ctx context.Context, envInfo *cmds.Agent, proxy proxy.Proxy) (*config.N newNodePasswordFile := filepath.Join(nodeConfigPath, "password") upgradeOldNodePasswordPath(oldNodePasswordFile, newNodePasswordFile) - nodeName, nodeIPs, err := util.GetHostnameAndIPs(envInfo.NodeName, envInfo.NodeIP) + nodeName, nodeIPs, err := util.GetHostnameAndIPs(envInfo.NodeName, envInfo.NodeIP.Value()) if err != nil { return nil, err } @@ -515,10 +515,10 @@ func get(ctx context.Context, envInfo *cmds.Agent, proxy proxy.Proxy) (*config.N // Overwrite nodeip and flannel interface and throw a warning if user explicitly set those parameters if len(vpnIPs) != 0 { logrus.Infof("Node-ip changed to %v due to VPN", vpnIPs) - if len(envInfo.NodeIP) != 0 { + if len(envInfo.NodeIP.Value()) != 0 { logrus.Warn("VPN provider overrides configured node-ip parameter") } - if len(envInfo.NodeExternalIP) != 0 { + if len(envInfo.NodeExternalIP.Value()) != 0 { logrus.Warn("VPN provider overrides node-external-ip parameter") } nodeIPs = vpnIPs @@ -537,7 +537,7 @@ func get(ctx context.Context, envInfo *cmds.Agent, proxy proxy.Proxy) (*config.N } } - nodeExternalIPs, err := util.ParseStringSliceToIPs(envInfo.NodeExternalIP) + nodeExternalIPs, err := util.ParseStringSliceToIPs(envInfo.NodeExternalIP.Value()) if err != nil { return nil, fmt.Errorf("invalid node-external-ip: %w", err) } @@ -762,7 +762,7 @@ func get(ctx context.Context, envInfo *cmds.Agent, proxy proxy.Proxy) (*config.N } nodeConfig.AgentConfig.PauseImage = envInfo.PauseImage - nodeConfig.AgentConfig.AirgapExtraRegistry = envInfo.AirgapExtraRegistry + nodeConfig.AgentConfig.AirgapExtraRegistry = envInfo.AirgapExtraRegistry.Value() nodeConfig.AgentConfig.SystemDefaultRegistry = controlConfig.SystemDefaultRegistry // Apply SystemDefaultRegistry to PauseImage and AirgapExtraRegistry @@ -775,10 +775,10 @@ func get(ctx context.Context, envInfo *cmds.Agent, proxy proxy.Proxy) (*config.N } } - nodeConfig.AgentConfig.ExtraKubeletArgs = envInfo.ExtraKubeletArgs - nodeConfig.AgentConfig.ExtraKubeProxyArgs = envInfo.ExtraKubeProxyArgs - nodeConfig.AgentConfig.NodeTaints = envInfo.Taints - nodeConfig.AgentConfig.NodeLabels = envInfo.Labels + nodeConfig.AgentConfig.ExtraKubeletArgs = envInfo.ExtraKubeletArgs.Value() + nodeConfig.AgentConfig.ExtraKubeProxyArgs = envInfo.ExtraKubeProxyArgs.Value() + nodeConfig.AgentConfig.NodeTaints = envInfo.Taints.Value() + nodeConfig.AgentConfig.NodeLabels = envInfo.Labels.Value() nodeConfig.AgentConfig.ImageCredProvBinDir = envInfo.ImageCredProvBinDir nodeConfig.AgentConfig.ImageCredProvConfig = envInfo.ImageCredProvConfig nodeConfig.AgentConfig.DisableCCM = controlConfig.DisableCCM diff --git a/pkg/agent/run.go b/pkg/agent/run.go index b18cee4811c..c2fb7280803 100644 --- a/pkg/agent/run.go +++ b/pkg/agent/run.go @@ -311,7 +311,7 @@ func Run(ctx context.Context, cfg cmds.Agent) error { } if cfg.Rootless && !cfg.RootlessAlreadyUnshared { - dualNode, err := utilsnet.IsDualStackIPStrings(cfg.NodeIP) + dualNode, err := utilsnet.IsDualStackIPStrings(cfg.NodeIP.Value()) if err != nil { return err } @@ -336,7 +336,7 @@ func createProxyAndValidateToken(ctx context.Context, cfg *cmds.Agent) (proxy.Pr if err := os.MkdirAll(agentDir, 0700); err != nil { return nil, err } - isIPv6 := utilsnet.IsIPv6(net.ParseIP(util.GetFirstValidIPString(cfg.NodeIP))) + isIPv6 := utilsnet.IsIPv6(net.ParseIP(util.GetFirstValidIPString(cfg.NodeIP.Value()))) proxy, err := proxy.NewSupervisorProxy(ctx, !cfg.DisableLoadBalancer, agentDir, cfg.ServerURL, cfg.LBServerPort, isIPv6) if err != nil { diff --git a/pkg/cli/agent/agent.go b/pkg/cli/agent/agent.go index 064909a1a5a..6fc542fadf9 100644 --- a/pkg/cli/agent/agent.go +++ b/pkg/cli/agent/agent.go @@ -24,7 +24,7 @@ import ( pkgerrors "github.com/pkg/errors" "github.com/rancher/wrangler/v3/pkg/signals" "github.com/sirupsen/logrus" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) func Run(ctx *cli.Context) error { @@ -72,7 +72,7 @@ func Run(ctx *cli.Context) error { return fmt.Errorf("--server is required") } - if cmds.AgentConfig.FlannelIface != "" && len(cmds.AgentConfig.NodeIP) == 0 { + if cmds.AgentConfig.FlannelIface != "" && len(cmds.AgentConfig.NodeIP.Value()) == 0 { ip, err := util.GetIPFromInterface(cmds.AgentConfig.FlannelIface) if err != nil { return err @@ -88,7 +88,7 @@ func Run(ctx *cli.Context) error { } cfg := cmds.AgentConfig - cfg.Debug = ctx.GlobalBool("debug") + cfg.Debug = ctx.Bool("debug") cfg.DataDir = dataDir contextCtx := signals.SetupSignalContext() diff --git a/pkg/cli/cert/cert.go b/pkg/cli/cert/cert.go index 7ed7350619d..ce4cb84825b 100644 --- a/pkg/cli/cert/cert.go +++ b/pkg/cli/cert/cert.go @@ -25,7 +25,7 @@ import ( pkgerrors "github.com/pkg/errors" certutil "github.com/rancher/dynamiclistener/cert" "github.com/sirupsen/logrus" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) func commandSetup(app *cli.Context, cfg *cmds.Server, sc *server.Config) (string, error) { @@ -72,7 +72,7 @@ func check(app *cli.Context, cfg *cmds.Server) error { return err } - if len(cmds.ServicesList) == 0 { + if len(cmds.ServicesList.Value()) == 0 { // detecting if the command is being run on an agent or server based on presence of the server data-dir _, err := os.Stat(serverConfig.ControlConfig.DataDir) if err != nil { @@ -80,14 +80,14 @@ func check(app *cli.Context, cfg *cmds.Server) error { return err } logrus.Infof("Agent detected, checking agent certificates") - cmds.ServicesList = services.Agent + cmds.ServicesList = *cli.NewStringSlice(services.Agent...) } else { logrus.Infof("Server detected, checking agent and server certificates") - cmds.ServicesList = services.All + cmds.ServicesList = *cli.NewStringSlice(services.All...) } } - fileMap, err := services.FilesForServices(serverConfig.ControlConfig, cmds.ServicesList) + fileMap, err := services.FilesForServices(serverConfig.ControlConfig, cmds.ServicesList.Value()) if err != nil { return err } @@ -172,7 +172,7 @@ func rotate(app *cli.Context, cfg *cmds.Server) error { return err } - if len(cmds.ServicesList) == 0 { + if len(cmds.ServicesList.Value()) == 0 { // detecting if the command is being run on an agent or server based on presence of the server data-dir _, err := os.Stat(serverConfig.ControlConfig.DataDir) if err != nil { @@ -180,14 +180,14 @@ func rotate(app *cli.Context, cfg *cmds.Server) error { return err } logrus.Infof("Agent detected, rotating agent certificates") - cmds.ServicesList = services.Agent + cmds.ServicesList = *cli.NewStringSlice(services.Agent...) } else { logrus.Infof("Server detected, rotating agent and server certificates") - cmds.ServicesList = services.All + cmds.ServicesList = *cli.NewStringSlice(services.All...) } } - fileMap, err := services.FilesForServices(serverConfig.ControlConfig, cmds.ServicesList) + fileMap, err := services.FilesForServices(serverConfig.ControlConfig, cmds.ServicesList.Value()) if err != nil { return err } @@ -201,7 +201,7 @@ func rotate(app *cli.Context, cfg *cmds.Server) error { // The dynamiclistener cache file can't be simply deleted, we need to create a trigger // file to indicate that the cert needs to be regenerated on startup. - for _, service := range cmds.ServicesList { + for _, service := range cmds.ServicesList.Value() { if service == version.Program+services.ProgramServer { dynamicListenerRegenFilePath := filepath.Join(serverConfig.ControlConfig.DataDir, "tls", "dynamic-cert-regenerate") if err := os.WriteFile(dynamicListenerRegenFilePath, []byte{}, 0600); err != nil { @@ -257,7 +257,7 @@ func backupCertificates(serverDataDir, agentDataDir string, fileMap map[string][ } func validateCertConfig() error { - for _, s := range cmds.ServicesList { + for _, s := range cmds.ServicesList.Value() { if !services.IsValid(s) { return errors.New("service " + s + " is not recognized") } diff --git a/pkg/cli/cmds/agent.go b/pkg/cli/cmds/agent.go index 46091a3aa8c..10e74badce6 100644 --- a/pkg/cli/cmds/agent.go +++ b/pkg/cli/cmds/agent.go @@ -5,7 +5,7 @@ import ( "path/filepath" "github.com/k3s-io/k3s/pkg/version" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) type Agent struct { @@ -68,35 +68,37 @@ var ( appName = filepath.Base(os.Args[0]) AgentConfig Agent AgentTokenFlag = &cli.StringFlag{ - Name: "token,t", + Name: "token", + Aliases: []string{"t"}, Usage: "(cluster) Token to use for authentication", - EnvVar: version.ProgramUpper + "_TOKEN", + EnvVars: []string{version.ProgramUpper + "_TOKEN"}, Destination: &AgentConfig.Token, } NodeIPFlag = &cli.StringSliceFlag{ - Name: "node-ip,i", - Usage: "(agent/networking) IPv4/IPv6 addresses to advertise for node", - Value: &AgentConfig.NodeIP, + Name: "node-ip", + Aliases: []string{"i"}, + Usage: "(agent/networking) IPv4/IPv6 addresses to advertise for node", + Destination: &AgentConfig.NodeIP, } NodeExternalIPFlag = &cli.StringSliceFlag{ - Name: "node-external-ip", - Usage: "(agent/networking) IPv4/IPv6 external IP addresses to advertise for node", - Value: &AgentConfig.NodeExternalIP, + Name: "node-external-ip", + Usage: "(agent/networking) IPv4/IPv6 external IP addresses to advertise for node", + Destination: &AgentConfig.NodeExternalIP, } NodeInternalDNSFlag = &cli.StringSliceFlag{ - Name: "node-internal-dns", - Usage: "(agent/networking) internal DNS addresses to advertise for node", - Value: &AgentConfig.NodeInternalDNS, + Name: "node-internal-dns", + Usage: "(agent/networking) internal DNS addresses to advertise for node", + Destination: &AgentConfig.NodeInternalDNS, } NodeExternalDNSFlag = &cli.StringSliceFlag{ - Name: "node-external-dns", - Usage: "(agent/networking) external DNS addresses to advertise for node", - Value: &AgentConfig.NodeExternalDNS, + Name: "node-external-dns", + Usage: "(agent/networking) external DNS addresses to advertise for node", + Destination: &AgentConfig.NodeExternalDNS, } NodeNameFlag = &cli.StringFlag{ Name: "node-name", Usage: "(agent/node) Node name", - EnvVar: version.ProgramUpper + "_NODE_NAME", + EnvVars: []string{version.ProgramUpper + "_NODE_NAME"}, Destination: &AgentConfig.NodeName, } WithNodeIDFlag = &cli.BoolFlag{ @@ -113,13 +115,13 @@ var ( Name: "selinux", Usage: "(agent/node) Enable SELinux in containerd", Destination: &AgentConfig.EnableSELinux, - EnvVar: version.ProgramUpper + "_SELINUX", + EnvVars: []string{version.ProgramUpper + "_SELINUX"}, } LBServerPortFlag = &cli.IntFlag{ Name: "lb-server-port", Usage: "(agent/node) Local port for supervisor client load-balancer. If the supervisor and apiserver are not colocated an additional port 1 less than this port will also be used for the apiserver client load-balancer.", Destination: &AgentConfig.LBServerPort, - EnvVar: version.ProgramUpper + "_LB_SERVER_PORT", + EnvVars: []string{version.ProgramUpper + "_LB_SERVER_PORT"}, Value: 6444, } DockerFlag = &cli.BoolFlag{ @@ -184,40 +186,40 @@ var ( VPNAuth = &cli.StringFlag{ Name: "vpn-auth", Usage: "(agent/networking) (experimental) Credentials for the VPN provider. It must include the provider name and join key in the format name=,joinKey=[,controlServerURL=][,extraArgs=]", - EnvVar: version.ProgramUpper + "_VPN_AUTH", + EnvVars: []string{version.ProgramUpper + "_VPN_AUTH"}, Destination: &AgentConfig.VPNAuth, } VPNAuthFile = &cli.StringFlag{ Name: "vpn-auth-file", Usage: "(agent/networking) (experimental) File containing credentials for the VPN provider. It must include the provider name and join key in the format name=,joinKey=[,controlServerURL=][,extraArgs=]", - EnvVar: version.ProgramUpper + "_VPN_AUTH_FILE", + EnvVars: []string{version.ProgramUpper + "_VPN_AUTH_FILE"}, Destination: &AgentConfig.VPNAuthFile, } ResolvConfFlag = &cli.StringFlag{ Name: "resolv-conf", Usage: "(agent/networking) Kubelet resolv.conf file", - EnvVar: version.ProgramUpper + "_RESOLV_CONF", + EnvVars: []string{version.ProgramUpper + "_RESOLV_CONF"}, Destination: &AgentConfig.ResolvConf, } ExtraKubeletArgs = &cli.StringSliceFlag{ - Name: "kubelet-arg", - Usage: "(agent/flags) Customized flag for kubelet process", - Value: &AgentConfig.ExtraKubeletArgs, + Name: "kubelet-arg", + Usage: "(agent/flags) Customized flag for kubelet process", + Destination: &AgentConfig.ExtraKubeletArgs, } ExtraKubeProxyArgs = &cli.StringSliceFlag{ - Name: "kube-proxy-arg", - Usage: "(agent/flags) Customized flag for kube-proxy process", - Value: &AgentConfig.ExtraKubeProxyArgs, + Name: "kube-proxy-arg", + Usage: "(agent/flags) Customized flag for kube-proxy process", + Destination: &AgentConfig.ExtraKubeProxyArgs, } NodeTaints = &cli.StringSliceFlag{ - Name: "node-taint", - Usage: "(agent/node) Registering kubelet with set of taints", - Value: &AgentConfig.Taints, + Name: "node-taint", + Usage: "(agent/node) Registering kubelet with set of taints", + Destination: &AgentConfig.Taints, } NodeLabels = &cli.StringSliceFlag{ - Name: "node-label", - Usage: "(agent/node) Registering and starting kubelet with set of labels", - Value: &AgentConfig.Labels, + Name: "node-label", + Usage: "(agent/node) Registering and starting kubelet with set of labels", + Destination: &AgentConfig.Labels, } ImageCredProvBinDirFlag = &cli.StringFlag{ Name: "image-credential-provider-bin-dir", @@ -258,8 +260,8 @@ var ( } ) -func NewAgentCommand(action func(ctx *cli.Context) error) cli.Command { - return cli.Command{ +func NewAgentCommand(action func(ctx *cli.Context) error) *cli.Command { + return &cli.Command{ Name: "agent", Usage: "Run node agent", UsageText: appName + " agent [OPTIONS]", @@ -275,23 +277,25 @@ func NewAgentCommand(action func(ctx *cli.Context) error) cli.Command { &cli.StringFlag{ Name: "token-file", Usage: "(cluster) Token file to use for authentication", - EnvVar: version.ProgramUpper + "_TOKEN_FILE", + EnvVars: []string{version.ProgramUpper + "_TOKEN_FILE"}, Destination: &AgentConfig.TokenFile, }, &cli.StringFlag{ - Name: "server,s", + Name: "server", + Aliases: []string{"s"}, Usage: "(cluster) Server to connect to", - EnvVar: version.ProgramUpper + "_URL", + EnvVars: []string{version.ProgramUpper + "_URL"}, Destination: &AgentConfig.ServerURL, }, // Note that this is different from DataDirFlag used elswhere in the CLI, // as this is bound to AgentConfig instead of ServerConfig. &cli.StringFlag{ - Name: "data-dir,d", + Name: "data-dir", + Aliases: []string{"d"}, Usage: "(agent/data) Folder to hold state", Destination: &AgentConfig.DataDir, Value: "/var/lib/rancher/" + version.Program + "", - EnvVar: version.ProgramUpper + "_DATA_DIR", + EnvVars: []string{version.ProgramUpper + "_DATA_DIR"}, }, NodeNameFlag, WithNodeIDFlag, diff --git a/pkg/cli/cmds/certs.go b/pkg/cli/cmds/certs.go index 44440a040db..c073401f053 100644 --- a/pkg/cli/cmds/certs.go +++ b/pkg/cli/cmds/certs.go @@ -2,7 +2,7 @@ package cmds import ( "github.com/k3s-io/k3s/pkg/version" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) const CertCommand = "certificate" @@ -22,27 +22,29 @@ var ( AlsoLogToStderr, DataDirFlag, &cli.StringSliceFlag{ - Name: "service,s", - Usage: "List of services to manage certificates for. Options include (admin, api-server, controller-manager, scheduler, supervisor, " + version.Program + "-controller, " + version.Program + "-server, cloud-controller, etcd, auth-proxy, kubelet, kube-proxy)", - Value: &ServicesList, + Name: "service", + Aliases: []string{"s"}, + Usage: "List of services to manage certificates for. Options include (admin, api-server, controller-manager, scheduler, supervisor, " + version.Program + "-controller, " + version.Program + "-server, cloud-controller, etcd, auth-proxy, kubelet, kube-proxy)", + Destination: &ServicesList, }, } CertRotateCACommandFlags = []cli.Flag{ DataDirFlag, - cli.StringFlag{ - Name: "server,s", + &cli.StringFlag{ + Name: "server", + Aliases: []string{"s"}, Usage: "(cluster) Server to connect to", - EnvVar: version.ProgramUpper + "_URL", + EnvVars: []string{version.ProgramUpper + "_URL"}, Value: "https://127.0.0.1:6443", Destination: &ServerConfig.ServerURL, }, - cli.StringFlag{ + &cli.StringFlag{ Name: "path", Usage: "Path to directory containing new CA certificates", Destination: &CertRotateCAConfig.CACertPath, Required: true, }, - cli.BoolFlag{ + &cli.BoolFlag{ Name: "force", Usage: "Force certificate replacement, even if consistency checks fail", Destination: &CertRotateCAConfig.Force, @@ -50,30 +52,28 @@ var ( } ) -func NewCertCommands(check, rotate, rotateCA func(ctx *cli.Context) error) cli.Command { - return cli.Command{ +func NewCertCommands(check, rotate, rotateCA func(ctx *cli.Context) error) *cli.Command { + return &cli.Command{ Name: CertCommand, Usage: "Manage K3s certificates", SkipFlagParsing: false, - SkipArgReorder: true, - Subcommands: []cli.Command{ + Subcommands: []*cli.Command{ { Name: "check", Usage: "Check " + version.Program + " component certificates on disk", SkipFlagParsing: false, - SkipArgReorder: true, Action: check, Flags: append(CertRotateCommandFlags, &cli.StringFlag{ - Name: "output,o", - Usage: "Format output. Options: text, table", - Value: "text", + Name: "output", + Aliases: []string{"o"}, + Usage: "Format output. Options: text, table", + Value: "text", }), }, { Name: "rotate", Usage: "Rotate " + version.Program + " component certificates on disk", SkipFlagParsing: false, - SkipArgReorder: true, Action: rotate, Flags: CertRotateCommandFlags, }, @@ -81,7 +81,6 @@ func NewCertCommands(check, rotate, rotateCA func(ctx *cli.Context) error) cli.C Name: "rotate-ca", Usage: "Write updated " + version.Program + " CA certificates to the datastore", SkipFlagParsing: false, - SkipArgReorder: true, Action: rotateCA, Flags: CertRotateCACommandFlags, }, diff --git a/pkg/cli/cmds/check-config.go b/pkg/cli/cmds/check-config.go index ead97e47a9b..d24c7f6d391 100644 --- a/pkg/cli/cmds/check-config.go +++ b/pkg/cli/cmds/check-config.go @@ -1,15 +1,14 @@ package cmds import ( - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) -func NewCheckConfigCommand(action func(*cli.Context) error) cli.Command { - return cli.Command{ +func NewCheckConfigCommand(action func(*cli.Context) error) *cli.Command { + return &cli.Command{ Name: "check-config", Usage: "Run config check", SkipFlagParsing: true, - SkipArgReorder: true, Action: action, } } diff --git a/pkg/cli/cmds/completion.go b/pkg/cli/cmds/completion.go index 5801f263258..0303282669b 100644 --- a/pkg/cli/cmds/completion.go +++ b/pkg/cli/cmds/completion.go @@ -1,11 +1,11 @@ package cmds import ( - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) -func NewCompletionCommand(action func(*cli.Context) error) cli.Command { - return cli.Command{ +func NewCompletionCommand(action func(*cli.Context) error) *cli.Command { + return &cli.Command{ Name: "completion", Usage: "Install shell completion script", UsageText: appName + " completion [SHELL] (valid shells: bash, zsh)", diff --git a/pkg/cli/cmds/config.go b/pkg/cli/cmds/config.go index 9255c585576..be4f66ca804 100644 --- a/pkg/cli/cmds/config.go +++ b/pkg/cli/cmds/config.go @@ -2,16 +2,17 @@ package cmds import ( "github.com/k3s-io/k3s/pkg/version" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) var ( // ConfigFlag is here to show to the user, but the actually processing is done by configfileargs before // call urfave ConfigFlag = &cli.StringFlag{ - Name: "config,c", - Usage: "(config) Load configuration from `FILE`", - EnvVar: version.ProgramUpper + "_CONFIG_FILE", - Value: "/etc/rancher/" + version.Program + "/config.yaml", + Name: "config", + Aliases: []string{"c"}, + Usage: "(config) Load configuration from `FILE`", + EnvVars: []string{version.ProgramUpper + "_CONFIG_FILE"}, + Value: "/etc/rancher/" + version.Program + "/config.yaml", } ) diff --git a/pkg/cli/cmds/crictl.go b/pkg/cli/cmds/crictl.go index ff1bbbbfd0c..e6abc60bdc3 100644 --- a/pkg/cli/cmds/crictl.go +++ b/pkg/cli/cmds/crictl.go @@ -1,15 +1,14 @@ package cmds import ( - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) -func NewCRICTL(action func(*cli.Context) error) cli.Command { - return cli.Command{ +func NewCRICTL(action func(*cli.Context) error) *cli.Command { + return &cli.Command{ Name: "crictl", Usage: "Run crictl", SkipFlagParsing: true, - SkipArgReorder: true, Action: action, } } diff --git a/pkg/cli/cmds/ctr.go b/pkg/cli/cmds/ctr.go index c6a5e30ef74..8be452937da 100644 --- a/pkg/cli/cmds/ctr.go +++ b/pkg/cli/cmds/ctr.go @@ -1,15 +1,14 @@ package cmds import ( - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) -func NewCtrCommand(action func(*cli.Context) error) cli.Command { - return cli.Command{ +func NewCtrCommand(action func(*cli.Context) error) *cli.Command { + return &cli.Command{ Name: "ctr", Usage: "Run ctr", SkipFlagParsing: true, - SkipArgReorder: true, Action: action, } } diff --git a/pkg/cli/cmds/etcd_snapshot.go b/pkg/cli/cmds/etcd_snapshot.go index 12c678d9463..d9fba135767 100644 --- a/pkg/cli/cmds/etcd_snapshot.go +++ b/pkg/cli/cmds/etcd_snapshot.go @@ -4,7 +4,7 @@ import ( "time" "github.com/k3s-io/k3s/pkg/version" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) const EtcdSnapshotCommand = "etcd-snapshot" @@ -17,23 +17,26 @@ var EtcdSnapshotFlags = []cli.Flag{ &cli.StringFlag{ Name: "node-name", Usage: "(agent/node) Node name", - EnvVar: version.ProgramUpper + "_NODE_NAME", + EnvVars: []string{version.ProgramUpper + "_NODE_NAME"}, Destination: &AgentConfig.NodeName, }, DataDirFlag, &cli.StringFlag{ - Name: "etcd-token,t", + Name: "etcd-token", + Aliases: []string{"t"}, Usage: "(cluster) Shared secret used to authenticate to etcd server", Destination: &ServerConfig.Token, }, &cli.StringFlag{ - Name: "etcd-server, s", + Name: "etcd-server", + Aliases: []string{"s"}, Usage: "(cluster) Server with etcd role to connect to for snapshot management operations", Value: "https://127.0.0.1:6443", Destination: &ServerConfig.ServerURL, }, &cli.StringFlag{ - Name: "dir,etcd-snapshot-dir", + Name: "dir", + Aliases: []string{"etcd-snapshot-dir"}, Usage: "(db) Directory to save etcd on-demand snapshot. (default: ${data-dir}/server/db/snapshots)", Destination: &ServerConfig.EtcdSnapshotDir, }, @@ -44,105 +47,119 @@ var EtcdSnapshotFlags = []cli.Flag{ Value: "on-demand", }, &cli.BoolFlag{ - Name: "snapshot-compress,etcd-snapshot-compress", + Name: "snapshot-compress", + Aliases: []string{"etcd-snapshot-compress"}, Usage: "(db) Compress etcd snapshot", Destination: &ServerConfig.EtcdSnapshotCompress, }, &cli.IntFlag{ - Name: "snapshot-retention,etcd-snapshot-retention", + Name: "snapshot-retention,", + Aliases: []string{"etcd-snapshot-retention"}, Usage: "(db) Number of snapshots to retain.", Destination: &ServerConfig.EtcdSnapshotRetention, Value: defaultSnapshotRentention, }, &cli.BoolFlag{ - Name: "s3,etcd-s3", + Name: "s3", + Aliases: []string{"etcd-s3"}, Usage: "(db) Enable backup to S3", Destination: &ServerConfig.EtcdS3, }, &cli.StringFlag{ - Name: "s3-endpoint,etcd-s3-endpoint", + Name: "s3-endpoint", + Aliases: []string{"etcd-s3-endpoint"}, Usage: "(db) S3 endpoint url", Destination: &ServerConfig.EtcdS3Endpoint, Value: "s3.amazonaws.com", }, &cli.StringFlag{ - Name: "s3-endpoint-ca,etcd-s3-endpoint-ca", + Name: "s3-endpoint-ca", + Aliases: []string{"etcd-s3-endpoint-ca"}, Usage: "(db) S3 custom CA cert to connect to S3 endpoint", Destination: &ServerConfig.EtcdS3EndpointCA, }, &cli.BoolFlag{ - Name: "s3-skip-ssl-verify,etcd-s3-skip-ssl-verify", + Name: "s3-skip-ssl-verify", + Aliases: []string{"etcd-s3-skip-ssl-verify"}, Usage: "(db) Disables S3 SSL certificate validation", Destination: &ServerConfig.EtcdS3SkipSSLVerify, }, &cli.StringFlag{ - Name: "s3-access-key,etcd-s3-access-key", + Name: "s3-access-key", + Aliases: []string{"etcd-s3-access-key"}, Usage: "(db) S3 access key", - EnvVar: "AWS_ACCESS_KEY_ID", + EnvVars: []string{"AWS_ACCESS_KEY_ID"}, Destination: &ServerConfig.EtcdS3AccessKey, }, &cli.StringFlag{ - Name: "s3-secret-key,etcd-s3-secret-key", + Name: "s3-secret-key", + Aliases: []string{"etcd-s3-secret-key"}, Usage: "(db) S3 secret key", - EnvVar: "AWS_SECRET_ACCESS_KEY", + EnvVars: []string{"AWS_SECRET_ACCESS_KEY"}, Destination: &ServerConfig.EtcdS3SecretKey, }, &cli.StringFlag{ - Name: "s3-session-token,etcd-s3-session-token", + Name: "s3-session-token", + Aliases: []string{"etcd-s3-session-token"}, Usage: "(db) S3 session token", - EnvVar: "AWS_SESSION_TOKEN", + EnvVars: []string{"AWS_SESSION_TOKEN"}, Destination: &ServerConfig.EtcdS3SessionToken, }, &cli.StringFlag{ - Name: "s3-bucket,etcd-s3-bucket", + Name: "s3-bucket", + Aliases: []string{"etcd-s3-bucket"}, Usage: "(db) S3 bucket name", Destination: &ServerConfig.EtcdS3BucketName, }, &cli.StringFlag{ - Name: "s3-region,etcd-s3-region", + Name: "s3-region", + Aliases: []string{"etcd-s3-region"}, Usage: "(db) S3 region / bucket location (optional)", Destination: &ServerConfig.EtcdS3Region, Value: "us-east-1", }, &cli.StringFlag{ - Name: "s3-folder,etcd-s3-folder", + Name: "s3-folder", + Aliases: []string{"etcd-s3-folder"}, Usage: "(db) S3 folder", Destination: &ServerConfig.EtcdS3Folder, }, &cli.StringFlag{ - Name: "s3-proxy,etcd-s3-proxy", + Name: "s3-proxy", + Aliases: []string{"etcd-s3-proxy"}, Usage: "(db) Proxy server to use when connecting to S3, overriding any proxy-releated environment variables", Destination: &ServerConfig.EtcdS3Proxy, }, &cli.StringFlag{ - Name: "s3-config-secret,etcd-s3-config-secret", + Name: "s3-config-secret", + Aliases: []string{"etcd-s3-config-secret"}, Usage: "(db) Name of secret in the kube-system namespace used to configure S3, if etcd-s3 is enabled and no other etcd-s3 options are set", Destination: &ServerConfig.EtcdS3ConfigSecret, }, &cli.BoolFlag{ - Name: "s3-insecure,etcd-s3-insecure", + Name: "s3-insecure", + Aliases: []string{"etcd-s3-insecure"}, Usage: "(db) Disables S3 over HTTPS", Destination: &ServerConfig.EtcdS3Insecure, }, &cli.DurationFlag{ - Name: "s3-timeout,etcd-s3-timeout", + Name: "s3-timeout", + Aliases: []string{"etcd-s3-timeout"}, Usage: "(db) S3 timeout", Destination: &ServerConfig.EtcdS3Timeout, Value: 5 * time.Minute, }, } -func NewEtcdSnapshotCommands(delete, list, prune, save func(ctx *cli.Context) error) cli.Command { - return cli.Command{ +func NewEtcdSnapshotCommands(delete, list, prune, save func(ctx *cli.Context) error) *cli.Command { + return &cli.Command{ Name: EtcdSnapshotCommand, SkipFlagParsing: false, - SkipArgReorder: true, - Subcommands: []cli.Command{ + Subcommands: []*cli.Command{ { Name: "save", Usage: "Trigger an immediate etcd snapshot", SkipFlagParsing: false, - SkipArgReorder: true, Action: save, Flags: EtcdSnapshotFlags, }, @@ -150,7 +167,6 @@ func NewEtcdSnapshotCommands(delete, list, prune, save func(ctx *cli.Context) er Name: "delete", Usage: "Delete given snapshot(s)", SkipFlagParsing: false, - SkipArgReorder: true, Action: delete, Flags: EtcdSnapshotFlags, }, @@ -159,10 +175,10 @@ func NewEtcdSnapshotCommands(delete, list, prune, save func(ctx *cli.Context) er Aliases: []string{"list", "l"}, Usage: "List snapshots", SkipFlagParsing: false, - SkipArgReorder: true, Action: list, Flags: append(EtcdSnapshotFlags, &cli.StringFlag{ - Name: "o,output", + Name: "output", + Aliases: []string{"o"}, Usage: "(db) List format. Default: standard. Optional: json", Destination: &ServerConfig.EtcdListFormat, }), @@ -171,7 +187,6 @@ func NewEtcdSnapshotCommands(delete, list, prune, save func(ctx *cli.Context) er Name: "prune", Usage: "Remove snapshots that match the name prefix that exceed the configured retention count", SkipFlagParsing: false, - SkipArgReorder: true, Action: prune, Flags: EtcdSnapshotFlags, }, diff --git a/pkg/cli/cmds/kubectl.go b/pkg/cli/cmds/kubectl.go index 72bdd92371a..4bf444b02b0 100644 --- a/pkg/cli/cmds/kubectl.go +++ b/pkg/cli/cmds/kubectl.go @@ -1,15 +1,14 @@ package cmds import ( - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) -func NewKubectlCommand(action func(*cli.Context) error) cli.Command { - return cli.Command{ +func NewKubectlCommand(action func(*cli.Context) error) *cli.Command { + return &cli.Command{ Name: "kubectl", Usage: "Run kubectl", SkipFlagParsing: true, - SkipArgReorder: true, Action: action, } } diff --git a/pkg/cli/cmds/log.go b/pkg/cli/cmds/log.go index 7e34b101362..c6683088355 100644 --- a/pkg/cli/cmds/log.go +++ b/pkg/cli/cmds/log.go @@ -6,7 +6,7 @@ import ( "time" "github.com/sirupsen/logrus" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) type Log struct { @@ -30,7 +30,8 @@ var ( Destination: &LogConfig.VModule, } LogFile = &cli.StringFlag{ - Name: "log,l", + Name: "log", + Aliases: []string{"l"}, Usage: "(logging) Log to file", Destination: &LogConfig.LogFile, } diff --git a/pkg/cli/cmds/root.go b/pkg/cli/cmds/root.go index e57133baae5..27b64b64c2d 100644 --- a/pkg/cli/cmds/root.go +++ b/pkg/cli/cmds/root.go @@ -6,7 +6,7 @@ import ( "runtime" "github.com/k3s-io/k3s/pkg/version" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) var ( @@ -15,7 +15,7 @@ var ( Name: "debug", Usage: "(logging) Turn on debug logs", Destination: &Debug, - EnvVar: version.ProgramUpper + "_DEBUG", + EnvVars: []string{version.ProgramUpper + "_DEBUG"}, } PreferBundledBin = &cli.BoolFlag{ Name: "prefer-bundled-bin", diff --git a/pkg/cli/cmds/secrets_encrypt.go b/pkg/cli/cmds/secrets_encrypt.go index 3fcf0c839f2..786fce9b991 100644 --- a/pkg/cli/cmds/secrets_encrypt.go +++ b/pkg/cli/cmds/secrets_encrypt.go @@ -2,14 +2,15 @@ package cmds import ( "github.com/k3s-io/k3s/pkg/version" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) const SecretsEncryptCommand = "secrets-encrypt" var ( forceFlag = &cli.BoolFlag{ - Name: "f,force", + Name: "force", + Aliases: []string{"f"}, Usage: "Force this stage.", Destination: &ServerConfig.EncryptForce, } @@ -17,65 +18,60 @@ var ( DataDirFlag, ServerToken, &cli.StringFlag{ - Name: "server, s", + Name: "server", + Aliases: []string{"s"}, Usage: "(cluster) Server to connect to", - EnvVar: version.ProgramUpper + "_URL", + EnvVars: []string{version.ProgramUpper + "_URL"}, Value: "https://127.0.0.1:6443", Destination: &ServerConfig.ServerURL, }, } ) -func NewSecretsEncryptCommands(status, enable, disable, prepare, rotate, reencrypt, rotateKeys func(ctx *cli.Context) error) cli.Command { - return cli.Command{ - Name: SecretsEncryptCommand, - Usage: "Control secrets encryption and keys rotation", - SkipArgReorder: true, - Subcommands: []cli.Command{ +func NewSecretsEncryptCommands(status, enable, disable, prepare, rotate, reencrypt, rotateKeys func(ctx *cli.Context) error) *cli.Command { + return &cli.Command{ + Name: SecretsEncryptCommand, + Usage: "Control secrets encryption and keys rotation", + Subcommands: []*cli.Command{ { - Name: "status", - Usage: "Print current status of secrets encryption", - SkipArgReorder: true, - Action: status, + Name: "status", + Usage: "Print current status of secrets encryption", + Action: status, Flags: append(EncryptFlags, &cli.StringFlag{ - Name: "output,o", + Name: "output", + Aliases: []string{"o"}, Usage: "Status format. Default: text. Optional: json", Destination: &ServerConfig.EncryptOutput, }), }, { - Name: "enable", - Usage: "Enable secrets encryption", - SkipArgReorder: true, - Action: enable, - Flags: EncryptFlags, + Name: "enable", + Usage: "Enable secrets encryption", + Action: enable, + Flags: EncryptFlags, }, { - Name: "disable", - Usage: "Disable secrets encryption", - SkipArgReorder: true, - Action: disable, - Flags: EncryptFlags, + Name: "disable", + Usage: "Disable secrets encryption", + Action: disable, + Flags: EncryptFlags, }, { - Name: "prepare", - Usage: "Prepare for encryption keys rotation", - SkipArgReorder: true, - Action: prepare, - Flags: append(EncryptFlags, forceFlag), + Name: "prepare", + Usage: "Prepare for encryption keys rotation", + Action: prepare, + Flags: append(EncryptFlags, forceFlag), }, { - Name: "rotate", - Usage: "Rotate secrets encryption keys", - SkipArgReorder: true, - Action: rotate, - Flags: append(EncryptFlags, forceFlag), + Name: "rotate", + Usage: "Rotate secrets encryption keys", + Action: rotate, + Flags: append(EncryptFlags, forceFlag), }, { - Name: "reencrypt", - Usage: "Reencrypt all data with new encryption key", - SkipArgReorder: true, - Action: reencrypt, + Name: "reencrypt", + Usage: "Reencrypt all data with new encryption key", + Action: reencrypt, Flags: append(EncryptFlags, forceFlag, &cli.BoolFlag{ @@ -85,11 +81,10 @@ func NewSecretsEncryptCommands(status, enable, disable, prepare, rotate, reencry }), }, { - Name: "rotate-keys", - Usage: "(experimental) Dynamically rotates secrets encryption keys and re-encrypt secrets", - SkipArgReorder: true, - Action: rotateKeys, - Flags: EncryptFlags, + Name: "rotate-keys", + Usage: "(experimental) Dynamically rotates secrets encryption keys and re-encrypt secrets", + Action: rotateKeys, + Flags: EncryptFlags, }, }, } diff --git a/pkg/cli/cmds/server.go b/pkg/cli/cmds/server.go index 37fcb131ced..84b8a1816de 100644 --- a/pkg/cli/cmds/server.go +++ b/pkg/cli/cmds/server.go @@ -6,7 +6,7 @@ import ( "time" "github.com/k3s-io/k3s/pkg/version" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) const ( @@ -116,26 +116,28 @@ type Server struct { var ( ServerConfig Server DataDirFlag = &cli.StringFlag{ - Name: "data-dir,d", + Name: "data-dir", + Aliases: []string{"d"}, Usage: "(data) Folder to hold state default /var/lib/rancher/" + version.Program + " or ${HOME}/.rancher/" + version.Program + " if not root", Destination: &ServerConfig.DataDir, - EnvVar: version.ProgramUpper + "_DATA_DIR", + EnvVars: []string{version.ProgramUpper + "_DATA_DIR"}, } ServerToken = &cli.StringFlag{ - Name: "token,t", + Name: "token", + Aliases: []string{"t"}, Usage: "(cluster) Shared secret used to join a server or agent to a cluster", Destination: &ServerConfig.Token, - EnvVar: version.ProgramUpper + "_TOKEN", + EnvVars: []string{version.ProgramUpper + "_TOKEN"}, } ClusterCIDR = &cli.StringSliceFlag{ - Name: "cluster-cidr", - Usage: "(networking) IPv4/IPv6 network CIDRs to use for pod IPs (default: 10.42.0.0/16)", - Value: &ServerConfig.ClusterCIDR, + Name: "cluster-cidr", + Usage: "(networking) IPv4/IPv6 network CIDRs to use for pod IPs (default: 10.42.0.0/16)", + Destination: &ServerConfig.ClusterCIDR, } ServiceCIDR = &cli.StringSliceFlag{ - Name: "service-cidr", - Usage: "(networking) IPv4/IPv6 network CIDRs to use for service IPs (default: 10.43.0.0/16)", - Value: &ServerConfig.ServiceCIDR, + Name: "service-cidr", + Usage: "(networking) IPv4/IPv6 network CIDRs to use for service IPs (default: 10.43.0.0/16)", + Destination: &ServerConfig.ServiceCIDR, } ServiceNodePortRange = &cli.StringFlag{ Name: "service-node-port-range", @@ -144,9 +146,9 @@ var ( Value: "30000-32767", } ClusterDNS = &cli.StringSliceFlag{ - Name: "cluster-dns", - Usage: "(networking) IPv4/IPv6 Cluster IP for coredns service. Should be in your service-cidr range (default: 10.43.0.10)", - Value: &ServerConfig.ClusterDNS, + Name: "cluster-dns", + Usage: "(networking) IPv4/IPv6 Cluster IP for coredns service. Should be in your service-cidr range (default: 10.43.0.10)", + Destination: &ServerConfig.ClusterDNS, } ClusterDomain = &cli.StringFlag{ Name: "cluster-domain", @@ -155,24 +157,24 @@ var ( Value: "cluster.local", } ExtraAPIArgs = &cli.StringSliceFlag{ - Name: "kube-apiserver-arg", - Usage: "(flags) Customized flag for kube-apiserver process", - Value: &ServerConfig.ExtraAPIArgs, + Name: "kube-apiserver-arg", + Usage: "(flags) Customized flag for kube-apiserver process", + Destination: &ServerConfig.ExtraAPIArgs, } ExtraEtcdArgs = &cli.StringSliceFlag{ - Name: "etcd-arg", - Usage: "(flags) Customized flag for etcd process", - Value: &ServerConfig.ExtraEtcdArgs, + Name: "etcd-arg", + Usage: "(flags) Customized flag for etcd process", + Destination: &ServerConfig.ExtraEtcdArgs, } ExtraSchedulerArgs = &cli.StringSliceFlag{ - Name: "kube-scheduler-arg", - Usage: "(flags) Customized flag for kube-scheduler process", - Value: &ServerConfig.ExtraSchedulerArgs, + Name: "kube-scheduler-arg", + Usage: "(flags) Customized flag for kube-scheduler process", + Destination: &ServerConfig.ExtraSchedulerArgs, } ExtraControllerArgs = &cli.StringSliceFlag{ - Name: "kube-controller-manager-arg", - Usage: "(flags) Customized flag for kube-controller-manager process", - Value: &ServerConfig.ExtraControllerArgs, + Name: "kube-controller-manager-arg", + Usage: "(flags) Customized flag for kube-controller-manager process", + Destination: &ServerConfig.ExtraControllerArgs, } ) @@ -192,21 +194,21 @@ var ServerFlags = []cli.Flag{ }, &cli.IntFlag{ Name: "supervisor-port", - EnvVar: version.ProgramUpper + "_SUPERVISOR_PORT", + EnvVars: []string{version.ProgramUpper + "_SUPERVISOR_PORT"}, Usage: "(experimental) Supervisor listen port override", Hidden: true, Destination: &ServerConfig.SupervisorPort, }, &cli.IntFlag{ Name: "apiserver-port", - EnvVar: version.ProgramUpper + "_APISERVER_PORT", + EnvVars: []string{version.ProgramUpper + "_APISERVER_PORT"}, Usage: "(experimental) apiserver internal listen port override", Hidden: true, Destination: &ServerConfig.APIServerPort, }, &cli.StringFlag{ Name: "apiserver-bind-address", - EnvVar: version.ProgramUpper + "_APISERVER_BIND_ADDRESS", + EnvVars: []string{version.ProgramUpper + "_APISERVER_BIND_ADDRESS"}, Usage: "(experimental) apiserver internal bind address override", Hidden: true, Destination: &ServerConfig.APIServerBindAddress, @@ -222,14 +224,15 @@ var ServerFlags = []cli.Flag{ Destination: &ServerConfig.AdvertisePort, }, &cli.StringSliceFlag{ - Name: "tls-san", - Usage: "(listener) Add additional hostnames or IPv4/IPv6 addresses as Subject Alternative Names on the server TLS cert", - Value: &ServerConfig.TLSSan, + Name: "tls-san", + Usage: "(listener) Add additional hostnames or IPv4/IPv6 addresses as Subject Alternative Names on the server TLS cert", + Destination: &ServerConfig.TLSSan, }, - &cli.BoolTFlag{ + &cli.BoolFlag{ Name: "tls-san-security", Usage: "(listener) Protect the server TLS cert by refusing to add Subject Alternative Names not associated with the kubernetes apiserver service, server nodes, or values of the tls-san option (default: true)", Destination: &ServerConfig.TLSSanSecurity, + Value: true, }, DataDirFlag, ClusterCIDR, @@ -266,22 +269,23 @@ var ServerFlags = []cli.Flag{ Value: "kube-system", }, &cli.StringFlag{ - Name: "write-kubeconfig,o", + Name: "write-kubeconfig", + Aliases: []string{"o"}, Usage: "(client) Write kubeconfig for admin client to this file", Destination: &ServerConfig.KubeConfigOutput, - EnvVar: version.ProgramUpper + "_KUBECONFIG_OUTPUT", + EnvVars: []string{version.ProgramUpper + "_KUBECONFIG_OUTPUT"}, }, &cli.StringFlag{ Name: "write-kubeconfig-mode", Usage: "(client) Write kubeconfig with this mode", Destination: &ServerConfig.KubeConfigMode, - EnvVar: version.ProgramUpper + "_KUBECONFIG_MODE", + EnvVars: []string{version.ProgramUpper + "_KUBECONFIG_MODE"}, }, &cli.StringFlag{ Name: "write-kubeconfig-group", Usage: "(client) Write kubeconfig with this group", Destination: &ServerConfig.KubeConfigGroup, - EnvVar: version.ProgramUpper + "_KUBECONFIG_GROUP", + EnvVars: []string{version.ProgramUpper + "_KUBECONFIG_GROUP"}, }, &cli.StringFlag{ Name: "helm-job-image", @@ -293,36 +297,37 @@ var ServerFlags = []cli.Flag{ Name: "token-file", Usage: "(cluster) File containing the token", Destination: &ServerConfig.TokenFile, - EnvVar: version.ProgramUpper + "_TOKEN_FILE", + EnvVars: []string{version.ProgramUpper + "_TOKEN_FILE"}, }, &cli.StringFlag{ Name: "agent-token", Usage: "(cluster) Shared secret used to join agents to the cluster, but not servers", Destination: &ServerConfig.AgentToken, - EnvVar: version.ProgramUpper + "_AGENT_TOKEN", + EnvVars: []string{version.ProgramUpper + "_AGENT_TOKEN"}, }, &cli.StringFlag{ Name: "agent-token-file", Usage: "(cluster) File containing the agent secret", Destination: &ServerConfig.AgentTokenFile, - EnvVar: version.ProgramUpper + "_AGENT_TOKEN_FILE", + EnvVars: []string{version.ProgramUpper + "_AGENT_TOKEN_FILE"}, }, &cli.StringFlag{ - Name: "server,s", + Name: "server", + Aliases: []string{"s"}, Usage: "(cluster) Server to connect to, used to join a cluster", - EnvVar: version.ProgramUpper + "_URL", + EnvVars: []string{version.ProgramUpper + "_URL"}, Destination: &ServerConfig.ServerURL, }, &cli.BoolFlag{ Name: "cluster-init", Usage: "(cluster) Initialize a new cluster using embedded Etcd", - EnvVar: version.ProgramUpper + "_CLUSTER_INIT", + EnvVars: []string{version.ProgramUpper + "_CLUSTER_INIT"}, Destination: &ServerConfig.ClusterInit, }, &cli.BoolFlag{ Name: "cluster-reset", Usage: "(cluster) Forget all peers and become sole member of a new cluster", - EnvVar: version.ProgramUpper + "_CLUSTER_RESET", + EnvVars: []string{version.ProgramUpper + "_CLUSTER_RESET"}, Destination: &ServerConfig.ClusterReset, }, &cli.StringFlag{ @@ -335,9 +340,9 @@ var ServerFlags = []cli.Flag{ ExtraControllerArgs, ExtraSchedulerArgs, &cli.StringSliceFlag{ - Name: "kube-cloud-controller-manager-arg", - Usage: "(flags) Customized flag for kube-cloud-controller-manager process", - Value: &ServerConfig.ExtraCloudControllerArgs, + Name: "kube-cloud-controller-manager-arg", + Usage: "(flags) Customized flag for kube-cloud-controller-manager process", + Destination: &ServerConfig.ExtraCloudControllerArgs, }, &cli.BoolFlag{ Name: "kine-tls", @@ -349,25 +354,25 @@ var ServerFlags = []cli.Flag{ Name: "datastore-endpoint", Usage: "(db) Specify etcd, NATS, MySQL, Postgres, or SQLite (default) data source name", Destination: &ServerConfig.DatastoreEndpoint, - EnvVar: version.ProgramUpper + "_DATASTORE_ENDPOINT", + EnvVars: []string{version.ProgramUpper + "_DATASTORE_ENDPOINT"}, }, &cli.StringFlag{ Name: "datastore-cafile", Usage: "(db) TLS Certificate Authority file used to secure datastore backend communication", Destination: &ServerConfig.DatastoreCAFile, - EnvVar: version.ProgramUpper + "_DATASTORE_CAFILE", + EnvVars: []string{version.ProgramUpper + "_DATASTORE_CAFILE"}, }, &cli.StringFlag{ Name: "datastore-certfile", Usage: "(db) TLS certification file used to secure datastore backend communication", Destination: &ServerConfig.DatastoreCertFile, - EnvVar: version.ProgramUpper + "_DATASTORE_CERTFILE", + EnvVars: []string{version.ProgramUpper + "_DATASTORE_CERTFILE"}, }, &cli.StringFlag{ Name: "datastore-keyfile", Usage: "(db) TLS key file used to secure datastore backend communication", Destination: &ServerConfig.DatastoreKeyFile, - EnvVar: version.ProgramUpper + "_DATASTORE_KEYFILE", + EnvVars: []string{version.ProgramUpper + "_DATASTORE_KEYFILE"}, }, &cli.BoolFlag{ Name: "etcd-expose-metrics", @@ -437,19 +442,19 @@ var ServerFlags = []cli.Flag{ &cli.StringFlag{ Name: "etcd-s3-access-key", Usage: "(db) S3 access key", - EnvVar: "AWS_ACCESS_KEY_ID", + EnvVars: []string{"AWS_ACCESS_KEY_ID"}, Destination: &ServerConfig.EtcdS3AccessKey, }, &cli.StringFlag{ Name: "etcd-s3-secret-key", Usage: "(db) S3 secret key", - EnvVar: "AWS_SECRET_ACCESS_KEY", + EnvVars: []string{"AWS_SECRET_ACCESS_KEY"}, Destination: &ServerConfig.EtcdS3SecretKey, }, &cli.StringFlag{ Name: "etcd-s3-session-token", Usage: "(db) S3 session token", - EnvVar: "AWS_SESSION_TOKEN", + EnvVars: []string{"AWS_SESSION_TOKEN"}, Destination: &ServerConfig.EtcdS3SessionToken, }, &cli.StringFlag{ @@ -569,7 +574,7 @@ var ServerFlags = []cli.Flag{ &cli.StringFlag{ Name: "system-default-registry", Usage: "(agent/runtime) Private registry to be used for all system images", - EnvVar: version.ProgramUpper + "_SYSTEM_DEFAULT_REGISTRY", + EnvVars: []string{version.ProgramUpper + "_SYSTEM_DEFAULT_REGISTRY"}, Destination: &ServerConfig.SystemDefaultRegistry, }, AirgapExtraRegistryFlag, @@ -611,21 +616,21 @@ var ServerFlags = []cli.Flag{ Destination: &ServerConfig.DisableAgent, }, &cli.StringSliceFlag{ - Hidden: true, - Name: "kube-controller-arg", - Usage: "(flags) Customized flag for kube-controller-manager process", - Value: &ServerConfig.ExtraControllerArgs, + Hidden: true, + Name: "kube-controller-arg", + Usage: "(flags) Customized flag for kube-controller-manager process", + Destination: &ServerConfig.ExtraControllerArgs, }, &cli.StringSliceFlag{ - Hidden: true, - Name: "kube-cloud-controller-arg", - Usage: "(flags) Customized flag for kube-cloud-controller-manager process", - Value: &ServerConfig.ExtraCloudControllerArgs, + Hidden: true, + Name: "kube-cloud-controller-arg", + Usage: "(flags) Customized flag for kube-cloud-controller-manager process", + Destination: &ServerConfig.ExtraCloudControllerArgs, }, } -func NewServerCommand(action func(*cli.Context) error) cli.Command { - return cli.Command{ +func NewServerCommand(action func(*cli.Context) error) *cli.Command { + return &cli.Command{ Name: "server", Usage: "Run management server", UsageText: appName + " server [OPTIONS]", diff --git a/pkg/cli/cmds/token.go b/pkg/cli/cmds/token.go index 3e671cac58a..a0ace8e6338 100644 --- a/pkg/cli/cmds/token.go +++ b/pkg/cli/cmds/token.go @@ -4,7 +4,7 @@ import ( "time" "github.com/k3s-io/k3s/pkg/version" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) const TokenCommand = "token" @@ -26,22 +26,21 @@ var ( TokenConfig = Token{} TokenFlags = []cli.Flag{ DataDirFlag, - cli.StringFlag{ + &cli.StringFlag{ Name: "kubeconfig", Usage: "(cluster) Server to connect to", - EnvVar: "KUBECONFIG", + EnvVars: []string{"KUBECONFIG"}, Destination: &TokenConfig.Kubeconfig, }, } ) -func NewTokenCommands(create, delete, generate, list, rotate func(ctx *cli.Context) error) cli.Command { - return cli.Command{ +func NewTokenCommands(create, delete, generate, list, rotate func(ctx *cli.Context) error) *cli.Command { + return &cli.Command{ Name: TokenCommand, Usage: "Manage tokens", SkipFlagParsing: false, - SkipArgReorder: true, - Subcommands: []cli.Command{ + Subcommands: []*cli.Command{ { Name: "create", Usage: "Create bootstrap tokens on the server", @@ -50,21 +49,20 @@ func NewTokenCommands(create, delete, generate, list, rotate func(ctx *cli.Conte Usage: "A human friendly description of how this token is used", Destination: &TokenConfig.Description, }, &cli.StringSliceFlag{ - Name: "groups", - Usage: "Extra groups that this token will authenticate as when used for authentication", - Value: &TokenConfig.Groups, + Name: "groups", + Usage: "Extra groups that this token will authenticate as when used for authentication", + Destination: &TokenConfig.Groups, }, &cli.DurationFlag{ Name: "ttl", Usage: "The duration before the token is automatically deleted (e.g. 1s, 2m, 3h). If set to '0', the token will never expire", Value: time.Hour * 24, Destination: &TokenConfig.TTL, }, &cli.StringSliceFlag{ - Name: "usages", - Usage: "Describes the ways in which this token can be used.", - Value: &TokenConfig.Usages, + Name: "usages", + Usage: "Describes the ways in which this token can be used.", + Destination: &TokenConfig.Usages, }), SkipFlagParsing: false, - SkipArgReorder: true, Action: create, }, { @@ -72,7 +70,6 @@ func NewTokenCommands(create, delete, generate, list, rotate func(ctx *cli.Conte Usage: "Delete bootstrap tokens on the server", Flags: TokenFlags, SkipFlagParsing: false, - SkipArgReorder: true, Action: delete, }, { @@ -80,19 +77,18 @@ func NewTokenCommands(create, delete, generate, list, rotate func(ctx *cli.Conte Usage: "Generate and print a bootstrap token, but do not create it on the server", Flags: TokenFlags, SkipFlagParsing: false, - SkipArgReorder: true, Action: generate, }, { Name: "list", Usage: "List bootstrap tokens on the server", Flags: append(TokenFlags, &cli.StringFlag{ - Name: "output,o", + Name: "output", + Aliases: []string{"o"}, Value: "text", Destination: &TokenConfig.Output, }), SkipFlagParsing: false, - SkipArgReorder: true, Action: list, }, { @@ -100,16 +96,18 @@ func NewTokenCommands(create, delete, generate, list, rotate func(ctx *cli.Conte Usage: "Rotate original server token with a new server token", Flags: append(TokenFlags, &cli.StringFlag{ - Name: "token,t", + Name: "token", + Aliases: []string{"t"}, Usage: "Existing token used to join a server or agent to a cluster", Destination: &TokenConfig.Token, - EnvVar: version.ProgramUpper + "_TOKEN", + EnvVars: []string{version.ProgramUpper + "_TOKEN"}, }, &cli.StringFlag{ - Name: "server, s", + Name: "server", + Aliases: []string{"s"}, Usage: "(cluster) Server to connect to", Destination: &TokenConfig.ServerURL, - EnvVar: version.ProgramUpper + "_URL", + EnvVars: []string{version.ProgramUpper + "_URL"}, Value: "https://127.0.0.1:6443", }, &cli.StringFlag{ @@ -118,7 +116,6 @@ func NewTokenCommands(create, delete, generate, list, rotate func(ctx *cli.Conte Destination: &TokenConfig.NewToken, }), SkipFlagParsing: false, - SkipArgReorder: true, Action: rotate, }, }, diff --git a/pkg/cli/completion/completion.go b/pkg/cli/completion/completion.go index 29e54158a45..6c1d482a77b 100644 --- a/pkg/cli/completion/completion.go +++ b/pkg/cli/completion/completion.go @@ -6,14 +6,14 @@ import ( "github.com/k3s-io/k3s/pkg/version" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) func Run(ctx *cli.Context) error { if ctx.NArg() < 1 { return fmt.Errorf("must provide a valid SHELL argument") } - shell := ctx.Args()[0] + shell := ctx.Args().Get(0) completetionScript, err := genCompletionScript(shell) if err != nil { return err diff --git a/pkg/cli/crictl/crictl.go b/pkg/cli/crictl/crictl.go index de0f7a56eba..635baf700e8 100644 --- a/pkg/cli/crictl/crictl.go +++ b/pkg/cli/crictl/crictl.go @@ -4,7 +4,7 @@ import ( "os" "runtime" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" "sigs.k8s.io/cri-tools/cmd/crictl" ) diff --git a/pkg/cli/ctr/ctr.go b/pkg/cli/ctr/ctr.go index 63ae8bad2c2..1b90120f519 100644 --- a/pkg/cli/ctr/ctr.go +++ b/pkg/cli/ctr/ctr.go @@ -2,7 +2,7 @@ package ctr import ( "github.com/k3s-io/k3s/pkg/ctr" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) func Run(ctx *cli.Context) error { diff --git a/pkg/cli/etcdsnapshot/etcd_snapshot.go b/pkg/cli/etcdsnapshot/etcd_snapshot.go index 140c91dc5fd..eaad5e3e0b4 100644 --- a/pkg/cli/etcdsnapshot/etcd_snapshot.go +++ b/pkg/cli/etcdsnapshot/etcd_snapshot.go @@ -24,7 +24,7 @@ import ( util2 "github.com/k3s-io/k3s/pkg/util" pkgerrors "github.com/pkg/errors" "github.com/sirupsen/logrus" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/cli-runtime/pkg/printers" ) @@ -105,7 +105,7 @@ func Save(app *cli.Context) error { } func save(app *cli.Context, cfg *cmds.Server) error { - if len(app.Args()) > 0 { + if app.Args().Len() > 0 { return util2.ErrCommandNoArgs } @@ -150,7 +150,7 @@ func Delete(app *cli.Context) error { func delete(app *cli.Context, cfg *cmds.Server) error { snapshots := app.Args() - if len(snapshots) == 0 { + if snapshots.Len() == 0 { return errors.New("no snapshots given for removal") } @@ -160,7 +160,7 @@ func delete(app *cli.Context, cfg *cmds.Server) error { } sr.Operation = etcd.SnapshotOperationDelete - sr.Name = snapshots + sr.Name = snapshots.Slice() b, err := json.Marshal(sr) if err != nil { @@ -178,7 +178,7 @@ func delete(app *cli.Context, cfg *cmds.Server) error { for _, name := range resp.Deleted { logrus.Infof("Snapshot %s deleted.", name) } - for _, name := range snapshots { + for _, name := range snapshots.Slice() { if !slices.Contains(resp.Deleted, name) { logrus.Warnf("Snapshot %s not found.", name) } diff --git a/pkg/cli/kubectl/kubectl.go b/pkg/cli/kubectl/kubectl.go index c21ae769928..3d813b9967b 100644 --- a/pkg/cli/kubectl/kubectl.go +++ b/pkg/cli/kubectl/kubectl.go @@ -2,7 +2,7 @@ package kubectl import ( "github.com/k3s-io/k3s/pkg/kubectl" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) func Run(ctx *cli.Context) error { diff --git a/pkg/cli/secretsencrypt/secrets_encrypt.go b/pkg/cli/secretsencrypt/secrets_encrypt.go index c9832f04e23..930344f5692 100644 --- a/pkg/cli/secretsencrypt/secrets_encrypt.go +++ b/pkg/cli/secretsencrypt/secrets_encrypt.go @@ -18,7 +18,7 @@ import ( "github.com/k3s-io/k3s/pkg/server/handlers" "github.com/k3s-io/k3s/pkg/version" pkgerrors "github.com/pkg/errors" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" "k8s.io/utils/ptr" ) diff --git a/pkg/cli/server/server.go b/pkg/cli/server/server.go index 5d6af3aea07..f54c49d3f99 100644 --- a/pkg/cli/server/server.go +++ b/pkg/cli/server/server.go @@ -33,7 +33,7 @@ import ( pkgerrors "github.com/pkg/errors" "github.com/rancher/wrangler/v3/pkg/signals" "github.com/sirupsen/logrus" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" etcdversion "go.etcd.io/etcd/api/v3/version" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" utilnet "k8s.io/apimachinery/pkg/util/net" @@ -87,7 +87,7 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont } cfg.DataDir = dataDir if !cfg.DisableAgent { - dualNode, err := utilsnet.IsDualStackIPStrings(cmds.AgentConfig.NodeIP) + dualNode, err := utilsnet.IsDualStackIPStrings(cmds.AgentConfig.NodeIP.Value()) if err != nil { return err } @@ -139,17 +139,17 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont serverConfig.ControlConfig.HelmJobImage = cfg.HelmJobImage serverConfig.ControlConfig.Rootless = cfg.Rootless serverConfig.ControlConfig.ServiceLBNamespace = cfg.ServiceLBNamespace - serverConfig.ControlConfig.SANs = util.SplitStringSlice(cfg.TLSSan) + serverConfig.ControlConfig.SANs = util.SplitStringSlice(cfg.TLSSan.Value()) serverConfig.ControlConfig.SANSecurity = cfg.TLSSanSecurity serverConfig.ControlConfig.BindAddress = cmds.AgentConfig.BindAddress serverConfig.ControlConfig.SupervisorPort = cfg.SupervisorPort serverConfig.ControlConfig.HTTPSPort = cfg.HTTPSPort serverConfig.ControlConfig.APIServerPort = cfg.APIServerPort serverConfig.ControlConfig.APIServerBindAddress = cfg.APIServerBindAddress - serverConfig.ControlConfig.ExtraAPIArgs = cfg.ExtraAPIArgs - serverConfig.ControlConfig.ExtraControllerArgs = cfg.ExtraControllerArgs - serverConfig.ControlConfig.ExtraEtcdArgs = cfg.ExtraEtcdArgs - serverConfig.ControlConfig.ExtraSchedulerAPIArgs = cfg.ExtraSchedulerArgs + serverConfig.ControlConfig.ExtraAPIArgs = cfg.ExtraAPIArgs.Value() + serverConfig.ControlConfig.ExtraControllerArgs = cfg.ExtraControllerArgs.Value() + serverConfig.ControlConfig.ExtraEtcdArgs = cfg.ExtraEtcdArgs.Value() + serverConfig.ControlConfig.ExtraSchedulerAPIArgs = cfg.ExtraSchedulerArgs.Value() serverConfig.ControlConfig.ClusterDomain = cfg.ClusterDomain serverConfig.ControlConfig.Datastore.NotifyInterval = 5 * time.Second serverConfig.ControlConfig.Datastore.EmulatedETCDVersion = etcdversion.Version @@ -164,7 +164,7 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont serverConfig.ControlConfig.FlannelIPv6Masq = cfg.FlannelIPv6Masq serverConfig.ControlConfig.FlannelExternalIP = cfg.FlannelExternalIP serverConfig.ControlConfig.EgressSelectorMode = cfg.EgressSelectorMode - serverConfig.ControlConfig.ExtraCloudControllerArgs = cfg.ExtraCloudControllerArgs + serverConfig.ControlConfig.ExtraCloudControllerArgs = cfg.ExtraCloudControllerArgs.Value() serverConfig.ControlConfig.DisableCCM = cfg.DisableCCM serverConfig.ControlConfig.DisableNPC = cfg.DisableNPC serverConfig.ControlConfig.DisableHelmController = cfg.DisableHelmController @@ -251,7 +251,7 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont } } - if cmds.AgentConfig.FlannelIface != "" && len(cmds.AgentConfig.NodeIP) == 0 { + if cmds.AgentConfig.FlannelIface != "" && len(cmds.AgentConfig.NodeIP.Value()) == 0 { ip, err := util.GetIPFromInterface(cmds.AgentConfig.FlannelIface) if err != nil { return err @@ -259,14 +259,14 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont cmds.AgentConfig.NodeIP.Set(ip) } - if serverConfig.ControlConfig.PrivateIP == "" && len(cmds.AgentConfig.NodeIP) != 0 { - serverConfig.ControlConfig.PrivateIP = util.GetFirstValidIPString(cmds.AgentConfig.NodeIP) + if serverConfig.ControlConfig.PrivateIP == "" && len(cmds.AgentConfig.NodeIP.Value()) != 0 { + serverConfig.ControlConfig.PrivateIP = util.GetFirstValidIPString(cmds.AgentConfig.NodeIP.Value()) } // Ensure that we add the localhost name/ip and node name/ip to the SAN list. This list is shared by the // certs for the supervisor, kube-apiserver cert, and etcd. DNS entries for the in-cluster kubernetes // service endpoint are added later when the certificates are created. - nodeName, nodeIPs, err := util.GetHostnameAndIPs(cmds.AgentConfig.NodeName, cmds.AgentConfig.NodeIP) + nodeName, nodeIPs, err := util.GetHostnameAndIPs(cmds.AgentConfig.NodeName, cmds.AgentConfig.NodeIP.Value()) if err != nil { return err } @@ -310,13 +310,13 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont } else { // if not set, try setting advertise-ip from agent node-external-ip - if serverConfig.ControlConfig.AdvertiseIP == "" && len(cmds.AgentConfig.NodeExternalIP) != 0 { - serverConfig.ControlConfig.AdvertiseIP = util.GetFirstValidIPString(cmds.AgentConfig.NodeExternalIP) + if serverConfig.ControlConfig.AdvertiseIP == "" && len(cmds.AgentConfig.NodeExternalIP.Value()) != 0 { + serverConfig.ControlConfig.AdvertiseIP = util.GetFirstValidIPString(cmds.AgentConfig.NodeExternalIP.Value()) } // if not set, try setting advertise-ip from agent node-ip - if serverConfig.ControlConfig.AdvertiseIP == "" && len(cmds.AgentConfig.NodeIP) != 0 { - serverConfig.ControlConfig.AdvertiseIP = util.GetFirstValidIPString(cmds.AgentConfig.NodeIP) + if serverConfig.ControlConfig.AdvertiseIP == "" && len(cmds.AgentConfig.NodeIP.Value()) != 0 { + serverConfig.ControlConfig.AdvertiseIP = util.GetFirstValidIPString(cmds.AgentConfig.NodeIP.Value()) } } @@ -329,10 +329,10 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont // configure ClusterIPRanges. Use default 10.42.0.0/16 or fd00:42::/56 if user did not set it _, defaultClusterCIDR, defaultServiceCIDR, _ := util.GetDefaultAddresses(nodeIPs[0]) - if len(cmds.ServerConfig.ClusterCIDR) == 0 { + if len(cmds.ServerConfig.ClusterCIDR.Value()) == 0 { cmds.ServerConfig.ClusterCIDR.Set(defaultClusterCIDR) } - for _, cidr := range util.SplitStringSlice(cmds.ServerConfig.ClusterCIDR) { + for _, cidr := range util.SplitStringSlice(cmds.ServerConfig.ClusterCIDR.Value()) { _, parsed, err := net.ParseCIDR(cidr) if err != nil { return pkgerrors.WithMessagef(err, "invalid cluster-cidr %s", cidr) @@ -344,10 +344,10 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont serverConfig.ControlConfig.ClusterIPRange = serverConfig.ControlConfig.ClusterIPRanges[0] // configure ServiceIPRanges. Use default 10.43.0.0/16 or fd00:43::/112 if user did not set it - if len(cmds.ServerConfig.ServiceCIDR) == 0 { + if len(cmds.ServerConfig.ServiceCIDR.Value()) == 0 { cmds.ServerConfig.ServiceCIDR.Set(defaultServiceCIDR) } - for _, cidr := range util.SplitStringSlice(cmds.ServerConfig.ServiceCIDR) { + for _, cidr := range util.SplitStringSlice(cmds.ServerConfig.ServiceCIDR.Value()) { _, parsed, err := net.ParseCIDR(cidr) if err != nil { return pkgerrors.WithMessagef(err, "invalid service-cidr %s", cidr) @@ -374,7 +374,7 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont // i.e. when you set service-cidr to 192.168.0.0/16 and don't provide cluster-dns, it will be set to 192.168.0.10 // If there are no IPv4 ServiceCIDRs, an IPv6 ServiceCIDRs will be used. // If neither of IPv4 or IPv6 are found an error is raised. - if len(cmds.ServerConfig.ClusterDNS) == 0 { + if len(cmds.ServerConfig.ClusterDNS.Value()) == 0 { for _, svcCIDR := range serverConfig.ControlConfig.ServiceIPRanges { clusterDNS, err := utilsnet.GetIndexedIP(svcCIDR, 10) if err != nil { @@ -383,7 +383,7 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont serverConfig.ControlConfig.ClusterDNSs = append(serverConfig.ControlConfig.ClusterDNSs, clusterDNS) } } else { - for _, ip := range util.SplitStringSlice(cmds.ServerConfig.ClusterDNS) { + for _, ip := range util.SplitStringSlice(cmds.ServerConfig.ClusterDNS.Value()) { parsed := net.ParseIP(ip) if parsed == nil { return fmt.Errorf("invalid cluster-dns address %s", ip) @@ -543,7 +543,7 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont agentConfig := cmds.AgentConfig agentConfig.ContainerRuntimeReady = containerRuntimeReady - agentConfig.Debug = app.GlobalBool("debug") + agentConfig.Debug = app.Bool("debug") agentConfig.DataDir = filepath.Dir(serverConfig.ControlConfig.DataDir) agentConfig.ServerURL = url agentConfig.Token = token diff --git a/pkg/cli/token/token.go b/pkg/cli/token/token.go index 37dad582cfb..8957a93a928 100644 --- a/pkg/cli/token/token.go +++ b/pkg/cli/token/token.go @@ -21,7 +21,7 @@ import ( "github.com/k3s-io/k3s/pkg/util" "github.com/k3s-io/k3s/pkg/version" pkgerrors "github.com/pkg/errors" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" "gopkg.in/yaml.v2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/fields" @@ -70,8 +70,8 @@ func create(app *cli.Context, cfg *cmds.Token) error { Token: bts, Description: cfg.Description, TTL: &metav1.Duration{Duration: cfg.TTL}, - Usages: cfg.Usages, - Groups: cfg.Groups, + Usages: cfg.Usages.Value(), + Groups: cfg.Groups.Value(), } secretName := bootstraputil.BootstrapTokenSecretName(bt.Token.ID) @@ -102,7 +102,7 @@ func Delete(app *cli.Context) error { func delete(app *cli.Context, cfg *cmds.Token) error { args := app.Args() - if len(args) < 1 { + if args.Len() < 1 { return errors.New("missing argument; 'token delete' is missing token") } @@ -112,7 +112,7 @@ func delete(app *cli.Context, cfg *cmds.Token) error { return err } - for _, token := range args { + for _, token := range args.Slice() { if !bootstraputil.IsValidBootstrapTokenID(token) { bts, err := kubeadm.NewBootstrapTokenString(cfg.Token) if err != nil { diff --git a/pkg/configfilearg/defaultparser.go b/pkg/configfilearg/defaultparser.go index 608857c408c..85a0b558cef 100644 --- a/pkg/configfilearg/defaultparser.go +++ b/pkg/configfilearg/defaultparser.go @@ -7,7 +7,7 @@ import ( "github.com/k3s-io/k3s/pkg/cli/cmds" "github.com/k3s-io/k3s/pkg/version" "github.com/sirupsen/logrus" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) var DefaultParser = &Parser{ diff --git a/pkg/configfilearg/parser.go b/pkg/configfilearg/parser.go index c17a8f184ae..6d86f2c0c71 100644 --- a/pkg/configfilearg/parser.go +++ b/pkg/configfilearg/parser.go @@ -14,7 +14,7 @@ import ( "github.com/k3s-io/k3s/pkg/agent/util" "github.com/rancher/wrangler/v3/pkg/data/convert" "github.com/sirupsen/logrus" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" "gopkg.in/yaml.v2" ) @@ -76,7 +76,7 @@ func (p *Parser) stripInvalidFlags(command string, args []string) ([]string, err validFlags := make(map[string]bool, len(cmdFlags)) for _, f := range cmdFlags { //split flags with aliases into 2 entries - for _, s := range strings.Split(f.GetName(), ",") { + for _, s := range f.Names() { validFlags[s] = true } } diff --git a/pkg/kubeadm/token.go b/pkg/kubeadm/token.go index e42235d5331..ac0641765b3 100644 --- a/pkg/kubeadm/token.go +++ b/pkg/kubeadm/token.go @@ -5,7 +5,7 @@ import ( "github.com/k3s-io/k3s/pkg/cli/cmds" "github.com/k3s-io/k3s/pkg/version" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" bootstrapapi "k8s.io/cluster-bootstrap/token/api" bootstraputil "k8s.io/cluster-bootstrap/token/util" ) @@ -19,11 +19,11 @@ var ( // importing the cluster-bootstrap packages into the CLI. func SetDefaults(clx *cli.Context, cfg *cmds.Token) error { if !clx.IsSet("groups") { - cfg.Groups = []string{NodeBootstrapTokenAuthGroup} + cfg.Groups = *cli.NewStringSlice(NodeBootstrapTokenAuthGroup) } if !clx.IsSet("usages") { - cfg.Usages = bootstrapapi.KnownTokenUsages + cfg.Usages = *cli.NewStringSlice(bootstrapapi.KnownTokenUsages...) } if cfg.Output == "" { @@ -36,9 +36,8 @@ func SetDefaults(clx *cli.Context, cfg *cmds.Token) error { } } - args := clx.Args() - if len(args) > 0 { - cfg.Token = args[0] + if clx.Args().Len() > 0 { + cfg.Token = clx.Args().Get(0) } if cfg.Token == "" { diff --git a/pkg/util/client.go b/pkg/util/client.go index a7ca9fe26b6..b39e5a7152c 100644 --- a/pkg/util/client.go +++ b/pkg/util/client.go @@ -63,8 +63,11 @@ func GetUserAgent(controllerName string) string { } // SplitStringSlice is a helper function to handle StringSliceFlag containing multiple values -// By default, StringSliceFlag only supports repeated values, not multiple values +// By default, StringSliceFlag supports repeated values, and multiple values, seperated by a comma // e.g. --foo="bar,car" --foo=baz will result in []string{"bar", "car". "baz"} +// However, we disable this with urfave/cli/v2, as controls are not granular enough. You can either have all flags +// support comma separated values, or no flags. We can't have all flags support comma separated values +// because our kube-XXX-arg flags need to pass the value "as is" to the kubelet/kube-apiserver etc. func SplitStringSlice(ss []string) []string { result := []string{} for _, s := range ss { diff --git a/pkg/util/client_test.go b/pkg/util/client_test.go index 7559fb76d97..6ebf00d5e60 100644 --- a/pkg/util/client_test.go +++ b/pkg/util/client_test.go @@ -4,34 +4,34 @@ import ( "reflect" "testing" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) func Test_UnitSplitSliceString(t *testing.T) { tests := []struct { name string - arg cli.StringSlice + arg *cli.StringSlice want []string }{ { name: "Single Argument", - arg: cli.StringSlice{"foo"}, + arg: cli.NewStringSlice("foo"), want: []string{"foo"}, }, { name: "Repeated Arguments", - arg: cli.StringSlice{"foo", "bar", "baz"}, + arg: cli.NewStringSlice("foo", "bar", "baz"), want: []string{"foo", "bar", "baz"}, }, { name: "Multiple Arguments and Repeated Arguments", - arg: cli.StringSlice{"foo,bar", "zoo,clar", "baz"}, + arg: cli.NewStringSlice("foo,bar", "zoo,clar", "baz"), want: []string{"foo", "bar", "zoo", "clar", "baz"}, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := SplitStringSlice(tt.arg); !reflect.DeepEqual(got, tt.want) { + if got := SplitStringSlice(tt.arg.Value()); !reflect.DeepEqual(got, tt.want) { t.Errorf("SplitSliceString() = %+v\nWant = %+v", got, tt.want) } }) diff --git a/pkg/util/net.go b/pkg/util/net.go index 76304c584a7..05fd2180b15 100644 --- a/pkg/util/net.go +++ b/pkg/util/net.go @@ -11,7 +11,6 @@ import ( "github.com/rancher/wrangler/v3/pkg/merr" "github.com/sirupsen/logrus" - "github.com/urfave/cli" apinet "k8s.io/apimachinery/pkg/util/net" netutils "k8s.io/utils/net" ) @@ -137,7 +136,7 @@ func JoinIP6Nets(elems []*net.IPNet) string { // GetHostnameAndIPs takes a node name and list of IPs, usually from CLI args. // If set, these are used to return the node's name and addresses. If not set, // the system hostname and primary interface addresses are returned instead. -func GetHostnameAndIPs(name string, nodeIPs cli.StringSlice) (string, []net.IP, error) { +func GetHostnameAndIPs(name string, nodeIPs []string) (string, []net.IP, error) { ips := []net.IP{} if len(nodeIPs) == 0 { hostIP, err := apinet.ChooseHostInterface() @@ -177,7 +176,7 @@ func GetHostnameAndIPs(name string, nodeIPs cli.StringSlice) (string, []net.IP, // ParseStringSliceToIPs converts slice of strings that in turn can be lists of comma separated unparsed IP addresses // into a single slice of net.IP, it returns error if at any point parsing failed -func ParseStringSliceToIPs(s cli.StringSlice) ([]net.IP, error) { +func ParseStringSliceToIPs(s []string) ([]net.IP, error) { var ips []net.IP for _, unparsedIP := range s { for _, v := range strings.Split(unparsedIP, ",") { @@ -194,7 +193,7 @@ func ParseStringSliceToIPs(s cli.StringSlice) ([]net.IP, error) { // GetFirstValidIPString returns the first valid address from a list of IP address strings, // without preference for IP family. If no address are found, an empty string is returned. -func GetFirstValidIPString(s cli.StringSlice) string { +func GetFirstValidIPString(s []string) string { for _, unparsedIP := range s { for _, v := range strings.Split(unparsedIP, ",") { if ip := net.ParseIP(v); ip != nil { diff --git a/pkg/util/net_test.go b/pkg/util/net_test.go index aee482ffd9f..ee81ca3ef87 100644 --- a/pkg/util/net_test.go +++ b/pkg/util/net_test.go @@ -4,14 +4,12 @@ import ( "net" "reflect" "testing" - - "github.com/urfave/cli" ) func Test_UnitParseStringSliceToIPs(t *testing.T) { tests := []struct { name string - arg cli.StringSlice + arg []string want []net.IP wantErr bool }{ @@ -22,17 +20,17 @@ func Test_UnitParseStringSliceToIPs(t *testing.T) { }, { name: "empty string slice must return no errors", - arg: cli.StringSlice{}, + arg: []string{}, want: nil, }, { name: "single element slice with correct IP must succeed", - arg: cli.StringSlice{"10.10.10.10"}, + arg: []string{"10.10.10.10"}, want: []net.IP{net.ParseIP("10.10.10.10")}, }, { name: "single element slice with correct IP list must succeed", - arg: cli.StringSlice{"10.10.10.10,10.10.10.11"}, + arg: []string{"10.10.10.10,10.10.10.11"}, want: []net.IP{ net.ParseIP("10.10.10.10"), net.ParseIP("10.10.10.11"), @@ -40,7 +38,7 @@ func Test_UnitParseStringSliceToIPs(t *testing.T) { }, { name: "multi element slice with correct IP list must succeed", - arg: cli.StringSlice{"10.10.10.10,10.10.10.11", "10.10.10.12,10.10.10.13"}, + arg: []string{"10.10.10.10,10.10.10.11", "10.10.10.12,10.10.10.13"}, want: []net.IP{ net.ParseIP("10.10.10.10"), net.ParseIP("10.10.10.11"), @@ -50,19 +48,19 @@ func Test_UnitParseStringSliceToIPs(t *testing.T) { }, { name: "single element slice with correct IP list with trailing comma must fail", - arg: cli.StringSlice{"10.10.10.10,"}, + arg: []string{"10.10.10.10,"}, want: nil, wantErr: true, }, { name: "single element slice with incorrect IP (overflow) must fail", - arg: cli.StringSlice{"10.10.10.256"}, + arg: []string{"10.10.10.256"}, want: nil, wantErr: true, }, { name: "single element slice with incorrect IP (foreign symbols) must fail", - arg: cli.StringSlice{"xxx.yyy.zzz.www"}, + arg: []string{"xxx.yyy.zzz.www"}, want: nil, wantErr: true, },