mirror of
https://github.com/kubenetworks/kubevpn.git
synced 2025-12-24 11:51:13 +08:00
refactor: refactor cmd alias status and disconnect (#233)
* refactor: refactor cmd alias status and disconnect --------- Co-authored-by: wencaiwulue <895703375@qq.com>
This commit is contained in:
@@ -77,30 +77,10 @@ Config file support three field: Name,Needs,Flags
|
||||
},
|
||||
Args: cobra.MatchAll(cobra.ExactArgs(1)),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
var content []byte
|
||||
var err error
|
||||
var path string
|
||||
if localFile != "" {
|
||||
path = localFile
|
||||
content, err = os.ReadFile(path)
|
||||
} else if remoteAddr != "" {
|
||||
path = remoteAddr
|
||||
content, err = util.DownloadFileStream(path)
|
||||
} else {
|
||||
path = daemon.GetConfigFilePath()
|
||||
content, err = os.ReadFile(path)
|
||||
}
|
||||
configs, err := ParseAndGet(localFile, remoteAddr, args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
configList, err := ParseConfig(content)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
configs, err := GetConfigs(configList, args[0])
|
||||
if len(configs) == 0 {
|
||||
return fmt.Errorf("can not found any alias for name %s, please check your config file %s", args[0], path)
|
||||
}
|
||||
name, err := os.Executable()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -124,6 +104,38 @@ Config file support three field: Name,Needs,Flags
|
||||
return cmd
|
||||
}
|
||||
|
||||
func ParseAndGet(localFile, remoteAddr string, aliasName string) ([]Config, error) {
|
||||
var content []byte
|
||||
var err error
|
||||
var path string
|
||||
if localFile != "" {
|
||||
path = localFile
|
||||
content, err = os.ReadFile(path)
|
||||
} else if remoteAddr != "" {
|
||||
path = remoteAddr
|
||||
content, err = util.DownloadFileStream(path)
|
||||
} else {
|
||||
path = daemon.GetConfigFilePath()
|
||||
content, err = os.ReadFile(path)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
list, err := ParseConfig(content)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
configs, err := GetConfigs(list, aliasName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(configs) == 0 {
|
||||
err = fmt.Errorf("can not found any alias for name %s, please check your config file %s", aliasName, path)
|
||||
return nil, err
|
||||
}
|
||||
return configs, nil
|
||||
}
|
||||
|
||||
func ParseConfig(file []byte) ([]Config, error) {
|
||||
decoder := yaml.NewDecoder(strings.NewReader(string(file)))
|
||||
var configs []Config
|
||||
|
||||
@@ -145,8 +145,8 @@ func CmdClone(f cmdutil.Factory) *cobra.Command {
|
||||
cmd.Flags().StringVar(&options.TargetKubeconfig, "target-kubeconfig", "", "Clone workloads will create in this cluster, if not special, use origin cluster")
|
||||
cmd.Flags().StringVar(&options.TargetRegistry, "target-registry", "", "Clone workloads will create this registry domain to replace origin registry, if not special, use origin registry")
|
||||
|
||||
addExtraRoute(cmd, extraRoute)
|
||||
addSshFlags(cmd, sshConf)
|
||||
addExtraRoute(cmd.Flags(), extraRoute)
|
||||
addSshFlags(cmd.Flags(), sshConf)
|
||||
cmd.ValidArgsFunction = utilcomp.ResourceTypeAndNameCompletionFunc(f)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ func cmdConfigAdd(f cmdutil.Factory) *cobra.Command {
|
||||
return nil
|
||||
},
|
||||
}
|
||||
addSshFlags(cmd, sshConf)
|
||||
addSshFlags(cmd.Flags(), sshConf)
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
||||
@@ -152,7 +152,7 @@ func CmdConnect(f cmdutil.Factory) *cobra.Command {
|
||||
cmd.Flags().BoolVar(&foreground, "foreground", false, "Hang up")
|
||||
cmd.Flags().BoolVar(&lite, "lite", false, "connect to multiple cluster in lite mode, you needs to special this options")
|
||||
|
||||
addExtraRoute(cmd, extraRoute)
|
||||
addSshFlags(cmd, sshConf)
|
||||
addExtraRoute(cmd.Flags(), extraRoute)
|
||||
addSshFlags(cmd.Flags(), sshConf)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -134,6 +134,6 @@ func CmdCp(f cmdutil.Factory) *cobra.Command {
|
||||
cmd.Flags().BoolVarP(&o.NoPreserve, "no-preserve", "", false, "The copied file/directory's ownership and permissions will not be preserved in the container")
|
||||
cmd.Flags().IntVarP(&o.MaxTries, "retries", "", 0, "Set number of retries to complete a copy operation from a container. Specify 0 to disable or any negative value for infinite retrying. The default is 0 (no retry).")
|
||||
|
||||
addSshFlags(cmd, sshConf)
|
||||
addSshFlags(cmd.Flags(), sshConf)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ Startup your kubernetes workloads in local Docker container with same volume、e
|
||||
dockercomp.NetworkNames(cli),
|
||||
)
|
||||
|
||||
addExtraRoute(cmd, &options.ExtraRouteInfo)
|
||||
addSshFlags(cmd, sshConf)
|
||||
addExtraRoute(cmd.Flags(), &options.ExtraRouteInfo)
|
||||
addSshFlags(cmd.Flags(), sshConf)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
|
||||
func CmdDisconnect(f cmdutil.Factory) *cobra.Command {
|
||||
var all = false
|
||||
var clusterIDs []string
|
||||
cmd := &cobra.Command{
|
||||
Use: "disconnect",
|
||||
Short: i18n.T("Disconnect from kubernetes cluster network"),
|
||||
@@ -35,10 +36,13 @@ func CmdDisconnect(f cmdutil.Factory) *cobra.Command {
|
||||
Args: cobra.MatchAll(cobra.OnlyValidArgs),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if len(args) > 0 && all {
|
||||
return fmt.Errorf("either specify --all or specific ID, not both")
|
||||
return fmt.Errorf("either specify --all or ID, not both")
|
||||
}
|
||||
if len(args) == 0 && !all {
|
||||
return fmt.Errorf("either specify --all or specific ID")
|
||||
if len(clusterIDs) > 0 && all {
|
||||
return fmt.Errorf("either specify --all or cluster-id, not both")
|
||||
}
|
||||
if len(args) == 0 && !all && len(clusterIDs) == 0 {
|
||||
return fmt.Errorf("either specify --all or ID or cluster-id")
|
||||
}
|
||||
var ids *int32
|
||||
if len(args) > 0 {
|
||||
@@ -51,8 +55,9 @@ func CmdDisconnect(f cmdutil.Factory) *cobra.Command {
|
||||
client, err := daemon.GetClient(false).Disconnect(
|
||||
cmd.Context(),
|
||||
&rpc.DisconnectRequest{
|
||||
ID: ids,
|
||||
All: pointer.Bool(all),
|
||||
ID: ids,
|
||||
ClusterIDs: clusterIDs,
|
||||
All: pointer.Bool(all),
|
||||
},
|
||||
)
|
||||
var resp *rpc.DisconnectResponse
|
||||
@@ -72,6 +77,7 @@ func CmdDisconnect(f cmdutil.Factory) *cobra.Command {
|
||||
return nil
|
||||
},
|
||||
}
|
||||
cmd.Flags().BoolVar(&all, "all", all, "Select all, disconnect from all cluster network")
|
||||
cmd.Flags().BoolVar(&all, "all", all, "Disconnect all cluster, disconnect from all cluster network")
|
||||
cmd.Flags().StringArrayVar(&clusterIDs, "cluster-id", []string{}, "Cluster id, command status -o yaml/json will show cluster-id")
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
flag "github.com/spf13/pflag"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
@@ -173,29 +174,29 @@ func CmdProxy(f cmdutil.Factory) *cobra.Command {
|
||||
cmd.Flags().StringVar((*string)(&connect.Engine), "engine", string(config.EngineRaw), fmt.Sprintf(`transport engine ("%s"|"%s") %s: use gvisor and raw both (both performance and stable), %s: use raw mode (best stable)`, config.EngineMix, config.EngineRaw, config.EngineMix, config.EngineRaw))
|
||||
cmd.Flags().BoolVar(&foreground, "foreground", false, "foreground hang up")
|
||||
|
||||
addExtraRoute(cmd, extraRoute)
|
||||
addSshFlags(cmd, sshConf)
|
||||
addExtraRoute(cmd.Flags(), extraRoute)
|
||||
addSshFlags(cmd.Flags(), sshConf)
|
||||
cmd.ValidArgsFunction = utilcomp.ResourceTypeAndNameCompletionFunc(f)
|
||||
return cmd
|
||||
}
|
||||
|
||||
func addSshFlags(cmd *cobra.Command, sshConf *util.SshConfig) {
|
||||
func addSshFlags(flags *flag.FlagSet, sshConf *util.SshConfig) {
|
||||
// for ssh jumper host
|
||||
cmd.Flags().StringVar(&sshConf.Addr, "ssh-addr", "", "Optional ssh jump server address to dial as <hostname>:<port>, eg: 127.0.0.1:22")
|
||||
cmd.Flags().StringVar(&sshConf.User, "ssh-username", "", "Optional username for ssh jump server")
|
||||
cmd.Flags().StringVar(&sshConf.Password, "ssh-password", "", "Optional password for ssh jump server")
|
||||
cmd.Flags().StringVar(&sshConf.Keyfile, "ssh-keyfile", "", "Optional file with private key for SSH authentication")
|
||||
cmd.Flags().StringVar(&sshConf.ConfigAlias, "ssh-alias", "", "Optional config alias with ~/.ssh/config for SSH authentication")
|
||||
cmd.Flags().StringVar(&sshConf.GSSAPIPassword, "gssapi-password", "", "GSSAPI password")
|
||||
cmd.Flags().StringVar(&sshConf.GSSAPIKeytabConf, "gssapi-keytab", "", "GSSAPI keytab file path")
|
||||
cmd.Flags().StringVar(&sshConf.GSSAPICacheFile, "gssapi-cache", "", "GSSAPI cache file path, use command `kinit -c /path/to/cache USERNAME@RELAM` to generate")
|
||||
cmd.Flags().StringVar(&sshConf.RemoteKubeconfig, "remote-kubeconfig", "", "Remote kubeconfig abstract path of ssh server, default is /home/$USERNAME/.kube/config")
|
||||
lookup := cmd.Flags().Lookup("remote-kubeconfig")
|
||||
flags.StringVar(&sshConf.Addr, "ssh-addr", "", "Optional ssh jump server address to dial as <hostname>:<port>, eg: 127.0.0.1:22")
|
||||
flags.StringVar(&sshConf.User, "ssh-username", "", "Optional username for ssh jump server")
|
||||
flags.StringVar(&sshConf.Password, "ssh-password", "", "Optional password for ssh jump server")
|
||||
flags.StringVar(&sshConf.Keyfile, "ssh-keyfile", "", "Optional file with private key for SSH authentication")
|
||||
flags.StringVar(&sshConf.ConfigAlias, "ssh-alias", "", "Optional config alias with ~/.ssh/config for SSH authentication")
|
||||
flags.StringVar(&sshConf.GSSAPIPassword, "gssapi-password", "", "GSSAPI password")
|
||||
flags.StringVar(&sshConf.GSSAPIKeytabConf, "gssapi-keytab", "", "GSSAPI keytab file path")
|
||||
flags.StringVar(&sshConf.GSSAPICacheFile, "gssapi-cache", "", "GSSAPI cache file path, use command `kinit -c /path/to/cache USERNAME@RELAM` to generate")
|
||||
flags.StringVar(&sshConf.RemoteKubeconfig, "remote-kubeconfig", "", "Remote kubeconfig abstract path of ssh server, default is /home/$USERNAME/.kube/config")
|
||||
lookup := flags.Lookup("remote-kubeconfig")
|
||||
lookup.NoOptDefVal = "~/.kube/config"
|
||||
}
|
||||
|
||||
func addExtraRoute(cmd *cobra.Command, route *handler.ExtraRouteInfo) {
|
||||
cmd.Flags().StringArrayVar(&route.ExtraCIDR, "extra-cidr", []string{}, "Extra cidr string, add those cidr network to route table, eg: --extra-cidr 192.168.0.159/24 --extra-cidr 192.168.1.160/32")
|
||||
cmd.Flags().StringArrayVar(&route.ExtraDomain, "extra-domain", []string{}, "Extra domain string, the resolved ip will add to route table, eg: --extra-domain test.abc.com --extra-domain foo.test.com")
|
||||
cmd.Flags().BoolVar(&route.ExtraNodeIP, "extra-node-ip", false, "Extra node ip, add cluster node ip to route table.")
|
||||
func addExtraRoute(flags *flag.FlagSet, route *handler.ExtraRouteInfo) {
|
||||
flags.StringArrayVar(&route.ExtraCIDR, "extra-cidr", []string{}, "Extra cidr string, add those cidr network to route table, eg: --extra-cidr 192.168.0.159/24 --extra-cidr 192.168.1.160/32")
|
||||
flags.StringArrayVar(&route.ExtraDomain, "extra-domain", []string{}, "Extra domain string, the resolved ip will add to route table, eg: --extra-domain test.abc.com --extra-domain foo.test.com")
|
||||
flags.BoolVar(&route.ExtraNodeIP, "extra-node-ip", false, "Extra node ip, add cluster node ip to route table.")
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ func CmdReset(f cmdutil.Factory) *cobra.Command {
|
||||
},
|
||||
}
|
||||
|
||||
addSshFlags(cmd, sshConf)
|
||||
addSshFlags(cmd.Flags(), sshConf)
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ func CmdSSH(_ cmdutil.Factory) *cobra.Command {
|
||||
}
|
||||
},
|
||||
}
|
||||
addSshFlags(cmd, sshConf)
|
||||
addSshFlags(cmd.Flags(), sshConf)
|
||||
cmd.Flags().StringArrayVar(&ExtraCIDR, "extra-cidr", []string{}, "Extra cidr string, eg: --extra-cidr 192.168.0.159/24 --extra-cidr 192.168.1.160/32")
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -1,19 +1,38 @@
|
||||
package cmds
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
flag "github.com/spf13/pflag"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"k8s.io/kubectl/pkg/util/i18n"
|
||||
"k8s.io/kubectl/pkg/util/templates"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/daemon"
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/daemon/rpc"
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/handler"
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
|
||||
)
|
||||
|
||||
const (
|
||||
FormatJson = "json"
|
||||
FormatYaml = "yaml"
|
||||
FormatTable = "table"
|
||||
)
|
||||
|
||||
func CmdStatus(f cmdutil.Factory) *cobra.Command {
|
||||
var aliasName string
|
||||
var localFile string
|
||||
var remoteAddr string
|
||||
var format string
|
||||
cmd := &cobra.Command{
|
||||
Use: "status",
|
||||
Short: i18n.T("KubeVPN status"),
|
||||
@@ -21,21 +40,141 @@ func CmdStatus(f cmdutil.Factory) *cobra.Command {
|
||||
Example: templates.Examples(i18n.T(`
|
||||
# show status for kubevpn status
|
||||
kubevpn status
|
||||
|
||||
# query status by alias config name dev_new
|
||||
kubevpn status --alias dev_new
|
||||
`)),
|
||||
PreRunE: func(cmd *cobra.Command, args []string) (err error) {
|
||||
return daemon.StartupDaemon(cmd.Context())
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
client, err := daemon.GetClient(false).Status(
|
||||
var clusterIDs []string
|
||||
if aliasName != "" {
|
||||
configs, err := ParseAndGet(localFile, remoteAddr, aliasName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, config := range configs {
|
||||
clusterID, err := GetClusterIDByConfig(cmd, config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
clusterIDs = append(clusterIDs, clusterID)
|
||||
}
|
||||
}
|
||||
|
||||
resp, err := daemon.GetClient(false).Status(
|
||||
cmd.Context(),
|
||||
&rpc.StatusRequest{},
|
||||
&rpc.StatusRequest{
|
||||
ClusterIDs: clusterIDs,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprint(os.Stdout, client.GetMessage())
|
||||
output, err := genOutput(resp, format)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprint(os.Stdout, output)
|
||||
return nil
|
||||
},
|
||||
}
|
||||
cmd.Flags().StringVar(&aliasName, "alias", "", "Alias name, query connect status by alias config name")
|
||||
cmd.Flags().StringVarP(&localFile, "file", "f", daemon.GetConfigFilePath(), "Config file location")
|
||||
cmd.Flags().StringVarP(&remoteAddr, "remote", "r", "", "Remote config file, eg: https://raw.githubusercontent.com/kubenetworks/kubevpn/master/pkg/config/config.yaml")
|
||||
cmd.Flags().StringVarP(&format, "output", "o", FormatTable, fmt.Sprintf("Output format. One of: (%s, %s, %s)", FormatJson, FormatYaml, FormatTable))
|
||||
return cmd
|
||||
}
|
||||
|
||||
func genOutput(status *rpc.StatusResponse, format string) (string, error) {
|
||||
switch format {
|
||||
case FormatJson:
|
||||
if len(status.List) == 0 {
|
||||
return "", nil
|
||||
}
|
||||
marshal, err := json.Marshal(status.List)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(marshal), nil
|
||||
|
||||
case FormatYaml:
|
||||
if len(status.List) == 0 {
|
||||
return "", nil
|
||||
}
|
||||
marshal, err := yaml.Marshal(status.List)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(marshal), nil
|
||||
default:
|
||||
var sb = new(bytes.Buffer)
|
||||
w := tabwriter.NewWriter(sb, 1, 1, 1, ' ', 0)
|
||||
_, _ = fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\t%s\n", "ID", "Mode", "Cluster", "Kubeconfig", "Namespace", "Status", "Netif")
|
||||
|
||||
for _, s := range status.List {
|
||||
_, _ = fmt.Fprintf(w, "%d\t%s\t%s\t%s\t%s\t%s\t%s\n",
|
||||
s.ID, s.Mode, s.Cluster, s.Kubeconfig, s.Namespace, s.Status, s.Netif)
|
||||
}
|
||||
_ = w.Flush()
|
||||
return sb.String(), nil
|
||||
}
|
||||
}
|
||||
|
||||
func GetClusterIDByConfig(cmd *cobra.Command, config Config) (string, error) {
|
||||
flags := flag.NewFlagSet("", flag.ContinueOnError)
|
||||
var sshConf = &util.SshConfig{}
|
||||
addSshFlags(flags, sshConf)
|
||||
configFlags := genericclioptions.NewConfigFlags(false).WithDeprecatedPasswordFlag()
|
||||
configFlags.AddFlags(flags)
|
||||
matchVersionFlags := cmdutil.NewMatchVersionFlags(&warp{ConfigFlags: configFlags})
|
||||
matchVersionFlags.AddFlags(flags)
|
||||
factory := cmdutil.NewFactory(matchVersionFlags)
|
||||
|
||||
for _, command := range cmd.Parent().Commands() {
|
||||
command.Flags().VisitAll(func(f *flag.Flag) {
|
||||
if flags.Lookup(f.Name) == nil && flags.ShorthandLookup(f.Shorthand) == nil {
|
||||
flags.AddFlag(f)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
split := strings.Split(strings.Join(config.Flags, " "), " ")
|
||||
err := flags.ParseAll(split[:], func(flag *flag.Flag, value string) error {
|
||||
_ = flags.Set(flag.Name, value)
|
||||
return nil
|
||||
})
|
||||
bytes, ns, err := util.ConvertToKubeConfigBytes(factory)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
file, err := util.ConvertToTempKubeconfigFile(bytes)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
flags = flag.NewFlagSet("", flag.ContinueOnError)
|
||||
flags.AddFlag(&flag.Flag{
|
||||
Name: "kubeconfig",
|
||||
DefValue: file,
|
||||
})
|
||||
flags.AddFlag(&flag.Flag{
|
||||
Name: "namespace",
|
||||
DefValue: ns,
|
||||
})
|
||||
var path string
|
||||
path, err = util.SshJump(cmd.Context(), sshConf, flags, false)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
var c = &handler.ConnectOptions{}
|
||||
err = c.InitClient(util.InitFactoryByPath(path, ns))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
err = c.InitDHCP(cmd.Context())
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return c.GetClusterID(), nil
|
||||
}
|
||||
|
||||
31
cmd/kubevpn/cmds/status_test.go
Normal file
31
cmd/kubevpn/cmds/status_test.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package cmds
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func TestParseFlags(t *testing.T) {
|
||||
str := `
|
||||
Name: test
|
||||
Needs: test1
|
||||
Flags:
|
||||
- --kubeconfig ~/.kube/vke
|
||||
- --namespace test
|
||||
- --ssh-username admin
|
||||
- --ssh-addr 127.0.0.1:22
|
||||
|
||||
---`
|
||||
config, err := ParseConfig([]byte(str))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
sshConf, bytes, ns, err := GetClusterIDByConfig(config)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
t.Log(ns, string(bytes))
|
||||
t.Log(sshConf.Addr, sshConf.User)
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/pflag"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/daemon/rpc"
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/dns"
|
||||
@@ -69,6 +70,34 @@ func (svr *Server) Disconnect(req *rpc.DisconnectRequest, resp rpc.Daemon_Discon
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case len(req.ClusterIDs) != 0:
|
||||
s := sets.New(req.ClusterIDs...)
|
||||
var connects = *new(handler.Connects)
|
||||
var foundModeFull bool
|
||||
if s.Has(svr.connect.GetClusterID()) {
|
||||
connects = connects.Append(svr.connect)
|
||||
foundModeFull = true
|
||||
}
|
||||
for i := 0; i < len(svr.secondaryConnect); i++ {
|
||||
if s.Has(svr.secondaryConnect[i].GetClusterID()) {
|
||||
connects = connects.Append(svr.secondaryConnect[i])
|
||||
svr.secondaryConnect = append(svr.secondaryConnect[:i], svr.secondaryConnect[i+1:]...)
|
||||
i--
|
||||
}
|
||||
}
|
||||
for _, connect := range connects.Sort() {
|
||||
if connect != nil {
|
||||
connect.Cleanup()
|
||||
}
|
||||
}
|
||||
if foundModeFull {
|
||||
svr.connect = nil
|
||||
svr.t = time.Time{}
|
||||
if svr.clone != nil {
|
||||
_ = svr.clone.Cleanup()
|
||||
}
|
||||
svr.clone = nil
|
||||
}
|
||||
}
|
||||
|
||||
if svr.connect == nil && len(svr.secondaryConnect) == 0 {
|
||||
|
||||
@@ -1,47 +1,62 @@
|
||||
package action
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/daemon/rpc"
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/handler"
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
|
||||
)
|
||||
|
||||
const (
|
||||
StatusOk = "Connected"
|
||||
StatusFailed = "Disconnected"
|
||||
|
||||
ModeFull = "full"
|
||||
ModeLite = "lite"
|
||||
)
|
||||
|
||||
func (svr *Server) Status(ctx context.Context, request *rpc.StatusRequest) (*rpc.StatusResponse, error) {
|
||||
var sb = new(bytes.Buffer)
|
||||
w := tabwriter.NewWriter(sb, 1, 1, 1, ' ', 0)
|
||||
_, _ = fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\t%s\n", "ID", "Mode", "Cluster", "Kubeconfig", "Namespace", "Status", "Netif")
|
||||
if svr.connect != nil {
|
||||
cluster := util.GetKubeconfigCluster(svr.connect.GetFactory())
|
||||
namespace := svr.connect.Namespace
|
||||
kubeconfig := svr.connect.OriginKubeconfigPath
|
||||
name, _ := svr.connect.GetTunDeviceName()
|
||||
status := StatusOk
|
||||
if name == "" {
|
||||
status = StatusFailed
|
||||
}
|
||||
_, _ = fmt.Fprintf(w, "%d\t%s\t%s\t%s\t%s\t%s\t%s\n",
|
||||
0, "full", cluster, kubeconfig, namespace, status, name)
|
||||
}
|
||||
func (svr *Server) Status(ctx context.Context, req *rpc.StatusRequest) (*rpc.StatusResponse, error) {
|
||||
var list []*rpc.Status
|
||||
|
||||
for i, options := range svr.secondaryConnect {
|
||||
cluster := util.GetKubeconfigCluster(options.GetFactory())
|
||||
name, _ := options.GetTunDeviceName()
|
||||
status := StatusOk
|
||||
if name == "" {
|
||||
status = StatusFailed
|
||||
if len(req.ClusterIDs) != 0 {
|
||||
for _, clusterID := range req.ClusterIDs {
|
||||
if svr.connect.GetClusterID() == clusterID {
|
||||
list = append(list, genStatus(svr.connect, ModeFull, 0))
|
||||
}
|
||||
for i, options := range svr.secondaryConnect {
|
||||
if options.GetClusterID() == clusterID {
|
||||
list = append(list, genStatus(options, ModeLite, int32(i+1)))
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if svr.connect != nil {
|
||||
list = append(list, genStatus(svr.connect, ModeFull, 0))
|
||||
}
|
||||
|
||||
for i, options := range svr.secondaryConnect {
|
||||
list = append(list, genStatus(options, ModeLite, int32(i+1)))
|
||||
}
|
||||
_, _ = fmt.Fprintf(w, "%d\t%s\t%s\t%s\t%s\t%s\t%s\n",
|
||||
i+1, "lite", cluster, options.OriginKubeconfigPath, options.Namespace, status, name)
|
||||
}
|
||||
_ = w.Flush()
|
||||
return &rpc.StatusResponse{Message: sb.String()}, nil
|
||||
return &rpc.StatusResponse{List: list}, nil
|
||||
}
|
||||
|
||||
func genStatus(connect *handler.ConnectOptions, mode string, index int32) *rpc.Status {
|
||||
status := StatusOk
|
||||
tunName, _ := connect.GetTunDeviceName()
|
||||
if tunName == "" {
|
||||
status = StatusFailed
|
||||
}
|
||||
info := rpc.Status{
|
||||
ID: index,
|
||||
ClusterID: connect.GetClusterID(),
|
||||
Cluster: util.GetKubeconfigCluster(connect.GetFactory()),
|
||||
Mode: mode,
|
||||
Kubeconfig: connect.OriginKubeconfigPath,
|
||||
Namespace: connect.Namespace,
|
||||
Status: status,
|
||||
Netif: tunName,
|
||||
}
|
||||
return &info
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -68,7 +68,9 @@ message DisconnectRequest {
|
||||
// 3) disconnect by kubeConfig
|
||||
optional string KubeconfigBytes = 3;
|
||||
optional string Namespace = 4;
|
||||
SshJump SshJump = 10;
|
||||
SshJump SshJump = 5;
|
||||
// 4) disconnect by cluster ids
|
||||
repeated string ClusterIDs = 6;
|
||||
}
|
||||
|
||||
message DisconnectResponse {
|
||||
@@ -134,11 +136,22 @@ message QuitResponse {
|
||||
}
|
||||
|
||||
message StatusRequest {
|
||||
string name = 1;
|
||||
repeated string ClusterIDs = 1;
|
||||
}
|
||||
|
||||
message StatusResponse {
|
||||
string message = 1;
|
||||
repeated Status List = 1;
|
||||
}
|
||||
|
||||
message Status {
|
||||
int32 ID = 1;
|
||||
string ClusterID = 2;
|
||||
string Cluster = 3;
|
||||
string Mode = 4;
|
||||
string Kubeconfig = 5;
|
||||
string Namespace = 6;
|
||||
string Status = 7;
|
||||
string Netif = 8;
|
||||
}
|
||||
|
||||
message VersionRequest {
|
||||
|
||||
@@ -999,6 +999,13 @@ func (c *ConnectOptions) GetLocalTunIPv4() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (c *ConnectOptions) GetClusterID() string {
|
||||
if c != nil && c.dhcp != nil {
|
||||
return string(c.dhcp.clusterID)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (c *ConnectOptions) upgradeDeploy(ctx context.Context) error {
|
||||
deployment, err := c.clientset.AppsV1().Deployments(c.Namespace).Get(ctx, config.ConfigMapPodTrafficManager, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
|
||||
)
|
||||
|
||||
type DHCPManager struct {
|
||||
@@ -23,6 +24,7 @@ type DHCPManager struct {
|
||||
cidr *net.IPNet
|
||||
cidr6 *net.IPNet
|
||||
namespace string
|
||||
clusterID types.UID
|
||||
}
|
||||
|
||||
func NewDHCPManager(client corev1.ConfigMapInterface, namespace string) *DHCPManager {
|
||||
@@ -41,6 +43,7 @@ func (d *DHCPManager) initDHCP(ctx context.Context) error {
|
||||
if err != nil && !apierrors.IsNotFound(err) {
|
||||
return fmt.Errorf("failed to get configmap %s, err: %v", config.ConfigMapPodTrafficManager, err)
|
||||
}
|
||||
d.clusterID = util.GetClusterIDByCM(cm)
|
||||
if err == nil {
|
||||
// add key envoy in case of mount not exist content
|
||||
if _, found := cm.Data[config.KeyEnvoy]; !found {
|
||||
@@ -51,6 +54,8 @@ func (d *DHCPManager) initDHCP(ctx context.Context) error {
|
||||
[]byte(fmt.Sprintf(`{"data":{"%s":"%s"}}`, config.KeyEnvoy, "")),
|
||||
metav1.PatchOptions{},
|
||||
)
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to patch configmap %s, err: %v", config.ConfigMapPodTrafficManager, err)
|
||||
}
|
||||
return nil
|
||||
@@ -66,10 +71,11 @@ func (d *DHCPManager) initDHCP(ctx context.Context) error {
|
||||
config.KeyRefCount: "0",
|
||||
},
|
||||
}
|
||||
_, err = d.client.Create(ctx, cm, metav1.CreateOptions{})
|
||||
cm, err = d.client.Create(ctx, cm, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("create dhcp error, err: %v", err)
|
||||
}
|
||||
d.clusterID = util.GetClusterIDByCM(cm)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"reflect"
|
||||
"unsafe"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
@@ -24,12 +24,16 @@ import (
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
|
||||
)
|
||||
|
||||
func GetClusterId(client v12.ConfigMapInterface) (types.UID, error) {
|
||||
a, err := client.Get(context.Background(), config.ConfigMapPodTrafficManager, metav1.GetOptions{})
|
||||
func GetClusterID(ctx context.Context, client v12.ConfigMapInterface) (types.UID, error) {
|
||||
configMap, err := client.Get(ctx, config.ConfigMapPodTrafficManager, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return a.UID, nil
|
||||
return configMap.UID, nil
|
||||
}
|
||||
|
||||
func GetClusterIDByCM(cm *v1.ConfigMap) types.UID {
|
||||
return cm.UID
|
||||
}
|
||||
|
||||
func IsSameCluster(client v12.ConfigMapInterface, namespace string, clientB v12.ConfigMapInterface, namespaceB string) (bool, error) {
|
||||
@@ -37,16 +41,16 @@ func IsSameCluster(client v12.ConfigMapInterface, namespace string, clientB v12.
|
||||
return false, nil
|
||||
}
|
||||
ctx := context.Background()
|
||||
a, err := client.Get(ctx, config.ConfigMapPodTrafficManager, metav1.GetOptions{})
|
||||
clusterIDA, err := GetClusterID(ctx, client)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
var b *corev1.ConfigMap
|
||||
b, err = clientB.Get(ctx, config.ConfigMapPodTrafficManager, metav1.GetOptions{})
|
||||
var clusterIDB types.UID
|
||||
clusterIDB, err = GetClusterID(ctx, clientB)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return a.UID == b.UID, nil
|
||||
return clusterIDA == clusterIDB, nil
|
||||
}
|
||||
|
||||
func ConvertToKubeConfigBytes(factory cmdutil.Factory) ([]byte, string, error) {
|
||||
|
||||
@@ -524,14 +524,7 @@ func SshJump(ctx context.Context, conf *SshConfig, flags *pflag.FlagSet, print b
|
||||
configFlags.KubeConfig = pointer.String(temp.Name())
|
||||
} else {
|
||||
if flags != nil {
|
||||
lookup := flags.Lookup("kubeconfig")
|
||||
if lookup != nil {
|
||||
if lookup.Value != nil && lookup.Value.String() != "" {
|
||||
configFlags.KubeConfig = pointer.String(lookup.Value.String())
|
||||
} else if lookup.DefValue != "" {
|
||||
configFlags.KubeConfig = pointer.String(lookup.DefValue)
|
||||
}
|
||||
}
|
||||
configFlags.AddFlags(flags)
|
||||
}
|
||||
}
|
||||
matchVersionFlags := util.NewMatchVersionFlags(configFlags)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.30.0
|
||||
// protoc-gen-go v1.33.0
|
||||
// protoc v3.21.2
|
||||
// source: dhcpserver.proto
|
||||
|
||||
|
||||
Reference in New Issue
Block a user