-
Notifications
You must be signed in to change notification settings - Fork 290
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for --kube-context option into botkube CLI (#1457)
- Loading branch information
1 parent
d221782
commit acefb61
Showing
9 changed files
with
75 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,10 +12,12 @@ import ( | |
) | ||
|
||
var kubeconfig string | ||
var kubecontext string | ||
|
||
// RegisterKubeconfigFlag registers `--kubeconfig` flag. | ||
func RegisterKubeconfigFlag(flags *pflag.FlagSet) { | ||
flags.StringVar(&kubeconfig, clientcmd.RecommendedConfigPathFlag, "", "Paths to a kubeconfig. Only required if out-of-cluster.") | ||
flags.StringVar(&kubecontext, "kubecontext", "", "The name of the kubeconfig context to use.") | ||
} | ||
|
||
type ConfigWithMeta struct { | ||
|
@@ -35,53 +37,80 @@ type ConfigWithMeta struct { | |
// | ||
// code inspired by sigs.k8s.io/[email protected]/pkg/client/config/config.go | ||
func LoadRestConfigWithMetaInformation() (*ConfigWithMeta, error) { | ||
loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() | ||
// 1. --kubeconfig flag | ||
if kubeconfig != "" { | ||
c := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(&clientcmd.ClientConfigLoadingRules{ExplicitPath: kubeconfig}, nil) | ||
return transform(c) | ||
} | ||
|
||
// 2. KUBECONFIG environment variable pointing at a file | ||
kubeconfigPath := os.Getenv(clientcmd.RecommendedConfigPathEnvVar) | ||
if len(kubeconfigPath) == 0 { | ||
if c, err := rest.InClusterConfig(); err == nil { | ||
return &ConfigWithMeta{ | ||
K8s: c, | ||
CurrentContext: "In cluster", | ||
}, nil | ||
} | ||
} | ||
|
||
// 3. In-cluster config if running in cluster | ||
// 4. $HOME/.kube/config if exists | ||
// 5. user.HomeDir/.kube/config if exists | ||
// | ||
// NOTE: For default config file locations, upstream only checks | ||
// $HOME for the user's home directory, but we can also try | ||
// os/user.HomeDir when $HOME is unset. | ||
loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() | ||
if _, ok := os.LookupEnv("HOME"); !ok { | ||
u, err := user.Current() | ||
if err != nil { | ||
return nil, fmt.Errorf("could not get current user: %w", err) | ||
loadingRules.ExplicitPath = kubeconfig | ||
} else { | ||
// 2. KUBECONFIG environment variable pointing at a file | ||
kubeconfigPath := os.Getenv(clientcmd.RecommendedConfigPathEnvVar) | ||
if len(kubeconfigPath) == 0 { | ||
// 3. In-cluster config if running in cluster | ||
if c, err := rest.InClusterConfig(); err == nil { | ||
return &ConfigWithMeta{ | ||
K8s: c, | ||
CurrentContext: "In cluster", | ||
}, nil | ||
} | ||
} else { | ||
loadingRules.ExplicitPath = kubeconfigPath | ||
// 4. $HOME/.kube/config if exists | ||
// 5. user.HomeDir/.kube/config if exists | ||
// | ||
// NOTE: For default config file locations, upstream only checks | ||
// $HOME for the user's home directory, but we can also try | ||
// os/user.HomeDir when $HOME is unset. | ||
if _, ok := os.LookupEnv("HOME"); !ok { | ||
u, err := user.Current() | ||
if err != nil { | ||
return nil, fmt.Errorf("could not get current user: %w", err) | ||
} | ||
loadingRules.Precedence = append(loadingRules.Precedence, filepath.Join(u.HomeDir, clientcmd.RecommendedHomeDir, clientcmd.RecommendedFileName)) | ||
} | ||
} | ||
loadingRules.Precedence = append(loadingRules.Precedence, filepath.Join(u.HomeDir, clientcmd.RecommendedHomeDir, clientcmd.RecommendedFileName)) | ||
} | ||
|
||
return transform(clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, nil)) | ||
configOverrides := &clientcmd.ConfigOverrides{CurrentContext: loadKubecontext("")} | ||
return transform(clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, configOverrides)) | ||
} | ||
|
||
func transform(c clientcmd.ClientConfig) (*ConfigWithMeta, error) { | ||
rawConfig, err := c.RawConfig() | ||
if err != nil { | ||
return nil, fmt.Errorf("while getting raw config: %v", err) | ||
} | ||
|
||
clientConfig, err := c.ClientConfig() | ||
if err != nil { | ||
return nil, fmt.Errorf("while getting client config: %v", err) | ||
} | ||
|
||
return &ConfigWithMeta{ | ||
K8s: clientConfig, | ||
CurrentContext: rawConfig.CurrentContext, | ||
CurrentContext: loadKubecontext(rawConfig.CurrentContext), | ||
}, nil | ||
} | ||
|
||
// Loads kubecontext. | ||
// | ||
// Config precedence: | ||
// | ||
// * --kubecontext flag | ||
// | ||
// * KUBECONTEXT environment variable | ||
// | ||
// * fallback value | ||
func loadKubecontext(fallbackValue string) string { | ||
// 1. --kubecontext flag | ||
if kubecontext != "" { | ||
return kubecontext | ||
} | ||
|
||
// 2. KUBECONTEXT env | ||
kubeCtx := os.Getenv("KUBECONTEXT") | ||
if kubeCtx != "" { | ||
return kubeCtx | ||
} | ||
|
||
return fallbackValue | ||
} |