diff --git a/README.md b/README.md new file mode 100644 index 0000000..0fa15c7 --- /dev/null +++ b/README.md @@ -0,0 +1,25 @@ +# kubectls - one command to rule your all kubectl contexts + +Are you operating in multi-cluster environment? Are you tired of constantly switching your kubectl contexts to execute the same command in different clusters? +Good news! `kubectls` is here to help you! + +`kubectl` takes one kubernetes context as an input and executes the command in this context. +`kubectls` takes **a list of kubernetes context separated by comma** and simply executes the same command in each context! + +... and it's less than 70 lines of code! + + +# Demo + +[![asciicast](https://asciinema.org/a/sM4ogGmfBnk0wBC31K5RK3n88.svg)](https://asciinema.org/a/sM4ogGmfBnk0wBC31K5RK3n88) + +# Commands not supported +- exec +- port-forward +- attach +- edit + +# Install +Build it from source: + + $ git clone \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..70f4ab1 --- /dev/null +++ b/go.mod @@ -0,0 +1 @@ +module kubectls diff --git a/main.go b/main.go new file mode 100644 index 0000000..ca30e8f --- /dev/null +++ b/main.go @@ -0,0 +1,63 @@ +package main + +import ( + "flag" + "fmt" + "os" + "os/exec" + "strings" +) + +var Reset = "\033[0m" +var Red = "\033[31m" +var Green = "\033[32m" +var Yellow = "\033[33m" +var Blue = "\033[34m" +var Purple = "\033[35m" +var Cyan = "\033[36m" +var Gray = "\033[37m" +var White = "\033[97m" + +var Colors = []string{Red, Gray, Blue, Purple, Cyan, White, Green, Yellow} +var NotSupportedSubCommands = map[string]struct{}{"edit": {}, "port-forward": {}, "attach": {}, "exec": {}} + +func main() { + + var contextFlag string + flag.StringVar(&contextFlag, "context", "", "") + flag.Parse() + kubectlArgsLen := len(os.Args) - 2 + kubectlArgs := make([]string, kubectlArgsLen) + k := 0 + for _, arg := range os.Args[1:] { + if strings.HasPrefix(arg, "--context") { + continue + } + if _, notSupported := NotSupportedSubCommands[arg]; notSupported { + fmt.Printf("subcommand %s is currently not supported.\n", arg) + os.Exit(1) + } + kubectlArgs[k] = arg + k++ + } + + for i, k8sCtx := range strings.Split(contextFlag, ",") { + currentColor := Colors[i] + cmd := buildKubectlCommandForContext(k8sCtx, kubectlArgs) + fmt.Printf("%s---------------------------------------------------------------------------------------\n", currentColor) + output, err := cmd.CombinedOutput() + if err != nil { + fmt.Printf("got errors: %w", err) + } + fmt.Println(string(output), "\n---------------------------------------------------------------------------------------", Reset) + } + os.Exit(0) +} + +func buildKubectlCommandForContext(k8sCtx string, kubectlArgs []string) *exec.Cmd { + kubectlCmdArgs := []string{"--context", k8sCtx} + kubectlCmdArgs = append(kubectlCmdArgs, kubectlArgs...) + cmd := exec.Command("kubectl", kubectlCmdArgs...) + cmd.Env = os.Environ() + return cmd +}