Skip to content

Commit

Permalink
feat: add cmd uninstall and rename cmd reset
Browse files Browse the repository at this point in the history
  • Loading branch information
wencaiwulue committed Jan 18, 2025
1 parent b6cfba7 commit 2e96247
Show file tree
Hide file tree
Showing 11 changed files with 896 additions and 321 deletions.
43 changes: 15 additions & 28 deletions cmd/kubevpn/cmds/reset.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
package cmds

import (
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/templates"
"k8s.io/utils/ptr"

"github.com/wencaiwulue/kubevpn/v2/pkg/daemon"
"github.com/wencaiwulue/kubevpn/v2/pkg/daemon/rpc"
Expand All @@ -20,59 +18,48 @@ func CmdReset(f cmdutil.Factory) *cobra.Command {
var sshConf = &pkgssh.SshConfig{}
cmd := &cobra.Command{
Use: "reset",
Short: "Reset all resource create by kubevpn in k8s cluster",
Short: "Reset workloads to origin status",
Long: templates.LongDesc(i18n.T(`
Reset all resource create by kubevpn in k8s cluster
Reset workloads to origin status
Reset will delete all resources create by kubevpn in k8s cluster, like deployment, service, serviceAccount...
and it will also delete local develop docker containers, docker networks. delete hosts entry added by kubevpn,
cleanup DNS settings.
Reset will remove injected container envoy-proxy and vpn, and restore service mesh rules.
`)),
Example: templates.Examples(i18n.T(`
# Reset default namespace
kubevpn reset
# Reset default namespace workloads depooyment/productpage
kubevpn reset deployment/productpage
# Reset another namespace test
kubevpn reset -n test
# Reset another namespace test workloads depooyment/productpage
kubevpn reset deployment/productpage -n test
# Reset cluster api-server behind of bastion host or ssh jump host
kubevpn reset --ssh-addr 192.168.1.100:22 --ssh-username root --ssh-keyfile ~/.ssh/ssh.pem
# Reset workloads depooyment/productpage which api-server behind of bastion host or ssh jump host
kubevpn reset 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 reset --ssh-alias <alias>
kubevpn reset deployment/productpage --ssh-alias <alias>
# Support ssh auth GSSAPI
kubevpn reset --ssh-addr <HOST:PORT> --ssh-username <USERNAME> --gssapi-keytab /path/to/keytab
kubevpn reset --ssh-addr <HOST:PORT> --ssh-username <USERNAME> --gssapi-cache /path/to/cache
kubevpn reset --ssh-addr <HOST:PORT> --ssh-username <USERNAME> --gssapi-password <PASSWORD>
kubevpn reset deployment/productpage --ssh-addr <HOST:PORT> --ssh-username <USERNAME> --gssapi-keytab /path/to/keytab
kubevpn reset deployment/productpage --ssh-addr <HOST:PORT> --ssh-username <USERNAME> --gssapi-cache /path/to/cache
kubevpn reset deployment/productpage --ssh-addr <HOST:PORT> --ssh-username <USERNAME> --gssapi-password <PASSWORD>
`)),
PreRunE: func(cmd *cobra.Command, args []string) error {
util.InitLoggerForClient(false)
return daemon.StartupDaemon(cmd.Context())
},
Args: cobra.MatchAll(cobra.ExactArgs(1)),
RunE: func(cmd *cobra.Command, args []string) error {
bytes, ns, err := util.ConvertToKubeConfigBytes(f)
if err != nil {
return err
}
cli := daemon.GetClient(false)
disconnect, err := cli.Disconnect(cmd.Context(), &rpc.DisconnectRequest{
KubeconfigBytes: ptr.To(string(bytes)),
Namespace: ptr.To(ns),
SshJump: sshConf.ToRPC(),
})
if err != nil {
log.Warnf("Failed to disconnect from cluter: %v", err)
} else {
_ = util.PrintGRPCStream[rpc.DisconnectResponse](disconnect)
}

req := &rpc.ResetRequest{
KubeconfigBytes: string(bytes),
Namespace: ns,
Workloads: args,
SshJump: sshConf.ToRPC(),
}
resp, err := cli.Reset(cmd.Context(), req)
Expand Down
1 change: 1 addition & 0 deletions cmd/kubevpn/cmds/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ func NewKubeVPNCommand() *cobra.Command {
CmdLogs(factory),
CmdCp(factory),
CmdReset(factory),
CmdUninstall(factory),
CmdQuit(factory),
},
},
Expand Down
95 changes: 95 additions & 0 deletions cmd/kubevpn/cmds/uninstall.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package cmds

import (
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/templates"
"k8s.io/utils/ptr"

"github.com/wencaiwulue/kubevpn/v2/pkg/daemon"
"github.com/wencaiwulue/kubevpn/v2/pkg/daemon/rpc"
pkgssh "github.com/wencaiwulue/kubevpn/v2/pkg/ssh"
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
)

func CmdUninstall(f cmdutil.Factory) *cobra.Command {
var sshConf = &pkgssh.SshConfig{}
cmd := &cobra.Command{
Use: "uninstall",
Short: "Uninstall all resource create by kubevpn in k8s cluster",
Long: templates.LongDesc(i18n.T(`
Uninstall all resource create by kubevpn in k8s cluster
Uninstall will delete all resources create by kubevpn in k8s cluster, like deployment, service, serviceAccount...
and it will also delete local develop docker containers, docker networks. delete hosts entry added by kubevpn,
cleanup DNS settings.
`)),
Example: templates.Examples(i18n.T(`
# Uninstall default namespace
kubevpn uninstall
# Uninstall another namespace test
kubevpn uninstall -n test
# Uninstall cluster api-server behind of bastion host or ssh jump host
kubevpn uninstall --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 uninstall --ssh-alias <alias>
# Support ssh auth GSSAPI
kubevpn uninstall --ssh-addr <HOST:PORT> --ssh-username <USERNAME> --gssapi-keytab /path/to/keytab
kubevpn uninstall --ssh-addr <HOST:PORT> --ssh-username <USERNAME> --gssapi-cache /path/to/cache
kubevpn uninstall --ssh-addr <HOST:PORT> --ssh-username <USERNAME> --gssapi-password <PASSWORD>
`)),
PreRunE: func(cmd *cobra.Command, args []string) error {
util.InitLoggerForClient(false)
return daemon.StartupDaemon(cmd.Context())
},
RunE: func(cmd *cobra.Command, args []string) error {
bytes, ns, err := util.ConvertToKubeConfigBytes(f)
if err != nil {
return err
}
cli := daemon.GetClient(false)
disconnect, err := cli.Disconnect(cmd.Context(), &rpc.DisconnectRequest{
KubeconfigBytes: ptr.To(string(bytes)),
Namespace: ptr.To(ns),
SshJump: sshConf.ToRPC(),
})
if err != nil {
log.Warnf("Failed to disconnect from cluter: %v", err)
} else {
_ = util.PrintGRPCStream[rpc.DisconnectResponse](disconnect)
}

req := &rpc.UninstallRequest{
KubeconfigBytes: string(bytes),
Namespace: ns,
SshJump: sshConf.ToRPC(),
}
resp, err := cli.Uninstall(cmd.Context(), req)
if err != nil {
return err
}
err = util.PrintGRPCStream[rpc.UninstallResponse](resp)
if err != nil {
if status.Code(err) == codes.Canceled {
return nil
}
return err
}
return nil
},
}

pkgssh.AddSshFlags(cmd.Flags(), sshConf)
return cmd
}
2 changes: 1 addition & 1 deletion pkg/daemon/action/reset.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func (svr *Server) Reset(req *rpc.ResetRequest, resp rpc.Daemon_ResetServer) err

connect := &handler.ConnectOptions{
Namespace: req.Namespace,
Lock: &svr.Lock,
Workloads: req.Workloads,
}

file, err := util.ConvertToTempKubeconfigFile([]byte(req.KubeconfigBytes))
Expand Down
71 changes: 71 additions & 0 deletions pkg/daemon/action/uninstall.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package action

import (
"io"

log "github.com/sirupsen/logrus"
"github.com/spf13/pflag"

"github.com/wencaiwulue/kubevpn/v2/pkg/config"
"github.com/wencaiwulue/kubevpn/v2/pkg/daemon/rpc"
"github.com/wencaiwulue/kubevpn/v2/pkg/handler"
"github.com/wencaiwulue/kubevpn/v2/pkg/ssh"
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
)

func (svr *Server) Uninstall(req *rpc.UninstallRequest, resp rpc.Daemon_UninstallServer) error {
defer func() {
util.InitLoggerForServer(true)
log.SetOutput(svr.LogFile)
config.Debug = false
}()
out := io.MultiWriter(newUninstallWarp(resp), svr.LogFile)
util.InitLoggerForClient(config.Debug)
log.SetOutput(out)

connect := &handler.ConnectOptions{
Namespace: req.Namespace,
Lock: &svr.Lock,
}

file, err := util.ConvertToTempKubeconfigFile([]byte(req.KubeconfigBytes))
if err != nil {
return err
}
flags := pflag.NewFlagSet("", pflag.ContinueOnError)
flags.AddFlag(&pflag.Flag{
Name: "kubeconfig",
DefValue: file,
})
var sshConf = ssh.ParseSshFromRPC(req.SshJump)
var ctx = resp.Context()
var path string
path, err = ssh.SshJump(ctx, sshConf, flags, false)
if err != nil {
return err
}
err = connect.InitClient(util.InitFactoryByPath(path, req.Namespace))
if err != nil {
return err
}
err = connect.Uninstall(ctx)
if err != nil {
return err
}
return nil
}

type uninstallWarp struct {
server rpc.Daemon_UninstallServer
}

func (r *uninstallWarp) Write(p []byte) (n int, err error) {
_ = r.server.Send(&rpc.UninstallResponse{
Message: string(p),
})
return len(p), nil
}

func newUninstallWarp(server rpc.Daemon_UninstallServer) io.Writer {
return &uninstallWarp{server: server}
}
Loading

0 comments on commit 2e96247

Please sign in to comment.