diff --git a/main.go b/main.go index a01a6669b..920562017 100644 --- a/main.go +++ b/main.go @@ -92,6 +92,12 @@ func main() { config.Fprint(verbose) + // use kubeclient to check the current namespace + namespace, _ := k8s.CurrentNamespace() + if namespace == "kube-system" { + log.Fatal("You cannot run the OpenFaaS provider in the kube-system namespace, please try another namespace.") + } + deployConfig := k8s.DeploymentConfig{ RuntimeHTTPPort: 8080, HTTPProbe: config.HTTPProbe, diff --git a/pkg/k8s/namespaces.go b/pkg/k8s/namespaces.go new file mode 100644 index 000000000..25110ee37 --- /dev/null +++ b/pkg/k8s/namespaces.go @@ -0,0 +1,27 @@ +package k8s + +import ( + "io/ioutil" + "os" + "strings" +) + +// CurrentNamespace attempts to return the current namespace from the environment +// or from the service account file. If it cannot find the namespace, it returns +// an empty string. This will be empty when the not running in-cluster. +// +// This implementation is based on the clientcmd.inClusterClientConfig.Namespace method. +// This is not exported and not accessible via other methods, so we have to copy it. +func CurrentNamespace() (namespace string, found bool) { + if ns := os.Getenv("POD_NAMESPACE"); ns != "" { + return ns, true + } + + if data, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace"); err == nil { + if ns := strings.TrimSpace(string(data)); len(ns) > 0 { + return ns, true + } + } + + return "", false +}