mirror of
https://github.com/kubenetworks/kubevpn.git
synced 2025-09-27 03:36:09 +08:00
feat: add flags --kubeconfig-json (#694)
This commit is contained in:
@@ -61,6 +61,7 @@ func CmdAlias(f cmdutil.Factory) *cobra.Command {
|
|||||||
If you have following config in your ~/.kubevpn/config.yaml
|
If you have following config in your ~/.kubevpn/config.yaml
|
||||||
|
|
||||||
Name: dev
|
Name: dev
|
||||||
|
Description: This is dev k8s environment
|
||||||
Needs: jumper
|
Needs: jumper
|
||||||
Flags:
|
Flags:
|
||||||
- connect
|
- connect
|
||||||
@@ -69,11 +70,20 @@ func CmdAlias(f cmdutil.Factory) *cobra.Command {
|
|||||||
---
|
---
|
||||||
|
|
||||||
Name: jumper
|
Name: jumper
|
||||||
|
Description: This is jumper k8s environment
|
||||||
Flags:
|
Flags:
|
||||||
- connect
|
- connect
|
||||||
- --kubeconfig=~/.kube/jumper_config
|
- --kubeconfig=~/.kube/jumper_config
|
||||||
- --namespace=test
|
- --namespace=test
|
||||||
- --extra-hosts=xxx.com
|
- --extra-hosts=xxx.com
|
||||||
|
|
||||||
|
Name: all-in-one
|
||||||
|
Description: use special flags '--kubeconfig-json', no need to special kubeconfig path
|
||||||
|
Flags:
|
||||||
|
- connect
|
||||||
|
- --kubeconfig-json={"apiVersion":"v1","clusters":[{"cluster":{"certificate-authority-data":"LS0tLS1CRU..."}}]}
|
||||||
|
- --namespace=test
|
||||||
|
- --extra-hosts=xxx.com
|
||||||
|
|
||||||
Config file support three field: Name,Needs,Flags
|
Config file support three field: Name,Needs,Flags
|
||||||
|
|
||||||
@@ -82,6 +92,9 @@ func CmdAlias(f cmdutil.Factory) *cobra.Command {
|
|||||||
|
|
||||||
# kubevpn alias jumper, just connect to cluster jumper
|
# kubevpn alias jumper, just connect to cluster jumper
|
||||||
kubevpn alias jumper
|
kubevpn alias jumper
|
||||||
|
|
||||||
|
# support special flags '--kubeconfig-json', it will save kubeconfig into ~/.kubevpn/temp/[ALIAS_NAME]
|
||||||
|
kubevpn alias all-in-one
|
||||||
`)),
|
`)),
|
||||||
PreRunE: func(cmd *cobra.Command, args []string) (err error) {
|
PreRunE: func(cmd *cobra.Command, args []string) (err error) {
|
||||||
if localFile != "" {
|
if localFile != "" {
|
||||||
@@ -100,6 +113,10 @@ func CmdAlias(f cmdutil.Factory) *cobra.Command {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, conf := range configs {
|
for _, conf := range configs {
|
||||||
|
err = ParseArgs(cmd, &conf)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
c := exec.Command(name, conf.Flags...)
|
c := exec.Command(name, conf.Flags...)
|
||||||
c.Stdout = os.Stdout
|
c.Stdout = os.Stdout
|
||||||
c.Stdin = os.Stdin
|
c.Stdin = os.Stdin
|
||||||
|
@@ -5,6 +5,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/pflag"
|
||||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||||
"k8s.io/client-go/rest"
|
"k8s.io/client-go/rest"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
@@ -16,6 +17,7 @@ import (
|
|||||||
"k8s.io/utils/ptr"
|
"k8s.io/utils/ptr"
|
||||||
|
|
||||||
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
|
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
|
||||||
|
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewKubeVPNCommand() *cobra.Command {
|
func NewKubeVPNCommand() *cobra.Command {
|
||||||
@@ -97,8 +99,13 @@ func NewKubeVPNCommand() *cobra.Command {
|
|||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func AddKubeconfigJsonFlag(flags *pflag.FlagSet, kubeconfigJson *string) {
|
||||||
|
flags.StringVar(kubeconfigJson, "kubeconfig-json", ptr.Deref[string](kubeconfigJson, ""), "Json format of kubeconfig to use for CLI requests.")
|
||||||
|
}
|
||||||
|
|
||||||
type warp struct {
|
type warp struct {
|
||||||
*genericclioptions.ConfigFlags
|
*genericclioptions.ConfigFlags
|
||||||
|
KubeconfigJson string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *warp) ToRawKubeConfigLoader() clientcmd.ClientConfig {
|
func (f *warp) ToRawKubeConfigLoader() clientcmd.ClientConfig {
|
||||||
@@ -106,5 +113,11 @@ func (f *warp) ToRawKubeConfigLoader() clientcmd.ClientConfig {
|
|||||||
home := homedir.HomeDir()
|
home := homedir.HomeDir()
|
||||||
f.KubeConfig = ptr.To(strings.Replace(*f.KubeConfig, "~", home, 1))
|
f.KubeConfig = ptr.To(strings.Replace(*f.KubeConfig, "~", home, 1))
|
||||||
}
|
}
|
||||||
|
if strings.TrimSpace(f.KubeconfigJson) != "" {
|
||||||
|
path, err := util.ConvertToTempKubeconfigFile([]byte(f.KubeconfigJson))
|
||||||
|
if err == nil {
|
||||||
|
f.KubeConfig = ptr.To(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
return f.ConfigFlags.ToRawKubeConfigLoader()
|
return f.ConfigFlags.ToRawKubeConfigLoader()
|
||||||
}
|
}
|
||||||
|
@@ -5,6 +5,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/liggitt/tabwriter"
|
"github.com/liggitt/tabwriter"
|
||||||
@@ -233,9 +234,11 @@ func GetConnectionIDByConfig(cmd *cobra.Command, config Config) (string, error)
|
|||||||
handler.AddExtraRoute(flags, &handler.ExtraRouteInfo{})
|
handler.AddExtraRoute(flags, &handler.ExtraRouteInfo{})
|
||||||
configFlags := genericclioptions.NewConfigFlags(true)
|
configFlags := genericclioptions.NewConfigFlags(true)
|
||||||
configFlags.AddFlags(flags)
|
configFlags.AddFlags(flags)
|
||||||
matchVersionFlags := cmdutil.NewMatchVersionFlags(&warp{ConfigFlags: configFlags})
|
var kubeconfigJson string
|
||||||
|
AddKubeconfigJsonFlag(flags, &kubeconfigJson)
|
||||||
|
matchVersionFlags := cmdutil.NewMatchVersionFlags(&warp{ConfigFlags: configFlags, KubeconfigJson: kubeconfigJson})
|
||||||
matchVersionFlags.AddFlags(flags)
|
matchVersionFlags.AddFlags(flags)
|
||||||
factory := cmdutil.NewFactory(matchVersionFlags)
|
f := cmdutil.NewFactory(matchVersionFlags)
|
||||||
|
|
||||||
for _, command := range cmd.Parent().Commands() {
|
for _, command := range cmd.Parent().Commands() {
|
||||||
command.Flags().VisitAll(func(f *flag.Flag) {
|
command.Flags().VisitAll(func(f *flag.Flag) {
|
||||||
@@ -249,7 +252,7 @@ func GetConnectionIDByConfig(cmd *cobra.Command, config Config) (string, error)
|
|||||||
_ = flags.Set(flag.Name, value)
|
_ = flags.Set(flag.Name, value)
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
bytes, ns, err := util.ConvertToKubeConfigBytes(factory)
|
bytes, ns, err := util.ConvertToKubeConfigBytes(f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -275,3 +278,56 @@ func GetConnectionIDByConfig(cmd *cobra.Command, config Config) (string, error)
|
|||||||
}
|
}
|
||||||
return id, nil
|
return id, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ParseArgs(cmd *cobra.Command, conf *Config) error {
|
||||||
|
var str string
|
||||||
|
for i := 0; i < len(conf.Flags); i++ {
|
||||||
|
kubeconfigJson, err := parseKubeconfigJson(cmd, []string{conf.Flags[i]})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if kubeconfigJson != "" {
|
||||||
|
str = kubeconfigJson
|
||||||
|
conf.Flags = append(conf.Flags[:i], conf.Flags[i+1:]...)
|
||||||
|
i--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if str == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := util.ConvertToKubeconfigFile([]byte(str), filepath.Join(config.GetTempPath(), conf.Name))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
conf.Flags = append(conf.Flags, fmt.Sprintf("%s=%s", "--kubeconfig", file))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseKubeconfigJson(cmd *cobra.Command, args []string) (string, error) {
|
||||||
|
flags := flag.NewFlagSet("", flag.ContinueOnError)
|
||||||
|
var sshConf = &pkgssh.SshConfig{}
|
||||||
|
pkgssh.AddSshFlags(flags, sshConf)
|
||||||
|
handler.AddExtraRoute(flags, &handler.ExtraRouteInfo{})
|
||||||
|
configFlags := genericclioptions.NewConfigFlags(true)
|
||||||
|
configFlags.AddFlags(flags)
|
||||||
|
var kubeconfigJson string
|
||||||
|
AddKubeconfigJsonFlag(flags, &kubeconfigJson)
|
||||||
|
matchVersionFlags := cmdutil.NewMatchVersionFlags(&warp{ConfigFlags: configFlags})
|
||||||
|
matchVersionFlags.AddFlags(flags)
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
err := flags.ParseAll(args, func(flag *flag.Flag, value string) error {
|
||||||
|
_ = flags.Set(flag.Name, value)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
return kubeconfigJson, err
|
||||||
|
}
|
||||||
|
@@ -4,6 +4,7 @@
|
|||||||
# Just keep simple
|
# Just keep simple
|
||||||
|
|
||||||
Name: dev
|
Name: dev
|
||||||
|
Description: This is dev k8s environment, needs jump by qa env
|
||||||
Needs: qa
|
Needs: qa
|
||||||
Flags:
|
Flags:
|
||||||
- connect
|
- connect
|
||||||
@@ -13,6 +14,7 @@ Flags:
|
|||||||
---
|
---
|
||||||
|
|
||||||
Name: qa
|
Name: qa
|
||||||
|
Description: This is QA k8s environment
|
||||||
Flags:
|
Flags:
|
||||||
- connect
|
- connect
|
||||||
- --kubeconfig=~/.kube/jumper_config
|
- --kubeconfig=~/.kube/jumper_config
|
||||||
|
@@ -152,6 +152,26 @@ func ConvertToTempKubeconfigFile(kubeconfigBytes []byte) (string, error) {
|
|||||||
return temp.Name(), nil
|
return temp.Name(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ConvertToKubeconfigFile(kubeconfigBytes []byte, filename string) (string, error) {
|
||||||
|
f, err := os.Create(filename)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
_, err = f.Write(kubeconfigBytes)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
err = f.Chmod(0644)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
err = f.Close()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return f.Name(), nil
|
||||||
|
}
|
||||||
|
|
||||||
func containerPathSeparator(pattern string) bool {
|
func containerPathSeparator(pattern string) bool {
|
||||||
for i := 0; i < len(pattern); i++ {
|
for i := 0; i < len(pattern); i++ {
|
||||||
if os.IsPathSeparator(pattern[i]) {
|
if os.IsPathSeparator(pattern[i]) {
|
||||||
|
Reference in New Issue
Block a user