mirror of
https://github.com/openfaas/faasd.git
synced 2025-06-18 20:16:36 +00:00
Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
3fe0d8d8d3 | |||
5aa4c69e03 | |||
12b5e8ca7f |
@ -88,7 +88,7 @@ func makeProviderCmd() *cobra.Command {
|
||||
baseUserSecretsPath := path.Join(wd, "secrets")
|
||||
if err := moveSecretsToDefaultNamespaceSecrets(
|
||||
baseUserSecretsPath,
|
||||
faasd.FunctionNamespace); err != nil {
|
||||
faasd.DefaultFunctionNamespace); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,11 @@
|
||||
package pkg
|
||||
|
||||
const (
|
||||
// FunctionNamespace is the default containerd namespace functions are created
|
||||
FunctionNamespace = "openfaas-fn"
|
||||
// DefaultFunctionNamespace is the default containerd namespace functions are created
|
||||
DefaultFunctionNamespace = "openfaas-fn"
|
||||
|
||||
// NamespaceLabel indicates that a namespace is managed by faasd
|
||||
NamespaceLabel = "openfaas"
|
||||
|
||||
// FaasdNamespace is the containerd namespace services are created
|
||||
FaasdNamespace = "openfaas"
|
||||
|
@ -71,7 +71,7 @@ func buildCmd(ctx context.Context, req logs.Request) *exec.Cmd {
|
||||
|
||||
namespace := req.Namespace
|
||||
if namespace == "" {
|
||||
namespace = faasd.FunctionNamespace
|
||||
namespace = faasd.DefaultFunctionNamespace
|
||||
}
|
||||
|
||||
// find the description of the fields here
|
||||
|
@ -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
|
||||
valid, err := validNamespace(client, lookupNamespace)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if !valid {
|
||||
http.Error(w, "namespace not valid", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
name := req.FunctionName
|
||||
|
||||
function, err := GetFunction(client, name, lookupNamespace)
|
||||
|
@ -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
|
||||
valid, err := validNamespace(client, namespace)
|
||||
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if !valid {
|
||||
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
|
||||
|
@ -53,7 +53,7 @@ func Test_BuildLabels_WithAnnotations(t *testing.T) {
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(val, tc.result) {
|
||||
t.Errorf("Got: %s, expected %s", val, tc.result)
|
||||
t.Errorf("Want: %s, got: %s", val, tc.result)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package handlers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
@ -11,6 +12,7 @@ import (
|
||||
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/containerd/containerd/namespaces"
|
||||
"github.com/openfaas/faasd/pkg"
|
||||
faasd "github.com/openfaas/faasd/pkg"
|
||||
"github.com/openfaas/faasd/pkg/cninetwork"
|
||||
)
|
||||
@ -32,6 +34,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
|
||||
valid, err := validNamespace(client, namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !valid {
|
||||
return nil, errors.New("namespace not valid")
|
||||
}
|
||||
|
||||
ctx := namespaces.WithNamespace(context.Background(), namespace)
|
||||
functions := make(map[string]*Function)
|
||||
|
||||
@ -187,7 +200,7 @@ func ListNamespaces(client *containerd.Client) []string {
|
||||
namespaces, err := store.List(context.Background())
|
||||
if err != nil {
|
||||
log.Printf("Error listing namespaces: %s", err.Error())
|
||||
set = append(set, faasd.FunctionNamespace)
|
||||
set = append(set, faasd.DefaultFunctionNamespace)
|
||||
return set
|
||||
}
|
||||
|
||||
@ -198,12 +211,12 @@ func ListNamespaces(client *containerd.Client) []string {
|
||||
continue
|
||||
}
|
||||
|
||||
if _, found := labels["openfaas"]; found {
|
||||
if _, found := labels[pkg.NamespaceLabel]; found {
|
||||
set = append(set, namespace)
|
||||
}
|
||||
|
||||
if !findNamespace(faasd.FunctionNamespace, set) {
|
||||
set = append(set, faasd.FunctionNamespace)
|
||||
if !findNamespace(faasd.DefaultFunctionNamespace, set) {
|
||||
set = append(set, faasd.DefaultFunctionNamespace)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ func (i *InvokeResolver) Resolve(functionName string) (url.URL, error) {
|
||||
actualFunctionName := functionName
|
||||
log.Printf("Resolve: %q\n", actualFunctionName)
|
||||
|
||||
namespace := getNamespace(functionName, faasd.FunctionNamespace)
|
||||
namespace := getNamespace(functionName, faasd.DefaultFunctionNamespace)
|
||||
|
||||
if strings.Contains(functionName, ".") {
|
||||
actualFunctionName = strings.TrimSuffix(functionName, "."+namespace)
|
||||
|
@ -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
|
||||
valid, err := validNamespace(client, lookupNamespace)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if !valid {
|
||||
http.Error(w, "namespace not valid", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
res := []types.FunctionStatus{}
|
||||
fns, err := ListFunctions(client, lookupNamespace)
|
||||
|
@ -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
|
||||
valid, err := validNamespace(client, lookupNamespace)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if !valid {
|
||||
http.Error(w, "namespace not valid", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if f, err := GetFunction(client, functionName, lookupNamespace); err == nil {
|
||||
found := types.FunctionStatus{
|
||||
Name: functionName,
|
||||
|
@ -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
|
||||
valid, err := validNamespace(client, namespace)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if !valid {
|
||||
http.Error(w, "namespace not valid", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
name := req.ServiceName
|
||||
|
||||
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) {
|
||||
|
||||
lookupNamespace := getRequestNamespace(readNamespaceFromQuery(r))
|
||||
// Check if namespace exists, and it has the openfaas label
|
||||
valid, err := validNamespace(c, lookupNamespace)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if !valid {
|
||||
http.Error(w, "namespace not valid", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
mountPath = getNamespaceSecretMountPath(mountPath, lookupNamespace)
|
||||
|
||||
files, err := ioutil.ReadDir(mountPath)
|
||||
|
@ -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
|
||||
valid, err := validNamespace(client, namespace)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if !valid {
|
||||
http.Error(w, "namespace not valid", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
namespaceSecretMountPath := getNamespaceSecretMountPath(secretMountPath, namespace)
|
||||
|
||||
function, err := GetFunction(client, name, namespace)
|
||||
|
@ -1,9 +1,13 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"path"
|
||||
|
||||
"github.com/containerd/containerd"
|
||||
|
||||
"github.com/openfaas/faasd/pkg"
|
||||
faasd "github.com/openfaas/faasd/pkg"
|
||||
)
|
||||
|
||||
@ -12,7 +16,7 @@ func getRequestNamespace(namespace string) string {
|
||||
if len(namespace) > 0 {
|
||||
return namespace
|
||||
}
|
||||
return faasd.FunctionNamespace
|
||||
return faasd.DefaultFunctionNamespace
|
||||
}
|
||||
|
||||
func readNamespaceFromQuery(r *http.Request) string {
|
||||
@ -23,3 +27,23 @@ func readNamespaceFromQuery(r *http.Request) string {
|
||||
func getNamespaceSecretMountPath(userSecretPath string, namespace string) string {
|
||||
return path.Join(userSecretPath, namespace)
|
||||
}
|
||||
|
||||
// validNamespace indicates whether the namespace is eligable to be
|
||||
// used for OpenFaaS functions.
|
||||
func validNamespace(client *containerd.Client, namespace string) (bool, error) {
|
||||
if namespace == faasd.DefaultFunctionNamespace {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
store := client.NamespaceService()
|
||||
labels, err := store.Labels(context.Background(), namespace)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if value, found := labels[pkg.NamespaceLabel]; found && value == "true" {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ func Test_getRequestNamespace(t *testing.T) {
|
||||
requestNamespace string
|
||||
expectedNamespace string
|
||||
}{
|
||||
{name: "RequestNamespace is not provided", requestNamespace: "", expectedNamespace: faasd.FunctionNamespace},
|
||||
{name: "RequestNamespace is not provided", requestNamespace: "", expectedNamespace: faasd.DefaultFunctionNamespace},
|
||||
{name: "RequestNamespace is provided", requestNamespace: "user-namespace", expectedNamespace: "user-namespace"},
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@ func Test_getRequestNamespace(t *testing.T) {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
actualNamespace := getRequestNamespace(tc.requestNamespace)
|
||||
if actualNamespace != tc.expectedNamespace {
|
||||
t.Errorf("Got: %s, expected %s", actualNamespace, tc.expectedNamespace)
|
||||
t.Errorf("Want: %s, got: %s", actualNamespace, tc.expectedNamespace)
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -36,7 +36,7 @@ func Test_getNamespaceSecretMountPath(t *testing.T) {
|
||||
requestNamespace string
|
||||
expectedSecretPath string
|
||||
}{
|
||||
{name: "Default Namespace is provided", requestNamespace: faasd.FunctionNamespace, expectedSecretPath: "/var/openfaas/secrets/" + faasd.FunctionNamespace},
|
||||
{name: "Default Namespace is provided", requestNamespace: faasd.DefaultFunctionNamespace, expectedSecretPath: "/var/openfaas/secrets/" + faasd.DefaultFunctionNamespace},
|
||||
{name: "User Namespace is provided", requestNamespace: "user-namespace", expectedSecretPath: "/var/openfaas/secrets/user-namespace"},
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@ func Test_getNamespaceSecretMountPath(t *testing.T) {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
actualNamespace := getNamespaceSecretMountPath(userSecretPath, tc.requestNamespace)
|
||||
if actualNamespace != tc.expectedSecretPath {
|
||||
t.Errorf("Got: %s, expected %s", actualNamespace, tc.expectedSecretPath)
|
||||
t.Errorf("Want: %s, got: %s", actualNamespace, tc.expectedSecretPath)
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -68,7 +68,7 @@ func Test_readNamespaceFromQuery(t *testing.T) {
|
||||
|
||||
actualNamespace := readNamespaceFromQuery(r)
|
||||
if actualNamespace != tc.expectedNamespace {
|
||||
t.Errorf("Got: %s, expected %s", actualNamespace, tc.expectedNamespace)
|
||||
t.Errorf("Want: %s, got: %s", actualNamespace, tc.expectedNamespace)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
Reference in New Issue
Block a user