From 1aa19ecc8648281c1aed3c25a446a1d421afa05f Mon Sep 17 00:00:00 2001 From: Lucas Roesler Date: Fri, 30 Sep 2022 16:46:26 +0200 Subject: [PATCH] feat: add startup error when running in the kube-system namespace To avoid any accedential security issues, we block running anything in the kube-system namespace. We already have this explicitly blocked in the rest of the code that deals with namespaces and it causes hard to debug errors for users that try to deploy to the kube-system namespace. This adds an explicit check so that this mis-configuration is easier to detect and debug for end users. Signed-off-by: Lucas Roesler --- main.go | 6 ++++++ pkg/k8s/namespaces.go | 27 +++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 pkg/k8s/namespaces.go diff --git a/main.go b/main.go index 17df1f4a2..15a00eee4 100644 --- a/main.go +++ b/main.go @@ -98,6 +98,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 +}