Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
sunny0826 committed Aug 24, 2021
2 parents df2bd43 + 2486678 commit 3a9de90
Show file tree
Hide file tree
Showing 54 changed files with 1,728 additions and 590 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/go.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: Go

on:
push:
branches: [master]
branches:
- "master"
pull_request:
branches: [master]

jobs:
test:
Expand Down
15 changes: 0 additions & 15 deletions .github/workflows/homebrew.yaml

This file was deleted.

11 changes: 8 additions & 3 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
name: Release

on:
create:
tags:
- v*
push:
tags: 'v*'

jobs:
release:
Expand All @@ -25,3 +25,8 @@ jobs:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
HOMEBREW_TOKEN: ${{secrets.HOMEBREW_TOKEN}}

- name: Bump formulae
uses: dawidd6/[email protected]
with:
token: ${{ secrets.HOMEBREW_TOKEN }}
formula: kubecm
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,7 @@
dist/
kubecm

target
target
tmp
mergeDir
config.yaml
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@ test: fmt vet lint
go test -race -coverprofile=coverage.txt -covermode=atomic ./cmd/...

doc-gen:
rm -r docs/en/cli/*
ifneq ($(wildcard "tmp/cli"),)
rm -r tmp/cli/*
endif
go run hack/docgen/gen.go

GOLANGCILINT_VERSION ?= v1.29.0
Expand Down
53 changes: 28 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,50 +4,53 @@
[![Go Report Card](https://goreportcard.com/badge/github.com/sunny0826/kubecm)](https://goreportcard.com/report/github.com/sunny0826/kubecm)
![GitHub](https://img.shields.io/github/license/sunny0826/kubecm.svg)
[![GitHub release](https://img.shields.io/github/release/sunny0826/kubecm)](https://github.com/sunny0826/kubecm/releases)
[![codecov](https://codecov.io/gh/sunny0826/kubecm/branch/master/graph/badge.svg?token=KGTLBQ8HYZ)](undefined)
[![codecov](https://codecov.io/gh/sunny0826/kubecm/branch/master/graph/badge.svg?token=KGTLBQ8HYZ)](https://codecov.io/gh/sunny0826/kubecm)

```text
KubeConfig Manager
_ _
| | ___ _| |__ ___ ___ _ __ ___
| |/ / | | | '_ \ / _ \/ __| '_ \ _ \
| <| |_| | |_) | __/ (__| | | | | |
|_|\_\\__,_|_.__/ \___|\___|_| |_| |_|
Find more information at: https://github.com/sunny0826/kubecm
Manage your kubeconfig more easily.
██ ██ ██ ██ ██████ ███████ ██████ ███ ███
██ ██ ██ ██ ██ ██ ██ ██ ████ ████
█████ ██ ██ ██████ █████ ██ ██ ████ ██
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
██ ██ ██████ ██████ ███████ ██████ ██ ██
Tips Find more information at: https://kubecm.cloud
Usage:
kubecm [flags]
kubecm [command]
Available Commands:
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
add Add KubeConfig to $HOME/.kube/config
alias Generate alias for all contexts
clear Clear lapsed context, cluster and user
completion Generates bash/zsh completion scripts
create Create new KubeConfig(experiment)
delete Delete the specified context from the kubeconfig
help Help about any command
list 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")
-h, --help help for kubecm
-h, --help help for kubecm
Use "kubecm [command] --help" for more information about a command.
```

## Documentation

For full documentation, please visit the KubeVela website: [https://kubecm.cloud](https://kubecm.cloud)
For full documentation, please visit the KubeCM website: [https://kubecm.cloud](https://kubecm.cloud)

## Video
## Demo

[![](https://tva3.sinaimg.cn/large/ad5fbf65gy1gij1pl0pn5j218o0p81kx.jpg)](https://www.bilibili.com/video/av88259938/)
[![asciicast](https://asciinema.org/a/389595.svg)](https://asciinema.org/a/389595)

## Contribute

Expand Down
145 changes: 73 additions & 72 deletions cmd/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ package cmd
import (
"errors"
"fmt"
"os"
"strings"
"strconv"

"github.com/spf13/cobra"
"k8s.io/client-go/tools/clientcmd"
Expand All @@ -16,117 +15,119 @@ type AddCommand struct {
BaseCommand
}

type KubeConfigOption struct {
config *clientcmdapi.Config
fileName string
}

// Init AddCommand
func (ac *AddCommand) Init() {
ac.command = &cobra.Command{
Use: "add",
Short: "Merge configuration file with $HOME/.kube/config",
Long: "Merge configuration file with $HOME/.kube/config",
Short: "Add KubeConfig to $HOME/.kube/config",
Long: "Add KubeConfig to $HOME/.kube/config",
RunE: func(cmd *cobra.Command, args []string) error {
return ac.runAdd(cmd, args)
},
Example: addExample(),
}
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(cmd *cobra.Command, args []string) error {
file, _ := ac.command.Flags().GetString("file")
if fileNotExists(file) {
return errors.New(file + " file does not exist")
}
name := ac.command.Flag("name").Value.String()
newConfig, err := formatNewConfig(file, name)
// check path
file, err := CheckAndTransformFilePath(file)
if err != nil {
return err
}
oldConfig, err := clientcmd.LoadFromFile(cfgFile)
newConfig, err := clientcmd.LoadFromFile(file)
if err != nil {
return err
}
outConfig := appendConfig(oldConfig, newConfig)
cover, _ := ac.command.Flags().GetBool("cover")
err = WriteConfig(cover, file, outConfig)
oldConfig, err := clientcmd.LoadFromFile(cfgFile)
if err != nil {
return err
}
return nil
}

func formatNewConfig(file, nameFlag string) (*clientcmdapi.Config, error) {
config, err := clientcmd.LoadFromFile(file)
if err != nil {
return nil, err
}
if len(config.AuthInfos) != 1 {
return nil, errors.New("Only support add 1 context. You can use `merge` cmd")
kco := &KubeConfigOption{
config: newConfig,
fileName: getFileName(file),
}
name, err := formatAndCheckName(file, nameFlag)
// merge context loop
outConfig, err := kco.handleContexts(oldConfig)
if err != nil {
return nil, err
return err
}
suffix := HashSuf(config)
userName := fmt.Sprintf("user-%v", suffix)
clusterName := fmt.Sprintf("cluster-%v", suffix)
for key, obj := range config.AuthInfos {
config.AuthInfos[userName] = obj
delete(config.AuthInfos, key)
break
if len(outConfig.Contexts) == 1 {
for k := range outConfig.Contexts {
outConfig.CurrentContext = k
}
}
for key, obj := range config.Clusters {
config.Clusters[clusterName] = obj
delete(config.Clusters, key)
break
cover := BoolUI(fmt.Sprintf("Does it overwrite File 「%s」?", cfgFile))
confirm, err := strconv.ParseBool(cover)
if err != nil {
return err
}
for key, obj := range config.Contexts {
obj.AuthInfo = userName
obj.Cluster = clusterName
config.Contexts[name] = obj
delete(config.Contexts, key)
break
err = WriteConfig(confirm, file, outConfig)
if err != nil {
return err
}
fmt.Printf("Context Add: %s \n", name)
return config, nil
return nil
}

func formatAndCheckName(file, name string) (string, error) {
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
}
for key := range config.Contexts {
if key == name {
return key, errors.New("The name: " + name + " already exists, please replace it")
func (kc *KubeConfigOption) handleContexts(oldConfig *clientcmdapi.Config) (*clientcmdapi.Config, error) {
newConfig := clientcmdapi.NewConfig()
for name, ctx := range kc.config.Contexts {
var newName string
if len(kc.config.Contexts) > 1 {
newName = fmt.Sprintf("%s-%s", kc.fileName, HashSufString(name))
} else {
newName = kc.fileName
}
if checkContextName(newName, oldConfig) {
nameConfirm := BoolUI(fmt.Sprintf("「%s」 Name already exists, do you want to rename it. (If you select `False`, this context will not be merged)", newName))
if nameConfirm == "True" {
newName = PromptUI("Rename", newName)
if newName == kc.fileName {
return nil, errors.New("need to rename")
}
} else {
continue
}
}
itemConfig := kc.handleContext(newName, ctx)
newConfig = appendConfig(newConfig, itemConfig)
fmt.Printf("Add Context: %s \n", newName)
}
return name, nil
outConfig := appendConfig(oldConfig, newConfig)
return outConfig, nil
}

func fileNotExists(path string) bool {
_, err := os.Stat(path) //os.Stat获取文件信息
if err != nil {
return !os.IsExist(err)
func checkContextName(name string, oldConfig *clientcmdapi.Config) bool {
if _, ok := oldConfig.Contexts[name]; ok {
return true
}
return false
}

func (kc *KubeConfigOption) handleContext(key string, ctx *clientcmdapi.Context) *clientcmdapi.Config {
newConfig := clientcmdapi.NewConfig()
suffix := HashSufString(key)
userName := fmt.Sprintf("user-%v", suffix)
clusterName := fmt.Sprintf("cluster-%v", suffix)
newCtx := ctx.DeepCopy()
newConfig.AuthInfos[userName] = kc.config.AuthInfos[newCtx.AuthInfo]
newConfig.Clusters[clusterName] = kc.config.Clusters[newCtx.Cluster]
newConfig.Contexts[key] = newCtx
newConfig.Contexts[key].AuthInfo = userName
newConfig.Contexts[key].Cluster = clusterName
return newConfig
}

func addExample() string {
return `
# Merge 1.yaml with $HOME/.kube/config
kubecm add -f 1.yaml
# 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 1.yaml -c
# Merge test.yaml with $HOME/.kube/config
kubecm add -f test.yaml
`
}
Loading

0 comments on commit 3a9de90

Please sign in to comment.