diff --git a/cmd/nomos/nomos.go b/cmd/nomos/nomos.go index d97b121a26..5b309c6d6e 100644 --- a/cmd/nomos/nomos.go +++ b/cmd/nomos/nomos.go @@ -29,7 +29,9 @@ import ( "kpt.dev/configsync/cmd/nomos/version" "kpt.dev/configsync/cmd/nomos/vet" "kpt.dev/configsync/pkg/api/configmanagement" + "kpt.dev/configsync/pkg/client/restconfig" pkgversion "kpt.dev/configsync/pkg/version" + "sigs.k8s.io/controller-runtime/pkg/client/config" ) var ( @@ -57,6 +59,20 @@ func main() { // Register klog flags klog.InitFlags(fs) + // Work around the controller-runtime init registering a --kubeconfig flag + // with no default value. Use the same default as kubectl instead. + // https://github.com/kubernetes-sigs/controller-runtime/blob/v0.16.3/pkg/client/config/config.go#L44 + if f := fs.Lookup(config.KubeconfigFlagName); f != nil { + // Change the default value & usage. + // This path should be expected because import inits load first. + defaultKubeConfigPath, err := restconfig.KubeConfigPath() + if err != nil { + klog.Fatal(err) + } + f.DefValue = defaultKubeConfigPath + f.Usage = "Path to the client config file." + } + // Cobra uses the pflag lib, instead of the go flag lib. // So re-register all go flags as global (aka persistent) pflags. rootCmd.PersistentFlags().AddGoFlagSet(fs) diff --git a/pkg/client/restconfig/config.go b/pkg/client/restconfig/config.go index 0a9537f317..9437d1dfab 100644 --- a/pkg/client/restconfig/config.go +++ b/pkg/client/restconfig/config.go @@ -40,15 +40,15 @@ func defaultGetCurrentUser() (*user.User, error) { return user.Current() } -// newConfigPath returns the correct kubeconfig file path to use, depending on -// the current user settings and the runtime environment. -func newConfigPath() (string, error) { - // First try the KUBECONFIG variable. +// KubeConfigPath returns the path to the kubeconfig: +// 1. ${KUBECONFIG}, if non-empty +// 2. ${userCurrentTestHook.HomeDir}/.kube/config, if userCurrentTestHook is set +// 3. ${HOME}/.kube/config +func KubeConfigPath() (string, error) { envPath := os.Getenv("KUBECONFIG") if envPath != "" { return envPath, nil } - // Try the current user. curentUser, err := userCurrentTestHook() if err != nil { return "", errors.Wrapf(err, "failed to get current user") @@ -60,7 +60,7 @@ func newConfigPath() (string, error) { // newRawConfigWithRules returns a clientcmdapi.Config from a configuration file whose path is // provided by newConfigPath, and the clientcmd.ClientConfigLoadingRules associated with it func newRawConfigWithRules() (*clientcmdapi.Config, *clientcmd.ClientConfigLoadingRules, error) { - configPath, err := newConfigPath() + configPath, err := KubeConfigPath() if err != nil { return nil, nil, errors.Wrap(err, "while getting config path") } diff --git a/pkg/client/restconfig/restconfig.go b/pkg/client/restconfig/restconfig.go index 2fccc729bf..8ec775eff1 100644 --- a/pkg/client/restconfig/restconfig.go +++ b/pkg/client/restconfig/restconfig.go @@ -38,7 +38,7 @@ const DefaultTimeout = 15 * time.Second func NewRestConfig(timeout time.Duration) (*rest.Config, error) { var cfg *rest.Config // Detect kubectl config file - path, err := newConfigPath() + path, err := KubeConfigPath() if err != nil { // Build from k8s downward API cfg, err = NewFromInClusterConfig()