mirror of
https://github.com/openfaas/faasd.git
synced 2025-06-19 12:36:38 +00:00
Add check for namespace label openfaas=true
This commit adds the checks that the namespace supplied by the user has the `openfaas=true` label. Without this check the user can deploy/update/read functions in any namespace using the CLI. The UI is not effected because it calls the listnamesaces endpoint, which has the check for the label Signed-off-by: Alistair Hey <alistair@heyal.co.uk>
This commit is contained in:
@ -42,6 +42,18 @@ func MakeDeleteHandler(client *containerd.Client, cni gocni.CNI) func(w http.Res
|
|||||||
|
|
||||||
lookupNamespace := getRequestNamespace(readNamespaceFromQuery(r))
|
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
|
name := req.FunctionName
|
||||||
|
|
||||||
function, err := GetFunction(client, name, lookupNamespace)
|
function, err := GetFunction(client, name, lookupNamespace)
|
||||||
|
@ -52,10 +52,25 @@ func MakeDeployHandler(client *containerd.Client, cni gocni.CNI, secretMountPath
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace := getRequestNamespace(req.Namespace)
|
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)
|
namespaceSecretMountPath := getNamespaceSecretMountPath(secretMountPath, namespace)
|
||||||
err = validateSecrets(namespaceSecretMountPath, req.Secrets)
|
err = validateSecrets(namespaceSecretMountPath, req.Secrets)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
name := req.Service
|
name := req.Service
|
||||||
|
@ -2,6 +2,7 @@ package handlers
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
@ -32,6 +33,17 @@ type Function struct {
|
|||||||
|
|
||||||
// ListFunctions returns a map of all functions with running tasks on namespace
|
// ListFunctions returns a map of all functions with running tasks on namespace
|
||||||
func ListFunctions(client *containerd.Client, namespace string) (map[string]*Function, error) {
|
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)
|
ctx := namespaces.WithNamespace(context.Background(), namespace)
|
||||||
functions := make(map[string]*Function)
|
functions := make(map[string]*Function)
|
||||||
|
|
||||||
|
@ -14,6 +14,17 @@ func MakeReadHandler(client *containerd.Client) func(w http.ResponseWriter, r *h
|
|||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
lookupNamespace := getRequestNamespace(readNamespaceFromQuery(r))
|
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{}
|
res := []types.FunctionStatus{}
|
||||||
fns, err := ListFunctions(client, lookupNamespace)
|
fns, err := ListFunctions(client, lookupNamespace)
|
||||||
|
@ -16,6 +16,18 @@ func MakeReplicaReaderHandler(client *containerd.Client) func(w http.ResponseWri
|
|||||||
functionName := vars["name"]
|
functionName := vars["name"]
|
||||||
lookupNamespace := getRequestNamespace(readNamespaceFromQuery(r))
|
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 {
|
if f, err := GetFunction(client, functionName, lookupNamespace); err == nil {
|
||||||
found := types.FunctionStatus{
|
found := types.FunctionStatus{
|
||||||
Name: functionName,
|
Name: functionName,
|
||||||
|
@ -41,6 +41,18 @@ func MakeReplicaUpdateHandler(client *containerd.Client, cni gocni.CNI) func(w h
|
|||||||
|
|
||||||
namespace := getRequestNamespace(readNamespaceFromQuery(r))
|
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
|
name := req.ServiceName
|
||||||
|
|
||||||
if _, err := GetFunction(client, name, namespace); err != nil {
|
if _, err := GetFunction(client, name, namespace); err != nil {
|
||||||
|
@ -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) {
|
func listSecrets(c *containerd.Client, w http.ResponseWriter, r *http.Request, mountPath string) {
|
||||||
|
|
||||||
lookupNamespace := getRequestNamespace(readNamespaceFromQuery(r))
|
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)
|
mountPath = getNamespaceSecretMountPath(mountPath, lookupNamespace)
|
||||||
|
|
||||||
files, err := ioutil.ReadDir(mountPath)
|
files, err := ioutil.ReadDir(mountPath)
|
||||||
|
@ -41,6 +41,19 @@ func MakeUpdateHandler(client *containerd.Client, cni gocni.CNI, secretMountPath
|
|||||||
}
|
}
|
||||||
name := req.Service
|
name := req.Service
|
||||||
namespace := getRequestNamespace(req.Namespace)
|
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)
|
namespaceSecretMountPath := getNamespaceSecretMountPath(secretMountPath, namespace)
|
||||||
|
|
||||||
function, err := GetFunction(client, name, namespace)
|
function, err := GetFunction(client, name, namespace)
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/containerd/containerd"
|
||||||
"net/http"
|
"net/http"
|
||||||
"path"
|
"path"
|
||||||
|
|
||||||
@ -23,3 +25,25 @@ func readNamespaceFromQuery(r *http.Request) string {
|
|||||||
func getNamespaceSecretMountPath(userSecretPath string, namespace string) string {
|
func getNamespaceSecretMountPath(userSecretPath string, namespace string) string {
|
||||||
return path.Join(userSecretPath, namespace)
|
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
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user