How to get namespace from current-context set in .kube/config

I found a solution using NewDefaultClientConfigLoadingRules and then loading the rules. This works if your config is loadable with the default client config loading rules.

Example:

package main

import (
        "github.com/davecgh/go-spew/spew"
        "k8s.io/client-go/tools/clientcmd"
)

func main() {
        clientCfg, err := clientcmd.NewDefaultClientConfigLoadingRules().Load()
        spew.Dump(clientCfg, err)
}

Gives you a https://godoc.org/k8s.io/client-go/tools/clientcmd/api#Config which contains the current context including its namespace.

Contexts: (map[string]*api.Context) (len=1) {
  (string) (len=17) "xxx.xxxxx.xxx": (*api.Context)(0xc0001b2b40)({
   LocationOfOrigin: (string) (len=30) "/path/to/.kube/config",
   Cluster: (string) (len=17) "xxx.xxxxx.xxx",
   AuthInfo: (string) (len=29) "[email protected]",
   Namespace: (string) (len=7) "default",
   Extensions: (map[string]runtime.Object) {
   }
  })
 },
 CurrentContext: (string) (len=17) "xxx.xxxxx.xxx",

For your information, ClientConfigLoadingRules is a structure with different properties to tell the client where to load the config from. The default one will use the path in your KUBECONFIG environment variable in the Precedence field.

(*clientcmd.ClientConfigLoadingRules)(0xc0000a31d0)({
 ExplicitPath: (string) "",
 Precedence: ([]string) (len=1 cap=1) {
  (string) (len=30) "/path/to/.kube/config"
 },
 MigrationRules: (map[string]string) (len=1) {
  (string) (len=30) "/path/to/.kube/config": (string) (len=35) "/path/to/.kube/.kubeconfig"
 },
 DoNotResolvePaths: (bool) false,
 DefaultClientConfig: (clientcmd.ClientConfig) <nil>
})

This code, based on answer https://stackoverflow.com/a/55315895/2784039, returns the namespace set in the current context of the kubeconfig file. In addition, it sets namespace to default if namespace is not defined in the kubeconfig current context:

package main

import (
    "fmt"

    "k8s.io/client-go/tools/clientcmd"
)

func main() {

    clientCfg, _ := clientcmd.NewDefaultClientConfigLoadingRules().Load()
    namespace := clientCfg.Contexts[clientCfg.CurrentContext].Namespace

    if namespace == "" {
        namespace = "default"
    }
    fmt.Printf(namespace)
}

This code works fine on user side, it it is run outside the cluster. Check comments below to retrieve namespace for a pod inside the cluster.


import "k8s.io/client-go/tools/clientcmd"

loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
configOverrides := &clientcmd.ConfigOverrides{} 
kubeConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules,
configOverrides)

namespace, _, err = kubeConfig.Namespace()

Tags:

Go

Kubernetes