go/mirko: move kubernetes clientset state to singleton
We want to access the clientset (or at least check the fact that we're
in a cluster) outside of the Mirko object lifecycle.
In reality, this should _probably_ be moved outside of the Mirko library
and get a better API than this (ie. one that returns complete
information about the state of being in production/dev/...).
Change-Id: I86444477e0306a39a1611207855127a7b963603e
diff --git a/go/mirko/kubernetes.go b/go/mirko/kubernetes.go
index c3a0bb3..a05d4c1 100644
--- a/go/mirko/kubernetes.go
+++ b/go/mirko/kubernetes.go
@@ -1,23 +1,54 @@
package mirko
import (
+ "sync"
+
"github.com/golang/glog"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
)
-func (m *Mirko) kubernetesConnect() {
+var (
+ // kubernetesCS is a kubernetes clientset that can connect to the cluster
+ // that this program is running in, or nil if uninitialized (or not in a
+ // cluster.
+ kubernetesCS *kubernetes.Clientset
+ // kubernetesCSValid is true when kubernetesCS is 'valid', ie. when the
+ // clientset is either an actual clientset object, or nil if the program is
+ // not running in production.
+ kubernetesCSValid bool
+ // kubernetesCSMu guards kubernetesCS and kubernetesCSValid.
+ kubernetesCSMu sync.Mutex
+)
+
+// KubernetesClient attempts to connect to Kubernetes using in-cluster
+// configuration and returns the resulting clientset. If connecting fails, nil
+// is returned. Connection will fail if the program is not running in
+// production.
+// The connection result is cached for the rest of the program lifetime, so
+// this function is cheap to call.
+func KubernetesClient() *kubernetes.Clientset {
+ kubernetesCSMu.Lock()
+ defer kubernetesCSMu.Unlock()
+
+ if kubernetesCSValid {
+ return kubernetesCS
+ }
+
+ kubernetesCSValid = true
config, err := rest.InClusterConfig()
if err != nil {
- glog.Errorf("mirko.KubernetesClientSet: %v", err)
- return
+ glog.Errorf("Kubernetes InClusterConfig: %v", err)
+ glog.Infof("Mirko: no kubernetes config available...")
+ return nil
}
-
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
- glog.Errorf("kubernetes.NewForConfig: %v", err)
- return
+ glog.Errorf("Kubernetes NewForConfig: %v", err)
+ glog.Infof("Mirko: no kubernetes client available...")
+ return nil
}
- m.kubernetesCS = clientset
+ kubernetesCS = clientset
+ return clientset
}
diff --git a/go/mirko/mirko.go b/go/mirko/mirko.go
index f4c45eb..339e70c 100644
--- a/go/mirko/mirko.go
+++ b/go/mirko/mirko.go
@@ -130,7 +130,7 @@
http.Redirect(w, r, "/debug/status", http.StatusSeeOther)
})
- m.kubernetesConnect()
+ m.kubernetesCS = KubernetesClient()
debugParts := strings.Split(flagDebugAddress, ":")
debugPort := debugParts[len(debugParts)-1]