From 4f42a4a81da0f4a17500db3f58c2fd5c4165bf9b 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 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 +}