Enabling multi-tenancy for fission objects. (#655)
This feature allows creation of fission objects in different namespaces, in addition to retaining the existing behavior of creating fission objects in default namespace if user doesnt provide one. It also removes cluster admin roles for fission-fetcher and fission-builder Service Accounts and grants them only those privileges that they need.
This commit is contained in:
@@ -66,7 +66,7 @@ func (w *packageBuildWatcher) watch(ctx context.Context) {
|
||||
}
|
||||
|
||||
// poll list of packages (TODO: convert to watch)
|
||||
pkgs, err := w.fclient.PackageList()
|
||||
pkgs, err := w.fclient.PackageList(metav1.NamespaceAll)
|
||||
checkErr(err, "Getting list of packages")
|
||||
|
||||
// find packages that (a) are in the app spec and (b) have an interesting
|
||||
|
||||
+3
-3
@@ -205,10 +205,10 @@ func createArchive(client *client.Client, fileName string, specFile string) *fis
|
||||
return &archive
|
||||
}
|
||||
|
||||
func createPackage(client *client.Client, envName, srcArchiveName, deployArchiveName, buildcmd string, specFile string) *metav1.ObjectMeta {
|
||||
func createPackage(client *client.Client, pkgNamespace, envName, envNamespace, srcArchiveName, deployArchiveName, buildcmd string, specFile string) *metav1.ObjectMeta {
|
||||
pkgSpec := fission.PackageSpec{
|
||||
Environment: fission.EnvironmentReference{
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Namespace: envNamespace,
|
||||
Name: envName,
|
||||
},
|
||||
}
|
||||
@@ -239,7 +239,7 @@ func createPackage(client *client.Client, envName, srcArchiveName, deployArchive
|
||||
pkg := &crd.Package{
|
||||
Metadata: metav1.ObjectMeta{
|
||||
Name: pkgName,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Namespace: pkgNamespace,
|
||||
},
|
||||
Spec: pkgSpec,
|
||||
Status: fission.PackageStatus{
|
||||
|
||||
+33
-6
@@ -28,9 +28,24 @@ import (
|
||||
"k8s.io/client-go/pkg/api/v1"
|
||||
|
||||
"github.com/fission/fission"
|
||||
"github.com/fission/fission/controller/client"
|
||||
"github.com/fission/fission/crd"
|
||||
)
|
||||
|
||||
func getFunctionsByEnvironment(client *client.Client, envName, envNamespace string) ([]crd.Function, error) {
|
||||
fnList, err := client.FunctionList(metav1.NamespaceAll)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fns := []crd.Function{}
|
||||
for _, fn := range fnList {
|
||||
if fn.Spec.Environment.Name == envName && fn.Spec.Environment.Namespace == envNamespace {
|
||||
fns = append(fns, fn)
|
||||
}
|
||||
}
|
||||
return fns, nil
|
||||
}
|
||||
|
||||
func envCreate(c *cli.Context) error {
|
||||
client := getClient(c.GlobalString("server"))
|
||||
|
||||
@@ -38,6 +53,14 @@ func envCreate(c *cli.Context) error {
|
||||
if len(envName) == 0 {
|
||||
fatal("Need a name, use --name.")
|
||||
}
|
||||
envNamespace := c.String("envNamespace")
|
||||
|
||||
envList, err := client.EnvironmentList(envNamespace)
|
||||
if err == nil && len(envList) > 0 {
|
||||
warn(fmt.Sprintf("%d environment(s) are present in this ns: %s. All these envs share"+
|
||||
" the same service account token, with previleges to view secrets of all the functions referencing them. "+
|
||||
"Envs can be created in different ns if isolation is needed", len(envList), envNamespace))
|
||||
}
|
||||
|
||||
var poolsize int
|
||||
if c.IsSet("poolsize") {
|
||||
@@ -80,7 +103,7 @@ func envCreate(c *cli.Context) error {
|
||||
env := &crd.Environment{
|
||||
Metadata: metav1.ObjectMeta{
|
||||
Name: envName,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Namespace: envNamespace,
|
||||
},
|
||||
Spec: fission.EnvironmentSpec{
|
||||
Version: envVersion,
|
||||
@@ -106,7 +129,7 @@ func envCreate(c *cli.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
_, err := client.EnvironmentCreate(env)
|
||||
_, err = client.EnvironmentCreate(env)
|
||||
checkErr(err, "create environment")
|
||||
|
||||
fmt.Printf("environment '%v' created\n", envName)
|
||||
@@ -120,10 +143,11 @@ func envGet(c *cli.Context) error {
|
||||
if len(envName) == 0 {
|
||||
fatal("Need a name, use --name.")
|
||||
}
|
||||
envNamespace := c.String("envNamespace")
|
||||
|
||||
m := &metav1.ObjectMeta{
|
||||
Name: envName,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Namespace: envNamespace,
|
||||
}
|
||||
env, err := client.EnvironmentGet(m)
|
||||
checkErr(err, "get environment")
|
||||
@@ -143,6 +167,7 @@ func envUpdate(c *cli.Context) error {
|
||||
if len(envName) == 0 {
|
||||
fatal("Need a name, use --name.")
|
||||
}
|
||||
envNamespace := c.String("envNamespace")
|
||||
|
||||
envImg := c.String("image")
|
||||
envBuilderImg := c.String("builder")
|
||||
@@ -155,7 +180,7 @@ func envUpdate(c *cli.Context) error {
|
||||
|
||||
env, err := client.EnvironmentGet(&metav1.ObjectMeta{
|
||||
Name: envName,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Namespace: envNamespace,
|
||||
})
|
||||
checkErr(err, "find environment")
|
||||
|
||||
@@ -198,10 +223,11 @@ func envDelete(c *cli.Context) error {
|
||||
if len(envName) == 0 {
|
||||
fatal("Need a name , use --name.")
|
||||
}
|
||||
envNamespace := c.String("envNamespace")
|
||||
|
||||
m := &metav1.ObjectMeta{
|
||||
Name: envName,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Namespace: envNamespace,
|
||||
}
|
||||
err := client.EnvironmentDelete(m)
|
||||
checkErr(err, "delete environment")
|
||||
@@ -212,8 +238,9 @@ func envDelete(c *cli.Context) error {
|
||||
|
||||
func envList(c *cli.Context) error {
|
||||
client := getClient(c.GlobalString("server"))
|
||||
envNamespace := c.String("envNamespace")
|
||||
|
||||
envs, err := client.EnvironmentList()
|
||||
envs, err := client.EnvironmentList(envNamespace)
|
||||
checkErr(err, "list environments")
|
||||
|
||||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)
|
||||
|
||||
+82
-38
@@ -30,6 +30,7 @@ import (
|
||||
|
||||
"github.com/satori/go.uuid"
|
||||
"github.com/urfave/cli"
|
||||
k8serrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
apiv1 "k8s.io/client-go/pkg/api/v1"
|
||||
|
||||
@@ -115,9 +116,13 @@ func getTargetCPU(c *cli.Context) int {
|
||||
return targetCPU
|
||||
}
|
||||
|
||||
// From this change onwards, we mandate that a function should reference a secret, config map and package in its own ns
|
||||
func fnCreate(c *cli.Context) error {
|
||||
client := getClient(c.GlobalString("server"))
|
||||
|
||||
fnNamespace := c.String("fnNamespace")
|
||||
envNamespace := c.String("envNamespace")
|
||||
|
||||
fnName := c.String("name")
|
||||
if len(fnName) == 0 {
|
||||
fatal("Need --name argument.")
|
||||
@@ -131,7 +136,8 @@ func fnCreate(c *cli.Context) error {
|
||||
specFile = fmt.Sprintf("function-%v.yaml", fnName)
|
||||
}
|
||||
|
||||
fnList, err := client.FunctionList()
|
||||
// check for unique function names within a namespace
|
||||
fnList, err := client.FunctionList(fnNamespace)
|
||||
checkErr(err, "get function list")
|
||||
// check function existence before creating package
|
||||
for _, fn := range fnList {
|
||||
@@ -148,18 +154,16 @@ func fnCreate(c *cli.Context) error {
|
||||
secretName := c.String("secret")
|
||||
cfgMapName := c.String("configmap")
|
||||
|
||||
secretNameSpace := c.String("secretNamespace")
|
||||
cfgMapNameSpace := c.String("configmapNamespace")
|
||||
|
||||
if len(pkgName) > 0 {
|
||||
// use existing package
|
||||
pkg, err := client.PackageGet(&metav1.ObjectMeta{
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Namespace: fnNamespace,
|
||||
Name: pkgName,
|
||||
})
|
||||
checkErr(err, fmt.Sprintf("read package '%v'", pkgName))
|
||||
checkErr(err, fmt.Sprintf("read package in '%v' in Namespace: %s. Package needs to be present in the same namespace as function", pkgName, fnNamespace))
|
||||
pkgMetadata = &pkg.Metadata
|
||||
envName = pkg.Spec.Environment.Name
|
||||
envNamespace = pkg.Spec.Environment.Namespace
|
||||
} else {
|
||||
// need to specify environment for creating new package
|
||||
envName = c.String("env")
|
||||
@@ -169,7 +173,7 @@ func fnCreate(c *cli.Context) error {
|
||||
|
||||
// examine existence of given environment
|
||||
_, err := client.EnvironmentGet(&metav1.ObjectMeta{
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Namespace: envNamespace,
|
||||
Name: envName,
|
||||
})
|
||||
if err != nil {
|
||||
@@ -192,8 +196,8 @@ func fnCreate(c *cli.Context) error {
|
||||
|
||||
buildcmd := c.String("buildcmd")
|
||||
|
||||
// create new package
|
||||
pkgMetadata = createPackage(client, envName, srcArchiveName, deployArchiveName, buildcmd, specFile)
|
||||
// create new package in the same namespace as the function.
|
||||
pkgMetadata = createPackage(client, fnNamespace, envName, envNamespace, srcArchiveName, deployArchiveName, buildcmd, specFile)
|
||||
}
|
||||
|
||||
invokeStrategy := getInvokeStrategy(c.Int("minscale"), c.Int("maxscale"), c.String("executortype"), getTargetCPU(c))
|
||||
@@ -207,23 +211,35 @@ func fnCreate(c *cli.Context) error {
|
||||
var cfgmaps []fission.ConfigMapReference
|
||||
|
||||
if len(secretName) > 0 {
|
||||
if len(secretNameSpace) == 0 {
|
||||
secretNameSpace = metav1.NamespaceDefault
|
||||
// check the referenced secret is in the same ns as the function, if not give a warning.
|
||||
_, err := client.SecretGet(&metav1.ObjectMeta{
|
||||
Namespace: fnNamespace,
|
||||
Name: secretName,
|
||||
})
|
||||
if k8serrors.IsNotFound(err) {
|
||||
warn(fmt.Sprintf("Secret %s not found in Namespace: %s. Secret needs to be present in the same namespace as function", secretName, fnNamespace))
|
||||
}
|
||||
|
||||
newSecret := fission.SecretReference{
|
||||
Name: secretName,
|
||||
Namespace: secretNameSpace,
|
||||
Namespace: fnNamespace,
|
||||
}
|
||||
secrets = []fission.SecretReference{newSecret}
|
||||
}
|
||||
|
||||
if len(cfgMapName) > 0 {
|
||||
if len(cfgMapNameSpace) == 0 {
|
||||
cfgMapNameSpace = metav1.NamespaceDefault
|
||||
// check the referenced cfgmap is in the same ns as the function, if not give a warning.
|
||||
_, err := client.ConfigMapGet(&metav1.ObjectMeta{
|
||||
Namespace: fnNamespace,
|
||||
Name: cfgMapName,
|
||||
})
|
||||
if k8serrors.IsNotFound(err) {
|
||||
warn(fmt.Sprintf("ConfigMap %s not found in Namespace: %s. ConfigMap needs to be present in the same namespace as function", cfgMapName, fnNamespace))
|
||||
}
|
||||
|
||||
newCfgMap := fission.ConfigMapReference{
|
||||
Name: cfgMapName,
|
||||
Namespace: cfgMapNameSpace,
|
||||
Namespace: fnNamespace,
|
||||
}
|
||||
cfgmaps = []fission.ConfigMapReference{newCfgMap}
|
||||
}
|
||||
@@ -231,12 +247,12 @@ func fnCreate(c *cli.Context) error {
|
||||
function := &crd.Function{
|
||||
Metadata: metav1.ObjectMeta{
|
||||
Name: fnName,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Namespace: fnNamespace,
|
||||
},
|
||||
Spec: fission.FunctionSpec{
|
||||
Environment: fission.EnvironmentReference{
|
||||
Name: envName,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Namespace: envNamespace,
|
||||
},
|
||||
Package: fission.FunctionPackageRef{
|
||||
FunctionName: entrypoint,
|
||||
@@ -283,7 +299,7 @@ func fnCreate(c *cli.Context) error {
|
||||
ht := &crd.HTTPTrigger{
|
||||
Metadata: metav1.ObjectMeta{
|
||||
Name: triggerName,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Namespace: fnNamespace,
|
||||
},
|
||||
Spec: fission.HTTPTriggerSpec{
|
||||
RelativeURL: triggerUrl,
|
||||
@@ -308,9 +324,10 @@ func fnGet(c *cli.Context) error {
|
||||
if len(fnName) == 0 {
|
||||
fatal("Need name of function, use --name")
|
||||
}
|
||||
fnNamespace := c.String("fnNamespace")
|
||||
m := &metav1.ObjectMeta{
|
||||
Name: fnName,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Namespace: fnNamespace,
|
||||
}
|
||||
fn, err := client.FunctionGet(m)
|
||||
checkErr(err, "get function")
|
||||
@@ -332,10 +349,11 @@ func fnGetMeta(c *cli.Context) error {
|
||||
if len(fnName) == 0 {
|
||||
fatal("Need name of function, use --name")
|
||||
}
|
||||
fnNamespace := c.String("fnNamespace")
|
||||
|
||||
m := &metav1.ObjectMeta{
|
||||
Name: fnName,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Namespace: fnNamespace,
|
||||
}
|
||||
|
||||
f, err := client.FunctionGet(m)
|
||||
@@ -364,14 +382,16 @@ func fnUpdate(c *cli.Context) error {
|
||||
if len(fnName) == 0 {
|
||||
fatal("Need name of function, use --name")
|
||||
}
|
||||
fnNamespace := c.String("fnNamespace")
|
||||
|
||||
function, err := client.FunctionGet(&metav1.ObjectMeta{
|
||||
Name: fnName,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Namespace: fnNamespace,
|
||||
})
|
||||
checkErr(err, fmt.Sprintf("read function '%v'", fnName))
|
||||
|
||||
envName := c.String("env")
|
||||
envNamespace := c.String("envNamespace")
|
||||
deployArchiveName := c.String("code")
|
||||
if len(deployArchiveName) == 0 {
|
||||
deployArchiveName = c.String("deploy")
|
||||
@@ -385,9 +405,6 @@ func fnUpdate(c *cli.Context) error {
|
||||
secretName := c.String("secret")
|
||||
cfgMapName := c.String("configmap")
|
||||
|
||||
secretNameSpace := c.String("secretNamespace")
|
||||
cfgMapNameSpace := c.String("configmapNamespace")
|
||||
|
||||
if len(srcArchiveName) > 0 && len(deployArchiveName) > 0 {
|
||||
fatal("Need either of --src or --deploy and not both arguments.")
|
||||
}
|
||||
@@ -396,12 +413,19 @@ func fnUpdate(c *cli.Context) error {
|
||||
if len(function.Spec.Secrets) > 1 {
|
||||
fatal("Please use 'fission spec apply' to update list of secrets")
|
||||
}
|
||||
if len(secretNameSpace) == 0 {
|
||||
secretNameSpace = metav1.NamespaceDefault
|
||||
|
||||
// check that the referenced secret is in the same ns as the function, if not give a warning.
|
||||
_, err := client.SecretGet(&metav1.ObjectMeta{
|
||||
Namespace: fnNamespace,
|
||||
Name: secretName,
|
||||
})
|
||||
if k8serrors.IsNotFound(err) {
|
||||
warn(fmt.Sprintf("secret %s not found in Namespace: %s. Secret needs to be present in the same namespace as function", secretName, fnNamespace))
|
||||
}
|
||||
|
||||
newSecret := fission.SecretReference{
|
||||
Name: secretName,
|
||||
Namespace: secretNameSpace,
|
||||
Namespace: fnNamespace,
|
||||
}
|
||||
function.Spec.Secrets = []fission.SecretReference{newSecret}
|
||||
}
|
||||
@@ -410,18 +434,26 @@ func fnUpdate(c *cli.Context) error {
|
||||
if len(function.Spec.ConfigMaps) > 1 {
|
||||
fatal("Please use 'fission spec apply' to update list of configmaps")
|
||||
}
|
||||
if len(cfgMapNameSpace) == 0 {
|
||||
cfgMapNameSpace = metav1.NamespaceDefault
|
||||
|
||||
// check that the referenced cfgmap is in the same ns as the function, if not give a warning.
|
||||
_, err := client.ConfigMapGet(&metav1.ObjectMeta{
|
||||
Namespace: fnNamespace,
|
||||
Name: cfgMapName,
|
||||
})
|
||||
if k8serrors.IsNotFound(err) {
|
||||
warn(fmt.Sprintf("ConfigMap %s not found in Namespace: %s. ConfigMap needs to be present in the same namespace as the function", cfgMapName, fnNamespace))
|
||||
}
|
||||
|
||||
newCfgMap := fission.ConfigMapReference{
|
||||
Name: cfgMapName,
|
||||
Namespace: cfgMapNameSpace,
|
||||
Namespace: fnNamespace,
|
||||
}
|
||||
function.Spec.ConfigMaps = []fission.ConfigMapReference{newCfgMap}
|
||||
}
|
||||
|
||||
if len(envName) > 0 {
|
||||
function.Spec.Environment.Name = envName
|
||||
function.Spec.Environment.Namespace = envNamespace
|
||||
}
|
||||
|
||||
if len(entrypoint) > 0 {
|
||||
@@ -432,22 +464,22 @@ func fnUpdate(c *cli.Context) error {
|
||||
}
|
||||
|
||||
pkg, err := client.PackageGet(&metav1.ObjectMeta{
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Namespace: fnNamespace,
|
||||
Name: pkgName,
|
||||
})
|
||||
checkErr(err, fmt.Sprintf("read package '%v'", pkgName))
|
||||
checkErr(err, fmt.Sprintf("read package '%v.%v'. Pkg should be present in the same ns as the function", pkgName, fnNamespace))
|
||||
|
||||
pkgMetadata := &pkg.Metadata
|
||||
|
||||
if len(deployArchiveName) != 0 || len(srcArchiveName) != 0 || len(buildcmd) != 0 || len(envName) != 0 {
|
||||
fnList, err := getFunctionsByPackage(client, pkg.Metadata.Name)
|
||||
fnList, err := getFunctionsByPackage(client, pkg.Metadata.Name, pkg.Metadata.Namespace)
|
||||
checkErr(err, "get function list")
|
||||
|
||||
if !force && len(fnList) > 1 {
|
||||
fatal("Package is used by multiple functions, use --force to force update")
|
||||
}
|
||||
|
||||
pkgMetadata = updatePackage(client, pkg, envName, srcArchiveName, deployArchiveName, buildcmd)
|
||||
pkgMetadata = updatePackage(client, pkg, envName, envNamespace, srcArchiveName, deployArchiveName, buildcmd)
|
||||
checkErr(err, fmt.Sprintf("update package '%v'", pkgName))
|
||||
|
||||
fmt.Printf("package '%v' updated\n", pkgMetadata.GetName())
|
||||
@@ -463,6 +495,9 @@ func fnUpdate(c *cli.Context) error {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO : One corner case where user just updates the pkg reference with fnUpdate, but internally this new pkg reference
|
||||
// references a diff env than the spec
|
||||
|
||||
// update function spec with new package metadata
|
||||
function.Spec.Package.PackageRef = fission.PackageRef{
|
||||
Namespace: pkgMetadata.Namespace,
|
||||
@@ -532,10 +567,11 @@ func fnDelete(c *cli.Context) error {
|
||||
if len(fnName) == 0 {
|
||||
fatal("Need name of function, use --name")
|
||||
}
|
||||
fnNamespace := c.String("fnNamespace")
|
||||
|
||||
m := &metav1.ObjectMeta{
|
||||
Name: fnName,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Namespace: fnNamespace,
|
||||
}
|
||||
|
||||
err := client.FunctionDelete(m)
|
||||
@@ -547,8 +583,9 @@ func fnDelete(c *cli.Context) error {
|
||||
|
||||
func fnList(c *cli.Context) error {
|
||||
client := getClient(c.GlobalString("server"))
|
||||
ns := c.String("fnNamespace")
|
||||
|
||||
fns, err := client.FunctionList()
|
||||
fns, err := client.FunctionList(ns)
|
||||
checkErr(err, "list functions")
|
||||
|
||||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)
|
||||
@@ -581,6 +618,7 @@ func fnLogs(c *cli.Context) error {
|
||||
if len(fnName) == 0 {
|
||||
fatal("Need name of function, use --name")
|
||||
}
|
||||
fnNamespace := c.String("fnNamespace")
|
||||
|
||||
dbType := c.String("dbtype")
|
||||
if len(dbType) == 0 {
|
||||
@@ -590,7 +628,7 @@ func fnLogs(c *cli.Context) error {
|
||||
fnPod := c.String("pod")
|
||||
m := &metav1.ObjectMeta{
|
||||
Name: fnName,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Namespace: fnNamespace,
|
||||
}
|
||||
|
||||
recordLimit := c.Int("recordcount")
|
||||
@@ -659,6 +697,7 @@ func fnTest(c *cli.Context) error {
|
||||
if len(fnName) == 0 {
|
||||
fatal("Need function name to be specified with --name")
|
||||
}
|
||||
ns := c.String("fnNamespace")
|
||||
|
||||
routerURL := os.Getenv("FISSION_ROUTER")
|
||||
if len(routerURL) == 0 {
|
||||
@@ -670,7 +709,12 @@ func fnTest(c *cli.Context) error {
|
||||
routerURL = strings.TrimPrefix(routerURL, "http://")
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("http://%s/fission-function/%s", routerURL, fnName)
|
||||
fnUri := fnName
|
||||
if ns != metav1.NamespaceDefault {
|
||||
fnUri = fmt.Sprintf("%v/%v", ns, fnName)
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("http://%s/fission-function/%s", routerURL, fnUri)
|
||||
|
||||
resp := httpRequest(c.String("method"), url, c.String("body"), c.StringSlice("header"))
|
||||
if resp.StatusCode < 400 {
|
||||
|
||||
+13
-8
@@ -58,10 +58,10 @@ func getMethod(method string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func checkFunctionExistence(fissionClient *client.Client, fnName string) {
|
||||
func checkFunctionExistence(fissionClient *client.Client, fnName string, fnNamespace string) {
|
||||
meta := &metav1.ObjectMeta{
|
||||
Name: fnName,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Namespace: fnNamespace,
|
||||
}
|
||||
|
||||
_, err := fissionClient.FunctionGet(meta)
|
||||
@@ -77,6 +77,8 @@ func htCreate(c *cli.Context) error {
|
||||
if len(fnName) == 0 {
|
||||
fatal("Need a function name to create a trigger, use --function")
|
||||
}
|
||||
fnNamespace := c.String("fnNamespace")
|
||||
|
||||
triggerUrl := c.String("url")
|
||||
if len(triggerUrl) == 0 {
|
||||
fatal("Need a trigger URL, use --url")
|
||||
@@ -90,7 +92,7 @@ func htCreate(c *cli.Context) error {
|
||||
method = "GET"
|
||||
}
|
||||
|
||||
checkFunctionExistence(client, fnName)
|
||||
checkFunctionExistence(client, fnName, fnNamespace)
|
||||
|
||||
// just name triggers by uuid.
|
||||
triggerName := uuid.NewV4().String()
|
||||
@@ -98,7 +100,7 @@ func htCreate(c *cli.Context) error {
|
||||
ht := &crd.HTTPTrigger{
|
||||
Metadata: metav1.ObjectMeta{
|
||||
Name: triggerName,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Namespace: fnNamespace,
|
||||
},
|
||||
Spec: fission.HTTPTriggerSpec{
|
||||
RelativeURL: triggerUrl,
|
||||
@@ -135,6 +137,7 @@ func htUpdate(c *cli.Context) error {
|
||||
if len(htName) == 0 {
|
||||
fatal("Need name of trigger, use --name")
|
||||
}
|
||||
triggerNamespace := c.String("triggerNamespace")
|
||||
|
||||
// update function ref
|
||||
newFn := c.String("function")
|
||||
@@ -142,11 +145,11 @@ func htUpdate(c *cli.Context) error {
|
||||
fatal("Nothing to update. Use --function to specify a new function.")
|
||||
}
|
||||
|
||||
checkFunctionExistence(client, newFn)
|
||||
checkFunctionExistence(client, newFn, triggerNamespace)
|
||||
|
||||
ht, err := client.HTTPTriggerGet(&metav1.ObjectMeta{
|
||||
Name: htName,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Namespace: triggerNamespace,
|
||||
})
|
||||
checkErr(err, "get HTTP trigger")
|
||||
|
||||
@@ -167,10 +170,11 @@ func htDelete(c *cli.Context) error {
|
||||
if len(htName) == 0 {
|
||||
fatal("Need name of trigger to delete, use --name")
|
||||
}
|
||||
triggerNamespace := c.String("triggerNamespace")
|
||||
|
||||
err := client.HTTPTriggerDelete(&metav1.ObjectMeta{
|
||||
Name: htName,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Namespace: triggerNamespace,
|
||||
})
|
||||
checkErr(err, "delete trigger")
|
||||
|
||||
@@ -180,8 +184,9 @@ func htDelete(c *cli.Context) error {
|
||||
|
||||
func htList(c *cli.Context) error {
|
||||
client := getClient(c.GlobalString("server"))
|
||||
triggerNamespace := c.String("triggerNamespace")
|
||||
|
||||
hts, err := client.HTTPTriggerList()
|
||||
hts, err := client.HTTPTriggerList(triggerNamespace)
|
||||
checkErr(err, "list HTTP triggers")
|
||||
|
||||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)
|
||||
|
||||
+51
-44
@@ -26,6 +26,7 @@ import (
|
||||
|
||||
version "github.com/fission/fission"
|
||||
"github.com/urfave/cli"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func getFissionNamespace() string {
|
||||
@@ -107,6 +108,12 @@ func main() {
|
||||
// all resource create commands accept --spec
|
||||
specSaveFlag := cli.BoolFlag{Name: "spec", Usage: "Save to the spec directory instead of creating on cluster"}
|
||||
|
||||
// namespace reference for all objects
|
||||
fnNamespaceFlag := cli.StringFlag{Name: "fnNamespace, fns", Value: metav1.NamespaceDefault, Usage: "Namespace for function object"}
|
||||
envNamespaceFlag := cli.StringFlag{Name: "envNamespace, envns", Value: metav1.NamespaceDefault, Usage: "Namespace for environment object"}
|
||||
pkgNamespaceFlag := cli.StringFlag{Name: "pkgNamespace, pkgns", Value: metav1.NamespaceDefault, Usage: "Namespace for package object"}
|
||||
triggerNamespaceFlag := cli.StringFlag{Name: "triggerNamespace, triggerns", Value: metav1.NamespaceDefault, Usage: "Namespace for trigger object"}
|
||||
|
||||
// trigger method and url flags (used in function and route CLIs)
|
||||
htMethodFlag := cli.StringFlag{Name: "method", Value: "GET", Usage: "HTTP Method: GET|POST|PUT|DELETE|HEAD"}
|
||||
htUrlFlag := cli.StringFlag{Name: "url", Usage: "URL pattern (See gorilla/mux supported patterns)"}
|
||||
@@ -126,7 +133,7 @@ func main() {
|
||||
fnCodeFlag := cli.StringFlag{Name: "code", Usage: "local path or URL for source code"}
|
||||
fnDeployArchiveFlag := cli.StringFlag{Name: "deployarchive, deploy", Usage: "local path or URL for deployment archive"}
|
||||
fnSrcArchiveFlag := cli.StringFlag{Name: "sourcearchive, src", Usage: "local path or URL for source archive"}
|
||||
fnPkgNameFlag := cli.StringFlag{Name: "pkgname, pkg", Usage: "Name of the existing package (--deploy and --src and --env will be ignored)"}
|
||||
fnPkgNameFlag := cli.StringFlag{Name: "pkgname, pkg", Usage: "Name of the existing package (--deploy and --src and --env will be ignored), should be in the same namespace as the function"}
|
||||
fnPodFlag := cli.StringFlag{Name: "pod", Usage: "function pod name, optional (use latest if unspecified)"}
|
||||
fnFollowFlag := cli.BoolFlag{Name: "follow, f", Usage: "specify if the logs should be streamed"}
|
||||
fnDetailFlag := cli.BoolFlag{Name: "detail, d", Usage: "display detailed information"}
|
||||
@@ -135,34 +142,34 @@ func main() {
|
||||
fnHeaderFlag := cli.StringSliceFlag{Name: "header, H", Usage: "request headers"}
|
||||
fnEntryPointFlag := cli.StringFlag{Name: "entrypoint", Usage: "entry point for environment v2 to load with"}
|
||||
fnBuildCmdFlag := cli.StringFlag{Name: "buildcmd", Usage: "build command for builder to run with"}
|
||||
fnSecretFlag := cli.StringFlag{Name: "secret", Usage: "function access to secret"}
|
||||
fnSecretnsFlag := cli.StringFlag{Name: "secretNamespace", Usage: "namespace of secret"}
|
||||
fnCfgMapFlag := cli.StringFlag{Name: "configmap", Usage: "function access to configmap"}
|
||||
fnCfgMapnsFlag := cli.StringFlag{Name: "configmapNamespace", Usage: "namespace of configmap"}
|
||||
fnSecretFlag := cli.StringFlag{Name: "secret", Usage: "function access to secret, should be present in the same namespace as the function"}
|
||||
fnCfgMapFlag := cli.StringFlag{Name: "configmap", Usage: "function access to configmap, should be present in the same namespace as the function"}
|
||||
fnLogCountFlag := cli.StringFlag{Name: "recordcount", Usage: "the n most recent log records"}
|
||||
fnForceFlag := cli.BoolFlag{Name: "force", Usage: "Force update a package even if it is used by one or more functions"}
|
||||
fnExecutorTypeFlag := cli.StringFlag{Name: "executortype", Value: "poolmgr", Usage: "Executor type for execution; one of 'poolmgr', 'newdeploy'"}
|
||||
fnExecutorTypeFlag := cli.StringFlag{Name: "executortype", Usage: "Executor type for execution; one of 'poolmgr', 'newdeploy' defaults to 'poolmgr'"}
|
||||
|
||||
fnSubcommands := []cli.Command{
|
||||
{Name: "create", Usage: "Create new function (and optionally, an HTTP route to it)", Flags: []cli.Flag{fnNameFlag, fnEnvNameFlag, specSaveFlag, fnCodeFlag, fnSrcArchiveFlag, fnDeployArchiveFlag, fnEntryPointFlag, fnBuildCmdFlag, fnPkgNameFlag, htUrlFlag, htMethodFlag, minCpu, maxCpu, minMem, maxMem, minScale, maxScale, fnExecutorTypeFlag, targetcpu, fnCfgMapFlag, fnSecretFlag, fnSecretnsFlag, fnCfgMapnsFlag}, Action: fnCreate},
|
||||
{Name: "get", Usage: "Get function source code", Flags: []cli.Flag{fnNameFlag}, Action: fnGet},
|
||||
{Name: "getmeta", Usage: "Get function metadata", Flags: []cli.Flag{fnNameFlag}, Action: fnGetMeta},
|
||||
{Name: "update", Usage: "Update function source code", Flags: []cli.Flag{fnNameFlag, fnEnvNameFlag, fnCodeFlag, fnSrcArchiveFlag, fnDeployArchiveFlag, fnEntryPointFlag, fnPkgNameFlag, fnBuildCmdFlag, fnForceFlag, minCpu, maxCpu, minMem, maxMem, minScale, maxScale, fnExecutorTypeFlag, targetcpu}, Action: fnUpdate},
|
||||
{Name: "delete", Usage: "Delete function", Flags: []cli.Flag{fnNameFlag}, Action: fnDelete},
|
||||
{Name: "list", Usage: "List all functions", Flags: []cli.Flag{}, Action: fnList},
|
||||
{Name: "logs", Usage: "Display function logs", Flags: []cli.Flag{fnNameFlag, fnPodFlag, fnFollowFlag, fnDetailFlag, fnLogDBTypeFlag, fnLogCountFlag}, Action: fnLogs},
|
||||
{Name: "test", Usage: "Test a function", Flags: []cli.Flag{fnNameFlag, fnEnvNameFlag, fnCodeFlag, fnSrcArchiveFlag, htMethodFlag, fnBodyFlag, fnHeaderFlag}, Action: fnTest},
|
||||
{Name: "create", Usage: "Create new function (and optionally, an HTTP route to it)", Flags: []cli.Flag{fnNameFlag, fnNamespaceFlag, fnEnvNameFlag, envNamespaceFlag, specSaveFlag, fnCodeFlag, fnSrcArchiveFlag, fnDeployArchiveFlag, fnEntryPointFlag, fnBuildCmdFlag, fnPkgNameFlag, htUrlFlag, htMethodFlag, minCpu, maxCpu, minMem, maxMem, minScale, maxScale, fnExecutorTypeFlag, targetcpu, fnCfgMapFlag, fnSecretFlag}, Action: fnCreate},
|
||||
{Name: "get", Usage: "Get function source code", Flags: []cli.Flag{fnNameFlag, fnNamespaceFlag}, Action: fnGet},
|
||||
{Name: "getmeta", Usage: "Get function metadata", Flags: []cli.Flag{fnNameFlag, fnNamespaceFlag}, Action: fnGetMeta},
|
||||
{Name: "update", Usage: "Update function source code", Flags: []cli.Flag{fnNameFlag, fnNamespaceFlag, fnEnvNameFlag, envNamespaceFlag, fnCodeFlag, fnSrcArchiveFlag, fnDeployArchiveFlag, fnEntryPointFlag, fnPkgNameFlag, pkgNamespaceFlag, fnBuildCmdFlag, fnForceFlag, minCpu, maxCpu, minMem, maxMem, minScale, maxScale, fnExecutorTypeFlag, targetcpu}, Action: fnUpdate},
|
||||
{Name: "delete", Usage: "Delete function", Flags: []cli.Flag{fnNameFlag, fnNamespaceFlag}, Action: fnDelete},
|
||||
// TODO : for fnList, i feel like it's nice to allow --fns all, to list functions across all namespaces for cluster admins, although, this is against ns isolation.
|
||||
// so, in the future, if we end up using kubeconfig in fission cli and enforcing rolebindings to be created for users by admins etc, we can add this option at the time.
|
||||
{Name: "list", Usage: "List all functions in a namespace if specified, else, list functions across all namespaces", Flags: []cli.Flag{fnNamespaceFlag}, Action: fnList},
|
||||
{Name: "logs", Usage: "Display function logs", Flags: []cli.Flag{fnNameFlag, fnNamespaceFlag, fnPodFlag, fnFollowFlag, fnDetailFlag, fnLogDBTypeFlag, fnLogCountFlag}, Action: fnLogs},
|
||||
{Name: "test", Usage: "Test a function", Flags: []cli.Flag{fnNameFlag, fnNamespaceFlag, fnEnvNameFlag, fnCodeFlag, fnSrcArchiveFlag, htMethodFlag, fnBodyFlag, fnHeaderFlag}, Action: fnTest},
|
||||
}
|
||||
|
||||
// httptriggers
|
||||
htNameFlag := cli.StringFlag{Name: "name", Usage: "HTTP Trigger name"}
|
||||
htFnNameFlag := cli.StringFlag{Name: "function", Usage: "Function name"}
|
||||
htSubcommands := []cli.Command{
|
||||
{Name: "create", Aliases: []string{"add"}, Usage: "Create HTTP trigger", Flags: []cli.Flag{htMethodFlag, htUrlFlag, htFnNameFlag, specSaveFlag}, Action: htCreate},
|
||||
{Name: "create", Aliases: []string{"add"}, Usage: "Create HTTP trigger", Flags: []cli.Flag{htMethodFlag, htUrlFlag, htFnNameFlag, fnNameFlag, fnNamespaceFlag, specSaveFlag}, Action: htCreate},
|
||||
{Name: "get", Usage: "Get HTTP trigger", Flags: []cli.Flag{htMethodFlag, htUrlFlag}, Action: htGet},
|
||||
{Name: "update", Usage: "Update HTTP trigger", Flags: []cli.Flag{htNameFlag, htFnNameFlag}, Action: htUpdate},
|
||||
{Name: "delete", Usage: "Delete HTTP trigger", Flags: []cli.Flag{htNameFlag}, Action: htDelete},
|
||||
{Name: "list", Usage: "List HTTP triggers", Flags: []cli.Flag{}, Action: htList},
|
||||
{Name: "update", Usage: "Update HTTP trigger", Flags: []cli.Flag{htNameFlag, triggerNamespaceFlag, htFnNameFlag}, Action: htUpdate},
|
||||
{Name: "delete", Usage: "Delete HTTP trigger", Flags: []cli.Flag{htNameFlag, triggerNamespaceFlag}, Action: htDelete},
|
||||
{Name: "list", Usage: "List HTTP triggers", Flags: []cli.Flag{triggerNamespaceFlag}, Action: htList},
|
||||
}
|
||||
|
||||
// timetriggers
|
||||
@@ -170,11 +177,11 @@ func main() {
|
||||
ttCronFlag := cli.StringFlag{Name: "cron", Usage: "Time Trigger cron spec ('0 30 * * *', '@every 5m', '@hourly')"}
|
||||
ttFnNameFlag := cli.StringFlag{Name: "function", Usage: "Function name"}
|
||||
ttSubcommands := []cli.Command{
|
||||
{Name: "create", Aliases: []string{"add"}, Usage: "Create Time trigger", Flags: []cli.Flag{ttNameFlag, ttFnNameFlag, ttCronFlag, specSaveFlag}, Action: ttCreate},
|
||||
{Name: "get", Usage: "Get Time trigger", Flags: []cli.Flag{}, Action: ttGet},
|
||||
{Name: "update", Usage: "Update Time trigger", Flags: []cli.Flag{ttNameFlag, ttCronFlag, ttFnNameFlag}, Action: ttUpdate},
|
||||
{Name: "delete", Usage: "Delete Time trigger", Flags: []cli.Flag{ttNameFlag}, Action: ttDelete},
|
||||
{Name: "list", Usage: "List Time triggers", Flags: []cli.Flag{}, Action: ttList},
|
||||
{Name: "create", Aliases: []string{"add"}, Usage: "Create Time trigger", Flags: []cli.Flag{ttNameFlag, ttFnNameFlag, fnNamespaceFlag, ttCronFlag, specSaveFlag}, Action: ttCreate},
|
||||
{Name: "get", Usage: "Get Time trigger", Flags: []cli.Flag{triggerNamespaceFlag}, Action: ttGet},
|
||||
{Name: "update", Usage: "Update Time trigger", Flags: []cli.Flag{ttNameFlag, triggerNamespaceFlag, ttCronFlag, ttFnNameFlag}, Action: ttUpdate},
|
||||
{Name: "delete", Usage: "Delete Time trigger", Flags: []cli.Flag{ttNameFlag, triggerNamespaceFlag}, Action: ttDelete},
|
||||
{Name: "list", Usage: "List Time triggers", Flags: []cli.Flag{triggerNamespaceFlag}, Action: ttList},
|
||||
}
|
||||
|
||||
// Message queue trigger
|
||||
@@ -185,11 +192,11 @@ func main() {
|
||||
mqtRespTopicFlag := cli.StringFlag{Name: "resptopic", Usage: "Topic that the function response is sent on (optional; response discarded if unspecified)"}
|
||||
mqtMsgContentType := cli.StringFlag{Name: "contenttype, c", Value: "application/json", Usage: "Content type of messages that publish to the topic (optional)"}
|
||||
mqtSubcommands := []cli.Command{
|
||||
{Name: "create", Aliases: []string{"add"}, Usage: "Create Message queue trigger", Flags: []cli.Flag{mqtNameFlag, mqtFnNameFlag, mqtMQTypeFlag, mqtTopicFlag, mqtRespTopicFlag, mqtMsgContentType, specSaveFlag}, Action: mqtCreate},
|
||||
{Name: "get", Usage: "Get message queue trigger", Flags: []cli.Flag{}, Action: mqtGet},
|
||||
{Name: "update", Usage: "Update message queue trigger", Flags: []cli.Flag{mqtNameFlag, mqtTopicFlag, mqtRespTopicFlag, mqtFnNameFlag, mqtMsgContentType}, Action: mqtUpdate},
|
||||
{Name: "delete", Usage: "Delete message queue trigger", Flags: []cli.Flag{mqtNameFlag}, Action: mqtDelete},
|
||||
{Name: "list", Usage: "List message queue triggers", Flags: []cli.Flag{mqtMQTypeFlag}, Action: mqtList},
|
||||
{Name: "create", Aliases: []string{"add"}, Usage: "Create Message queue trigger", Flags: []cli.Flag{mqtNameFlag, mqtFnNameFlag, fnNamespaceFlag, mqtMQTypeFlag, mqtTopicFlag, mqtRespTopicFlag, mqtMsgContentType, specSaveFlag}, Action: mqtCreate},
|
||||
{Name: "get", Usage: "Get message queue trigger", Flags: []cli.Flag{triggerNamespaceFlag}, Action: mqtGet},
|
||||
{Name: "update", Usage: "Update message queue trigger", Flags: []cli.Flag{mqtNameFlag, triggerNamespaceFlag, mqtTopicFlag, mqtRespTopicFlag, mqtFnNameFlag, mqtMsgContentType}, Action: mqtUpdate},
|
||||
{Name: "delete", Usage: "Delete message queue trigger", Flags: []cli.Flag{mqtNameFlag, triggerNamespaceFlag}, Action: mqtDelete},
|
||||
{Name: "list", Usage: "List message queue triggers", Flags: []cli.Flag{mqtMQTypeFlag, triggerNamespaceFlag}, Action: mqtList},
|
||||
}
|
||||
|
||||
// environments
|
||||
@@ -202,11 +209,11 @@ func main() {
|
||||
envTerminationGracePeriodFlag := cli.Int64Flag{Name: "graceperiod, period", Value: 360, Usage: "The grace time (in seconds) for pod to perform connection draining before termination (optional)"}
|
||||
envVersionFlag := cli.IntFlag{Name: "version", Value: 1, Usage: "Environment API version (1 means v1 interface)"}
|
||||
envSubcommands := []cli.Command{
|
||||
{Name: "create", Aliases: []string{"add"}, Usage: "Add an environment", Flags: []cli.Flag{envNameFlag, envPoolsizeFlag, envImageFlag, envBuilderImageFlag, envBuildCmdFlag, minCpu, maxCpu, minMem, maxMem, envVersionFlag, envExternalNetworkFlag, envTerminationGracePeriodFlag, specSaveFlag}, Action: envCreate},
|
||||
{Name: "get", Usage: "Get environment details", Flags: []cli.Flag{envNameFlag}, Action: envGet},
|
||||
{Name: "update", Usage: "Update environment", Flags: []cli.Flag{envNameFlag, envPoolsizeFlag, envImageFlag, envBuilderImageFlag, envBuildCmdFlag, minCpu, maxCpu, minMem, maxMem, envExternalNetworkFlag, envTerminationGracePeriodFlag}, Action: envUpdate},
|
||||
{Name: "delete", Usage: "Delete environment", Flags: []cli.Flag{envNameFlag}, Action: envDelete},
|
||||
{Name: "list", Usage: "List all environments", Flags: []cli.Flag{}, Action: envList},
|
||||
{Name: "create", Aliases: []string{"add"}, Usage: "Add an environment", Flags: []cli.Flag{envNameFlag, envNamespaceFlag, envPoolsizeFlag, envImageFlag, envBuilderImageFlag, envBuildCmdFlag, minCpu, maxCpu, minMem, maxMem, envVersionFlag, envExternalNetworkFlag, envTerminationGracePeriodFlag, specSaveFlag}, Action: envCreate},
|
||||
{Name: "get", Usage: "Get environment details", Flags: []cli.Flag{envNameFlag, envNamespaceFlag}, Action: envGet},
|
||||
{Name: "update", Usage: "Update environment", Flags: []cli.Flag{envNameFlag, envNamespaceFlag, envPoolsizeFlag, envImageFlag, envBuilderImageFlag, envBuildCmdFlag, minCpu, maxCpu, minMem, maxMem, envExternalNetworkFlag, envTerminationGracePeriodFlag}, Action: envUpdate},
|
||||
{Name: "delete", Usage: "Delete environment", Flags: []cli.Flag{envNameFlag, envNamespaceFlag}, Action: envDelete},
|
||||
{Name: "list", Usage: "List all environments", Flags: []cli.Flag{envNamespaceFlag}, Action: envList},
|
||||
}
|
||||
|
||||
// watches
|
||||
@@ -216,11 +223,11 @@ func main() {
|
||||
wObjTypeFlag := cli.StringFlag{Name: "type", Usage: "Type of resource to watch (Pod, Service, etc.)"}
|
||||
wLabelsFlag := cli.StringFlag{Name: "labels", Usage: "Label selector of the form a=b,c=d"}
|
||||
wSubCommands := []cli.Command{
|
||||
{Name: "create", Aliases: []string{"add"}, Usage: "Create a watch", Flags: []cli.Flag{wFnNameFlag, wNamespaceFlag, wObjTypeFlag, wLabelsFlag, specSaveFlag}, Action: wCreate},
|
||||
{Name: "get", Usage: "Get details about a watch", Flags: []cli.Flag{wNameFlag}, Action: wGet},
|
||||
{Name: "create", Aliases: []string{"add"}, Usage: "Create a watch", Flags: []cli.Flag{wFnNameFlag, fnNamespaceFlag, wNamespaceFlag, wObjTypeFlag, wLabelsFlag, specSaveFlag}, Action: wCreate},
|
||||
{Name: "get", Usage: "Get details about a watch", Flags: []cli.Flag{wNameFlag, triggerNamespaceFlag}, Action: wGet},
|
||||
// TODO add update flag when supported
|
||||
{Name: "delete", Usage: "Delete watch", Flags: []cli.Flag{wNameFlag}, Action: wDelete},
|
||||
{Name: "list", Usage: "List all watches", Flags: []cli.Flag{}, Action: wList},
|
||||
{Name: "delete", Usage: "Delete watch", Flags: []cli.Flag{wNameFlag, triggerNamespaceFlag}, Action: wDelete},
|
||||
{Name: "list", Usage: "List all watches", Flags: []cli.Flag{triggerNamespaceFlag}, Action: wList},
|
||||
}
|
||||
|
||||
// packages
|
||||
@@ -233,13 +240,13 @@ func main() {
|
||||
pkgOutputFlag := cli.StringFlag{Name: "output, o", Usage: "Output filename to save archive content"}
|
||||
pkgOrphanFlag := cli.BoolFlag{Name: "orphan", Usage: "orphan packages that are not referenced by any function"}
|
||||
pkgSubCommands := []cli.Command{
|
||||
{Name: "create", Usage: "Create new package", Flags: []cli.Flag{pkgEnvironmentFlag, pkgSrcArchiveFlag, pkgDeployArchiveFlag, pkgBuildCmdFlag}, Action: pkgCreate},
|
||||
{Name: "update", Usage: "Update package", Flags: []cli.Flag{pkgNameFlag, pkgEnvironmentFlag, pkgSrcArchiveFlag, pkgDeployArchiveFlag, pkgBuildCmdFlag, pkgForceFlag}, Action: pkgUpdate},
|
||||
{Name: "getsrc", Usage: "Get source archive content", Flags: []cli.Flag{pkgNameFlag, pkgOutputFlag}, Action: pkgSourceGet},
|
||||
{Name: "getdeploy", Usage: "Get deployment archive content", Flags: []cli.Flag{pkgNameFlag, pkgOutputFlag}, Action: pkgDeployGet},
|
||||
{Name: "info", Usage: "Show package information", Flags: []cli.Flag{pkgNameFlag}, Action: pkgInfo},
|
||||
{Name: "list", Usage: "List all packages", Flags: []cli.Flag{pkgOrphanFlag}, Action: pkgList},
|
||||
{Name: "delete", Usage: "Delete package", Flags: []cli.Flag{pkgNameFlag, pkgForceFlag, pkgOrphanFlag}, Action: pkgDelete},
|
||||
{Name: "create", Usage: "Create new package", Flags: []cli.Flag{pkgNamespaceFlag, pkgEnvironmentFlag, envNamespaceFlag, pkgSrcArchiveFlag, pkgDeployArchiveFlag, pkgBuildCmdFlag}, Action: pkgCreate},
|
||||
{Name: "update", Usage: "Update package", Flags: []cli.Flag{pkgNameFlag, pkgNamespaceFlag, pkgEnvironmentFlag, envNamespaceFlag, pkgSrcArchiveFlag, pkgDeployArchiveFlag, pkgBuildCmdFlag, pkgForceFlag}, Action: pkgUpdate},
|
||||
{Name: "getsrc", Usage: "Get source archive content", Flags: []cli.Flag{pkgNameFlag, pkgNamespaceFlag, pkgOutputFlag}, Action: pkgSourceGet},
|
||||
{Name: "getdeploy", Usage: "Get deployment archive content", Flags: []cli.Flag{pkgNameFlag, pkgNamespaceFlag, pkgOutputFlag}, Action: pkgDeployGet},
|
||||
{Name: "info", Usage: "Show package information", Flags: []cli.Flag{pkgNameFlag, pkgNamespaceFlag}, Action: pkgInfo},
|
||||
{Name: "list", Usage: "List all packages", Flags: []cli.Flag{pkgOrphanFlag, pkgNamespaceFlag}, Action: pkgList},
|
||||
{Name: "delete", Usage: "Delete package", Flags: []cli.Flag{pkgNameFlag, pkgNamespaceFlag, pkgForceFlag, pkgOrphanFlag}, Action: pkgDelete},
|
||||
}
|
||||
|
||||
// upgrades, data migrations
|
||||
|
||||
+8
-7
@@ -23,6 +23,7 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/fission/fission"
|
||||
"github.com/fission/fission/controller/client"
|
||||
@@ -42,19 +43,19 @@ type (
|
||||
)
|
||||
|
||||
func migrateDumpTPRResource(client *client.Client, filename string) {
|
||||
pkgs, err := client.PackageList()
|
||||
pkgs, err := client.PackageList(metav1.NamespaceAll)
|
||||
checkErr(err, "dump packages")
|
||||
fns, err := client.FunctionList()
|
||||
fns, err := client.FunctionList(metav1.NamespaceAll)
|
||||
checkErr(err, "dump functions")
|
||||
httpTriggers, err := client.HTTPTriggerList()
|
||||
httpTriggers, err := client.HTTPTriggerList(metav1.NamespaceAll)
|
||||
checkErr(err, "dump http triggers")
|
||||
envs, err := client.EnvironmentList()
|
||||
envs, err := client.EnvironmentList(metav1.NamespaceAll)
|
||||
checkErr(err, "dump environments")
|
||||
watches, err := client.WatchList()
|
||||
watches, err := client.WatchList(metav1.NamespaceAll)
|
||||
checkErr(err, "dump watches")
|
||||
timeTriggers, err := client.TimeTriggerList()
|
||||
timeTriggers, err := client.TimeTriggerList(metav1.NamespaceAll)
|
||||
checkErr(err, "dump time triggers")
|
||||
mqTriggers, err := client.MessageQueueTriggerList(fission.MessageQueueTypeNats)
|
||||
mqTriggers, err := client.MessageQueueTriggerList(fission.MessageQueueTypeNats, metav1.NamespaceAll)
|
||||
checkErr(err, "dump message queue triggers")
|
||||
|
||||
tprResource := TPRResource{
|
||||
|
||||
+11
-4
@@ -40,6 +40,7 @@ func mqtCreate(c *cli.Context) error {
|
||||
if len(fnName) == 0 {
|
||||
fatal("Need a function name to create a trigger, use --function")
|
||||
}
|
||||
fnNamespace := c.String("fnNamespace")
|
||||
|
||||
var mqType fission.MessageQueueType
|
||||
switch c.String("mqtype") {
|
||||
@@ -76,7 +77,7 @@ func mqtCreate(c *cli.Context) error {
|
||||
mqt := &crd.MessageQueueTrigger{
|
||||
Metadata: metav1.ObjectMeta{
|
||||
Name: mqtName,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Namespace: fnNamespace,
|
||||
},
|
||||
Spec: fission.MessageQueueTriggerSpec{
|
||||
FunctionReference: fission.FunctionReference{
|
||||
@@ -115,6 +116,8 @@ func mqtUpdate(c *cli.Context) error {
|
||||
if len(mqtName) == 0 {
|
||||
fatal("Need name of trigger, use --name")
|
||||
}
|
||||
mqtNs := c.String("triggerns")
|
||||
|
||||
topic := c.String("topic")
|
||||
respTopic := c.String("resptopic")
|
||||
fnName := c.String("function")
|
||||
@@ -122,10 +125,12 @@ func mqtUpdate(c *cli.Context) error {
|
||||
|
||||
mqt, err := client.MessageQueueTriggerGet(&metav1.ObjectMeta{
|
||||
Name: mqtName,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Namespace: mqtNs,
|
||||
})
|
||||
checkErr(err, "get Time trigger")
|
||||
|
||||
// TODO : Find out if we can make a call to checkIfFunctionExists, in the same ns more importantly.
|
||||
|
||||
checkMQTopicAvailability(mqt.Spec.MessageQueueType, topic, respTopic)
|
||||
|
||||
updated := false
|
||||
@@ -163,10 +168,11 @@ func mqtDelete(c *cli.Context) error {
|
||||
if len(mqtName) == 0 {
|
||||
fatal("Need name of trigger to delete, use --name")
|
||||
}
|
||||
mqtNs := c.String("triggerns")
|
||||
|
||||
err := client.MessageQueueTriggerDelete(&metav1.ObjectMeta{
|
||||
Name: mqtName,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Namespace: mqtNs,
|
||||
})
|
||||
checkErr(err, "delete trigger")
|
||||
|
||||
@@ -176,8 +182,9 @@ func mqtDelete(c *cli.Context) error {
|
||||
|
||||
func mqtList(c *cli.Context) error {
|
||||
client := getClient(c.GlobalString("server"))
|
||||
mqtNs := c.String("triggerns")
|
||||
|
||||
mqts, err := client.MessageQueueTriggerList(c.String("mqtype"))
|
||||
mqts, err := client.MessageQueueTriggerList(c.String("mqtype"), mqtNs)
|
||||
checkErr(err, "list message queue triggers")
|
||||
|
||||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)
|
||||
|
||||
+32
-23
@@ -33,8 +33,8 @@ import (
|
||||
"github.com/fission/fission/crd"
|
||||
)
|
||||
|
||||
func getFunctionsByPackage(client *client.Client, pkgName string) ([]crd.Function, error) {
|
||||
fnList, err := client.FunctionList()
|
||||
func getFunctionsByPackage(client *client.Client, pkgName, pkgNamespace string) ([]crd.Function, error) {
|
||||
fnList, err := client.FunctionList(pkgNamespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -65,11 +65,12 @@ func downloadStoragesvcURL(client *client.Client, fileUrl string) io.ReadCloser
|
||||
func pkgCreate(c *cli.Context) error {
|
||||
client := getClient(c.GlobalString("server"))
|
||||
|
||||
pkgNamespace := c.String("pkgNamespace")
|
||||
envName := c.String("env")
|
||||
if len(envName) == 0 {
|
||||
fatal("Need --env argument.")
|
||||
}
|
||||
|
||||
envNamespace := c.String("envNamespace")
|
||||
srcArchiveName := c.String("src")
|
||||
deployArchiveName := c.String("deploy")
|
||||
buildcmd := c.String("buildcmd")
|
||||
@@ -78,7 +79,7 @@ func pkgCreate(c *cli.Context) error {
|
||||
fatal("Need --src to specify source archive, or use --deploy to specify deployment archive.")
|
||||
}
|
||||
|
||||
meta := createPackage(client, envName, srcArchiveName, deployArchiveName, buildcmd, "")
|
||||
meta := createPackage(client, pkgNamespace, envName, envNamespace, srcArchiveName, deployArchiveName, buildcmd, "")
|
||||
fmt.Printf("Package '%v' created\n", meta.GetName())
|
||||
|
||||
return nil
|
||||
@@ -91,9 +92,11 @@ func pkgUpdate(c *cli.Context) error {
|
||||
if len(pkgName) == 0 {
|
||||
fatal("Need --name argument.")
|
||||
}
|
||||
pkgNamespace := c.String("pkgNamespace")
|
||||
|
||||
force := c.Bool("f")
|
||||
envName := c.String("env")
|
||||
envNamespace := c.String("envNamespace")
|
||||
srcArchiveName := c.String("src")
|
||||
deployArchiveName := c.String("deploy")
|
||||
buildcmd := c.String("buildcmd")
|
||||
@@ -108,12 +111,12 @@ func pkgUpdate(c *cli.Context) error {
|
||||
}
|
||||
|
||||
pkg, err := client.PackageGet(&metav1.ObjectMeta{
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Namespace: pkgNamespace,
|
||||
Name: pkgName,
|
||||
})
|
||||
checkErr(err, "get package")
|
||||
|
||||
fnList, err := getFunctionsByPackage(client, pkg.Metadata.Name)
|
||||
fnList, err := getFunctionsByPackage(client, pkg.Metadata.Name, pkg.Metadata.Namespace)
|
||||
checkErr(err, "get function list")
|
||||
|
||||
if !force && len(fnList) > 1 {
|
||||
@@ -121,7 +124,7 @@ func pkgUpdate(c *cli.Context) error {
|
||||
}
|
||||
|
||||
newPkgMeta := updatePackage(client, pkg,
|
||||
envName, srcArchiveName, deployArchiveName, buildcmd)
|
||||
envName, envNamespace, srcArchiveName, deployArchiveName, buildcmd)
|
||||
|
||||
// update resource version of package reference of functions that shared the same package
|
||||
for _, fn := range fnList {
|
||||
@@ -135,7 +138,7 @@ func pkgUpdate(c *cli.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func updatePackage(client *client.Client, pkg *crd.Package, envName,
|
||||
func updatePackage(client *client.Client, pkg *crd.Package, envName, envNamespace,
|
||||
srcArchiveName, deployArchiveName, buildcmd string) *metav1.ObjectMeta {
|
||||
|
||||
var srcArchiveMetadata, deployArchiveMetadata *fission.Archive
|
||||
@@ -143,6 +146,7 @@ func updatePackage(client *client.Client, pkg *crd.Package, envName,
|
||||
|
||||
if len(envName) > 0 {
|
||||
pkg.Spec.Environment.Name = envName
|
||||
pkg.Spec.Environment.Namespace = envNamespace
|
||||
needToBuild = true
|
||||
}
|
||||
|
||||
@@ -183,11 +187,12 @@ func pkgSourceGet(c *cli.Context) error {
|
||||
if len(pkgName) == 0 {
|
||||
fatal("Need name of package, use --name")
|
||||
}
|
||||
pkgNamespace := c.String("pkgNamespace")
|
||||
|
||||
output := c.String("output")
|
||||
|
||||
pkg, err := client.PackageGet(&metav1.ObjectMeta{
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Namespace: pkgNamespace,
|
||||
Name: pkgName,
|
||||
})
|
||||
if err != nil {
|
||||
@@ -219,11 +224,12 @@ func pkgDeployGet(c *cli.Context) error {
|
||||
if len(pkgName) == 0 {
|
||||
fatal("Need name of package, use --name")
|
||||
}
|
||||
pkgNamespace := c.String("pkgNamespace")
|
||||
|
||||
output := c.String("output")
|
||||
|
||||
pkg, err := client.PackageGet(&metav1.ObjectMeta{
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Namespace: pkgNamespace,
|
||||
Name: pkgName,
|
||||
})
|
||||
if err != nil {
|
||||
@@ -255,9 +261,10 @@ func pkgInfo(c *cli.Context) error {
|
||||
if len(pkgName) == 0 {
|
||||
fatal("Need name of package, use --name")
|
||||
}
|
||||
pkgNamespace := c.String("pkgNamespace")
|
||||
|
||||
pkg, err := client.PackageGet(&metav1.ObjectMeta{
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Namespace: pkgNamespace,
|
||||
Name: pkgName,
|
||||
})
|
||||
if err != nil {
|
||||
@@ -278,8 +285,9 @@ func pkgList(c *cli.Context) error {
|
||||
client := getClient(c.GlobalString("server"))
|
||||
// option for the user to list all orphan packages (not referenced by any function)
|
||||
listOrphans := c.Bool("orphan")
|
||||
pkgNamespace := c.String("pkgNamespace")
|
||||
|
||||
pkgList, err := client.PackageList()
|
||||
pkgList, err := client.PackageList(pkgNamespace)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -288,7 +296,7 @@ func pkgList(c *cli.Context) error {
|
||||
fmt.Fprintf(w, "%v\t%v\t%v\n", "NAME", "BUILD_STATUS", "ENV")
|
||||
if listOrphans {
|
||||
for _, pkg := range pkgList {
|
||||
fnList, err := getFunctionsByPackage(client, pkg.Metadata.Name)
|
||||
fnList, err := getFunctionsByPackage(client, pkg.Metadata.Name, pkg.Metadata.Namespace)
|
||||
checkErr(err, fmt.Sprintf("get functions sharing package %s", pkg.Metadata.Name))
|
||||
if len(fnList) == 0 {
|
||||
fmt.Fprintf(w, "%v\t%v\t%v\n", pkg.Metadata.Name, pkg.Status.BuildStatus, pkg.Spec.Environment.Name)
|
||||
@@ -306,18 +314,18 @@ func pkgList(c *cli.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func deleteOrphanPkgs(client *client.Client) error {
|
||||
pkgList, err := client.PackageList()
|
||||
func deleteOrphanPkgs(client *client.Client, pkgNamespace string) error {
|
||||
pkgList, err := client.PackageList(pkgNamespace)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// range through all packages and find out the ones not referenced by any function
|
||||
for _, pkg := range pkgList {
|
||||
fnList, err := getFunctionsByPackage(client, pkg.Metadata.Name)
|
||||
fnList, err := getFunctionsByPackage(client, pkg.Metadata.Name, pkgNamespace)
|
||||
checkErr(err, fmt.Sprintf("get functions sharing package %s", pkg.Metadata.Name))
|
||||
if len(fnList) == 0 {
|
||||
err = deletePackage(client, pkg.Metadata.Name)
|
||||
err = deletePackage(client, pkg.Metadata.Name, pkgNamespace)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -326,9 +334,9 @@ func deleteOrphanPkgs(client *client.Client) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func deletePackage(client *client.Client, pkgName string) error {
|
||||
func deletePackage(client *client.Client, pkgName string, pkgNamespace string) error {
|
||||
return client.PackageDelete(&metav1.ObjectMeta{
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Namespace: pkgNamespace,
|
||||
Name: pkgName,
|
||||
})
|
||||
}
|
||||
@@ -337,6 +345,7 @@ func pkgDelete(c *cli.Context) error {
|
||||
client := getClient(c.GlobalString("server"))
|
||||
|
||||
pkgName := c.String("name")
|
||||
pkgNamespace := c.String("pkgNamespace")
|
||||
deleteOrphans := c.Bool("orphan")
|
||||
|
||||
if len(pkgName) == 0 && !deleteOrphans {
|
||||
@@ -352,25 +361,25 @@ func pkgDelete(c *cli.Context) error {
|
||||
force := c.Bool("f")
|
||||
|
||||
_, err := client.PackageGet(&metav1.ObjectMeta{
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Namespace: pkgNamespace,
|
||||
Name: pkgName,
|
||||
})
|
||||
checkErr(err, "find package")
|
||||
|
||||
fnList, err := getFunctionsByPackage(client, pkgName)
|
||||
fnList, err := getFunctionsByPackage(client, pkgName, pkgNamespace)
|
||||
|
||||
if !force && len(fnList) > 0 {
|
||||
fatal("Package is used by at least one function, use -f to force delete")
|
||||
}
|
||||
|
||||
err = deletePackage(client, pkgName)
|
||||
err = deletePackage(client, pkgName, pkgNamespace)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Package '%v' deleted\n", pkgName)
|
||||
} else {
|
||||
err := deleteOrphanPkgs(client)
|
||||
err := deleteOrphanPkgs(client, pkgNamespace)
|
||||
checkErr(err, "error deleting orphan packages")
|
||||
fmt.Println("Orphan packages deleted")
|
||||
}
|
||||
|
||||
+30
-11
@@ -242,7 +242,8 @@ func (fr *FissionResources) validate() error {
|
||||
// check references: both dangling refs + garbage
|
||||
// packages -> archives
|
||||
// functions -> packages
|
||||
// functions -> environments [TODO]
|
||||
// functions -> environments + shared environments between functions [TODO]
|
||||
// functions -> secrets + configmaps (same ns) [TODO]
|
||||
// triggers -> functions
|
||||
|
||||
// index archives
|
||||
@@ -301,12 +302,30 @@ func (fr *FissionResources) validate() error {
|
||||
for _, f := range fr.functions {
|
||||
functions[mapKey(&f.Metadata)] = false
|
||||
|
||||
// check package ref from function
|
||||
pkgMeta := &metav1.ObjectMeta{
|
||||
Name: f.Spec.Package.PackageRef.Name,
|
||||
Namespace: f.Spec.Package.PackageRef.Namespace,
|
||||
}
|
||||
if _, ok := packages[mapKey(pkgMeta)]; !ok {
|
||||
|
||||
// check package ref from function
|
||||
packageRefExists := func() bool {
|
||||
_, ok := packages[mapKey(pkgMeta)]
|
||||
return ok
|
||||
}
|
||||
|
||||
// check that the package referenced by each function is in the same ns as the function
|
||||
packageRefInFuncNs := func(f *crd.Function) bool {
|
||||
return f.Spec.Package.PackageRef.Namespace == f.Metadata.Namespace
|
||||
}
|
||||
|
||||
if !packageRefInFuncNs(&f) {
|
||||
result = multierror.Append(result, fmt.Errorf(
|
||||
"%v: function '%v' references a package outside of its namespace %v/%v",
|
||||
fr.sourceMap.locations["Function"][f.Metadata.Namespace][f.Metadata.Name],
|
||||
f.Metadata.Name,
|
||||
f.Spec.Package.PackageRef.Namespace,
|
||||
f.Spec.Package.PackageRef.Name))
|
||||
} else if !packageRefExists() {
|
||||
result = multierror.Append(result, fmt.Errorf(
|
||||
"%v: function '%v' references unknown package %v/%v",
|
||||
fr.sourceMap.locations["Function"][f.Metadata.Namespace][f.Metadata.Name],
|
||||
@@ -781,7 +800,7 @@ func applyArchives(fclient *client.Client, specDir string, fr *FissionResources)
|
||||
|
||||
// get list of packages, make content-indexed map of available archives
|
||||
availableArchives := make(map[string]string) // (sha256 -> url)
|
||||
pkgs, err := fclient.PackageList()
|
||||
pkgs, err := fclient.PackageList(metav1.NamespaceAll)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1031,7 +1050,7 @@ func waitForPackageBuild(fclient *client.Client, pkg *crd.Package) (*crd.Package
|
||||
|
||||
func applyPackages(fclient *client.Client, fr *FissionResources, delete bool) (map[string]metav1.ObjectMeta, *resourceApplyStatus, error) {
|
||||
// get list
|
||||
allObjs, err := fclient.PackageList()
|
||||
allObjs, err := fclient.PackageList(metav1.NamespaceAll)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -1136,7 +1155,7 @@ func applyPackages(fclient *client.Client, fr *FissionResources, delete bool) (m
|
||||
|
||||
func applyFunctions(fclient *client.Client, fr *FissionResources, delete bool) (map[string]metav1.ObjectMeta, *resourceApplyStatus, error) {
|
||||
// get list
|
||||
allObjs, err := fclient.FunctionList()
|
||||
allObjs, err := fclient.FunctionList(metav1.NamespaceAll)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -1219,7 +1238,7 @@ func applyFunctions(fclient *client.Client, fr *FissionResources, delete bool) (
|
||||
|
||||
func applyEnvironments(fclient *client.Client, fr *FissionResources, delete bool) (map[string]metav1.ObjectMeta, *resourceApplyStatus, error) {
|
||||
// get list
|
||||
allObjs, err := fclient.EnvironmentList()
|
||||
allObjs, err := fclient.EnvironmentList(metav1.NamespaceAll)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -1302,7 +1321,7 @@ func applyEnvironments(fclient *client.Client, fr *FissionResources, delete bool
|
||||
|
||||
func applyHTTPTriggers(fclient *client.Client, fr *FissionResources, delete bool) (map[string]metav1.ObjectMeta, *resourceApplyStatus, error) {
|
||||
// get list
|
||||
allObjs, err := fclient.HTTPTriggerList()
|
||||
allObjs, err := fclient.HTTPTriggerList(metav1.NamespaceAll)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -1385,7 +1404,7 @@ func applyHTTPTriggers(fclient *client.Client, fr *FissionResources, delete bool
|
||||
|
||||
func applyKubernetesWatchTriggers(fclient *client.Client, fr *FissionResources, delete bool) (map[string]metav1.ObjectMeta, *resourceApplyStatus, error) {
|
||||
// get list
|
||||
allObjs, err := fclient.WatchList()
|
||||
allObjs, err := fclient.WatchList(metav1.NamespaceAll)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -1468,7 +1487,7 @@ func applyKubernetesWatchTriggers(fclient *client.Client, fr *FissionResources,
|
||||
|
||||
func applyTimeTriggers(fclient *client.Client, fr *FissionResources, delete bool) (map[string]metav1.ObjectMeta, *resourceApplyStatus, error) {
|
||||
// get list
|
||||
allObjs, err := fclient.TimeTriggerList()
|
||||
allObjs, err := fclient.TimeTriggerList(metav1.NamespaceAll)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -1551,7 +1570,7 @@ func applyTimeTriggers(fclient *client.Client, fr *FissionResources, delete bool
|
||||
|
||||
func applyMessageQueueTriggers(fclient *client.Client, fr *FissionResources, delete bool) (map[string]metav1.ObjectMeta, *resourceApplyStatus, error) {
|
||||
// get list
|
||||
allObjs, err := fclient.MessageQueueTriggerList("")
|
||||
allObjs, err := fclient.MessageQueueTriggerList("", metav1.NamespaceAll)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
+13
-4
@@ -40,6 +40,8 @@ func ttCreate(c *cli.Context) error {
|
||||
if len(fnName) == 0 {
|
||||
fatal("Need a function name to create a trigger, use --function")
|
||||
}
|
||||
fnNamespace := c.String("fnNamespace")
|
||||
|
||||
cron := c.String("cron")
|
||||
if len(cron) == 0 {
|
||||
fatal("Need a cron spec like '0 30 * * *', '@every 1h30m', or '@hourly'; use --cron")
|
||||
@@ -48,7 +50,7 @@ func ttCreate(c *cli.Context) error {
|
||||
tt := &crd.TimeTrigger{
|
||||
Metadata: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Namespace: fnNamespace,
|
||||
},
|
||||
Spec: fission.TimeTriggerSpec{
|
||||
Cron: cron,
|
||||
@@ -84,10 +86,11 @@ func ttUpdate(c *cli.Context) error {
|
||||
if len(ttName) == 0 {
|
||||
fatal("Need name of trigger, use --name")
|
||||
}
|
||||
ttNs := c.String("triggerns")
|
||||
|
||||
tt, err := client.TimeTriggerGet(&metav1.ObjectMeta{
|
||||
Name: ttName,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Namespace: ttNs,
|
||||
})
|
||||
checkErr(err, "get time trigger")
|
||||
|
||||
@@ -97,6 +100,10 @@ func ttUpdate(c *cli.Context) error {
|
||||
tt.Spec.Cron = newCron
|
||||
updated = true
|
||||
}
|
||||
|
||||
// TODO : During update, function has to be in the same ns as the trigger object
|
||||
// but since we are not checking this for other triggers too, not sure if we need a check here.
|
||||
|
||||
fnName := c.String("function")
|
||||
if len(fnName) > 0 {
|
||||
tt.Spec.FunctionReference.Name = fnName
|
||||
@@ -120,10 +127,11 @@ func ttDelete(c *cli.Context) error {
|
||||
if len(ttName) == 0 {
|
||||
fatal("Need name of trigger to delete, use --name")
|
||||
}
|
||||
ttNs := c.String("triggerns")
|
||||
|
||||
err := client.TimeTriggerDelete(&metav1.ObjectMeta{
|
||||
Name: ttName,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Namespace: ttNs,
|
||||
})
|
||||
checkErr(err, "delete trigger")
|
||||
|
||||
@@ -133,8 +141,9 @@ func ttDelete(c *cli.Context) error {
|
||||
|
||||
func ttList(c *cli.Context) error {
|
||||
client := getClient(c.GlobalString("server"))
|
||||
ttNs := c.String("triggerns")
|
||||
|
||||
tts, err := client.TimeTriggerList()
|
||||
tts, err := client.TimeTriggerList(ttNs)
|
||||
checkErr(err, "list Time triggers")
|
||||
|
||||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)
|
||||
|
||||
+7
-3
@@ -36,6 +36,7 @@ func wCreate(c *cli.Context) error {
|
||||
if len(fnName) == 0 {
|
||||
fatal("Need a function name to create a watch, use --function")
|
||||
}
|
||||
fnNamespace := c.String("fnNamespace")
|
||||
|
||||
namespace := c.String("ns")
|
||||
if len(namespace) == 0 {
|
||||
@@ -64,7 +65,7 @@ func wCreate(c *cli.Context) error {
|
||||
w := &crd.KubernetesWatchTrigger{
|
||||
Metadata: metav1.ObjectMeta{
|
||||
Name: watchName,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Namespace: fnNamespace,
|
||||
},
|
||||
Spec: fission.KubernetesWatchTriggerSpec{
|
||||
Namespace: namespace,
|
||||
@@ -111,10 +112,11 @@ func wDelete(c *cli.Context) error {
|
||||
if len(wName) == 0 {
|
||||
fatal("Need name of watch to delete, use --name")
|
||||
}
|
||||
wNs := c.String("triggerns")
|
||||
|
||||
err := client.WatchDelete(&metav1.ObjectMeta{
|
||||
Name: wName,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Namespace: wNs,
|
||||
})
|
||||
checkErr(err, "delete watch")
|
||||
|
||||
@@ -125,7 +127,9 @@ func wDelete(c *cli.Context) error {
|
||||
func wList(c *cli.Context) error {
|
||||
client := getClient(c.GlobalString("server"))
|
||||
|
||||
ws, err := client.WatchList()
|
||||
wNs := c.String("triggerns")
|
||||
|
||||
ws, err := client.WatchList(wNs)
|
||||
checkErr(err, "list watches")
|
||||
|
||||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)
|
||||
|
||||
Reference in New Issue
Block a user