Skip to content

Commit db090b6

Browse files
committed
feat: handle path list for KUBECONFIG env var
1 parent 966bcb3 commit db090b6

File tree

3 files changed

+124
-11
lines changed

3 files changed

+124
-11
lines changed

klient/conf/config.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"os"
2424
"os/user"
2525
"path"
26+
"path/filepath"
2627

2728
"k8s.io/client-go/rest"
2829
"k8s.io/client-go/tools/clientcmd"
@@ -97,7 +98,15 @@ func ResolveKubeConfigFile() string {
9798
// if KUBECONFIG env is defined then use that
9899
kubeConfigPath = os.Getenv(clientcmd.RecommendedConfigPathEnvVar)
99100
if kubeConfigPath != "" {
100-
return kubeConfigPath
101+
// handle the variable as a path list, similar to client-go.
102+
filePaths := filepath.SplitList(kubeConfigPath)
103+
for _, filename := range filePaths {
104+
if _, err := os.Stat(filename); err == nil {
105+
return filename
106+
}
107+
}
108+
// return the last path in the list if none exist yet.
109+
return filePaths[len(filePaths)-1]
101110
}
102111

103112
var (

klient/conf/config_test.go

Lines changed: 86 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ limitations under the License.
1717
package conf
1818

1919
import (
20+
"fmt"
21+
"os"
2022
"path/filepath"
2123
"testing"
2224

@@ -25,15 +27,95 @@ import (
2527

2628
var kubeconfig string
2729

28-
func TestResolveKubeConfigFile(t *testing.T) {
29-
home := homedir.HomeDir()
30+
func TestResolveKubeConfigFileFlag(t *testing.T) {
3031
filename := ResolveKubeConfigFile()
31-
32-
if filename != filepath.Join(home, "test", ".kube", "config") {
32+
if filename != kubeconfigpath {
3333
t.Errorf("unexpected config path: %s", filename)
3434
}
3535
}
3636

37+
func TestResolveKubeConfigFileEnv(t *testing.T) {
38+
// NOTE: not considered safe to run in parallel with other tests thats
39+
// require the --kubeconfig and --kubecontext flags.
40+
clearKubeconfigFlags()
41+
defer setKubeconfigFlags()
42+
43+
kubeConfigPath1 := filepath.Join(t.TempDir(), "config")
44+
if _, err := os.Create(kubeConfigPath1); err != nil {
45+
t.Errorf("failed to create kubeconfig: %v", err)
46+
}
47+
48+
kubeConfigPath2 := filepath.Join(t.TempDir(), "config")
49+
if _, err := os.Create(kubeConfigPath2); err != nil {
50+
t.Errorf("failed to create kubeconfig: %v", err)
51+
}
52+
53+
t.Run("WithEnvEmpty", func(t *testing.T) {
54+
t.Setenv("KUBECONFIG", "")
55+
56+
filename := ResolveKubeConfigFile()
57+
58+
// this will fallback to the true home directory.
59+
if filename != filepath.Join(homedir.HomeDir(), ".kube", "config") {
60+
t.Errorf("unexpected config path: %s", filename)
61+
}
62+
})
63+
64+
t.Run("WithEnvPath", func(t *testing.T) {
65+
t.Setenv("KUBECONFIG", kubeConfigPath1)
66+
67+
filename := ResolveKubeConfigFile()
68+
69+
if filename != kubeConfigPath1 {
70+
t.Errorf("unexpected config path: %s", filename)
71+
}
72+
})
73+
74+
t.Run("WithEnvPathListAllExist", func(t *testing.T) {
75+
t.Setenv("KUBECONFIG", fmt.Sprintf("%s:%s", kubeConfigPath1, kubeConfigPath2))
76+
77+
filename := ResolveKubeConfigFile()
78+
79+
// if all exist then it will take the first.
80+
if filename != kubeConfigPath1 {
81+
t.Errorf("unexpected config path: %s", filename)
82+
}
83+
})
84+
85+
t.Run("WithEnvPathListFirstExists", func(t *testing.T) {
86+
t.Setenv("KUBECONFIG", fmt.Sprintf("%s:fake", kubeConfigPath1))
87+
88+
filename := ResolveKubeConfigFile()
89+
90+
// if first exists then it will take the first.
91+
if filename != kubeConfigPath1 {
92+
t.Errorf("unexpected config path: %s", filename)
93+
}
94+
})
95+
96+
t.Run("WithEnvPathListLastExists", func(t *testing.T) {
97+
t.Setenv("KUBECONFIG", fmt.Sprintf("%s:fake", kubeConfigPath1))
98+
99+
filename := ResolveKubeConfigFile()
100+
101+
// if only last exists then it will take the last.
102+
if filename != kubeConfigPath1 {
103+
t.Errorf("unexpected config path: %s", filename)
104+
}
105+
})
106+
107+
t.Run("WithEnvPathListNoneExist", func(t *testing.T) {
108+
t.Setenv("KUBECONFIG", "fake-foo:fake-bar")
109+
110+
filename := ResolveKubeConfigFile()
111+
112+
// if none exist then it will take the last.
113+
if filename != "fake-bar" {
114+
t.Errorf("unexpected config path: %s", filename)
115+
}
116+
})
117+
}
118+
37119
func TestNew(t *testing.T) {
38120
cfg, err := New(ResolveKubeConfigFile())
39121
if err != nil {

klient/conf/main_test.go

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,14 @@ import (
2828
"k8s.io/client-go/util/homedir"
2929
)
3030

31+
var (
32+
kubeconfigpath string
33+
kubeContext string
34+
)
35+
3136
func TestMain(m *testing.M) {
3237
setup()
38+
setKubeconfigFlags()
3339
code := m.Run()
3440
teardown()
3541
os.Exit(code)
@@ -39,8 +45,8 @@ func setup() {
3945
home := homedir.HomeDir()
4046

4147
kubeconfigdir := filepath.Join(home, "test", ".kube")
42-
kubeconfigpath := filepath.Join(kubeconfigdir, "config")
43-
kubeContext := "test-context"
48+
kubeconfigpath = filepath.Join(kubeconfigdir, "config")
49+
kubeContext = "test-context"
4450

4551
// check if file exists
4652
_, err := os.Stat(kubeconfigpath)
@@ -66,17 +72,33 @@ func setup() {
6672

6773
flag.StringVar(&kubeconfig, "kubeconfig", "", "Paths to a kubeconfig. Only required if out-of-cluster.")
6874
flag.StringVar(&kubeContext, "context", "", "The name of the kubeconfig context to use. Only required if out-of-cluster.")
75+
}
6976

77+
func setKubeconfigFlags() {
7078
// set --kubeconfig flag
71-
err = flag.Set("kubeconfig", kubeconfigpath)
72-
if err != nil {
79+
if err := flag.Set("kubeconfig", kubeconfigpath); err != nil {
7380
log.ErrorS(err, "unexpected error while setting kubeconfig flag value")
7481
return
7582
}
7683

7784
// set --context flag
78-
err = flag.Set("context", kubeContext)
79-
if err != nil {
85+
if err := flag.Set("context", kubeContext); err != nil {
86+
log.ErrorS(err, "unexpected error while setting context flag value")
87+
return
88+
}
89+
90+
flag.Parse()
91+
}
92+
93+
func clearKubeconfigFlags() {
94+
// clear --kubeconfig flag
95+
if err := flag.Set("kubeconfig", ""); err != nil {
96+
log.ErrorS(err, "unexpected error while setting kubeconfig flag value")
97+
return
98+
}
99+
100+
// clear --context flag
101+
if err := flag.Set("context", ""); err != nil {
80102
log.ErrorS(err, "unexpected error while setting context flag value")
81103
return
82104
}

0 commit comments

Comments
 (0)