Skip to content

Instantly share code, notes, and snippets.

@mniak
Last active March 29, 2022 14:26
Show Gist options
  • Save mniak/79dfc8d590552c3312ea35926bac33ef to your computer and use it in GitHub Desktop.
Save mniak/79dfc8d590552c3312ea35926bac33ef to your computer and use it in GitHub Desktop.
package main
import (
"bytes"
"errors"
"fmt"
"log"
"os"
"os/exec"
"path/filepath"
"strings"
"github.com/manifoldco/promptui"
"github.com/samber/lo"
"github.com/spf13/cobra"
"golang.org/x/exp/slices"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/util/homedir"
)
func main() {
if home := homedir.HomeDir(); home != "" {
rootCmd.Flags().String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
} else {
rootCmd.Flags().String("kubeconfig", "", "absolute path to the kubeconfig file")
}
rootCmd.Flags().StringP("output", "p", ".env", "output file")
rootCmd.Execute()
}
func handle(err error) {
if err != nil {
log.Fatalln("Fatal:", err)
}
}
func execSimple(program string, args ...string) (string, error) {
cmd := exec.Command(program, args...)
var stdoutBuffer bytes.Buffer
var stderrBuffer bytes.Buffer
cmd.Stdout = &stdoutBuffer
cmd.Stderr = &stderrBuffer
err := cmd.Run()
if err != nil {
return stdoutBuffer.String(), err
}
return stdoutBuffer.String(), err
}
func selectItem[T any](prompt string, items map[string]T) (T, error) {
if len(items) == 0 {
var zero T
return zero, errors.New("the list has no items")
}
if len(items) == 1 {
for _, v := range items {
return v, nil
}
}
keys := lo.Keys(items)
slices.Sort(keys)
_, selectedKey, err := (&promptui.Select{
Label: "Select Pod",
Items: keys,
}).Run()
if err != nil {
var zero T
return zero, err
}
return items[selectedKey], nil
}
var rootCmd = cobra.Command{
Use: "export-env",
Run: func(cmd *cobra.Command, args []string) {
kubeconfig, err := cmd.Flags().GetString("kubeconfig")
handle(err)
outputFile, err := cmd.Flags().GetString("output")
handle(err)
config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
handle(err)
clientset, err := kubernetes.NewForConfig(config)
handle(err)
ns, err := execSimple("kubens", "-c")
handle(err)
ns = strings.Trim(ns, "\n")
deployments, err := clientset.AppsV1().Deployments(ns).List(cmd.Context(), metav1.ListOptions{})
handle(err)
gApp := lo.GroupBy(deployments.Items, func(p appsv1.Deployment) string {
return p.Labels["app"]
})
deploymentsList, err := selectItem("Select the Application", gApp)
handle(err)
gDeployment := lo.KeyBy(deploymentsList, func(p appsv1.Deployment) string {
return p.Labels["fullname"]
})
deployment, err := selectItem("Select the Deployment", gDeployment)
handle(err)
gContainer := lo.KeyBy(deployment.Spec.Template.Spec.Containers, func(c corev1.Container) string {
return c.Name
})
container, err := selectItem("Select the Container", gContainer)
envmap := lo.MapValues(
lo.KeyBy(container.Env, func(x corev1.EnvVar) string {
return x.Name
}),
func(v corev1.EnvVar, k string) string {
return v.Value
},
)
for _, envFrom := range container.EnvFrom {
if envFrom.ConfigMapRef != nil {
configmap, err := clientset.CoreV1().ConfigMaps(ns).Get(cmd.Context(), envFrom.ConfigMapRef.Name, metav1.GetOptions{})
handle(err)
for k, v := range configmap.Data {
envmap[k] = v
}
} else if envFrom.SecretRef != nil {
secret, err := clientset.CoreV1().Secrets(ns).Get(cmd.Context(), envFrom.SecretRef.Name, metav1.GetOptions{})
handle(err)
for k, v := range secret.Data {
envmap[k] = string(v)
}
for k, v := range secret.StringData {
envmap[k] = v
}
}
}
os.WriteFile(outputFile, []byte(buildDotEnv(envmap)), 0o755)
},
}
func quote(text string) string {
replacer := strings.NewReplacer(
"\n", "\\n",
)
return fmt.Sprintf(`"%s"`, replacer.Replace(text))
}
func buildDotEnv(envmap map[string]string) string {
var sb strings.Builder
for k, v := range envmap {
sb.WriteString(fmt.Sprintf("%s=%s\n", k, quote(v)))
}
return sb.String()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment