diff --git a/pkg/provider/handlers/delete.go b/pkg/provider/handlers/delete.go index b7cc740..34a94eb 100644 --- a/pkg/provider/handlers/delete.go +++ b/pkg/provider/handlers/delete.go @@ -42,6 +42,18 @@ func MakeDeleteHandler(client *containerd.Client, cni gocni.CNI) func(w http.Res lookupNamespace := getRequestNamespace(readNamespaceFromQuery(r)) + // Check if namespace exists, and it has the openfaas label + nsValid, err := validateNamespace(client, lookupNamespace) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + if !nsValid { + http.Error(w, "namespace not valid", http.StatusBadRequest) + return + } + name := req.FunctionName function, err := GetFunction(client, name, lookupNamespace) diff --git a/pkg/provider/handlers/deploy.go b/pkg/provider/handlers/deploy.go index b4919e7..3dbe63f 100644 --- a/pkg/provider/handlers/deploy.go +++ b/pkg/provider/handlers/deploy.go @@ -52,10 +52,25 @@ func MakeDeployHandler(client *containerd.Client, cni gocni.CNI, secretMountPath } namespace := getRequestNamespace(req.Namespace) + + // Check if namespace exists, and it has the openfaas label + nsValid, err := validateNamespace(client, namespace) + + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + if !nsValid { + http.Error(w, "namespace not valid", http.StatusBadRequest) + return + } + namespaceSecretMountPath := getNamespaceSecretMountPath(secretMountPath, namespace) err = validateSecrets(namespaceSecretMountPath, req.Secrets) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) + return } name := req.Service diff --git a/pkg/provider/handlers/functions.go b/pkg/provider/handlers/functions.go index 24ee9a6..aa08f76 100644 --- a/pkg/provider/handlers/functions.go +++ b/pkg/provider/handlers/functions.go @@ -2,6 +2,7 @@ package handlers import ( "context" + "errors" "fmt" "log" "strings" @@ -32,6 +33,17 @@ type Function struct { // ListFunctions returns a map of all functions with running tasks on namespace func ListFunctions(client *containerd.Client, namespace string) (map[string]*Function, error) { + + // Check if namespace exists, and it has the openfaas label + nsValid, err := validateNamespace(client, namespace) + if err != nil { + return nil, err + } + + if !nsValid { + return nil, errors.New("namespace not valid") + } + ctx := namespaces.WithNamespace(context.Background(), namespace) functions := make(map[string]*Function) diff --git a/pkg/provider/handlers/read.go b/pkg/provider/handlers/read.go index 9707266..e2adc00 100644 --- a/pkg/provider/handlers/read.go +++ b/pkg/provider/handlers/read.go @@ -14,6 +14,17 @@ func MakeReadHandler(client *containerd.Client) func(w http.ResponseWriter, r *h return func(w http.ResponseWriter, r *http.Request) { lookupNamespace := getRequestNamespace(readNamespaceFromQuery(r)) + // Check if namespace exists, and it has the openfaas label + nsValid, err := validateNamespace(client, lookupNamespace) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + if !nsValid { + http.Error(w, "namespace not valid", http.StatusBadRequest) + return + } res := []types.FunctionStatus{} fns, err := ListFunctions(client, lookupNamespace) diff --git a/pkg/provider/handlers/replicas.go b/pkg/provider/handlers/replicas.go index 0c7d143..9e35839 100644 --- a/pkg/provider/handlers/replicas.go +++ b/pkg/provider/handlers/replicas.go @@ -16,6 +16,18 @@ func MakeReplicaReaderHandler(client *containerd.Client) func(w http.ResponseWri functionName := vars["name"] lookupNamespace := getRequestNamespace(readNamespaceFromQuery(r)) + // Check if namespace exists, and it has the openfaas label + nsValid, err := validateNamespace(client, lookupNamespace) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + if !nsValid { + http.Error(w, "namespace not valid", http.StatusBadRequest) + return + } + if f, err := GetFunction(client, functionName, lookupNamespace); err == nil { found := types.FunctionStatus{ Name: functionName, diff --git a/pkg/provider/handlers/scale.go b/pkg/provider/handlers/scale.go index e7dfa6a..c230876 100644 --- a/pkg/provider/handlers/scale.go +++ b/pkg/provider/handlers/scale.go @@ -41,6 +41,18 @@ func MakeReplicaUpdateHandler(client *containerd.Client, cni gocni.CNI) func(w h namespace := getRequestNamespace(readNamespaceFromQuery(r)) + // Check if namespace exists, and it has the openfaas label + nsValid, err := validateNamespace(client, namespace) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + if !nsValid { + http.Error(w, "namespace not valid", http.StatusBadRequest) + return + } + name := req.ServiceName if _, err := GetFunction(client, name, namespace); err != nil { diff --git a/pkg/provider/handlers/secret.go b/pkg/provider/handlers/secret.go index 3fc2f30..b52625c 100644 --- a/pkg/provider/handlers/secret.go +++ b/pkg/provider/handlers/secret.go @@ -49,6 +49,18 @@ func MakeSecretHandler(c *containerd.Client, mountPath string) func(w http.Respo func listSecrets(c *containerd.Client, w http.ResponseWriter, r *http.Request, mountPath string) { lookupNamespace := getRequestNamespace(readNamespaceFromQuery(r)) + // Check if namespace exists, and it has the openfaas label + nsValid, err := validateNamespace(c, lookupNamespace) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + if !nsValid { + http.Error(w, "namespace not valid", http.StatusBadRequest) + return + } + mountPath = getNamespaceSecretMountPath(mountPath, lookupNamespace) files, err := ioutil.ReadDir(mountPath) diff --git a/pkg/provider/handlers/update.go b/pkg/provider/handlers/update.go index 812be77..6f35f4e 100644 --- a/pkg/provider/handlers/update.go +++ b/pkg/provider/handlers/update.go @@ -41,6 +41,19 @@ func MakeUpdateHandler(client *containerd.Client, cni gocni.CNI, secretMountPath } name := req.Service namespace := getRequestNamespace(req.Namespace) + + // Check if namespace exists, and it has the openfaas label + nsValid, err := validateNamespace(client, namespace) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + if !nsValid { + http.Error(w, "namespace not valid", http.StatusBadRequest) + return + } + namespaceSecretMountPath := getNamespaceSecretMountPath(secretMountPath, namespace) function, err := GetFunction(client, name, namespace) diff --git a/pkg/provider/handlers/utils.go b/pkg/provider/handlers/utils.go index 7f8938a..d2d71a9 100644 --- a/pkg/provider/handlers/utils.go +++ b/pkg/provider/handlers/utils.go @@ -1,6 +1,8 @@ package handlers import ( + "context" + "github.com/containerd/containerd" "net/http" "path" @@ -23,3 +25,25 @@ func readNamespaceFromQuery(r *http.Request) string { func getNamespaceSecretMountPath(userSecretPath string, namespace string) string { return path.Join(userSecretPath, namespace) } + +func validateNamespace(client *containerd.Client, namespace string) (bool, error) { + if namespace == faasd.FunctionNamespace { + return true, nil + } + + store := client.NamespaceService() + labels, err := store.Labels(context.Background(), namespace) + if err != nil { + return false, err + } + + value, found := labels["openfaas"] + + if found { + if value == "true" { + return true, nil + } + } + + return false, nil +}