/
contexts.go
115 lines (98 loc) · 2.88 KB
/
contexts.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// Package kube offers utilities for working with Kubernetes.
package kube
import (
"fmt"
"log"
"os"
"slices"
"sort"
"github.com/aideneyre/acli/internal/common"
"github.com/aideneyre/acli/internal/prompt"
"github.com/manifoldco/promptui"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/tools/clientcmd/api"
)
var (
kubeConfig *api.Config
kubeConfigPath string
)
func init() {
var err error
kubeConfig, kubeConfigPath, err = loadConfig()
if err != nil {
log.Fatalf("failed to initialize K8s API config:: %v", err)
}
}
// SetKubeContext takes in the context name and sets it as the current kube context.
func SetKubeContext(context string) error {
kubeConfig.CurrentContext = context
err := clientcmd.WriteToFile(*kubeConfig, kubeConfigPath)
if err != nil {
return err
}
fmt.Printf("context successfully set to %s\n", context)
return nil
}
// SetKubeContextWithPrompt will grab all the available contexts, prompt the user to make a choice,
// and set the context.
func SetKubeContextWithPrompt() error {
currentContext := kubeConfig.CurrentContext
contexts := make([]string, 0, len(kubeConfig.Contexts))
for ctx := range kubeConfig.Contexts {
contexts = append(contexts, ctx)
}
if len(contexts) == 0 {
fmt.Println("no configured configs found, exiting")
os.Exit(0)
}
if slices.Contains(contexts, currentContext) {
contexts = common.ColorSliceStringGreen(contexts, currentContext)
}
selectedContext, err := promptContext(contexts)
if err == promptui.ErrInterrupt {
fmt.Print("\033[u\033[J") // Clear the terminal
fmt.Println("CLI exited early!")
os.Exit(0)
}
if err != nil {
return fmt.Errorf("unable to get user context selection: %w", err)
}
selectedContext = common.RemoveGreenStringFormatting(selectedContext)
err = SetKubeContext(selectedContext)
if err != nil {
return fmt.Errorf("failed to write kube config: %w", err)
}
return nil
}
// loadConfig returns a Kubernetes client API config and the defined config
// path
func loadConfig() (*api.Config, string, error) {
loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
overrides := &clientcmd.ConfigOverrides{}
clientConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, overrides)
apiConfig, err := clientConfig.RawConfig()
if err != nil {
return nil, "", err
}
// Use the first file if multiple exist, as it's the highest precedence
if len(loadingRules.Precedence) == 0 {
return nil, "", fmt.Errorf("failed to find config file")
}
return &apiConfig, loadingRules.Precedence[0], nil
}
func promptContext(contexts []string) (string, error) {
sort.Strings(contexts)
promptCtx := promptui.Select{
Label: "Select Context",
Items: contexts,
Stdout: &prompt.BellSkipper{},
Size: 15,
HideHelp: true,
HideSelected: true,
}
_, context, err := promptCtx.Run()
if err != nil {
return "", err
}
return context, nil
}