Skip to content

Commit

Permalink
add new cmd:alias
Browse files Browse the repository at this point in the history
  • Loading branch information
sunny0826 committed Oct 21, 2020
1 parent a611d49 commit 0b6a9e2
Show file tree
Hide file tree
Showing 14 changed files with 317 additions and 389 deletions.
43 changes: 30 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,18 @@ Usage:
kubecm [command]
Available Commands:
add Merge configuration file with $HOME/.kube/config
completion Generates bash/zsh completion scripts
delete Delete the specified context from the kubeconfig
help Help about any command
merge Merge the kubeconfig files in the specified directory
namespace Switch or change namespace interactively
rename Rename the contexts of kubeconfig
switch Switch Kube Context interactively
version Print version info
add Merge configuration file with $HOME/.kube/config
alias Generate alias for all contexts
completion Generates bash/zsh completion scripts
delete Delete the specified context from the kubeconfig
help Help about any command
ls List kubeconfig
merge Merge the kubeconfig files in the specified directory
namespace Switch or change namespace interactively
rename Rename the contexts of kubeconfig
switch Switch Kube Context interactively
version Print version info
Flags:
--config string path of kubeconfig (default "$HOME/.kube/config")
Expand Down Expand Up @@ -107,6 +110,24 @@ kubecm ls
kubecm l
```

### Generate alias

Generate alias for all contexts.

```shell script
$ kubecm alias
# dev
alias k-dev='kubectl --context dev'
# test
alias k-test='kubectl --context test'
# prod
alias k-prod='kubectl --context prod'
$ kubecm alias -o zsh
# add alias context to ~/.zshrc
$ kubecm alias -o bash
# add alias context to ~/.bash_profile
```

### Add configuration to `$HOME/.kube/config`

```shell script
Expand Down Expand Up @@ -151,10 +172,6 @@ kubecm delete my-context
```shell script
# Renamed the context interactively
kubecm rename
# Renamed dev to test
kubecm rename -o dev -n test
# Renamed current-context name to dev
kubecm rename -n dev -c
```

### Switch namespace
Expand Down
184 changes: 53 additions & 131 deletions cmd/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,15 @@ limitations under the License.
package cmd

import (
"errors"
"fmt"
"github.com/spf13/cobra"
"io/ioutil"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/tools/clientcmd"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
clientcmdlatest "k8s.io/client-go/tools/clientcmd/api/latest"
"log"
"os"
syaml "sigs.k8s.io/yaml"
"strings"
)

var file string
var name string
var cover bool

type AddCommand struct {
baseCommand
}
Expand All @@ -47,178 +39,108 @@ func (ac *AddCommand) Init() {
},
Example: addExample(),
}
ac.command.Flags().StringVarP(&file, "file", "f", "", "Path to merge kubeconfig files")
ac.command.Flags().StringVarP(&name, "name", "n", "", "The name of contexts. if this field is null,it will be named with file name.")
ac.command.Flags().StringP("file", "f", "", "Path to merge kubeconfig files")
ac.command.Flags().StringP("name", "n", "", "The name of contexts. if this field is null,it will be named with file name.")
ac.command.Flags().BoolP("cover", "c", false, "Overwrite the original kubeconfig file")
ac.command.MarkFlagRequired("file")
}

func (ac *AddCommand) runAdd(command *cobra.Command, args []string) error {
if fileExists(file) {
err := configCheck(file)
if err != nil {
log.Fatal(err)
}
cover, _ = ac.command.Flags().GetBool("cover")
config, err := getAddConfig(file)
if err != nil {
Error.Println(err)
}
output := merge2Master(config)
err = WriteConfig(output)
if err != nil {
Error.Println(err.Error())
} else {
if cover {
ac.command.Printf("「%s」 add successful!\n", file)
err = Formatable(nil)
} else {
ac.command.Println("generate ./config.yaml")
}
if err != nil {
log.Fatal(err)
}
}
} else {
log.Fatalf("%s file does not exist", file)
func (ac *AddCommand) runAdd(cmd *cobra.Command, args []string) error {
file, _ := ac.command.Flags().GetString("file")
if fileNotExists(file) {
return errors.New(file + " file does not exist")
}
newConfig, err := ac.formatNewConfig(file)
if err != nil {
return err
}
oldConfig, err := clientcmd.LoadFromFile(cfgFile)
if err != nil {
return err
}
outConfig := appendConfig(oldConfig, newConfig)
cover, _ := ac.command.Flags().GetBool("cover")
err = ac.WriteConfig(cover, file, outConfig)
if err != nil {
return err
}
return nil
}

func getAddConfig(kubeconfig string) (*clientcmdapi.Config, error) {

config, err := LoadClientConfig(kubeconfig)
func (ac *AddCommand) formatNewConfig(file string) (*clientcmdapi.Config, error) {
config, err := clientcmd.LoadFromFile(file)
if err != nil {
return nil, err
}

if len(config.AuthInfos) != 1 {
log.Fatal("Only support add 1 context.")
return nil, errors.New("Only support add 1 context. You can use `merge` cmd.\n")
}

name := getName(kubeconfig)
err = nameCheck(name)
name, err := ac.fotmatAndCheckName(file)
if err != nil {
log.Fatal(err)
return nil, err
}
suffix := HashSuf(config)
username := fmt.Sprintf("user-%v", suffix)
clustername := fmt.Sprintf("cluster-%v", suffix)

userName := fmt.Sprintf("user-%v", suffix)
clusterName := fmt.Sprintf("cluster-%v", suffix)
for key, obj := range config.AuthInfos {
config.AuthInfos[username] = obj
config.AuthInfos[userName] = obj
delete(config.AuthInfos, key)
break
}
for key, obj := range config.Clusters {
config.Clusters[clustername] = obj
config.Clusters[clusterName] = obj
delete(config.Clusters, key)
break
}
for key, obj := range config.Contexts {
obj.AuthInfo = username
obj.Cluster = clustername
obj.AuthInfo = userName
obj.Cluster = clusterName
config.Contexts[name] = obj
delete(config.Contexts, key)
break
}

return config, nil
}

func nameCheck(name string) error {
c, err := LoadClientConfig(cfgFile)
func (ac *AddCommand) fotmatAndCheckName(file string) (string, error) {
name, _ := ac.command.Flags().GetString("name")
if name == "" {
n := strings.Split(file, "/")
result := strings.Split(n[len(n)-1], ".")
name = result[0]
}
config, err := clientcmd.LoadFromFile(cfgFile)
if err != nil {
return err
return "", err
}
for key, _ := range c.Contexts {
for key, _ := range config.Contexts {
if key == name {
return fmt.Errorf("The name: %s already exists, please replace it.", name)
return "", errors.New("The name: " + name + " already exists, please replace it.\n")
}
}
return nil
return name, nil
}

func fileExists(path string) bool {
func fileNotExists(path string) bool {
_, err := os.Stat(path) //os.Stat获取文件信息
if err != nil {
if os.IsExist(err) {
return true
return false
}
return false
}
return true
}

func getName(kubeconfig string) string {
if file == ""{
return kubeconfig
}
if name == "" {
n := strings.Split(file, "/")
result := strings.Split(n[len(n)-1], ".")
return result[0]
} else {
return name
}
}

func configCheck(kubeconfigPath string) error {
_, err := clientcmd.BuildConfigFromFlags("", kubeconfigPath)
if err != nil {
return err
return true
}
return nil
}

func LoadClientConfig(kubeconfig string) (*clientcmdapi.Config, error) {
b, err := ioutil.ReadFile(kubeconfig)
if err != nil {
return nil, err
}
config, err := clientcmd.Load(b)
if err != nil {
return nil, err
}
return config, nil
}

func merge2Master(config *clientcmdapi.Config) []byte {
commandLineFile, _ := ioutil.TempFile("", "")
defer os.Remove(commandLineFile.Name())
configType := clientcmdapi.Config{
AuthInfos: config.AuthInfos,
Clusters: config.Clusters,
Contexts: config.Contexts,
}
_ = clientcmd.WriteToFile(configType, commandLineFile.Name())
loadingRules := &clientcmd.ClientConfigLoadingRules{
Precedence: []string{cfgFile, commandLineFile.Name()},
}

mergedConfig, err := loadingRules.Load()

json, err := runtime.Encode(clientcmdlatest.Codec, mergedConfig)
if err != nil {
Error.Printf("Unexpected error: %v", err)
}
output, err := syaml.JSONToYAML(json)
if err != nil {
Error.Printf("Unexpected error: %v", err)
}

return output
return false
}

func addExample() string {
return `
# Merge example.yaml with $HOME/.kube/config
kubecm add -f example.yaml
# Merge 1.yaml with $HOME/.kube/config
kubecm add -f 1.yaml
# Merge example.yaml and name contexts test with $HOME/.kube/config
kubecm add -f example.yaml -n test
# Merge 1.yaml and name contexts test with $HOME/.kube/config
kubecm add -f 1.yaml -n test
# Overwrite the original kubeconfig file
kubecm add -f example.yaml -c
kubecm add -f 1.yaml -c
`
}
Loading

0 comments on commit 0b6a9e2

Please sign in to comment.