From b3b13fce86431d69fb46ae02c5d1dc6deccac4ab Mon Sep 17 00:00:00 2001 From: naison <895703375@qq.com> Date: Mon, 4 Aug 2025 23:00:38 +0800 Subject: [PATCH] refactor: rename cmd dev to run (#684) * refactor: code * refactor: optimize code --- README.md | 28 ++++++---------- README_ZH.md | 28 ++++++---------- cmd/kubevpn/cmds/connect.go | 2 +- cmd/kubevpn/cmds/connection.go | 3 -- cmd/kubevpn/cmds/proxy.go | 15 +++++---- cmd/kubevpn/cmds/root.go | 3 +- cmd/kubevpn/cmds/{dev.go => run.go} | 50 ++++++++++++++--------------- cmd/kubevpn/cmds/sync.go | 11 ++++--- pkg/core/gvisorlocaltcpforwarder.go | 5 ++- pkg/core/gvisorlocaltcphandler.go | 8 ++--- pkg/core/gvisorlocaltunendpoint.go | 2 +- pkg/core/gvisorlocaludpforwarder.go | 5 ++- pkg/core/gvisortcpforwarder.go | 9 +++++- pkg/core/gvisortunendpoint.go | 2 +- pkg/core/gvisorudpforwarder.go | 10 +++++- pkg/core/gvisorudphandler.go | 17 +++++++--- pkg/{dev => run}/docker_opts.go | 2 +- pkg/{dev => run}/docker_utils.go | 2 +- pkg/{dev => run}/options.go | 8 ++--- pkg/{dev => run}/runconfig.go | 2 +- pkg/util/unstructure.go | 2 -- 21 files changed, 110 insertions(+), 104 deletions(-) rename cmd/kubevpn/cmds/{dev.go => run.go} (76%) rename pkg/{dev => run}/docker_opts.go (99%) rename pkg/{dev => run}/docker_utils.go (98%) rename pkg/{dev => run}/options.go (98%) rename pkg/{dev => run}/runconfig.go (99%) diff --git a/README.md b/README.md index bb7cced0..41a9782e 100644 --- a/README.md +++ b/README.md @@ -137,9 +137,7 @@ Forwarding port... Connected tunnel Adding route... Configured DNS service -+----------------------------------------------------------+ -| Now you can access resources in the kubernetes cluster ! | -+----------------------------------------------------------+ +Now you can access resources in the kubernetes cluster ! ➜ ~ ``` @@ -270,9 +268,7 @@ Forwarding port... Connected tunnel Adding route... Configured DNS service -+----------------------------------------------------------+ -| Now you can access resources in the kubernetes cluster ! | -+----------------------------------------------------------+ +Now you can access resources in the kubernetes cluster ! ``` use command `kubevpn status` to check connection status @@ -297,9 +293,7 @@ Checking rollout status for deployment/productpage Waiting for deployment "productpage" rollout to finish: 1 old replicas are pending termination... Waiting for deployment "productpage" rollout to finish: 1 old replicas are pending termination... Rollout successfully for deployment/productpage -+----------------------------------------------------------+ -| Now you can access resources in the kubernetes cluster ! | -+----------------------------------------------------------+ +Now you can access resources in the kubernetes cluster ! ➜ ~ ``` @@ -398,9 +392,7 @@ Checking rollout status for deployment/productpage Waiting for deployment "productpage" rollout to finish: 1 old replicas are pending termination... Waiting for deployment "productpage" rollout to finish: 1 old replicas are pending termination... Rollout successfully for deployment/productpage -+----------------------------------------------------------+ -| Now you can access resources in the kubernetes cluster ! | -+----------------------------------------------------------+ +Now you can access resources in the kubernetes cluster ! ➜ ~ ``` @@ -456,7 +448,7 @@ Run the Kubernetes pod in the local Docker container, and cooperate with the ser the specified header to the local, or all the traffic to the local. ```shell -➜ ~ kubevpn dev deployment/authors --headers foo=bar --entrypoint sh +➜ ~ kubevpn run deployment/authors --headers foo=bar --entrypoint sh Starting connect Got network CIDR from cache Use exist traffic manager @@ -551,13 +543,13 @@ docker logs $(docker ps --format '{{.Names}}' | grep nginx_default_kubevpn) If you just want to start up a docker image, you can use a simple way like this: ```shell -kubevpn dev deployment/authors --no-proxy +kubevpn run deployment/authors --no-proxy ``` Example: ```shell -➜ ~ kubevpn dev deployment/authors --no-proxy +➜ ~ kubevpn run deployment/authors --no-proxy Starting connect Got network CIDR from cache Use exist traffic manager @@ -585,7 +577,7 @@ Now the main process will hang up to show you log. If you want to specify the image to start the container locally, you can use the parameter `--dev-image`. When the image does not exist locally, it will be pulled from the corresponding mirror warehouse. If you want to specify startup parameters, you can use `--entrypoint` parameter, replace it with the command you want to execute, such -as `--entrypoint /bin/bash`, for more parameters, see `kubevpn dev --help`. +as `--entrypoint /bin/bash`, for more parameters, see `kubevpn run --help`. ### DinD ( Docker in Docker ) use kubevpn in Docker @@ -616,7 +608,7 @@ ca82aef6a9eb: Pull complete Digest: sha256:368db2e0d98f6866dcefd60512960ce1310e85c24a398fea2a347905ced9507d Status: Downloaded newer image for ghcr.io/kubenetworks/kubevpn:latest WARNING: image with reference ghcr.io/kubenetworks/kubevpn was found but does not match the specified platform: wanted linux/amd64, actual: linux/arm64 -root@5732124e6447:/app# kubevpn dev deployment/authors --headers user=naison --entrypoint sh +root@5732124e6447:/app# kubevpn run deployment/authors --headers user=naison --entrypoint sh hostname is 5732124e6447 Starting connect Got network CIDR from cache @@ -645,7 +637,7 @@ Created main container: authors_default_kubevpn_6df5f /opt/microservices # ps -ef PID USER TIME COMMAND 1 root 0:00 {bash} /usr/bin/qemu-x86_64 /bin/bash /bin/bash - 14 root 0:02 {kubevpn} /usr/bin/qemu-x86_64 /usr/local/bin/kubevpn kubevpn dev deployment/authors --headers + 14 root 0:02 {kubevpn} /usr/bin/qemu-x86_64 /usr/local/bin/kubevpn kubevpn run deployment/authors --headers 25 root 0:01 {kubevpn} /usr/bin/qemu-x86_64 /usr/local/bin/kubevpn /usr/local/bin/kubevpn daemon 37 root 0:04 {kubevpn} /usr/bin/qemu-x86_64 /usr/local/bin/kubevpn /usr/local/bin/kubevpn daemon --sudo 53 root 0:00 nginx: master process nginx -g daemon off; diff --git a/README_ZH.md b/README_ZH.md index 7367d6bd..69a56b4a 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -125,9 +125,7 @@ Forwarding port... Connected tunnel Adding route... Configured DNS service -+----------------------------------------------------------+ -| Now you can access resources in the kubernetes cluster ! | -+----------------------------------------------------------+ +Now you can access resources in the kubernetes cluster ! ➜ ~ ``` @@ -253,9 +251,7 @@ Forwarding port... Connected tunnel Adding route... Configured DNS service -+----------------------------------------------------------+ -| Now you can access resources in the kubernetes cluster ! | -+----------------------------------------------------------+ +Now you can access resources in the kubernetes cluster ! ``` 使用命令 `kubevpn status` 查看当前链接状态。 @@ -282,9 +278,7 @@ Checking rollout status for deployment/productpage Waiting for deployment "productpage" rollout to finish: 1 old replicas are pending termination... Waiting for deployment "productpage" rollout to finish: 1 old replicas are pending termination... Rollout successfully for deployment/productpage -+----------------------------------------------------------+ -| Now you can access resources in the kubernetes cluster ! | -+----------------------------------------------------------+ +Now you can access resources in the kubernetes cluster ! ➜ ~ ``` @@ -341,9 +335,7 @@ Checking rollout status for deployment/productpage Waiting for deployment "productpage" rollout to finish: 1 old replicas are pending termination... Waiting for deployment "productpage" rollout to finish: 1 old replicas are pending termination... Rollout successfully for deployment/productpage -+----------------------------------------------------------+ -| Now you can access resources in the kubernetes cluster ! | -+----------------------------------------------------------+ +Now you can access resources in the kubernetes cluster ! ➜ ~ ``` @@ -398,7 +390,7 @@ Rollout successfully for deployments/productpage Docker。 ```shell -➜ ~ kubevpn dev deployment/authors --headers foo=bar --entrypoint sh +➜ ~ kubevpn run deployment/authors --headers foo=bar --entrypoint sh Starting connect Got network CIDR from cache Use exist traffic manager @@ -478,13 +470,13 @@ fc04e42799a5 nginx:latest "/docker-entrypoint.…" 37 sec 如果你只是想在本地启动镜像,可以用一种简单的方式: ```shell -kubevpn dev deployment/authors --no-proxy +kubevpn run deployment/authors --no-proxy ``` 例如: ```shell -➜ ~ kubevpn dev deployment/authors --no-proxy +➜ ~ kubevpn run deployment/authors --no-proxy Starting connect Got network CIDR from cache Use exist traffic manager @@ -511,7 +503,7 @@ Created main container: authors_default_kubevpn_ff34b 如果你想指定在本地启动容器的镜像, 可以使用参数 `--dev-image`, 当本地不存在该镜像时, 会从对应的镜像仓库拉取。如果你想指定启动参数,可以使用 `--entrypoint` -参数,替换为你想要执行的命令,比如 `--entrypoint /bin/bash`, 更多使用参数,请参见 `kubevpn dev --help`. +参数,替换为你想要执行的命令,比如 `--entrypoint /bin/bash`, 更多使用参数,请参见 `kubevpn run --help`. ### DinD ( Docker in Docker ) 在 Docker 中使用 kubevpn @@ -541,7 +533,7 @@ ca82aef6a9eb: Pull complete Digest: sha256:368db2e0d98f6866dcefd60512960ce1310e85c24a398fea2a347905ced9507d Status: Downloaded newer image for ghcr.io/kubenetworks/kubevpn:latest WARNING: image with reference ghcr.io/kubenetworks/kubevpn was found but does not match the specified platform: wanted linux/amd64, actual: linux/arm64 -root@5732124e6447:/app# kubevpn dev deployment/authors --headers user=naison --entrypoint sh +root@5732124e6447:/app# kubevpn run deployment/authors --headers user=naison --entrypoint sh hostname is 5732124e6447 Starting connect Got network CIDR from cache @@ -570,7 +562,7 @@ Created main container: authors_default_kubevpn_6df5f /opt/microservices # ps -ef PID USER TIME COMMAND 1 root 0:00 {bash} /usr/bin/qemu-x86_64 /bin/bash /bin/bash - 14 root 0:02 {kubevpn} /usr/bin/qemu-x86_64 /usr/local/bin/kubevpn kubevpn dev deployment/authors --headers + 14 root 0:02 {kubevpn} /usr/bin/qemu-x86_64 /usr/local/bin/kubevpn kubevpn run deployment/authors --headers 25 root 0:01 {kubevpn} /usr/bin/qemu-x86_64 /usr/local/bin/kubevpn /usr/local/bin/kubevpn daemon 37 root 0:04 {kubevpn} /usr/bin/qemu-x86_64 /usr/local/bin/kubevpn /usr/local/bin/kubevpn daemon --sudo 53 root 0:00 nginx: master process nginx -g daemon off; diff --git a/cmd/kubevpn/cmds/connect.go b/cmd/kubevpn/cmds/connect.go index 54f9691d..dc8e0269 100644 --- a/cmd/kubevpn/cmds/connect.go +++ b/cmd/kubevpn/cmds/connect.go @@ -124,7 +124,7 @@ func CmdConnect(f cmdutil.Factory) *cobra.Command { return err } if !foreground { - util.Print(os.Stdout, config.Slogan) + _, _ = fmt.Fprintln(os.Stdout, config.Slogan) } else { <-cmd.Context().Done() err = disconnect(cli, bytes, ns, sshConf) diff --git a/cmd/kubevpn/cmds/connection.go b/cmd/kubevpn/cmds/connection.go index 8115f4c4..629bbae7 100644 --- a/cmd/kubevpn/cmds/connection.go +++ b/cmd/kubevpn/cmds/connection.go @@ -13,7 +13,6 @@ import ( "github.com/wencaiwulue/kubevpn/v2/pkg/daemon" "github.com/wencaiwulue/kubevpn/v2/pkg/daemon/rpc" - pkgssh "github.com/wencaiwulue/kubevpn/v2/pkg/ssh" ) func CmdConnection(f cmdutil.Factory) *cobra.Command { @@ -27,7 +26,6 @@ func CmdConnection(f cmdutil.Factory) *cobra.Command { } func cmdConnectionList(f cmdutil.Factory) *cobra.Command { - var sshConf = &pkgssh.SshConfig{} cmd := &cobra.Command{ Use: "list", Short: i18n.T("List all connections"), @@ -59,7 +57,6 @@ func cmdConnectionList(f cmdutil.Factory) *cobra.Command { return nil }, } - pkgssh.AddSshFlags(cmd.Flags(), sshConf) return cmd } diff --git a/cmd/kubevpn/cmds/proxy.go b/cmd/kubevpn/cmds/proxy.go index 67e96bd1..90fe836b 100644 --- a/cmd/kubevpn/cmds/proxy.go +++ b/cmd/kubevpn/cmds/proxy.go @@ -2,6 +2,7 @@ package cmds import ( "context" + "fmt" "os" log "github.com/sirupsen/logrus" @@ -58,10 +59,10 @@ func CmdProxy(f cmdutil.Factory) *cobra.Command { kubevpn proxy deployment authors productpage # Reverse proxy with mesh, traffic with header foo=bar, will hit local PC, otherwise no effect - kubevpn proxy service/productpage --headers foo=bar + kubevpn proxy deployment/productpage --headers foo=bar # Reverse proxy with mesh, traffic with header foo=bar and env=dev, will hit local PC, otherwise no effect - kubevpn proxy service/productpage --headers foo=bar --headers env=dev + kubevpn proxy deployment/productpage --headers foo=bar --headers env=dev # Connect to api-server behind of bastion host or ssh jump host and proxy kubernetes resource traffic into local PC kubevpn proxy deployment/productpage --ssh-addr 192.168.1.100:22 --ssh-username root --ssh-keyfile ~/.ssh/ssh.pem --headers foo=bar @@ -70,12 +71,12 @@ func CmdProxy(f cmdutil.Factory) *cobra.Command { ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌────────────┐ │ pc ├────►│ ssh1 ├────►│ ssh2 ├────►│ ssh3 ├─────►... ─────► │ api-server │ └──────┘ └──────┘ └──────┘ └──────┘ └────────────┘ - kubevpn proxy service/productpage --ssh-alias --headers foo=bar + kubevpn proxy deployment/productpage --ssh-alias --headers foo=bar # Support ssh auth GSSAPI - kubevpn proxy service/productpage --ssh-addr --ssh-username --gssapi-keytab /path/to/keytab - kubevpn proxy service/productpage --ssh-addr --ssh-username --gssapi-cache /path/to/cache - kubevpn proxy service/productpage --ssh-addr --ssh-username --gssapi-password + kubevpn proxy deployment/productpage --ssh-addr --ssh-username --gssapi-keytab /path/to/keytab + kubevpn proxy deployment/productpage --ssh-addr --ssh-username --gssapi-cache /path/to/cache + kubevpn proxy deployment/productpage --ssh-addr --ssh-username --gssapi-password # Support port map, you can proxy container port to local port by command: kubevpn proxy deployment/productpage --portmap 80:8080 @@ -145,7 +146,7 @@ func CmdProxy(f cmdutil.Factory) *cobra.Command { } return err } - util.Print(os.Stdout, config.Slogan) + _, _ = fmt.Fprintln(os.Stdout, config.Slogan) // hangup if foreground { // leave from cluster resources diff --git a/cmd/kubevpn/cmds/root.go b/cmd/kubevpn/cmds/root.go index 515ae0c5..23427be7 100644 --- a/cmd/kubevpn/cmds/root.go +++ b/cmd/kubevpn/cmds/root.go @@ -58,8 +58,7 @@ func NewKubeVPNCommand() *cobra.Command { CmdLeave(factory), CmdSync(factory), CmdUnsync(factory), - CmdDev(factory), - CmdConnection(factory), + CmdRun(factory), // Hidden, Server Commands (DO NOT USE IT !!!) CmdControlPlane(factory), CmdServer(factory), diff --git a/cmd/kubevpn/cmds/dev.go b/cmd/kubevpn/cmds/run.go similarity index 76% rename from cmd/kubevpn/cmds/dev.go rename to cmd/kubevpn/cmds/run.go index e9dc5ef0..fb7ec4f7 100644 --- a/cmd/kubevpn/cmds/dev.go +++ b/cmd/kubevpn/cmds/run.go @@ -12,16 +12,16 @@ import ( "github.com/wencaiwulue/kubevpn/v2/pkg/config" "github.com/wencaiwulue/kubevpn/v2/pkg/daemon" - "github.com/wencaiwulue/kubevpn/v2/pkg/dev" "github.com/wencaiwulue/kubevpn/v2/pkg/handler" plog "github.com/wencaiwulue/kubevpn/v2/pkg/log" + "github.com/wencaiwulue/kubevpn/v2/pkg/run" pkgssh "github.com/wencaiwulue/kubevpn/v2/pkg/ssh" "github.com/wencaiwulue/kubevpn/v2/pkg/util" "github.com/wencaiwulue/kubevpn/v2/pkg/util/regctl" ) -func CmdDev(f cmdutil.Factory) *cobra.Command { - var options = &dev.Options{ +func CmdRun(f cmdutil.Factory) *cobra.Command { + var options = &run.Options{ NoProxy: false, ExtraRouteInfo: handler.ExtraRouteInfo{}, } @@ -31,9 +31,9 @@ func CmdDev(f cmdutil.Factory) *cobra.Command { var managerNamespace string cmd := &cobra.Command{ Use: "dev TYPE/NAME [-c CONTAINER] [flags] -- [args...]", - Short: i18n.T("Startup your kubernetes workloads in local Docker container"), + Short: i18n.T("Run kubernetes workloads in local Docker container"), Long: templates.LongDesc(i18n.T(` - Startup your kubernetes workloads in local Docker container with same volume、env、and network + Run kubernetes workloads in local Docker container with same volume、env、and network ## What did it do: - Download volume which MountPath point to, mount to docker container @@ -41,36 +41,34 @@ func CmdDev(f cmdutil.Factory) *cobra.Command { - Get all environment with command (env), set env to docker container `)), Example: templates.Examples(i18n.T(` - # Develop workloads - - develop deployment - kubevpn dev deployment/productpage - - develop service - kubevpn dev service/productpage + # Run workloads + - run deployment + kubevpn run deployment/productpage - # Develop workloads with mesh, traffic with header foo=bar, will hit local PC, otherwise no effect - kubevpn dev service/productpage --headers foo=bar + # Run workloads with mesh, traffic with header foo=bar, will hit local PC, otherwise no effect + kubevpn run deployment/productpage --headers foo=bar - # Develop workloads without proxy traffic - kubevpn dev service/productpage --no-proxy + # Run workloads without proxy traffic + kubevpn run deployment/productpage --no-proxy - # Develop workloads which api-server behind of bastion host or ssh jump host - kubevpn dev deployment/productpage --ssh-addr 192.168.1.100:22 --ssh-username root --ssh-keyfile ~/.ssh/ssh.pem + # Run workloads which api-server behind of bastion host or ssh jump host + kubevpn run deployment/productpage --ssh-addr 192.168.1.100:22 --ssh-username root --ssh-keyfile ~/.ssh/ssh.pem # It also supports ProxyJump, like ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌────────────┐ │ pc ├────►│ ssh1 ├────►│ ssh2 ├────►│ ssh3 ├─────►... ─────► │ api-server │ └──────┘ └──────┘ └──────┘ └──────┘ └────────────┘ - kubevpn dev deployment/productpage --ssh-alias + kubevpn run deployment/productpage --ssh-alias # Switch to terminal mode; send stdin to 'bash' and sends stdout/stderror from 'bash' back to the client - kubevpn dev deployment/authors -n default --kubeconfig ~/.kube/config --ssh-alias dev --entrypoint /bin/bash + kubevpn run deployment/authors -n default --kubeconfig ~/.kube/config --ssh-alias dev --entrypoint /bin/bash or - kubevpn dev deployment/authors -n default --kubeconfig ~/.kube/config --ssh-alias dev --entrypoint /bin/bash + kubevpn run deployment/authors -n default --kubeconfig ~/.kube/config --ssh-alias dev --entrypoint /bin/bash # Support ssh auth GSSAPI - kubevpn dev deployment/authors -n default --ssh-addr --ssh-username --gssapi-keytab /path/to/keytab --entrypoint /bin/bash - kubevpn dev deployment/authors -n default --ssh-addr --ssh-username --gssapi-cache /path/to/cache --entrypoint /bin/bash - kubevpn dev deployment/authors -n default --ssh-addr --ssh-username --gssapi-password --entrypoint /bin/bash + kubevpn run deployment/authors -n default --ssh-addr --ssh-username --gssapi-keytab /path/to/keytab --entrypoint /bin/bash + kubevpn run deployment/authors -n default --ssh-addr --ssh-username --gssapi-cache /path/to/cache --entrypoint /bin/bash + kubevpn run deployment/authors -n default --ssh-addr --ssh-username --gssapi-password --entrypoint /bin/bash `)), ValidArgsFunction: completion.ResourceTypeAndNameCompletionFunc(f), Args: cobra.MatchAll(cobra.OnlyValidArgs, cobra.MinimumNArgs(1)), @@ -114,7 +112,7 @@ func CmdDev(f cmdutil.Factory) *cobra.Command { return err } - conf, hostConfig, err := dev.Parse(cmd.Flags(), options.ContainerOptions) + conf, hostConfig, err := run.Parse(cmd.Flags(), options.ContainerOptions) if err != nil { return err } @@ -137,15 +135,15 @@ func CmdDev(f cmdutil.Factory) *cobra.Command { cmd.Flags().BoolVar(&options.NoProxy, "no-proxy", false, "Whether proxy remote workloads traffic into local or not, true: just startup container on local without inject containers to intercept traffic, false: intercept traffic and forward to local") cmdutil.AddContainerVarFlags(cmd, &options.ContainerName, options.ContainerName) cmdutil.CheckErr(cmd.RegisterFlagCompletionFunc("container", completion.ContainerCompletionFunc(f))) - cmd.Flags().StringVar((*string)(&options.ConnectMode), "connect-mode", string(dev.ConnectModeHost), "Connect to kubernetes network in container or in host, eg: ["+string(dev.ConnectModeContainer)+"|"+string(dev.ConnectModeHost)+"]") + cmd.Flags().StringVar((*string)(&options.ConnectMode), "connect-mode", string(run.ConnectModeHost), "Connect to kubernetes network in container or in host, eg: ["+string(run.ConnectModeContainer)+"|"+string(run.ConnectModeHost)+"]") handler.AddCommonFlags(cmd.Flags(), &transferImage, &imagePullSecretName) cmd.Flags().StringVar(&managerNamespace, "manager-namespace", "", "The namespace where the traffic manager is to be found. Only works in cluster mode (install kubevpn server by helm)") // diy docker options cmd.Flags().StringVar(&options.DevImage, "dev-image", "", "Use to startup docker container, Default is pod image") // -- origin docker options -- start - options.ContainerOptions = dev.AddFlags(cmd.Flags()) - cmd.Flags().StringVar(&options.RunOptions.Pull, "pull", dev.PullImageMissing, `Pull image before running ("`+dev.PullImageAlways+`"|"`+dev.PullImageMissing+`"|"`+dev.PullImageNever+`")`) + options.ContainerOptions = run.AddFlags(cmd.Flags()) + cmd.Flags().StringVar(&options.RunOptions.Pull, "pull", run.PullImageMissing, `Pull image before running ("`+run.PullImageAlways+`"|"`+run.PullImageMissing+`"|"`+run.PullImageNever+`")`) command.AddPlatformFlag(cmd.Flags(), &options.RunOptions.Platform) // -- origin docker options -- end handler.AddExtraRoute(cmd.Flags(), &options.ExtraRouteInfo) diff --git a/cmd/kubevpn/cmds/sync.go b/cmd/kubevpn/cmds/sync.go index a289ebe3..8c16106f 100644 --- a/cmd/kubevpn/cmds/sync.go +++ b/cmd/kubevpn/cmds/sync.go @@ -2,6 +2,7 @@ package cmds import ( "context" + "fmt" "os" pkgerr "github.com/pkg/errors" @@ -57,12 +58,12 @@ func CmdSync(f cmdutil.Factory) *cobra.Command { ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌────────────┐ │ pc ├────►│ ssh1 ├────►│ ssh2 ├────►│ ssh3 ├─────►... ─────► │ api-server │ └──────┘ └──────┘ └──────┘ └──────┘ └────────────┘ - kubevpn sync service/productpage --ssh-alias --headers foo=bar + kubevpn sync deployment/productpage --ssh-alias --headers foo=bar # Support ssh auth GSSAPI - kubevpn sync service/productpage --ssh-addr --ssh-username --gssapi-keytab /path/to/keytab - kubevpn sync service/productpage --ssh-addr --ssh-username --gssapi-cache /path/to/cache - kubevpn sync service/productpage --ssh-addr --ssh-username --gssapi-password + kubevpn sync deployment/productpage --ssh-addr --ssh-username --gssapi-keytab /path/to/keytab + kubevpn sync deployment/productpage --ssh-addr --ssh-username --gssapi-cache /path/to/cache + kubevpn sync deployment/productpage --ssh-addr --ssh-username --gssapi-password `)), Args: cobra.MatchAll(cobra.OnlyValidArgs, cobra.MinimumNArgs(1)), PreRunE: func(cmd *cobra.Command, args []string) (err error) { @@ -134,7 +135,7 @@ func CmdSync(f cmdutil.Factory) *cobra.Command { } return err } - util.Print(os.Stdout, config.Slogan) + _, _ = fmt.Fprintln(os.Stdout, config.Slogan) return nil }, } diff --git a/pkg/core/gvisorlocaltcpforwarder.go b/pkg/core/gvisorlocaltcpforwarder.go index 58270aae..24a8e15d 100644 --- a/pkg/core/gvisorlocaltcpforwarder.go +++ b/pkg/core/gvisorlocaltcpforwarder.go @@ -46,15 +46,18 @@ func LocalTCPForwarder(ctx context.Context, s *stack.Stack) func(stack.Transport // 2, dial proxy var host string + var network string if id.LocalAddress.To4() != (tcpip.Address{}) { host = "127.0.0.1" + network = "tcp4" } else { host = net.IPv6loopback.String() + network = "tcp6" } port := fmt.Sprintf("%d", id.LocalPort) var d = net.Dialer{Timeout: time.Second * 5} var remote net.Conn - remote, err = d.DialContext(ctx, "tcp", net.JoinHostPort(host, port)) + remote, err = d.DialContext(ctx, network, net.JoinHostPort(host, port)) if err != nil { plog.G(ctx).Errorf("[TUN-TCP] Failed to connect addr %s: %v", net.JoinHostPort(host, port), err) return diff --git a/pkg/core/gvisorlocaltcphandler.go b/pkg/core/gvisorlocaltcphandler.go index dc6e0182..6950f63b 100644 --- a/pkg/core/gvisorlocaltcphandler.go +++ b/pkg/core/gvisorlocaltcphandler.go @@ -13,7 +13,7 @@ import ( "github.com/wencaiwulue/kubevpn/v2/pkg/util" ) -type gvisorLocalTCPHandler struct { +type gvisorLocalHandler struct { // read from tcp conn write to gvisor inbound gvisorInbound <-chan *Packet // write to tcp conn @@ -23,15 +23,15 @@ type gvisorLocalTCPHandler struct { errChan chan error } -func handleGvisorPacket(gvisorInbound <-chan *Packet, outbound chan<- *Packet) *gvisorLocalTCPHandler { - return &gvisorLocalTCPHandler{ +func handleGvisorPacket(gvisorInbound <-chan *Packet, outbound chan<- *Packet) *gvisorLocalHandler { + return &gvisorLocalHandler{ gvisorInbound: gvisorInbound, outbound: outbound, errChan: make(chan error, 1), } } -func (h *gvisorLocalTCPHandler) Run(ctx context.Context) { +func (h *gvisorLocalHandler) Run(ctx context.Context) { endpoint := channel.New(tcp.DefaultReceiveBufferSize, uint32(config.DefaultMTU), tcpip.GetRandMacAddr()) // for support ipv6 skip checksum // vendor/gvisor.dev/gvisor/pkg/tcpip/stack/nic.go:763 diff --git a/pkg/core/gvisorlocaltunendpoint.go b/pkg/core/gvisorlocaltunendpoint.go index 55a3b04d..8e4d04cb 100755 --- a/pkg/core/gvisorlocaltunendpoint.go +++ b/pkg/core/gvisorlocaltunendpoint.go @@ -88,6 +88,6 @@ func readFromGvisorInboundWriteToEndpoint(ctx context.Context, in <-chan *Packet sniffer.LogPacket("[gVISOR] ", sniffer.DirectionRecv, protocol, pkt) endpoint.InjectInbound(protocol, pkt) pkt.DecRef() - plog.G(ctx).Debugf("[TCP-GVISOR] Write to Gvisor. SRC: %s, DST: %s, Protocol: %s, Length: %d", src, dst, ipProto.String(), packet.length) + plog.G(ctx).Debugf("[TCP-GVISOR] Write to gvisor. SRC: %s, DST: %s, IPProtocol: %s, Protocol: %v, Length: %d", src, dst, ipProto.String(), protocol, packet.length) } } diff --git a/pkg/core/gvisorlocaludpforwarder.go b/pkg/core/gvisorlocaludpforwarder.go index 62556445..f85cfcf5 100644 --- a/pkg/core/gvisorlocaludpforwarder.go +++ b/pkg/core/gvisorlocaludpforwarder.go @@ -29,10 +29,13 @@ func LocalUDPForwarder(ctx context.Context, s *stack.Stack) func(id stack.Transp Port: int(id.RemotePort), } var ip net.IP + var network string if id.LocalAddress.To4() != (tcpip.Address{}) { ip = net.ParseIP("127.0.0.1") + network = "udp4" } else { ip = net.IPv6loopback + network = "udp6" } dst := &net.UDPAddr{ IP: ip, @@ -47,7 +50,7 @@ func LocalUDPForwarder(ctx context.Context, s *stack.Stack) func(id stack.Transp } // dial dst - remote, err1 := net.DialUDP("udp", nil, dst) + remote, err1 := net.DialUDP(network, nil, dst) if err1 != nil { plog.G(ctx).Errorf("[TUN-UDP] Failed to connect dst: %s: %v", dst.String(), err1) return diff --git a/pkg/core/gvisortcpforwarder.go b/pkg/core/gvisortcpforwarder.go index cded9e51..ce99d1ce 100644 --- a/pkg/core/gvisortcpforwarder.go +++ b/pkg/core/gvisortcpforwarder.go @@ -8,6 +8,7 @@ import ( "time" "github.com/pkg/errors" + "gvisor.dev/gvisor/pkg/tcpip" "gvisor.dev/gvisor/pkg/tcpip/adapters/gonet" "gvisor.dev/gvisor/pkg/tcpip/stack" "gvisor.dev/gvisor/pkg/tcpip/transport/tcp" @@ -42,10 +43,16 @@ func TCPForwarder(ctx context.Context, s *stack.Stack) func(stack.TransportEndpo }() // 2, dial proxy host := id.LocalAddress.String() + var network string + if id.LocalAddress.To4() != (tcpip.Address{}) { + network = "tcp4" + } else { + network = "tcp6" + } port := fmt.Sprintf("%d", id.LocalPort) var remote net.Conn var d = net.Dialer{Timeout: time.Second * 5} - remote, err = d.DialContext(ctx, "tcp", net.JoinHostPort(host, port)) + remote, err = d.DialContext(ctx, network, net.JoinHostPort(host, port)) if err != nil { plog.G(ctx).Errorf("[TUN-TCP] Failed to connect addr %s: %v", net.JoinHostPort(host, port), err) return diff --git a/pkg/core/gvisortunendpoint.go b/pkg/core/gvisortunendpoint.go index db91b123..80a978d8 100755 --- a/pkg/core/gvisortunendpoint.go +++ b/pkg/core/gvisortunendpoint.go @@ -112,7 +112,7 @@ func (h *gvisorTCPHandler) readFromTCPConnWriteToEndpoint(ctx context.Context, c sniffer.LogPacket("[gVISOR] ", sniffer.DirectionRecv, protocol, pkt) endpoint.InjectInbound(protocol, pkt) pkt.DecRef() - plog.G(ctx).Debugf("[TCP-GVISOR] Write to Gvisor. SRC: %s, DST: %s, Protocol: %s, Length: %d", src, dst, layers.IPProtocol(ipProtocol).String(), read) + plog.G(ctx).Debugf("[TCP-GVISOR] Write to gvisor. SRC: %s, DST: %s, Protocol: %s, Length: %d", src, dst, layers.IPProtocol(ipProtocol).String(), read) } else { util.SafeWrite(TCPPacketChan, &Packet{ data: buf[:], diff --git a/pkg/core/gvisorudpforwarder.go b/pkg/core/gvisorudpforwarder.go index 16d0033c..28119f6a 100644 --- a/pkg/core/gvisorudpforwarder.go +++ b/pkg/core/gvisorudpforwarder.go @@ -7,6 +7,7 @@ import ( "time" "github.com/pkg/errors" + "gvisor.dev/gvisor/pkg/tcpip" "gvisor.dev/gvisor/pkg/tcpip/adapters/gonet" "gvisor.dev/gvisor/pkg/tcpip/stack" "gvisor.dev/gvisor/pkg/tcpip/transport/udp" @@ -39,8 +40,15 @@ func UDPForwarder(ctx context.Context, s *stack.Stack) func(id stack.TransportEn return } + var network string + if id.LocalAddress.To4() != (tcpip.Address{}) { + network = "udp4" + } else { + network = "udp6" + } + // dial dst - remote, err1 := net.DialUDP("udp", nil, dst) + remote, err1 := net.DialUDP(network, nil, dst) if err1 != nil { plog.G(ctx).Errorf("[TUN-UDP] Failed to connect dst: %s: %v", dst.String(), err1) return diff --git a/pkg/core/gvisorudphandler.go b/pkg/core/gvisorudphandler.go index 4fae0818..e60ff5f7 100644 --- a/pkg/core/gvisorudphandler.go +++ b/pkg/core/gvisorudphandler.go @@ -8,6 +8,7 @@ import ( "time" "github.com/pkg/errors" + "gvisor.dev/gvisor/pkg/tcpip" "github.com/wencaiwulue/kubevpn/v2/pkg/config" plog "github.com/wencaiwulue/kubevpn/v2/pkg/log" @@ -24,21 +25,27 @@ func (h *gvisorUDPHandler) Handle(ctx context.Context, tcpConn net.Conn) { defer tcpConn.Close() plog.G(ctx).Debugf("[TUN-UDP] %s -> %s", tcpConn.RemoteAddr(), tcpConn.LocalAddr()) // 1, get proxy info - endpointID, err := util.ParseProxyInfo(tcpConn) + id, err := util.ParseProxyInfo(tcpConn) if err != nil { plog.G(ctx).Errorf("[TUN-UDP] Failed to parse proxy info: %v", err) return } plog.G(ctx).Infof("[TUN-UDP] LocalPort: %d, LocalAddress: %s, RemotePort: %d, RemoteAddress: %s", - endpointID.LocalPort, endpointID.LocalAddress.String(), endpointID.RemotePort, endpointID.RemoteAddress.String(), + id.LocalPort, id.LocalAddress.String(), id.RemotePort, id.RemoteAddress.String(), ) // 2, dial proxy addr := &net.UDPAddr{ - IP: endpointID.LocalAddress.AsSlice(), - Port: int(endpointID.LocalPort), + IP: id.LocalAddress.AsSlice(), + Port: int(id.LocalPort), + } + var network string + if id.LocalAddress.To4() != (tcpip.Address{}) { + network = "udp4" + } else { + network = "udp6" } var remote *net.UDPConn - remote, err = net.DialUDP("udp", nil, addr) + remote, err = net.DialUDP(network, nil, addr) if err != nil { plog.G(ctx).Errorf("[TUN-UDP] Failed to connect addr %s: %v", addr.String(), err) return diff --git a/pkg/dev/docker_opts.go b/pkg/run/docker_opts.go similarity index 99% rename from pkg/dev/docker_opts.go rename to pkg/run/docker_opts.go index f4edd35f..d47d4b26 100644 --- a/pkg/dev/docker_opts.go +++ b/pkg/run/docker_opts.go @@ -1,4 +1,4 @@ -package dev +package run import ( "fmt" diff --git a/pkg/dev/docker_utils.go b/pkg/run/docker_utils.go similarity index 98% rename from pkg/dev/docker_utils.go rename to pkg/run/docker_utils.go index 43bef00f..9d478c01 100644 --- a/pkg/dev/docker_utils.go +++ b/pkg/run/docker_utils.go @@ -1,4 +1,4 @@ -package dev +package run import ( "strings" diff --git a/pkg/dev/options.go b/pkg/run/options.go similarity index 98% rename from pkg/dev/options.go rename to pkg/run/options.go index ae267da6..b8c1df16 100644 --- a/pkg/dev/options.go +++ b/pkg/run/options.go @@ -1,4 +1,4 @@ -package dev +package run import ( "context" @@ -84,7 +84,7 @@ func (option *Options) Main(ctx context.Context, sshConfig *pkgssh.SshConfig, co return err } - return option.Dev(ctx, config, hostConfig) + return option.Run(ctx, config, hostConfig) } // Connect to cluster network on docker container or host @@ -103,7 +103,7 @@ func (option *Options) Connect(ctx context.Context, sshConfig *pkgssh.SshConfig, option.ExtraRouteInfo.ExtraCIDR = append(option.ExtraRouteInfo.ExtraCIDR, ip.String()) } } - // not needs to ssh jump in daemon, because dev mode will hang up until user exit, + // no need to ssh jump in daemon, because run mode will hang up until user exit, // so just ssh jump in client is enough req := &rpc.ProxyRequest{ KubeconfigBytes: string(kubeConfigBytes), @@ -181,7 +181,7 @@ func (option *Options) Connect(ctx context.Context, sshConfig *pkgssh.SshConfig, return fmt.Errorf("unsupport connect mode: %s", option.ConnectMode) } -func (option *Options) Dev(ctx context.Context, config *Config, hostConfig *HostConfig) error { +func (option *Options) Run(ctx context.Context, config *Config, hostConfig *HostConfig) error { templateSpec, err := option.GetPodTemplateSpec(ctx) if err != nil { plog.G(ctx).Errorf("Failed to get unstructured object error: %v", err) diff --git a/pkg/dev/runconfig.go b/pkg/run/runconfig.go similarity index 99% rename from pkg/dev/runconfig.go rename to pkg/run/runconfig.go index 5c05de2d..b9a87223 100644 --- a/pkg/dev/runconfig.go +++ b/pkg/run/runconfig.go @@ -1,4 +1,4 @@ -package dev +package run import ( "context" diff --git a/pkg/util/unstructure.go b/pkg/util/unstructure.go index 6a51113e..c615faf5 100644 --- a/pkg/util/unstructure.go +++ b/pkg/util/unstructure.go @@ -113,13 +113,11 @@ func GetPodTemplateSpecPath(u *unstructured.Unstructured) (*v1.PodTemplateSpec, NormalizedResource convert user parameter to standard, example: pod/productpage-7667dfcddb-cbsn5 --> deployments.apps/productpage - service/productpage --> deployments.apps/productpage replicaset/productpage-7667dfcddb --> deployments.apps/productpage deployment: productpage --> deployments.apps/productpage pods without controller pod/productpage-without-controller --> pod/productpage-without-controller - service/productpage-without-pod --> controller/controllerName */ func NormalizedResource(f util.Factory, ns string, workloads []string) ([]string, []*resource.Info, error) { if len(workloads) == 0 {