add namespace param for fn and env (#2556)

This PR moves fission CLI as closer as possible to kubectl command behaviour.  We have improved namespace handling behaviour across CLI.

* add namespace param for fn and env
* use common fn for ns check
* update validation
* default namespace for httpTrigger, env and package, config and triggers
* use default ns
* add namespace filter to spec
* add forceNamespace flag
* set current namespace
* add default namespace in config
* add namespace specific destroy
* add all namespace in the list of resources
* add namespace as global tag
* use %s instead of %v
* add test cases for namespace
* use ns in get all functions
This commit is contained in:
neha_gupta
2022-10-11 13:23:47 +05:30
committed by GitHub
parent 0739aca920
commit b9513868ed
74 changed files with 1289 additions and 304 deletions
+4 -1
View File
@@ -55,7 +55,7 @@ jobs:
with:
version: ${{ env.HELM_VERSION }}
- name: Kind Clutser
- name: Kind Cluster
uses: engineerd/setup-kind@v0.5.0
with:
image: kindest/node:${{ matrix.kindversion }}
@@ -67,6 +67,9 @@ jobs:
kubectl cluster-info --context kind-kind
kubectl get nodes
sudo apt-get install -y apache2-utils
kubectl config use-context kind-kind
kubectl config set-context --current --namespace=default
kubectl config view
- name: Helm chart lint
run: |
+3
View File
@@ -64,6 +64,9 @@ jobs:
kubectl cluster-info --context kind-kind
kubectl get nodes
kubectl get storageclasses.storage.k8s.io
kubectl config use-context kind-kind
kubectl config set-context --current --namespace=default
kubectl config view
- name: Dump system info
run: |
+2 -2
View File
@@ -87,7 +87,7 @@ func App() *cobra.Command {
})
wrapper.SetFlags(rootCmd, flag.FlagSet{
Global: []flag.Flag{flag.GlobalServer, flag.GlobalVerbosity, flag.KubeContext},
Global: []flag.Flag{flag.GlobalServer, flag.GlobalVerbosity, flag.KubeContext, flag.Namespace},
})
groups := helptemplate.CommandGroups{}
@@ -101,7 +101,7 @@ func App() *cobra.Command {
flagExposer := helptemplate.ActsAsRootCommand(rootCmd, nil, groups...)
// show global options in usage
flagExposer.ExposeFlags(rootCmd, flagkey.Server, flagkey.Verbosity, flagkey.KubeContext)
flagExposer.ExposeFlags(rootCmd, flagkey.Server, flagkey.Verbosity, flagkey.KubeContext, flagkey.Namespace)
return rootCmd
}
+11 -2
View File
@@ -150,12 +150,21 @@ func ValidateKubeName(field string, val string) error {
return result.ErrorOrNil()
}
// validateNS is to match the k8s behaviour. Where it is not mandatory to provide a NS. And so we validate it if user has provided one.
// Or we skip the validation on namespace.
func validateNS(refName string, namespace string) error {
if namespace != "" {
return ValidateKubeName(refName, namespace)
}
return nil
}
func ValidateKubeReference(refName string, name string, namespace string) error {
result := &multierror.Error{}
result = multierror.Append(result,
ValidateKubeName(fmt.Sprintf("%v.Name", refName), name),
ValidateKubeName(fmt.Sprintf("%v.Namespace", refName), namespace))
ValidateKubeName(fmt.Sprintf("%s.Name", refName), name),
validateNS(fmt.Sprintf("%s.Namespace", refName), namespace))
return result.ErrorOrNil()
}
+4 -4
View File
@@ -136,16 +136,16 @@ func (c *MessageQueueTrigger) Update(mqTrigger *fv1.MessageQueueTrigger) (*metav
}
func (c *MessageQueueTrigger) Delete(m *metav1.ObjectMeta) error {
relativeUrl := fmt.Sprintf("triggers/messagequeue/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
relativeUrl := fmt.Sprintf("triggers/messagequeue/%s", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%s", m.Namespace)
return c.client.Delete(relativeUrl)
}
func (c *MessageQueueTrigger) List(mqType string, ns string) ([]fv1.MessageQueueTrigger, error) {
relativeUrl := "triggers/messagequeue"
relativeUrl := fmt.Sprintf("triggers/messagequeue?namespace=%s", ns)
if len(mqType) > 0 {
// TODO remove this, replace with field selector
relativeUrl += fmt.Sprintf("?mqtype=%v&namespace=%v", mqType, ns)
relativeUrl += fmt.Sprintf("&mqtype=%s", mqType)
}
resp, err := c.client.Get(relativeUrl)
+1 -1
View File
@@ -76,7 +76,7 @@ func Commands() *cobra.Command {
RunE: wrapper.Wrapper(List),
}
wrapper.SetFlags(listCmd, flag.FlagSet{
Optional: []flag.Flag{flag.NamespaceCanary},
Optional: []flag.Flag{flag.NamespaceCanary, flag.AllNamespaces},
})
command := &cobra.Command{
+6 -3
View File
@@ -47,20 +47,23 @@ func (opts *CreateSubCommand) do(input cli.Input) error {
return opts.run(input)
}
func (opts *CreateSubCommand) complete(input cli.Input) error {
func (opts *CreateSubCommand) complete(input cli.Input) (err error) {
// canary configs can be created for functions in the same namespace
name := input.String(flagkey.CanaryName)
ht := input.String(flagkey.CanaryHTTPTriggerName)
newFunc := input.String(flagkey.CanaryNewFunc)
oldFunc := input.String(flagkey.CanaryOldFunc)
fnNs := input.String(flagkey.NamespaceFunction)
_, fnNs, err := util.GetResourceNamespace(input, flagkey.NamespaceFunction)
if err != nil {
return errors.Wrap(err, "error in creating canaryconfig")
}
incrementStep := input.Int(flagkey.CanaryWeightIncrement)
failureThreshold := input.Int(flagkey.CanaryFailureThreshold)
incrementInterval := input.String(flagkey.CanaryIncrementInterval)
// check for time parsing
_, err := time.ParseDuration(incrementInterval)
_, err = time.ParseDuration(incrementInterval)
if err != nil {
return errors.Wrap(err, "error parsing time duration")
}
+7 -3
View File
@@ -36,13 +36,17 @@ func Delete(input cli.Input) error {
return (&DeleteSubCommand{}).run(input)
}
func (opts *DeleteSubCommand) run(input cli.Input) error {
func (opts *DeleteSubCommand) run(input cli.Input) (err error) {
_, namespace, err := util.GetResourceNamespace(input, flagkey.NamespaceCanary)
if err != nil {
return errors.Wrap(err, "error in deleting canaryConfig ")
}
m := &metav1.ObjectMeta{
Name: input.String(flagkey.CanaryName),
Namespace: input.String(flagkey.NamespaceCanary),
Namespace: namespace,
}
err := opts.Client().V1().CanaryConfig().Delete(m)
err = opts.Client().V1().CanaryConfig().Delete(m)
if err != nil {
if input.Bool(flagkey.IgnoreNotFound) && util.IsNotFound(err) {
return nil
+9 -2
View File
@@ -27,6 +27,7 @@ import (
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
"github.com/fission/fission/pkg/fission-cli/cmd"
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
"github.com/fission/fission/pkg/fission-cli/util"
)
type GetSubCommand struct {
@@ -37,10 +38,16 @@ func Get(input cli.Input) error {
return (&GetSubCommand{}).run(input)
}
func (opts *GetSubCommand) run(input cli.Input) error {
func (opts *GetSubCommand) run(input cli.Input) (err error) {
_, namespace, err := util.GetResourceNamespace(input, flagkey.NamespaceCanary)
if err != nil {
return errors.Wrap(err, "error getting canary config")
}
canaryCfg, err := opts.Client().V1().CanaryConfig().Get(&metav1.ObjectMeta{
Name: input.String(flagkey.CanaryName),
Namespace: input.String(flagkey.NamespaceCanary),
Namespace: namespace,
})
if err != nil {
return errors.Wrap(err, "error getting canary config")
+15 -4
View File
@@ -23,9 +23,11 @@ import (
"github.com/pkg/errors"
v1 "github.com/fission/fission/pkg/apis/core/v1"
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
"github.com/fission/fission/pkg/fission-cli/cmd"
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
"github.com/fission/fission/pkg/fission-cli/util"
)
type ListSubCommand struct {
@@ -45,13 +47,22 @@ func (opts *ListSubCommand) do(input cli.Input) error {
return opts.run(input)
}
func (opts *ListSubCommand) complete(input cli.Input) error {
opts.namespace = input.String(flagkey.NamespaceCanary)
func (opts *ListSubCommand) complete(input cli.Input) (err error) {
_, opts.namespace, err = util.GetResourceNamespace(input, flagkey.NamespaceCanary)
if err != nil {
return errors.Wrap(err, "error in listing canary config ")
}
return nil
}
func (opts *ListSubCommand) run(input cli.Input) error {
canaryCfgs, err := opts.Client().V1().CanaryConfig().List(opts.namespace)
func (opts *ListSubCommand) run(input cli.Input) (err error) {
var canaryCfgs []v1.CanaryConfig
if input.Bool(flagkey.AllNamespaces) {
canaryCfgs, err = opts.Client().V1().CanaryConfig().List("")
} else {
canaryCfgs, err = opts.Client().V1().CanaryConfig().List(opts.namespace)
}
if err != nil {
return errors.Wrap(err, "error listing canary config")
}
+7 -3
View File
@@ -27,6 +27,7 @@ import (
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
"github.com/fission/fission/pkg/fission-cli/cmd"
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
"github.com/fission/fission/pkg/fission-cli/util"
)
type UpdateSubCommand struct {
@@ -46,16 +47,19 @@ func (opts *UpdateSubCommand) do(input cli.Input) error {
return opts.run(input)
}
func (opts *UpdateSubCommand) complete(input cli.Input) error {
func (opts *UpdateSubCommand) complete(input cli.Input) (err error) {
// get the current config
name := input.String(flagkey.CanaryName)
ns := input.String(flagkey.NamespaceCanary)
_, ns, err := util.GetResourceNamespace(input, flagkey.NamespaceCanary)
if err != nil {
return errors.Wrap(err, "error updating canary config")
}
incrementStep := input.Int(flagkey.CanaryWeightIncrement)
failureThreshold := input.Int(flagkey.CanaryFailureThreshold)
incrementInterval := input.String(flagkey.CanaryIncrementInterval)
// check for time parsing
_, err := time.ParseDuration(incrementInterval)
_, err = time.ParseDuration(incrementInterval)
if err != nil {
return errors.Wrap(err, "error parsing time duration")
}
+1 -1
View File
@@ -81,7 +81,7 @@ func Commands() *cobra.Command {
RunE: wrapper.Wrapper(List),
}
wrapper.SetFlags(listCmd, flag.FlagSet{
Optional: []flag.Flag{flag.NamespaceEnvironment},
Optional: []flag.Flag{flag.NamespaceEnvironment, flag.AllNamespaces},
})
listPodsCmd := &cobra.Command{
+26 -8
View File
@@ -63,7 +63,7 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
// run write the resource to a spec file or create a fission CRD with remote fission server.
// It also prints warning/error if necessary.
func (opts *CreateSubCommand) run(input cli.Input) error {
func (opts *CreateSubCommand) run(input cli.Input) (err error) {
m := opts.env.ObjectMeta
envList, err := opts.Client().V1().Environment().List(m.Namespace)
@@ -75,13 +75,30 @@ func (opts *CreateSubCommand) run(input cli.Input) error {
len(envList), m.Namespace)
}
userDefinedNS, currentNS, err := util.GetResourceNamespace(input, flagkey.NamespaceEnvironment)
if err != nil {
return fv1.AggregateValidationErrors("Environment", err)
}
// we use user provided NS in spec. While creating actual record we use the current context's NS.
opts.env.ObjectMeta.Namespace = userDefinedNS
// if we're writing a spec, don't call the API
// save to spec file or display the spec to console
if input.Bool(flagkey.SpecDry) {
err = opts.env.Validate()
if err != nil {
return fv1.AggregateValidationErrors("Environment", err)
}
return spec.SpecDry(*opts.env)
}
if input.Bool(flagkey.SpecSave) {
err = opts.env.Validate()
if err != nil {
return fv1.AggregateValidationErrors("Environment", err)
}
specFile := fmt.Sprintf("env-%v.yaml", m.Name)
err = spec.SpecSave(*opts.env, specFile)
if err != nil {
@@ -90,6 +107,12 @@ func (opts *CreateSubCommand) run(input cli.Input) error {
return nil
}
opts.env.ObjectMeta.Namespace = currentNS
err = opts.env.Validate()
if err != nil {
return fv1.AggregateValidationErrors("Environment", err)
}
_, err = opts.Client().V1().Environment().Create(opts.env)
if err != nil {
return errors.Wrap(err, "error creating environment")
@@ -105,7 +128,7 @@ func createEnvironmentFromCmd(input cli.Input) (*fv1.Environment, error) {
envName := input.String(flagkey.EnvName)
envImg := input.String(flagkey.EnvImage)
envNamespace := input.String(flagkey.NamespaceEnvironment)
envBuildCmd := input.String(flagkey.EnvBuildcommand)
envExternalNetwork := input.Bool(flagkey.EnvExternalNetwork)
keepArchive := input.Bool(flagkey.EnvKeeparchive)
@@ -165,8 +188,7 @@ func createEnvironmentFromCmd(input cli.Input) (*fv1.Environment, error) {
APIVersion: fv1.CRD_VERSION,
},
ObjectMeta: metav1.ObjectMeta{
Name: envName,
Namespace: envNamespace,
Name: envName,
},
Spec: fv1.EnvironmentSpec{
Version: envVersion,
@@ -196,10 +218,6 @@ func createEnvironmentFromCmd(input cli.Input) (*fv1.Environment, error) {
if err != nil {
return nil, err
}
err = env.Validate()
if err != nil {
return nil, fv1.AggregateValidationErrors("Environment", err)
}
return env, nil
}
+11 -3
View File
@@ -24,6 +24,7 @@ import (
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
"github.com/fission/fission/pkg/fission-cli/cmd"
"github.com/fission/fission/pkg/fission-cli/console"
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
"github.com/fission/fission/pkg/fission-cli/util"
)
@@ -36,10 +37,17 @@ func Delete(input cli.Input) error {
return (&DeleteSubCommand{}).do(input)
}
func (opts *DeleteSubCommand) do(input cli.Input) error {
func (opts *DeleteSubCommand) do(input cli.Input) (err error) {
_, currentContextNS, err := util.GetResourceNamespace(input, flagkey.NamespaceEnvironment)
if err != nil {
return errors.Wrap(err, "error creating environment")
}
console.Verbose(2, "Namespace used to delete resource: %s ", currentContextNS)
m := &metav1.ObjectMeta{
Name: input.String(flagkey.EnvName),
Namespace: input.String(flagkey.NamespaceEnvironment),
Namespace: currentContextNS,
}
if !input.Bool(flagkey.EnvForce) {
@@ -56,7 +64,7 @@ func (opts *DeleteSubCommand) do(input cli.Input) error {
}
}
err := opts.Client().V1().Environment().Delete(m)
err = opts.Client().V1().Environment().Delete(m)
if err != nil {
if input.Bool(flagkey.IgnoreNotFound) && util.IsNotFound(err) {
return nil
+9 -2
View File
@@ -27,6 +27,7 @@ import (
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
"github.com/fission/fission/pkg/fission-cli/cmd"
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
"github.com/fission/fission/pkg/fission-cli/util"
)
type GetSubCommand struct {
@@ -37,10 +38,16 @@ func Get(input cli.Input) error {
return (&GetSubCommand{}).do(input)
}
func (opts *GetSubCommand) do(input cli.Input) error {
func (opts *GetSubCommand) do(input cli.Input) (err error) {
_, currentNS, err := util.GetResourceNamespace(input, flagkey.NamespaceEnvironment)
if err != nil {
return errors.Wrap(err, "error creating environment")
}
m := &metav1.ObjectMeta{
Name: input.String(flagkey.EnvName),
Namespace: input.String(flagkey.NamespaceEnvironment),
Namespace: currentNS,
}
env, err := opts.Client().V1().Environment().Get(m)
+20 -5
View File
@@ -23,9 +23,11 @@ import (
"github.com/pkg/errors"
v1 "github.com/fission/fission/pkg/apis/core/v1"
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
"github.com/fission/fission/pkg/fission-cli/cmd"
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
"github.com/fission/fission/pkg/fission-cli/util"
)
type ListSubCommand struct {
@@ -36,20 +38,33 @@ func List(input cli.Input) error {
return (&ListSubCommand{}).do(input)
}
func (opts *ListSubCommand) do(input cli.Input) error {
envs, err := opts.Client().V1().Environment().List(input.String(flagkey.NamespaceEnvironment))
func (opts *ListSubCommand) do(input cli.Input) (err error) {
_, currentNS, err := util.GetResourceNamespace(input, flagkey.NamespaceEnvironment)
if err != nil {
return errors.Wrap(err, "error creating environment")
}
var envs []v1.Environment
if input.Bool(flagkey.AllNamespaces) {
envs, err = opts.Client().V1().Environment().List("")
} else {
envs, err = opts.Client().V1().Environment().List(currentNS)
}
if err != nil {
return errors.Wrap(err, "error listing environments")
}
w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)
fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\n", "NAME", "IMAGE", "BUILDER_IMAGE", "POOLSIZE", "MINCPU", "MAXCPU", "MINMEMORY", "MAXMEMORY", "EXTNET", "GRACETIME")
fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\n", "NAME", "IMAGE", "BUILDER_IMAGE", "POOLSIZE", "MINCPU", "MAXCPU", "MINMEMORY", "MAXMEMORY", "EXTNET", "GRACETIME", "NAMESPACE")
for _, env := range envs {
fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\n",
fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\n",
env.ObjectMeta.Name, env.Spec.Runtime.Image, env.Spec.Builder.Image, env.Spec.Poolsize,
env.Spec.Resources.Requests.Cpu(), env.Spec.Resources.Limits.Cpu(),
env.Spec.Resources.Requests.Memory(), env.Spec.Resources.Limits.Memory(),
env.Spec.AllowAccessToExternalNetwork, env.Spec.TerminationGracePeriod)
env.Spec.AllowAccessToExternalNetwork, env.Spec.TerminationGracePeriod, env.Namespace,
)
}
w.Flush()
+10 -4
View File
@@ -28,6 +28,7 @@ import (
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
"github.com/fission/fission/pkg/fission-cli/cmd"
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
"github.com/fission/fission/pkg/fission-cli/util"
"github.com/fission/fission/pkg/utils"
)
@@ -39,13 +40,18 @@ func ListPods(input cli.Input) error {
return (&ListPodsSubCommand{}).do(input)
}
func (opts *ListPodsSubCommand) do(input cli.Input) error {
func (opts *ListPodsSubCommand) do(input cli.Input) (err error) {
_, currentNS, err := util.GetResourceNamespace(input, flagkey.NamespaceEnvironment)
if err != nil {
return errors.Wrap(err, "error creating environment")
}
// validate environment
_, err := opts.Client().V1().Environment().Get(
_, err = opts.Client().V1().Environment().Get(
&metav1.ObjectMeta{
Name: input.String(flagkey.EnvName),
Namespace: input.String(flagkey.NamespaceEnvironment),
Namespace: currentNS,
})
if err != nil {
return errors.Wrap(err, "error getting environment")
@@ -54,7 +60,7 @@ func (opts *ListPodsSubCommand) do(input cli.Input) error {
m := &metav1.ObjectMeta{
Name: input.String(flagkey.EnvName),
Labels: map[string]string{
v1.ENVIRONMENT_NAMESPACE: input.String(flagkey.NamespaceEnvironment),
v1.ENVIRONMENT_NAMESPACE: currentNS,
v1.EXECUTOR_TYPE: input.String(flagkey.EnvExecutorType),
},
}
+10 -2
View File
@@ -52,10 +52,15 @@ func (opts *UpdateSubCommand) do(input cli.Input) error {
return opts.run(input)
}
func (opts *UpdateSubCommand) complete(input cli.Input) error {
func (opts *UpdateSubCommand) complete(input cli.Input) (err error) {
_, currentContextNS, err := util.GetResourceNamespace(input, flagkey.NamespaceEnvironment)
if err != nil {
return errors.Wrap(err, "error creating environment")
}
env, err := opts.Client().V1().Environment().Get(&metav1.ObjectMeta{
Name: input.String(flagkey.EnvName),
Namespace: input.String(flagkey.NamespaceEnvironment),
Namespace: currentContextNS,
})
if err != nil {
return errors.Wrap(err, "error finding environment")
@@ -127,6 +132,9 @@ func updateExistingEnvironmentWithCmd(env *fv1.Environment, input cli.Input) (*f
env.Spec.ImagePullSecret = input.String(flagkey.EnvImagePullSecret)
}
env.Spec.Resources.Requests = make(v1.ResourceList)
env.Spec.Resources.Limits = make(v1.ResourceList)
if input.IsSet(flagkey.RuntimeMincpu) {
mincpu := input.Int(flagkey.RuntimeMincpu)
cpuRequest, err := resource.ParseQuantity(strconv.Itoa(mincpu) + "m")
+2 -3
View File
@@ -49,8 +49,7 @@ func Commands() *cobra.Command {
flag.RunTimeMinCPU, flag.RunTimeMaxCPU, flag.RunTimeMinMemory,
flag.RunTimeMaxMemory, flag.ReplicasMin,
flag.ReplicasMax, flag.RunTimeTargetCPU,
flag.NamespaceFunction, flag.NamespaceEnvironment, flag.SpecSave, flag.SpecDry},
flag.NamespaceFunction, flag.SpecSave, flag.SpecDry},
})
getCmd := &cobra.Command{
@@ -121,7 +120,7 @@ func Commands() *cobra.Command {
RunE: wrapper.Wrapper(List),
}
wrapper.SetFlags(listCmd, flag.FlagSet{
Optional: []flag.Flag{flag.NamespaceFunction},
Optional: []flag.Flag{flag.NamespaceFunction, flag.AllNamespaces},
})
logsCmd := &cobra.Command{
+59 -36
View File
@@ -64,14 +64,17 @@ func (opts *CreateSubCommand) do(input cli.Input) error {
func (opts *CreateSubCommand) complete(input cli.Input) error {
fnName := input.String(flagkey.FnName)
fnNamespace := input.String(flagkey.NamespaceFunction)
envNamespace := input.String(flagkey.NamespaceEnvironment)
userProvidedNS, fnNamespace, err := util.GetResourceNamespace(input, flagkey.NamespaceFunction)
if err != nil {
return errors.Wrap(err, "error retrieving namespace information")
}
// user wants a spec, create a yaml file with package and function
toSpec := false
if input.Bool(flagkey.SpecSave) {
toSpec = true
opts.specFile = fmt.Sprintf("function-%v.yaml", fnName)
opts.specFile = fmt.Sprintf("function-%s.yaml", fnName)
}
specDir := util.GetSpecDir(input)
specIgnore := util.GetSpecIgnore(input)
@@ -80,7 +83,7 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
// check for unique function names within a namespace
fn, err := opts.Client().V1().Function().Get(&metav1.ObjectMeta{
Name: input.String(flagkey.FnName),
Namespace: input.String(flagkey.NamespaceFunction),
Namespace: fnNamespace,
})
if err != nil && !ferror.IsNotFound(err) {
return err
@@ -135,17 +138,19 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
fr, err := spec.ReadSpecs(specDir, specIgnore, false)
if err != nil {
return errors.Wrap(err, fmt.Sprintf("error reading spec in '%v'", specDir))
return errors.Wrap(err, fmt.Sprintf("error reading spec in '%s'", specDir))
}
obj := fr.SpecExists(&fv1.Package{
obj := fr.SpecExists(&fv1.Package{ // In case of spec I might or might not have the `fnNamespace`, how will I get pkg objectMeta here.
ObjectMeta: metav1.ObjectMeta{
Name: pkgName,
Namespace: fnNamespace,
Namespace: userProvidedNS,
},
}, true, false)
if obj == nil {
return errors.Errorf("please create package %v spec file before referencing it", pkgName)
return errors.Errorf("please create package %s spec file with namespace %s before referencing it", pkgName, userProvidedNS)
}
pkg = obj.(*fv1.Package)
pkgMetadata = &pkg.ObjectMeta
} else {
@@ -155,7 +160,7 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
Name: pkgName,
})
if err != nil {
return errors.Wrap(err, fmt.Sprintf("read package in '%v' in Namespace: %s. Package needs to be present in the same namespace as function", pkgName, fnNamespace))
return errors.Wrap(err, fmt.Sprintf("read package in '%s' in Namespace: %s. Package needs to be present in the same namespace as function", pkgName, fnNamespace))
}
pkgMetadata = &pkg.ObjectMeta
}
@@ -164,7 +169,6 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
if envName != input.String(flagkey.FnEnvironmentName) {
console.Warn("Function's environment is different than package's environment, package's environment will be used for creating function")
}
envNamespace = pkg.Spec.Environment.Namespace
} else {
// need to specify environment for creating new package
envName = input.String(flagkey.FnEnvironmentName)
@@ -176,29 +180,29 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
fr, err := spec.ReadSpecs(specDir, specIgnore, false)
if err != nil {
return errors.Wrap(err, fmt.Sprintf("error reading spec in '%v'", specDir))
return errors.Wrap(err, fmt.Sprintf("error reading spec in '%s'", specDir))
}
exists, err := fr.ExistsInSpecs(fv1.Environment{
ObjectMeta: metav1.ObjectMeta{
Name: envName,
Namespace: envNamespace,
Namespace: userProvidedNS,
},
})
if err != nil {
return err
}
if !exists {
console.Warn(fmt.Sprintf("Function '%v' references unknown Environment '%v', please create it before applying spec",
console.Warn(fmt.Sprintf("Function '%s' references unknown Environment '%s', please create it before applying spec",
fnName, envName))
}
} else {
_, err := opts.Client().V1().Environment().Get(&metav1.ObjectMeta{
Namespace: envNamespace,
Namespace: fnNamespace,
Name: envName,
})
if err != nil {
if e, ok := err.(ferror.Error); ok && e.Code == ferror.ErrorNotFound {
console.Warn(fmt.Sprintf("Environment \"%v\" does not exist. Please create the environment before executing the function. \nFor example: `fission env create --name %v --envns %v --image <image>`\n", envName, envName, envNamespace))
console.Warn(fmt.Sprintf("Environment \"%s\" does not exist. Please create the environment before executing the function. \nFor example: `fission env create --name %s --envns %s --image <image>`\n", envName, envName, fnNamespace))
} else {
return errors.Wrap(err, "error retrieving environment information")
}
@@ -228,8 +232,8 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
pkgName := generatePackageName(fnName, id.String())
// create new package in the same namespace as the function.
pkgMetadata, err = _package.CreatePackage(input, opts.Client(), pkgName, fnNamespace, envName, envNamespace,
srcArchiveFiles, deployArchiveFiles, buildcmd, specDir, opts.specFile, noZip)
pkgMetadata, err = _package.CreatePackage(input, opts.Client(), pkgName, fnNamespace, envName,
srcArchiveFiles, deployArchiveFiles, buildcmd, specDir, opts.specFile, noZip, userProvidedNS)
if err != nil {
return errors.Wrap(err, "error creating package")
}
@@ -253,15 +257,22 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
return errors.Wrapf(err, "error checking secret %s", secretName)
}
}
newSecret := fv1.SecretReference{
Name: secretName,
Namespace: fnNamespace,
}
secrets = append(secrets, newSecret)
}
} else {
for _, secretName := range secretNames {
newSecret := fv1.SecretReference{
Name: secretName,
Namespace: userProvidedNS,
}
secrets = append(secrets, newSecret)
}
}
for _, secretName := range secretNames {
newSecret := fv1.SecretReference{
Name: secretName,
Namespace: fnNamespace,
}
secrets = append(secrets, newSecret)
}
}
if len(cfgMapNames) > 0 {
@@ -279,14 +290,20 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
return errors.Wrapf(err, "error checking configmap %s", cfgMapName)
}
}
newCfgMap := fv1.ConfigMapReference{
Name: cfgMapName,
Namespace: fnNamespace,
}
cfgmaps = append(cfgmaps, newCfgMap)
}
}
for _, cfgMapName := range cfgMapNames {
newCfgMap := fv1.ConfigMapReference{
Name: cfgMapName,
Namespace: fnNamespace,
} else {
for _, cfgMapName := range cfgMapNames {
newCfgMap := fv1.ConfigMapReference{
Name: cfgMapName,
Namespace: userProvidedNS,
}
cfgmaps = append(cfgmaps, newCfgMap)
}
cfgmaps = append(cfgmaps, newCfgMap)
}
}
@@ -314,7 +331,7 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
}
opts.function.Spec.Environment = fv1.EnvironmentReference{
Name: envName,
Namespace: envNamespace,
Namespace: fnNamespace,
}
opts.function.Spec.Package = fv1.FunctionPackageRef{
FunctionName: entrypoint,
@@ -325,6 +342,12 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
},
}
if toSpec {
opts.function.ObjectMeta.Namespace = userProvidedNS
opts.function.Spec.Package.PackageRef.Namespace = userProvidedNS
opts.function.Spec.Environment.Namespace = userProvidedNS
}
return nil
}
@@ -336,12 +359,12 @@ func generatePackageName(fnName string, id string) string {
lastIndexOfChar int
)
if lenFnName+lenId <= 62 {
return fmt.Sprintf("%v-%v", fnName, id)
return fmt.Sprintf("%s-%s", fnName, id)
}
lastIndexOfChar = lenFnName - (lenFnName + lenId - 62)
pkgName := fmt.Sprintf("%v-%v", fnName[:lastIndexOfChar], id)
console.Info(fmt.Sprintf("Generated package %v from function to acceptable character limit", pkgName))
pkgName := fmt.Sprintf("%v-%s", fnName[:lastIndexOfChar], id)
console.Info(fmt.Sprintf("Generated package %s from function to acceptable character limit", pkgName))
return pkgName
}
@@ -367,7 +390,7 @@ func (opts *CreateSubCommand) run(input cli.Input) error {
return errors.Wrap(err, "error creating function")
}
fmt.Printf("function '%v' created\n", opts.function.ObjectMeta.Name)
fmt.Printf("function '%s' created\n", opts.function.ObjectMeta.Name)
// Allow the user to specify an HTTP trigger while creating a function.
triggerUrl := input.String(flagkey.HtUrl)
@@ -416,7 +439,7 @@ func (opts *CreateSubCommand) run(input cli.Input) error {
return errors.Wrap(err, "error creating HTTP trigger")
}
fmt.Printf("route created: %v %v -> %v\n", methods, triggerUrl, opts.function.ObjectMeta.Name)
fmt.Printf("route created: %s %s -> %s\n", methods, triggerUrl, opts.function.ObjectMeta.Name)
return nil
}
+9 -4
View File
@@ -37,19 +37,24 @@ func Delete(input cli.Input) error {
}
func (opts *DeleteSubCommand) do(input cli.Input) error {
_, namespace, err := util.GetResourceNamespace(input, flagkey.NamespaceFunction)
if err != nil {
return errors.Wrap(err, "error in deleting function ")
}
m := &metav1.ObjectMeta{
Name: input.String(flagkey.FnName),
Namespace: input.String(flagkey.NamespaceFunction),
Namespace: namespace,
}
err := opts.Client().V1().Function().Delete(m)
err = opts.Client().V1().Function().Delete(m)
if err != nil {
if input.Bool(flagkey.IgnoreNotFound) && util.IsNotFound(err) {
return nil
}
return errors.Wrap(err, fmt.Sprintf("delete function '%v'", m.Name))
return errors.Wrap(err, fmt.Sprintf("delete function '%s'", m.Name))
}
fmt.Printf("function '%v' deleted\n", m.Name)
fmt.Printf("function '%s' deleted\n", m.Name)
return nil
}
+6 -1
View File
@@ -25,6 +25,7 @@ import (
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
"github.com/fission/fission/pkg/fission-cli/cmd"
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
"github.com/fission/fission/pkg/fission-cli/util"
)
type GetSubCommand struct {
@@ -36,9 +37,13 @@ func Get(input cli.Input) error {
}
func (opts *GetSubCommand) do(input cli.Input) error {
_, namespace, err := util.GetResourceNamespace(input, flagkey.NamespaceFunction)
if err != nil {
return errors.Wrap(err, "error in get function ")
}
fn, err := opts.Client().V1().Function().Get(&metav1.ObjectMeta{
Name: input.String(flagkey.FnName),
Namespace: input.String(flagkey.NamespaceFunction),
Namespace: namespace,
})
if err != nil {
return errors.Wrap(err, "error getting function")
+7 -1
View File
@@ -25,6 +25,7 @@ import (
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
"github.com/fission/fission/pkg/fission-cli/cmd"
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
"github.com/fission/fission/pkg/fission-cli/util"
)
type GetMetaSubCommand struct {
@@ -36,9 +37,14 @@ func GetMeta(input cli.Input) error {
}
func (opts *GetMetaSubCommand) do(input cli.Input) error {
_, namespace, err := util.GetResourceNamespace(input, flagkey.NamespaceFunction)
if err != nil {
return errors.Wrap(err, "error in getting meta function ")
}
fn, err := opts.Client().V1().Function().Get(&metav1.ObjectMeta{
Name: input.String(flagkey.FnName),
Namespace: input.String(flagkey.NamespaceFunction),
Namespace: namespace,
})
if err != nil {
return errors.Wrap(err, "error getting function")
+16 -5
View File
@@ -24,9 +24,11 @@ import (
"github.com/pkg/errors"
v1 "github.com/fission/fission/pkg/apis/core/v1"
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
"github.com/fission/fission/pkg/fission-cli/cmd"
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
"github.com/fission/fission/pkg/fission-cli/util"
)
type ListSubCommand struct {
@@ -38,16 +40,24 @@ func List(input cli.Input) error {
}
func (opts *ListSubCommand) do(input cli.Input) error {
ns := input.String(flagkey.NamespaceFunction)
_, namespace, err := util.GetResourceNamespace(input, flagkey.NamespaceFunction)
if err != nil {
return errors.Wrap(err, "error in listing function ")
}
fns, err := opts.Client().V1().Function().List(ns)
var fns []v1.Function
if input.Bool(flagkey.AllNamespaces) {
fns, err = opts.Client().V1().Function().List("")
} else {
fns, err = opts.Client().V1().Function().List(namespace)
}
if err != nil {
return errors.Wrap(err, "error listing functions")
}
w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)
fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\n", "NAME", "ENV", "EXECUTORTYPE", "MINSCALE", "MAXSCALE", "MINCPU", "MAXCPU", "MINMEMORY", "MAXMEMORY", "SECRETS", "CONFIGMAPS")
fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\n", "NAME", "ENV", "EXECUTORTYPE", "MINSCALE", "MAXSCALE", "MINCPU", "MAXCPU", "MINMEMORY", "MAXMEMORY", "SECRETS", "CONFIGMAPS", "NAMESPACE")
for _, f := range fns {
secrets := f.Spec.Secrets
configMaps := f.Spec.ConfigMaps
@@ -59,7 +69,7 @@ func (opts *ListSubCommand) do(input cli.Input) error {
configMapList = append(configMapList, configMap.Name)
}
fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\n",
fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\n",
f.ObjectMeta.Name, f.Spec.Environment.Name,
f.Spec.InvokeStrategy.ExecutionStrategy.ExecutorType,
f.Spec.InvokeStrategy.ExecutionStrategy.MinScale,
@@ -69,7 +79,8 @@ func (opts *ListSubCommand) do(input cli.Input) error {
f.Spec.Resources.Requests.Memory().String(),
f.Spec.Resources.Limits.Memory().String(),
strings.Join(secretsList, ","),
strings.Join(configMapList, ","))
strings.Join(configMapList, ","),
f.ObjectMeta.Namespace)
}
w.Flush()
+6 -1
View File
@@ -40,6 +40,11 @@ func Log(input cli.Input) error {
}
func (opts *LogSubCommand) do(input cli.Input) error {
_, namespace, err := util.GetResourceNamespace(input, flagkey.NamespaceFunction)
if err != nil {
return errors.Wrap(err, "error in logs for function ")
}
dbType := input.String(flagkey.FnLogDBType)
fnPod := input.String(flagkey.FnLogPod)
kubeContext := input.String(flagkey.KubeContext)
@@ -53,7 +58,7 @@ func (opts *LogSubCommand) do(input cli.Input) error {
f, err := opts.Client().V1().Function().Get(&metav1.ObjectMeta{
Name: input.String(flagkey.FnName),
Namespace: input.String(flagkey.NamespaceFunction),
Namespace: namespace,
})
if err != nil {
return errors.Wrap(err, "error getting function")
+9 -3
View File
@@ -28,6 +28,7 @@ import (
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
"github.com/fission/fission/pkg/fission-cli/cmd"
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
"github.com/fission/fission/pkg/fission-cli/util"
"github.com/fission/fission/pkg/utils"
)
@@ -41,10 +42,15 @@ func ListPods(input cli.Input) error {
func (opts *ListPodsSubCommand) do(input cli.Input) error {
_, namespace, err := util.GetResourceNamespace(input, flagkey.NamespaceFunction)
if err != nil {
return errors.Wrap(err, "error in finding pod for function ")
}
// validate function
_, err := opts.Client().V1().Function().Get(&metav1.ObjectMeta{
_, err = opts.Client().V1().Function().Get(&metav1.ObjectMeta{
Name: input.String(flagkey.FnName),
Namespace: input.String(flagkey.NamespaceFunction),
Namespace: namespace,
})
if err != nil {
return errors.Wrap(err, "error getting function")
@@ -53,7 +59,7 @@ func (opts *ListPodsSubCommand) do(input cli.Input) error {
m := &metav1.ObjectMeta{
Name: input.String(flagkey.FnName),
Labels: map[string]string{
v1.FUNCTION_NAMESPACE: input.String(flagkey.NamespaceFunction),
v1.FUNCTION_NAMESPACE: namespace,
},
}
@@ -55,7 +55,11 @@ func (opts *RunContainerSubCommand) do(input cli.Input) error {
func (opts *RunContainerSubCommand) complete(input cli.Input) error {
fnName := input.String(flagkey.FnName)
fnNamespace := input.String(flagkey.NamespaceFunction)
_, fnNamespace, err := util.GetResourceNamespace(input, flagkey.NamespaceFunction)
if err != nil {
return errors.Wrap(err, "error in running container for function ")
}
// user wants a spec, create a yaml file with package and function
toSpec := false
@@ -68,7 +72,7 @@ func (opts *RunContainerSubCommand) complete(input cli.Input) error {
// check for unique function names within a namespace
fn, err := opts.Client().V1().Function().Get(&metav1.ObjectMeta{
Name: input.String(flagkey.FnName),
Namespace: input.String(flagkey.NamespaceFunction),
Namespace: fnNamespace,
})
if err != nil && !ferror.IsNotFound(err) {
return err
+7 -1
View File
@@ -51,9 +51,15 @@ func Test(input cli.Input) error {
}
func (opts *TestSubCommand) do(input cli.Input) error {
_, namespace, err := util.GetResourceNamespace(input, flagkey.NamespaceFunction)
if err != nil {
return errors.Wrap(err, "error in testing function ")
}
m := &metav1.ObjectMeta{
Name: input.String(flagkey.FnName),
Namespace: input.String(flagkey.NamespaceFunction),
Namespace: namespace,
}
kubeContext := input.String(flagkey.KubeContext)
routerURL := os.Getenv("FISSION_ROUTER")
+5 -2
View File
@@ -51,11 +51,14 @@ func (opts *UpdateSubCommand) do(input cli.Input) error {
func (opts *UpdateSubCommand) complete(input cli.Input) error {
fnName := input.String(flagkey.FnName)
fnNamespace := input.String(flagkey.NamespaceFunction)
_, fnNamespace, err := util.GetResourceNamespace(input, flagkey.NamespaceFunction)
if err != nil {
return errors.Wrap(err, "error in updating function ")
}
function, err := opts.Client().V1().Function().Get(&metav1.ObjectMeta{
Name: input.String(flagkey.FnName),
Namespace: input.String(flagkey.NamespaceFunction),
Namespace: fnNamespace,
})
if err != nil {
return errors.Wrap(err, fmt.Sprintf("read function '%v'", fnName))
@@ -52,11 +52,15 @@ func (opts *UpdateContainerSubCommand) do(input cli.Input) error {
func (opts *UpdateContainerSubCommand) complete(input cli.Input) error {
fnName := input.String(flagkey.FnName)
fnNamespace := input.String(flagkey.NamespaceFunction)
_, fnNamespace, err := util.GetResourceNamespace(input, flagkey.NamespaceFunction)
if err != nil {
return errors.Wrap(err, "error in updating container for function ")
}
function, err := opts.Client().V1().Function().Get(&metav1.ObjectMeta{
Name: input.String(flagkey.FnName),
Namespace: input.String(flagkey.NamespaceFunction),
Namespace: fnNamespace,
})
if err != nil {
return errors.Wrap(err, fmt.Sprintf("read function '%v'", fnName))
+1 -1
View File
@@ -79,7 +79,7 @@ func Commands() *cobra.Command {
RunE: wrapper.Wrapper(List),
}
wrapper.SetFlags(listCmd, flag.FlagSet{
Optional: []flag.Flag{flag.NamespaceTrigger, flag.HtFnFilter},
Optional: []flag.Flag{flag.NamespaceTrigger, flag.HtFnFilter, flag.AllNamespaces},
})
command := &cobra.Command{
+34 -17
View File
@@ -76,19 +76,10 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
}
triggerName = id.String()
}
fnNamespace := input.String(flagkey.NamespaceFunction)
m := &metav1.ObjectMeta{
Name: triggerName,
Namespace: fnNamespace,
}
htTrigger, err := opts.Client().V1().HTTPTrigger().Get(m)
if err != nil && !ferror.IsNotFound(err) {
return err
}
if htTrigger != nil {
return errors.New("duplicate trigger exists, choose a different name or leave it empty for fission to auto-generate it")
userProvidedNS, fnNamespace, err := util.GetResourceNamespace(input, flagkey.NamespaceFunction)
if err != nil {
return errors.Wrap(err, "error in deleting function ")
}
triggerUrl := input.String(flagkey.HtUrl)
@@ -130,9 +121,24 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
return err
}
}
m := metav1.ObjectMeta{
Name: triggerName,
Namespace: userProvidedNS,
}
console.Warn(fmt.Sprintf("Ns: %v", userProvidedNS))
// For Specs, the spec validate checks for function reference
if input.Bool(flagkey.SpecSave) {
htTrigger, err := opts.Client().V1().HTTPTrigger().Get(&m)
if err != nil && !ferror.IsNotFound(err) {
return err
}
if htTrigger != nil {
return errors.New("duplicate trigger exists, choose a different name or leave it empty for fission to auto-generate it")
}
specDir := util.GetSpecDir(input)
specIgnore := util.GetSpecIgnore(input)
fr, err := spec.ReadSpecs(specDir, specIgnore, false)
@@ -143,7 +149,7 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
exists, err := fr.ExistsInSpecs(fv1.Function{
ObjectMeta: metav1.ObjectMeta{
Name: fn,
Namespace: fnNamespace,
Namespace: userProvidedNS,
},
})
if err != nil {
@@ -155,6 +161,20 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
}
}
} else {
m = metav1.ObjectMeta{
Name: triggerName,
Namespace: fnNamespace,
}
htTrigger, err := opts.Client().V1().HTTPTrigger().Get(&m)
if err != nil && !ferror.IsNotFound(err) {
return err
}
if htTrigger != nil {
return errors.New("duplicate trigger exists, choose a different name or leave it empty for fission to auto-generate it")
}
err = util.CheckFunctionExistence(opts.Client(), functionList, fnNamespace)
if err != nil {
console.Warn(err.Error())
@@ -172,10 +192,7 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
host := input.String(flagkey.HtHost)
opts.trigger = &fv1.HTTPTrigger{
ObjectMeta: metav1.ObjectMeta{
Name: triggerName,
Namespace: fnNamespace,
},
ObjectMeta: m,
Spec: fv1.HTTPTriggerSpec{
Host: host,
RelativeURL: triggerUrl,
+6 -2
View File
@@ -49,7 +49,7 @@ func (opts *DeleteSubCommand) do(input cli.Input) error {
return opts.run(input)
}
func (opts *DeleteSubCommand) complete(input cli.Input) error {
func (opts *DeleteSubCommand) complete(input cli.Input) (err error) {
opts.triggerName = input.String(flagkey.HtName)
opts.functionName = input.String(flagkey.HtFnName)
if len(opts.triggerName) == 0 && len(opts.functionName) == 0 {
@@ -57,7 +57,11 @@ func (opts *DeleteSubCommand) complete(input cli.Input) error {
} else if len(opts.triggerName) > 0 && len(opts.functionName) > 0 {
return errors.Errorf("need either of --%v or --%v and not both arguments", flagkey.HtName, flagkey.HtFnName)
}
opts.namespace = input.String(flagkey.NamespaceTrigger)
_, opts.namespace, err = util.GetResourceNamespace(input, flagkey.NamespaceTrigger)
if err != nil {
return errors.Wrap(err, "error in deleting function ")
}
return nil
}
+11 -5
View File
@@ -29,6 +29,7 @@ import (
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
"github.com/fission/fission/pkg/fission-cli/cmd"
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
"github.com/fission/fission/pkg/fission-cli/util"
)
type GetSubCommand struct {
@@ -43,10 +44,15 @@ func (opts *GetSubCommand) do(input cli.Input) error {
return opts.run(input)
}
func (opts *GetSubCommand) run(input cli.Input) error {
func (opts *GetSubCommand) run(input cli.Input) (err error) {
_, namespace, err := util.GetResourceNamespace(input, flagkey.NamespaceFunction)
if err != nil {
return errors.Wrap(err, "error in deleting function ")
}
m := &metav1.ObjectMeta{
Name: input.String(flagkey.HtName),
Namespace: input.String(flagkey.NamespaceFunction),
Namespace: namespace,
}
ht, err := opts.Client().V1().HTTPTrigger().Get(m)
if err != nil {
@@ -60,7 +66,7 @@ func (opts *GetSubCommand) run(input cli.Input) error {
func printHtSummary(triggers []fv1.HTTPTrigger) {
w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)
fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\n", "NAME", "METHOD", "URL", "FUNCTION(s)", "INGRESS", "HOST", "PATH", "TLS", "ANNOTATIONS")
fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\n", "NAME", "METHOD", "URL", "FUNCTION(s)", "INGRESS", "HOST", "PATH", "TLS", "ANNOTATIONS", "NAMESPACE")
for _, trigger := range triggers {
function := ""
if trigger.Spec.FunctionReference.Type == fv1.FunctionReferenceTypeFunctionName {
@@ -93,8 +99,8 @@ func printHtSummary(triggers []fv1.HTTPTrigger) {
if len(trigger.Spec.Methods) > 0 {
methods = trigger.Spec.Methods
}
fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\n",
trigger.ObjectMeta.Name, methods, trigger.Spec.RelativeURL, function, trigger.Spec.CreateIngress, host, path, trigger.Spec.IngressConfig.TLS, ann)
fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\n",
trigger.ObjectMeta.Name, methods, trigger.Spec.RelativeURL, function, trigger.Spec.CreateIngress, host, path, trigger.Spec.IngressConfig.TLS, ann, trigger.ObjectMeta.Namespace)
}
w.Flush()
}
+15 -2
View File
@@ -23,6 +23,7 @@ import (
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
"github.com/fission/fission/pkg/fission-cli/cmd"
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
"github.com/fission/fission/pkg/fission-cli/util"
)
type ListSubCommand struct {
@@ -37,8 +38,20 @@ func (opts *ListSubCommand) do(input cli.Input) error {
return opts.run(input)
}
func (opts *ListSubCommand) run(input cli.Input) error {
hts, err := opts.Client().V1().HTTPTrigger().List(input.String(flagkey.NamespaceTrigger))
func (opts *ListSubCommand) run(input cli.Input) (err error) {
_, namespace, err := util.GetResourceNamespace(input, flagkey.NamespaceTrigger)
if err != nil {
return errors.Wrap(err, "error in deleting function ")
}
var hts []fv1.HTTPTrigger
if input.Bool(flagkey.AllNamespaces) {
hts, err = opts.Client().V1().HTTPTrigger().List("")
} else {
hts, err = opts.Client().V1().HTTPTrigger().List(namespace)
}
if err != nil {
return errors.Wrap(err, "error listing HTTP triggers")
}
+6 -2
View File
@@ -48,9 +48,13 @@ func (opts *UpdateSubCommand) do(input cli.Input) error {
return opts.run(input)
}
func (opts *UpdateSubCommand) complete(input cli.Input) error {
func (opts *UpdateSubCommand) complete(input cli.Input) (err error) {
htName := input.String(flagkey.HtName)
triggerNamespace := input.String(flagkey.NamespaceTrigger)
_, triggerNamespace, err := util.GetResourceNamespace(input, flagkey.NamespaceTrigger)
if err != nil {
return errors.Wrap(err, "error in deleting function ")
}
ht, err := opts.Client().V1().HTTPTrigger().Get(&metav1.ObjectMeta{
Name: htName,
+1 -1
View File
@@ -55,7 +55,7 @@ func Commands() *cobra.Command {
RunE: wrapper.Wrapper(List),
}
wrapper.SetFlags(listCmd, flag.FlagSet{
Optional: []flag.Flag{flag.NamespaceTrigger},
Optional: []flag.Flag{flag.NamespaceTrigger, flag.AllNamespaces},
})
command := &cobra.Command{
+8 -4
View File
@@ -60,8 +60,12 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
watchName = id.String()
}
fnName := input.String(flagkey.KwFnName)
fnNamespace := input.String(flagkey.NamespaceFunction)
namespace := input.String(flagkey.KwNamespace)
_, namespace, err := util.GetResourceNamespace(input, flagkey.KwNamespace)
if err != nil {
return errors.Wrap(err, "error in listing function ")
}
objType := input.String(flagkey.KwObjType)
if input.Bool(flagkey.SpecSave) {
@@ -75,7 +79,7 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
exists, err := fr.ExistsInSpecs(fv1.Function{
ObjectMeta: metav1.ObjectMeta{
Name: fnName,
Namespace: fnNamespace,
Namespace: namespace,
},
})
if err != nil {
@@ -90,7 +94,7 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
opts.watcher = &fv1.KubernetesWatchTrigger{
ObjectMeta: metav1.ObjectMeta{
Name: watchName,
Namespace: fnNamespace,
Namespace: namespace,
},
Spec: fv1.KubernetesWatchTriggerSpec{
Namespace: namespace,
+5 -2
View File
@@ -46,9 +46,12 @@ func (opts *DeleteSubCommand) do(input cli.Input) error {
return opts.run(input)
}
func (opts *DeleteSubCommand) complete(input cli.Input) error {
func (opts *DeleteSubCommand) complete(input cli.Input) (err error) {
opts.name = input.String(flagkey.KwName)
opts.namespace = input.String(flagkey.NamespaceTrigger)
_, opts.namespace, err = util.GetResourceNamespace(input, flagkey.NamespaceTrigger)
if err != nil {
return errors.Wrap(err, "error in deleting kubewatch")
}
return nil
}
+14 -4
View File
@@ -23,9 +23,11 @@ import (
"github.com/pkg/errors"
v1 "github.com/fission/fission/pkg/apis/core/v1"
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
"github.com/fission/fission/pkg/fission-cli/cmd"
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
"github.com/fission/fission/pkg/fission-cli/util"
)
type ListSubCommand struct {
@@ -45,13 +47,21 @@ func (opts *ListSubCommand) do(input cli.Input) error {
return opts.run(input)
}
func (opts *ListSubCommand) complete(input cli.Input) error {
opts.namespace = input.String(flagkey.NamespaceTrigger)
func (opts *ListSubCommand) complete(input cli.Input) (err error) {
_, opts.namespace, err = util.GetResourceNamespace(input, flagkey.NamespaceTrigger)
if err != nil {
return errors.Wrap(err, "error listing kubewatchers")
}
return nil
}
func (opts *ListSubCommand) run(input cli.Input) error {
ws, err := opts.Client().V1().KubeWatcher().List(opts.namespace)
func (opts *ListSubCommand) run(input cli.Input) (err error) {
var ws []v1.KubernetesWatchTrigger
if input.Bool(flagkey.AllNamespaces) {
ws, err = opts.Client().V1().KubeWatcher().List("")
} else {
ws, err = opts.Client().V1().KubeWatcher().List(opts.namespace)
}
if err != nil {
return errors.Wrap(err, "error listing kubewatchers")
}
+1 -1
View File
@@ -71,7 +71,7 @@ func Commands() *cobra.Command {
RunE: wrapper.Wrapper(List),
}
wrapper.SetFlags(listCmd, flag.FlagSet{
Optional: []flag.Flag{flag.NamespaceTrigger},
Optional: []flag.Flag{flag.NamespaceTrigger, flag.AllNamespaces},
})
command := &cobra.Command{
+19 -7
View File
@@ -61,7 +61,11 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
mqtName = id.String()
}
fnName := input.String(flagkey.MqtFnName)
fnNamespace := input.String(flagkey.NamespaceFunction)
userProvidedNS, fnNamespace, err := util.GetResourceNamespace(input, flagkey.NamespaceFunction)
if err != nil {
return errors.Wrap(err, "error in deleting function ")
}
mqtKind := input.String(flagkey.MqtKind)
@@ -94,7 +98,7 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
contentType = "application/json"
}
err := checkMQTopicAvailability(mqType, mqtKind, topic, respTopic)
err = checkMQTopicAvailability(mqType, mqtKind, topic, respTopic)
if err != nil {
return err
}
@@ -136,7 +140,7 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
exists, err := fr.ExistsInSpecs(fv1.Function{
ObjectMeta: metav1.ObjectMeta{
Name: fnName,
Namespace: fnNamespace,
Namespace: userProvidedNS,
},
})
if err != nil {
@@ -153,11 +157,19 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
}
}
opts.trigger = &fv1.MessageQueueTrigger{
ObjectMeta: metav1.ObjectMeta{
m := metav1.ObjectMeta{
Name: mqtName,
Namespace: fnNamespace,
}
if input.Bool(flagkey.SpecSave) || input.Bool(flagkey.SpecDry) {
m = metav1.ObjectMeta{
Name: mqtName,
Namespace: fnNamespace,
},
Namespace: userProvidedNS,
}
}
opts.trigger = &fv1.MessageQueueTrigger{
ObjectMeta: m,
Spec: fv1.MessageQueueTriggerSpec{
FunctionReference: fv1.FunctionReference{
Type: fv1.FunctionReferenceTypeFunctionName,
+8 -2
View File
@@ -45,10 +45,16 @@ func (opts *DeleteSubCommand) do(input cli.Input) error {
return opts.run(input)
}
func (opts *DeleteSubCommand) complete(input cli.Input) error {
func (opts *DeleteSubCommand) complete(input cli.Input) (err error) {
_, namespace, err := util.GetResourceNamespace(input, flagkey.NamespaceTrigger)
if err != nil {
return errors.Wrap(err, "error in deleting function ")
}
opts.metadata = &metav1.ObjectMeta{
Name: input.String(flagkey.MqtName),
Namespace: input.String(flagkey.NamespaceTrigger),
Namespace: namespace,
}
return nil
}
+19 -8
View File
@@ -23,9 +23,11 @@ import (
"github.com/pkg/errors"
v1 "github.com/fission/fission/pkg/apis/core/v1"
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
"github.com/fission/fission/pkg/fission-cli/cmd"
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
"github.com/fission/fission/pkg/fission-cli/util"
)
type ListSubCommand struct {
@@ -45,24 +47,33 @@ func (opts *ListSubCommand) do(input cli.Input) error {
return opts.run(input)
}
func (opts *ListSubCommand) complete(input cli.Input) error {
opts.namespace = input.String(flagkey.NamespaceTrigger)
func (opts *ListSubCommand) complete(input cli.Input) (err error) {
_, opts.namespace, err = util.GetResourceNamespace(input, flagkey.NamespaceTrigger)
if err != nil {
return errors.Wrap(err, "error in deleting function ")
}
return nil
}
func (opts *ListSubCommand) run(input cli.Input) error {
mqts, err := opts.Client().V1().MessageQueueTrigger().List(input.String(flagkey.MqtMQType), opts.namespace)
func (opts *ListSubCommand) run(input cli.Input) (err error) {
var mqts []v1.MessageQueueTrigger
if input.Bool(flagkey.AllNamespaces) {
mqts, err = opts.Client().V1().MessageQueueTrigger().List(input.String(flagkey.MqtMQType), "")
} else {
mqts, err = opts.Client().V1().MessageQueueTrigger().List(input.String(flagkey.MqtMQType), opts.namespace)
}
if err != nil {
return errors.Wrap(err, "error listing message queue triggers")
}
w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)
fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\n",
"NAME", "FUNCTION_NAME", "MESSAGE_QUEUE_TYPE", "TOPIC", "RESPONSE_TOPIC", "ERROR_TOPIC", "MAX_RETRIES", "PUB_MSG_CONTENT_TYPE")
fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\n",
"NAME", "FUNCTION_NAME", "MESSAGE_QUEUE_TYPE", "TOPIC", "RESPONSE_TOPIC", "ERROR_TOPIC", "MAX_RETRIES", "PUB_MSG_CONTENT_TYPE", "NAMESPACE")
for _, mqt := range mqts {
fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\n",
mqt.ObjectMeta.Name, mqt.Spec.FunctionReference.Name, mqt.Spec.MessageQueueType, mqt.Spec.Topic, mqt.Spec.ResponseTopic, mqt.Spec.ErrorTopic, mqt.Spec.MaxRetries, mqt.Spec.ContentType)
fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\n",
mqt.ObjectMeta.Name, mqt.Spec.FunctionReference.Name, mqt.Spec.MessageQueueType, mqt.Spec.Topic, mqt.Spec.ResponseTopic, mqt.Spec.ErrorTopic, mqt.Spec.MaxRetries, mqt.Spec.ContentType, mqt.ObjectMeta.Namespace)
}
w.Flush()
+14 -2
View File
@@ -25,6 +25,7 @@ import (
fv1 "github.com/fission/fission/pkg/apis/core/v1"
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
"github.com/fission/fission/pkg/fission-cli/cmd"
"github.com/fission/fission/pkg/fission-cli/console"
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
"github.com/fission/fission/pkg/fission-cli/util"
)
@@ -46,10 +47,15 @@ func (opts *UpdateSubCommand) do(input cli.Input) error {
return opts.run(input)
}
func (opts *UpdateSubCommand) complete(input cli.Input) error {
func (opts *UpdateSubCommand) complete(input cli.Input) (err error) {
_, namespace, err := util.GetResourceNamespace(input, flagkey.NamespaceTrigger)
if err != nil {
return errors.Wrap(err, "error in deleting function ")
}
mqt, err := opts.Client().V1().MessageQueueTrigger().Get(&metav1.ObjectMeta{
Name: input.String(flagkey.MqtName),
Namespace: input.String(flagkey.NamespaceTrigger),
Namespace: namespace,
})
if err != nil {
return errors.Wrap(err, "error getting message queue trigger")
@@ -93,6 +99,12 @@ func (opts *UpdateSubCommand) complete(input cli.Input) error {
updated = true
}
if len(fnName) > 0 {
functionList := []string{fnName}
err := util.CheckFunctionExistence(opts.Client(), functionList, namespace)
if err != nil {
console.Warn(err.Error())
}
mqt.Spec.FunctionReference.Name = fnName
updated = true
}
+2 -2
View File
@@ -33,7 +33,7 @@ func Commands() *cobra.Command {
Required: []flag.Flag{flag.PkgEnvironment},
Optional: []flag.Flag{flag.PkgName, flag.PkgCode, flag.PkgSrcArchive, flag.PkgDeployArchive,
flag.PkgSrcChecksum, flag.PkgDeployChecksum, flag.PkgInsecure, flag.PkgBuildCmd,
flag.NamespacePackage, flag.NamespaceEnvironment, flag.SpecSave, flag.SpecDry},
flag.NamespacePackage, flag.SpecSave, flag.SpecDry},
})
getSrcCmd := &cobra.Command{
@@ -84,7 +84,7 @@ func Commands() *cobra.Command {
RunE: wrapper.Wrapper(List),
}
wrapper.SetFlags(listCmd, flag.FlagSet{
Optional: []flag.Flag{flag.PkgOrphan, flag.PkgStatus, flag.NamespacePackage},
Optional: []flag.Flag{flag.PkgOrphan, flag.PkgStatus, flag.NamespacePackage, flag.AllNamespaces},
})
infoCmd := &cobra.Command{
+26 -12
View File
@@ -63,9 +63,13 @@ func (opts *CreateSubCommand) run(input cli.Input) error {
}
}
pkgNamespace := input.String(flagkey.NamespacePackage)
envName := input.String(flagkey.PkgEnvironment)
envNamespace := input.String(flagkey.NamespaceEnvironment)
userProvidedNS, pkgNamespace, err := util.GetResourceNamespace(input, flagkey.NamespacePackage)
if err != nil {
return fv1.AggregateValidationErrors("Environment", err)
}
srcArchiveFiles := input.StringSlice(flagkey.PkgSrcArchive)
deployArchiveFiles := input.StringSlice(flagkey.PkgDeployArchive)
buildcmd := input.String(flagkey.PkgBuildCmd)
@@ -100,30 +104,30 @@ func (opts *CreateSubCommand) run(input cli.Input) error {
exists, err := fr.ExistsInSpecs(fv1.Environment{
ObjectMeta: metav1.ObjectMeta{
Name: envName,
Namespace: envNamespace,
Namespace: userProvidedNS,
},
})
if err != nil {
return err
}
if !exists {
console.Warn(fmt.Sprintf("Package '%v' references unknown Environment '%v', please create it before applying spec",
pkgName, envName))
console.Warn(fmt.Sprintf("Package '%s' references unknown Environment '%s' in Namespace '%s', please create it before applying spec",
pkgName, envName, userProvidedNS))
}
specDir = util.GetSpecDir(input)
specFile = fmt.Sprintf("package-%v.yaml", pkgName)
specFile = fmt.Sprintf("package-%s.yaml", pkgName)
}
_, err := CreatePackage(input, opts.Client(), pkgName, pkgNamespace, envName, envNamespace,
srcArchiveFiles, deployArchiveFiles, buildcmd, specDir, specFile, noZip)
_, err = CreatePackage(input, opts.Client(), pkgName, pkgNamespace, envName,
srcArchiveFiles, deployArchiveFiles, buildcmd, specDir, specFile, noZip, userProvidedNS)
return err
}
// TODO: get all necessary value from CLI input directly
func CreatePackage(input cli.Input, client client.Interface, pkgName string, pkgNamespace string, envName string, envNamespace string,
srcArchiveFiles []string, deployArchiveFiles []string, buildcmd string, specDir string, specFile string, noZip bool) (*metav1.ObjectMeta, error) {
func CreatePackage(input cli.Input, client client.Interface, pkgName string, pkgNamespace string, envName string,
srcArchiveFiles []string, deployArchiveFiles []string, buildcmd string, specDir string, specFile string, noZip bool, userProvidedNS string) (*metav1.ObjectMeta, error) {
insecure := input.Bool(flagkey.PkgInsecure)
deployChecksum := input.String(flagkey.PkgDeployChecksum)
@@ -131,10 +135,19 @@ func CreatePackage(input cli.Input, client client.Interface, pkgName string, pkg
pkgSpec := fv1.PackageSpec{
Environment: fv1.EnvironmentReference{
Namespace: envNamespace,
Namespace: pkgNamespace,
Name: envName,
},
}
if input.Bool(flagkey.SpecSave) || input.Bool(flagkey.SpecDry) {
pkgSpec = fv1.PackageSpec{
Environment: fv1.EnvironmentReference{
Namespace: userProvidedNS,
Name: envName,
},
}
}
var pkgStatus fv1.BuildStatus = fv1.BuildStatusSucceeded
if len(deployArchiveFiles) > 0 {
@@ -177,7 +190,7 @@ func CreatePackage(input cli.Input, client client.Interface, pkgName string, pkg
pkg := &fv1.Package{
ObjectMeta: metav1.ObjectMeta{
Name: pkgName,
Namespace: pkgNamespace,
Namespace: userProvidedNS,
},
Spec: pkgSpec,
Status: fv1.PackageStatus{
@@ -210,6 +223,7 @@ func CreatePackage(input cli.Input, client client.Interface, pkgName string, pkg
}
return &pkg.ObjectMeta, nil
} else {
pkg.ObjectMeta.Namespace = pkgNamespace
pkgMetadata, err := client.V1().Package().Create(pkg)
if err != nil {
return nil, errors.Wrap(err, "error creating package")
+7 -2
View File
@@ -22,6 +22,7 @@ import (
"github.com/pkg/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
fv1 "github.com/fission/fission/pkg/apis/core/v1"
"github.com/fission/fission/pkg/controller/client"
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
"github.com/fission/fission/pkg/fission-cli/cmd"
@@ -49,9 +50,13 @@ func (opts *DeleteSubCommand) do(input cli.Input) error {
return opts.run(input)
}
func (opts *DeleteSubCommand) complete(input cli.Input) error {
func (opts *DeleteSubCommand) complete(input cli.Input) (err error) {
opts.name = input.String(flagkey.PkgName)
opts.namespace = input.String(flagkey.NamespacePackage)
_, opts.namespace, err = util.GetResourceNamespace(input, flagkey.NamespacePackage)
if err != nil {
return fv1.AggregateValidationErrors("Environment", err)
}
opts.deleteOrphans = input.Bool(flagkey.PkgOrphan)
opts.force = input.Bool(flagkey.PkgForce)
+6 -2
View File
@@ -28,6 +28,7 @@ import (
"github.com/fission/fission/pkg/fission-cli/cmd"
pkgutil "github.com/fission/fission/pkg/fission-cli/cmd/package/util"
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
"github.com/fission/fission/pkg/fission-cli/util"
)
const (
@@ -58,9 +59,12 @@ func (opts *GetSubCommand) do(input cli.Input) error {
return opts.run(input)
}
func (opts *GetSubCommand) complete(input cli.Input) error {
func (opts *GetSubCommand) complete(input cli.Input) (err error) {
opts.name = input.String(flagkey.PkgName)
opts.namespace = input.String(flagkey.NamespacePackage)
_, opts.namespace, err = util.GetResourceNamespace(input, flagkey.NamespacePackage)
if err != nil {
return fv1.AggregateValidationErrors("Environment", err)
}
opts.output = input.String(flagkey.PkgOutput)
return nil
}
+8 -2
View File
@@ -22,10 +22,12 @@ import (
"github.com/pkg/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
fv1 "github.com/fission/fission/pkg/apis/core/v1"
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
"github.com/fission/fission/pkg/fission-cli/cmd"
pkgutil "github.com/fission/fission/pkg/fission-cli/cmd/package/util"
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
"github.com/fission/fission/pkg/fission-cli/util"
)
type InfoSubCommand struct {
@@ -46,9 +48,13 @@ func (opts *InfoSubCommand) do(input cli.Input) error {
return opts.run(input)
}
func (opts *InfoSubCommand) complete(input cli.Input) error {
func (opts *InfoSubCommand) complete(input cli.Input) (err error) {
opts.name = input.String(flagkey.PkgName)
opts.namespace = input.String(flagkey.NamespacePackage)
_, opts.namespace, err = util.GetResourceNamespace(input, flagkey.NamespacePackage)
if err != nil {
return fv1.AggregateValidationErrors("Environment", err)
}
return nil
}
+17 -6
View File
@@ -25,9 +25,11 @@ import (
"github.com/pkg/errors"
fv1 "github.com/fission/fission/pkg/apis/core/v1"
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
"github.com/fission/fission/pkg/fission-cli/cmd"
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
"github.com/fission/fission/pkg/fission-cli/util"
)
type ListSubCommand struct {
@@ -49,16 +51,25 @@ func (opts *ListSubCommand) do(input cli.Input) error {
return opts.run(input)
}
func (opts *ListSubCommand) complete(input cli.Input) error {
func (opts *ListSubCommand) complete(input cli.Input) (err error) {
// option for the user to list all orphan packages (not referenced by any function)
opts.listOrphans = input.Bool(flagkey.PkgOrphan)
opts.status = input.String(flagkey.PkgStatus)
opts.pkgNamespace = input.String(flagkey.NamespacePackage)
_, opts.pkgNamespace, err = util.GetResourceNamespace(input, flagkey.NamespacePackage)
if err != nil {
return fv1.AggregateValidationErrors("Environment", err)
}
return nil
}
func (opts *ListSubCommand) run(input cli.Input) error {
pkgList, err := opts.Client().V1().Package().List(opts.pkgNamespace)
func (opts *ListSubCommand) run(input cli.Input) (err error) {
var pkgList []fv1.Package
if input.Bool(flagkey.AllNamespaces) {
pkgList, err = opts.Client().V1().Package().List("")
} else {
pkgList, err = opts.Client().V1().Package().List(opts.pkgNamespace)
}
if err != nil {
return err
}
@@ -69,7 +80,7 @@ func (opts *ListSubCommand) run(input cli.Input) error {
})
w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)
fmt.Fprintf(w, "%v\t%v\t%v\t%v\n", "NAME", "BUILD_STATUS", "ENV", "LASTUPDATEDAT")
fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\n", "NAME", "BUILD_STATUS", "ENV", "LASTUPDATEDAT", "NAMESPACE")
for _, pkg := range pkgList {
show := true
@@ -87,7 +98,7 @@ func (opts *ListSubCommand) run(input cli.Input) error {
show = false
}
if show {
fmt.Fprintf(w, "%v\t%v\t%v\t%v\n", pkg.ObjectMeta.Name, pkg.Status.BuildStatus, pkg.Spec.Environment.Name, pkg.Status.LastUpdateTimestamp.Format(time.RFC822))
fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\n", pkg.ObjectMeta.Name, pkg.Status.BuildStatus, pkg.Spec.Environment.Name, pkg.Status.LastUpdateTimestamp.Format(time.RFC822), pkg.ObjectMeta.Namespace)
}
}
+6 -2
View File
@@ -26,6 +26,7 @@ import (
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
"github.com/fission/fission/pkg/fission-cli/cmd"
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
"github.com/fission/fission/pkg/fission-cli/util"
)
type RebuildSubCommand struct {
@@ -46,9 +47,12 @@ func (opts *RebuildSubCommand) do(input cli.Input) error {
return opts.run(input)
}
func (opts *RebuildSubCommand) complete(input cli.Input) error {
func (opts *RebuildSubCommand) complete(input cli.Input) (err error) {
opts.name = input.String(flagkey.PkgName)
opts.namespace = input.String(flagkey.NamespacePackage)
_, opts.namespace, err = util.GetResourceNamespace(input, flagkey.NamespacePackage)
if err != nil {
return fv1.AggregateValidationErrors("Environment", err)
}
return nil
}
+6 -9
View File
@@ -29,6 +29,7 @@ import (
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
"github.com/fission/fission/pkg/fission-cli/cmd"
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
"github.com/fission/fission/pkg/fission-cli/util"
)
type UpdateSubCommand struct {
@@ -50,9 +51,12 @@ func (opts *UpdateSubCommand) do(input cli.Input) error {
return opts.run(input)
}
func (opts *UpdateSubCommand) complete(input cli.Input) error {
func (opts *UpdateSubCommand) complete(input cli.Input) (err error) {
opts.pkgName = input.String(flagkey.PkgName)
opts.pkgNamespace = input.String(flagkey.NamespacePackage)
_, opts.pkgNamespace, err = util.GetResourceNamespace(input, flagkey.NamespacePackage)
if err != nil {
return fv1.AggregateValidationErrors("Environment", err)
}
opts.force = input.Bool(flagkey.PkgForce)
return nil
}
@@ -94,7 +98,6 @@ func (opts *UpdateSubCommand) run(input cli.Input) error {
func UpdatePackage(input cli.Input, client client.Interface, pkg *fv1.Package) (*metav1.ObjectMeta, error) {
envName := input.String(flagkey.PkgEnvironment)
envNamespace := input.String(flagkey.NamespaceEnvironment)
srcArchiveFiles := input.StringSlice(flagkey.PkgSrcArchive)
deployArchiveFiles := input.StringSlice(flagkey.PkgDeployArchive)
buildcmd := input.String(flagkey.PkgBuildCmd)
@@ -119,12 +122,6 @@ func UpdatePackage(input cli.Input, client client.Interface, pkg *fv1.Package) (
needToUpdate = true
}
if input.IsSet(flagkey.NamespaceEnvironment) {
pkg.Spec.Environment.Namespace = envNamespace
needToRebuild = true
needToUpdate = true
}
if input.IsSet(flagkey.PkgBuildCmd) {
pkg.Spec.BuildCommand = buildcmd
needToRebuild = true
+68 -1
View File
@@ -62,6 +62,67 @@ func Apply(input cli.Input) error {
func (opts *ApplySubCommand) do(input cli.Input) error {
return opts.run(input)
}
// insertNamespace inserts the Namespace value if it was not provided at the time of `spec save`.
// we make sure that all component of a resource should be present in the same Namespace. i.e.
// Function's env and package should be present in same namespace
func (opts *ApplySubCommand) insertNamespace(input cli.Input, fr *FissionResources) error {
result := utils.MultiErrorWithFormat()
_, currentNS, err := util.GetResourceNamespace(input, flagkey.NamespaceEnvironment)
if err != nil {
return fv1.AggregateValidationErrors("Environment", err)
}
for i := range fr.Functions {
if fr.Functions[i].Namespace == "" || input.Bool(flagkey.ForceNamespace) {
fr.Functions[i].Namespace = currentNS
fr.Functions[i].Spec.Package.PackageRef.Namespace = currentNS
fr.Functions[i].Spec.Environment.Namespace = currentNS
for j := range fr.Functions[i].Spec.ConfigMaps {
fr.Functions[i].Spec.ConfigMaps[j].Namespace = currentNS
}
for j := range fr.Functions[i].Spec.Secrets {
fr.Functions[i].Spec.Secrets[j].Namespace = currentNS
}
}
}
for i := range fr.Environments {
if fr.Environments[i].Namespace == "" || input.Bool(flagkey.ForceNamespace) {
fr.Environments[i].Namespace = currentNS
}
}
for i := range fr.Packages {
if fr.Packages[i].Namespace == "" || input.Bool(flagkey.ForceNamespace) {
fr.Packages[i].Namespace = currentNS
fr.Packages[i].Spec.Environment.Namespace = currentNS
fr.Packages[i].ObjectMeta.Namespace = currentNS
}
}
for i := range fr.HttpTriggers {
if fr.HttpTriggers[i].Namespace == "" || input.Bool(flagkey.ForceNamespace) {
fr.HttpTriggers[i].Namespace = currentNS
}
}
for i := range fr.MessageQueueTriggers {
if fr.MessageQueueTriggers[i].Namespace == "" || input.Bool(flagkey.ForceNamespace) {
fr.MessageQueueTriggers[i].Namespace = currentNS
}
}
for i := range fr.TimeTriggers {
if fr.TimeTriggers[i].Namespace == "" || input.Bool(flagkey.ForceNamespace) {
fr.TimeTriggers[i].Namespace = currentNS
}
}
for i := range fr.KubernetesWatchTriggers {
if fr.KubernetesWatchTriggers[i].Namespace == "" || input.Bool(flagkey.ForceNamespace) {
fr.KubernetesWatchTriggers[i].Namespace = currentNS
}
}
return result.ErrorOrNil()
}
func (opts *ApplySubCommand) run(input cli.Input) error {
@@ -117,8 +178,13 @@ func (opts *ApplySubCommand) run(input cli.Input) error {
return errors.Wrap(err, "error reading specs")
}
err = opts.insertNamespace(input, fr)
if err != nil {
return errors.Wrap(err, "error reading specs")
}
if validateSpecs {
err = Validate(input)
err = validateForApply(input, fr)
if err != nil {
return errors.Wrap(err, "abort applying resources")
}
@@ -616,6 +682,7 @@ func applyPackages(fclient client.Interface, fr *FissionResources, delete bool,
for _, o := range fr.Packages {
// apply deploymentConfig so we can find our objects on future apply invocations
applyDeploymentConfig(&o.ObjectMeta, fr)
console.Verbose(2, fmt.Sprintf("Package is here '%s','%s','%s','%s'", o.Namespace, o.Name, o.Spec.Environment.Namespace, o.Spec.Environment.Name))
// index desired state
desired[mapKey(&o.ObjectMeta)] = true
+4 -3
View File
@@ -48,7 +48,8 @@ func Commands() *cobra.Command {
RunE: wrapper.Wrapper(Apply),
}
wrapper.SetFlags(applyCmd, flag.FlagSet{
Optional: []flag.Flag{flag.SpecDir, flag.SpecIgnore, flag.SpecDelete, flag.SpecWait, flag.SpecWatch, flag.SpecValidation, flag.SpecApplyCommitLabel, flag.SpecAllowConflicts},
Optional: []flag.Flag{flag.SpecDir, flag.SpecIgnore, flag.SpecDelete, flag.SpecWait, flag.SpecWatch,
flag.SpecValidation, flag.SpecApplyCommitLabel, flag.SpecAllowConflicts, flag.ForceNamespace},
})
destroyCmd := &cobra.Command{
@@ -57,7 +58,7 @@ func Commands() *cobra.Command {
RunE: wrapper.Wrapper(Destroy),
}
wrapper.SetFlags(destroyCmd, flag.FlagSet{
Optional: []flag.Flag{flag.SpecDir, flag.SpecIgnore},
Optional: []flag.Flag{flag.SpecDir, flag.SpecIgnore, flag.ForceDelete},
})
listCmd := &cobra.Command{
@@ -66,7 +67,7 @@ func Commands() *cobra.Command {
RunE: wrapper.Wrapper(List),
}
wrapper.SetFlags(listCmd, flag.FlagSet{
Optional: []flag.Flag{flag.SpecDeployID, flag.SpecDir, flag.SpecIgnore},
Optional: []flag.Flag{flag.SpecDeployID, flag.SpecDir, flag.SpecIgnore, flag.AllNamespaces},
})
command := &cobra.Command{
+243 -6
View File
@@ -17,12 +17,19 @@ limitations under the License.
package spec
import (
"fmt"
"strings"
"github.com/pkg/errors"
fv1 "github.com/fission/fission/pkg/apis/core/v1"
"github.com/fission/fission/pkg/controller/client"
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
"github.com/fission/fission/pkg/fission-cli/cmd"
"github.com/fission/fission/pkg/fission-cli/console"
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
"github.com/fission/fission/pkg/fission-cli/util"
"github.com/fission/fission/pkg/utils"
)
type DestroySubCommand struct {
@@ -49,12 +56,26 @@ func (opts *DestroySubCommand) run(input cli.Input) error {
return errors.Wrap(err, "error reading specs")
}
// set desired state to nothing, but keep the UID so "apply" can find it
emptyFr := FissionResources{}
emptyFr.DeploymentConfig = fr.DeploymentConfig
if !input.Bool(flagkey.ForceDelete) {
err = opts.insertNSToResource(input, fr)
if err != nil {
return errors.Wrap(err, "error adding namespace")
}
} else {
// if force delete set to true we fetch all resources with our deployment ID and delete them
// set desired state to nothing, but keep the UID so "apply" can find it
emptyFr := FissionResources{}
emptyFr.DeploymentConfig = fr.DeploymentConfig
// "apply" the empty state
err = deleteResources(opts.Client(), &emptyFr)
// "apply" the empty state
err = forceDeleteResources(opts.Client(), &emptyFr)
if err != nil {
return errors.Wrap(err, "error deleting resources")
}
return nil
}
forceDelete := input.Bool(flagkey.ForceDelete)
err = deleteResources(opts.Client(), fr, forceDelete)
if err != nil {
return errors.Wrap(err, "error deleting resources")
}
@@ -62,7 +83,7 @@ func (opts *DestroySubCommand) run(input cli.Input) error {
return nil
}
func deleteResources(fclient client.Interface, fr *FissionResources) error {
func forceDeleteResources(fclient client.Interface, fr *FissionResources) error {
var err error
@@ -103,3 +124,219 @@ func deleteResources(fclient client.Interface, fr *FissionResources) error {
return nil
}
// insertNSToResource provides a namespace to all resource which don't have a namespace specified
// in resource
func (opts *DestroySubCommand) insertNSToResource(input cli.Input, fr *FissionResources) error {
result := utils.MultiErrorWithFormat()
_, currentNS, err := util.GetResourceNamespace(input, flagkey.NamespaceEnvironment)
if err != nil {
return fv1.AggregateValidationErrors("Environment", err)
}
for i := range fr.Functions {
if fr.Functions[i].Namespace == "" {
fr.Functions[i].Namespace = currentNS
}
}
for i := range fr.Environments {
if fr.Environments[i].Namespace == "" {
fr.Environments[i].Namespace = currentNS
}
}
for i := range fr.Packages {
if fr.Packages[i].Namespace == "" {
fr.Packages[i].Namespace = currentNS
}
}
for i := range fr.HttpTriggers {
if fr.HttpTriggers[i].Namespace == "" {
fr.HttpTriggers[i].Namespace = currentNS
}
}
for i := range fr.MessageQueueTriggers {
if fr.MessageQueueTriggers[i].Namespace == "" {
fr.MessageQueueTriggers[i].Namespace = currentNS
}
}
for i := range fr.TimeTriggers {
if fr.TimeTriggers[i].Namespace == "" {
fr.TimeTriggers[i].Namespace = currentNS
}
}
for i := range fr.KubernetesWatchTriggers {
if fr.KubernetesWatchTriggers[i].Namespace == "" {
fr.KubernetesWatchTriggers[i].Namespace = currentNS
}
}
return result.ErrorOrNil()
}
func deleteResources(fclient client.Interface, fr *FissionResources, forceDelete bool) error {
var err error
err = destroyHTTPTriggers(fclient, fr)
if err != nil {
return errors.Wrap(err, "HTTPTrigger delete failed")
}
err = destroyKubernetesWatchTriggers(fclient, fr)
if err != nil {
return errors.Wrap(err, "KubernetesWatchTrigger delete failed")
}
err = destroyTimeTriggers(fclient, fr)
if err != nil {
return errors.Wrap(err, "TimeTrigger delete failed")
}
err = destroyMessageQueueTriggers(fclient, fr)
if err != nil {
return errors.Wrap(err, "MessageQueueTrigger delete failed")
}
err = destroyFunctions(fclient, fr)
if err != nil {
return errors.Wrap(err, "function delete failed")
}
err = destroyPackages(fclient, fr)
if err != nil {
return errors.Wrap(err, "package delete failed")
}
err = destroyEnvironments(fclient, fr)
if err != nil {
return errors.Wrap(err, "environment delete failed")
}
return nil
}
func destroyHTTPTriggers(fclient client.Interface, fr *FissionResources) error {
for _, o := range fr.HttpTriggers {
err := fclient.V1().HTTPTrigger().Delete(&o.ObjectMeta)
if err != nil && strings.Contains(err.Error(), "not found") {
console.Verbose(2, fmt.Sprintf("could not delete httptrigger: %s Namespace: %s", o.ObjectMeta.Name, o.ObjectMeta.Namespace))
err = nil
continue
} else if err != nil {
return err
}
fmt.Printf("Deleted %s %s/%s\n", o.TypeMeta.Kind, o.ObjectMeta.Namespace, o.ObjectMeta.Name)
}
return nil
}
func destroyKubernetesWatchTriggers(fclient client.Interface, fr *FissionResources) error {
for _, o := range fr.KubernetesWatchTriggers {
err := fclient.V1().KubeWatcher().Delete(&o.ObjectMeta)
if err != nil && strings.Contains(err.Error(), "not found") {
console.Verbose(2, fmt.Sprintf("could not delete watch: %s Namespace: %s", o.ObjectMeta.Name, o.ObjectMeta.Namespace))
err = nil
continue
} else if err != nil {
return err
}
fmt.Printf("Deleted %s %s/%s\n", o.TypeMeta.Kind, o.ObjectMeta.Namespace, o.ObjectMeta.Name)
}
return nil
}
func destroyTimeTriggers(fclient client.Interface, fr *FissionResources) error {
for _, o := range fr.TimeTriggers {
err := fclient.V1().TimeTrigger().Delete(&o.ObjectMeta)
if err != nil && strings.Contains(err.Error(), "not found") {
console.Verbose(2, fmt.Sprintf("could not delete Time trigger: %s Namespace: %s", o.ObjectMeta.Name, o.ObjectMeta.Namespace))
err = nil
continue
} else if err != nil {
return err
}
fmt.Printf("Deleted %s %s/%s\n", o.TypeMeta.Kind, o.ObjectMeta.Namespace, o.ObjectMeta.Name)
}
return nil
}
func destroyMessageQueueTriggers(fclient client.Interface, fr *FissionResources) error {
for _, o := range fr.MessageQueueTriggers {
err := fclient.V1().MessageQueueTrigger().Delete(&o.ObjectMeta)
if err != nil && strings.Contains(err.Error(), "not found") {
console.Verbose(2, fmt.Sprintf("could not delete Message trigger: %s Namespace: %s", o.ObjectMeta.Name, o.ObjectMeta.Namespace))
err = nil
continue
} else if err != nil {
return err
}
fmt.Printf("Deleted %s %s/%s\n", o.TypeMeta.Kind, o.ObjectMeta.Namespace, o.ObjectMeta.Name)
}
return nil
}
func destroyFunctions(fclient client.Interface, fr *FissionResources) error {
for _, o := range fr.Functions {
err := fclient.V1().Function().Delete(&o.ObjectMeta)
if err != nil && strings.Contains(err.Error(), "not found") {
console.Verbose(2, fmt.Sprintf("could not delete Functions: %s Namespace: %s", o.ObjectMeta.Name, o.ObjectMeta.Namespace))
err = nil
continue
} else if err != nil {
return err
}
fmt.Printf("Deleted %s %s/%s\n", o.TypeMeta.Kind, o.ObjectMeta.Namespace, o.ObjectMeta.Name)
}
return nil
}
func destroyPackages(fclient client.Interface, fr *FissionResources) error {
for _, o := range fr.Packages {
err := fclient.V1().Package().Delete(&o.ObjectMeta)
if err != nil && strings.Contains(err.Error(), "not found") {
console.Verbose(2, fmt.Sprintf("could not delete Package: %s Namespace: %s", o.ObjectMeta.Name, o.ObjectMeta.Namespace))
err = nil
continue
} else if err != nil {
return err
}
fmt.Printf("Deleted %s %s/%s\n", o.TypeMeta.Kind, o.ObjectMeta.Namespace, o.ObjectMeta.Name)
}
return nil
}
func destroyEnvironments(fclient client.Interface, fr *FissionResources) error {
for _, o := range fr.Environments {
err := fclient.V1().Environment().Delete(&o.ObjectMeta)
if err != nil && strings.Contains(err.Error(), "not found") {
console.Verbose(2, fmt.Sprintf("could not delete Env: %s Namespace: %s", o.ObjectMeta.Name, o.ObjectMeta.Namespace))
err = nil
continue
} else if err != nil {
return err
}
fmt.Printf("Deleted %s %s/%s\n", o.TypeMeta.Kind, o.ObjectMeta.Namespace, o.ObjectMeta.Name)
}
return nil
}
+61 -34
View File
@@ -60,63 +60,90 @@ func (opts *ListSubCommand) run(input cli.Input) error {
deployID = fr.DeploymentConfig.UID
}
allfn, err := getAllFunctions(opts.Client())
_, currentNS, err := util.GetResourceNamespace(input, flagkey.NamespaceEnvironment)
if err != nil {
return errors.Wrap(err, "error getting Functions from all namespaces")
return fv1.AggregateValidationErrors("Environment", err)
}
if input.Bool(flagkey.AllNamespaces) {
return opts.getResource(input, "", deployID)
} else {
return opts.getResource(input, currentNS, deployID)
}
}
func (opts *ListSubCommand) getResource(input cli.Input, namespace string, deployID string) (err error) {
var allfn []fv1.Function
printNS := namespace
if printNS == "" {
printNS = "all"
}
allfn, err = getAllFunctions(opts.Client(), namespace)
if err != nil {
return errors.Wrap(err, fmt.Sprintf("error getting Functions from %s namespaces", printNS))
}
specfns := getAppliedFunctions(allfn, deployID)
ShowFunctions(specfns)
allenvs, err := getAllEnvironments(opts.Client())
var allenvs []fv1.Environment
allenvs, err = getAllEnvironments(opts.Client(), namespace)
if err != nil {
return errors.Wrap(err, "error getting Environments from all namespaces")
return errors.Wrap(err, fmt.Sprintf("error getting Environments from %s namespaces", printNS))
}
specenvs := getAppliedEnvironments(allenvs, deployID)
ShowEnvironments(specenvs)
pkglists, err := getAllPackages(opts.Client())
var pkglists []fv1.Package
pkglists, err = getAllPackages(opts.Client(), namespace)
if err != nil {
return errors.Wrap(err, "error getting Packages from all namespaces")
return errors.Wrap(err, fmt.Sprintf("error getting Packages from %s namespaces", printNS))
}
specPkgs := getAppliedPackages(pkglists, deployID)
ShowPackages(specPkgs)
canaryCfgs, err := getAllCanaryConfigs(opts.Client())
var canaryCfgs []fv1.CanaryConfig
canaryCfgs, err = getAllCanaryConfigs(opts.Client(), namespace)
if err != nil {
return errors.Wrap(err, "error getting Canary Config from all namespaces")
return errors.Wrap(err, fmt.Sprintf("error getting Canary Config from %s namespaces", printNS))
}
specCanaryCfgs := getAppliedCanaryConfigs(canaryCfgs, deployID)
ShowCanaryConfigs(specCanaryCfgs)
hts, err := getAllHTTPTriggers(opts.Client())
var hts []fv1.HTTPTrigger
hts, err = getAllHTTPTriggers(opts.Client(), namespace)
if err != nil {
return errors.Wrap(err, "error getting HTTP Triggers from all namespaces")
return errors.Wrap(err, fmt.Sprintf("error getting HTTP Triggers from %s namespaces", printNS))
}
specHTTPTriggers := getAppliedHTTPTriggers(hts, deployID)
ShowHTTPTriggers(specHTTPTriggers)
mqts, err := getAllMessageQueueTriggers(opts.Client(), input.String(flagkey.MqtMQType))
var mqts []fv1.MessageQueueTrigger
mqts, err = getAllMessageQueueTriggers(opts.Client(), input.String(flagkey.MqtMQType), namespace)
if err != nil {
return errors.Wrap(err, "error getting MessageQueue Triggers from all namespaces")
return errors.Wrap(err, fmt.Sprintf("error getting MessageQueue Triggers from %s namespaces", printNS))
}
specMessageQueueTriggers := getAppliedMessageQueueTriggers(mqts, deployID)
ShowMQTriggers(specMessageQueueTriggers)
tts, err := getAllTimeTriggers(opts.Client())
var tts []fv1.TimeTrigger
tts, err = getAllTimeTriggers(opts.Client(), namespace)
if err != nil {
return errors.Wrap(err, "error getting Time Triggers from all namespaces")
return errors.Wrap(err, fmt.Sprintf("error getting Time Triggers from %s namespaces", printNS))
}
specTimeTriggers := getAppliedTimeTriggers(tts, deployID)
ShowTimeTriggers(specTimeTriggers)
kws, err := getAllKubeWatchTriggers(opts.Client())
var kws []fv1.KubernetesWatchTrigger
kws, err = getAllKubeWatchTriggers(opts.Client(), namespace)
if err != nil {
return errors.Wrap(err, "error getting Kube Watchers from all namespaces")
return errors.Wrap(err, fmt.Sprintf("error getting Kube Watchers from %s namespaces", printNS))
}
specKubeWatchers := getSpecKubeWatchers(kws, deployID)
ShowAppliedKubeWatchers(specKubeWatchers)
return nil
return err
}
func getAppliedFunctions(fns []fv1.Function, deployID string) []fv1.Function {
@@ -392,9 +419,9 @@ func ShowAppliedKubeWatchers(ws []fv1.KubernetesWatchTrigger) {
}
}
// getAllFunctions get lists of functions in all namespaces
func getAllFunctions(client client.Interface) ([]fv1.Function, error) {
fns, err := client.V1().Function().List("")
// getAllFunctions get lists of functions in provided namespaces
func getAllFunctions(client client.Interface, namespace string) ([]fv1.Function, error) {
fns, err := client.V1().Function().List(namespace)
if err != nil {
return nil, errors.Errorf("Unable to get Functions %v", err.Error())
}
@@ -402,8 +429,8 @@ func getAllFunctions(client client.Interface) ([]fv1.Function, error) {
}
// getAllEnvironments get lists of environments in all namespaces
func getAllEnvironments(client client.Interface) ([]fv1.Environment, error) {
envs, err := client.V1().Environment().List("")
func getAllEnvironments(client client.Interface, namespace string) ([]fv1.Environment, error) {
envs, err := client.V1().Environment().List(namespace)
if err != nil {
return nil, errors.Errorf("Unable to get Environments %v", err.Error())
}
@@ -411,8 +438,8 @@ func getAllEnvironments(client client.Interface) ([]fv1.Environment, error) {
}
// getAllPackages get lists of packages in all namespaces
func getAllPackages(client client.Interface) ([]fv1.Package, error) {
pkgList, err := client.V1().Package().List("")
func getAllPackages(client client.Interface, namespace string) ([]fv1.Package, error) {
pkgList, err := client.V1().Package().List(namespace)
if err != nil {
return nil, errors.Errorf("Unable to get Packages %v", err.Error())
}
@@ -420,8 +447,8 @@ func getAllPackages(client client.Interface) ([]fv1.Package, error) {
}
// getAllCanaryConfigs get lists of canary configs in all namespaces
func getAllCanaryConfigs(client client.Interface) ([]fv1.CanaryConfig, error) {
canaryCfgs, err := client.V1().CanaryConfig().List("")
func getAllCanaryConfigs(client client.Interface, namespace string) ([]fv1.CanaryConfig, error) {
canaryCfgs, err := client.V1().CanaryConfig().List(namespace)
if err != nil {
return nil, errors.Errorf("Unable to get Canary Configs %v", err.Error())
}
@@ -429,8 +456,8 @@ func getAllCanaryConfigs(client client.Interface) ([]fv1.CanaryConfig, error) {
}
// getAllHTTPTriggers get lists of HTTP Triggers in all namespaces
func getAllHTTPTriggers(client client.Interface) ([]fv1.HTTPTrigger, error) {
hts, err := client.V1().HTTPTrigger().List("")
func getAllHTTPTriggers(client client.Interface, namespace string) ([]fv1.HTTPTrigger, error) {
hts, err := client.V1().HTTPTrigger().List(namespace)
if err != nil {
return nil, errors.Errorf("Unable to get HTTP Triggers %v", err.Error())
}
@@ -438,8 +465,8 @@ func getAllHTTPTriggers(client client.Interface) ([]fv1.HTTPTrigger, error) {
}
// getAllMessageQueueTriggers get lists of MessageQueue Triggers in all namespaces
func getAllMessageQueueTriggers(client client.Interface, mqttype string) ([]fv1.MessageQueueTrigger, error) {
mqts, err := client.V1().MessageQueueTrigger().List(mqttype, "")
func getAllMessageQueueTriggers(client client.Interface, mqttype string, namespace string) ([]fv1.MessageQueueTrigger, error) {
mqts, err := client.V1().MessageQueueTrigger().List(mqttype, namespace)
if err != nil {
return nil, errors.Errorf("Unable to get MessageQueue Triggers %v", err.Error())
}
@@ -447,8 +474,8 @@ func getAllMessageQueueTriggers(client client.Interface, mqttype string) ([]fv1.
}
// getAllTimeTriggers get lists of Time Triggers in all namespaces
func getAllTimeTriggers(client client.Interface) ([]fv1.TimeTrigger, error) {
tts, err := client.V1().TimeTrigger().List("")
func getAllTimeTriggers(client client.Interface, namespace string) ([]fv1.TimeTrigger, error) {
tts, err := client.V1().TimeTrigger().List(namespace)
if err != nil {
return nil, errors.Errorf("Unable to get Time Triggers %v", err.Error())
}
@@ -456,8 +483,8 @@ func getAllTimeTriggers(client client.Interface) ([]fv1.TimeTrigger, error) {
}
// getAllKubeWatchTriggers get lists of Kube Watchers in all namespaces
func getAllKubeWatchTriggers(client client.Interface) ([]fv1.KubernetesWatchTrigger, error) {
ws, err := client.V1().KubeWatcher().List("")
func getAllKubeWatchTriggers(client client.Interface, namespace string) ([]fv1.KubernetesWatchTrigger, error) {
ws, err := client.V1().KubeWatcher().List(namespace)
if err != nil {
return nil, errors.Errorf("Unable to get Kube Watchers %v", err.Error())
}
+1 -1
View File
@@ -491,7 +491,7 @@ func (fr *FissionResources) Validate(input cli.Input) ([]string, error) {
for _, f := range fr.Functions {
if _, ok := environments[fmt.Sprintf("%s:%s", f.Spec.Environment.Name, f.Spec.Environment.Namespace)]; !ok {
warnings = append(warnings, "Environment %s is referenced in function %s but not declared in specs", f.Spec.Environment.Name, f.ObjectMeta.Name)
warnings = append(warnings, fmt.Sprintf("Environment %s is referenced in function %s but not declared in specs", f.Spec.Environment.Name, f.ObjectMeta.Name))
}
strategy := f.Spec.InvokeStrategy.ExecutionStrategy
if strategy.ExecutorType == fv1.ExecutorTypeNewdeploy && strategy.SpecializationTimeout < fv1.DefaultSpecializationTimeOut {
+26 -14
View File
@@ -48,17 +48,29 @@ func Validate(input cli.Input) error {
}
func (opts *ValidateSubCommand) do(input cli.Input) error {
return opts.run(input)
return opts.run(input, nil)
}
func (opts *ValidateSubCommand) run(input cli.Input) error {
func validateForApply(input cli.Input, fr *FissionResources) error {
return (&ValidateSubCommand{}).doValidateForApply(input, fr)
}
func (opts *ValidateSubCommand) doValidateForApply(input cli.Input, fr *FissionResources) error {
return opts.run(input, fr)
}
func (opts *ValidateSubCommand) run(input cli.Input, fr *FissionResources) (err error) {
// this will error on parse errors and on duplicates
specDir := util.GetSpecDir(input)
specIgnore := util.GetSpecIgnore(input)
fr, err := ReadSpecs(specDir, specIgnore, false)
if err != nil {
return errors.Wrap(err, "error reading specs")
// If the call for validate is from apply spec we already have a parsed fission resource
if fr == nil {
fr, err = ReadSpecs(specDir, specIgnore, false)
if err != nil {
return errors.Wrap(err, "error reading specs")
}
}
console.Infof("DeployUID: %v", fr.DeploymentConfig.UID)
@@ -72,7 +84,7 @@ func (opts *ValidateSubCommand) run(input cli.Input) error {
return errors.Wrap(err, "error validating specs")
}
err = resourceConflictCheck(opts.Client(), fr, input.Bool(flagkey.SpecAllowConflicts))
err = resourceConflictCheck(opts.Client(), fr, input.Bool(flagkey.SpecAllowConflicts), "")
if err != nil {
return errors.Wrap(err, "name conflict error")
}
@@ -90,11 +102,11 @@ func (opts *ValidateSubCommand) run(input cli.Input) error {
// the same name is already present in the same cluster namespace.
// If a same name resource exists in the same namespace, a name
// conflict error will be returned.
func resourceConflictCheck(c client.Interface, fr *FissionResources, specAllowConflicts bool) error {
func resourceConflictCheck(c client.Interface, fr *FissionResources, specAllowConflicts bool, namespace string) error {
deployUID := fr.DeploymentConfig.UID
result := utils.MultiErrorWithFormat()
fnList, err := getAllFunctions(c)
fnList, err := getAllFunctions(c, namespace)
if err != nil {
return errors.Errorf("Unable to get Functions %v", err.Error())
}
@@ -107,7 +119,7 @@ func resourceConflictCheck(c client.Interface, fr *FissionResources, specAllowCo
}
}
envList, err := getAllEnvironments(c)
envList, err := getAllEnvironments(c, namespace)
if err != nil {
return errors.Errorf("Unable to get Environments %v", err.Error())
}
@@ -120,7 +132,7 @@ func resourceConflictCheck(c client.Interface, fr *FissionResources, specAllowCo
}
}
pkgList, err := getAllPackages(c)
pkgList, err := getAllPackages(c, namespace)
if err != nil {
return errors.Errorf("Unable to get Packages %v", err.Error())
}
@@ -133,7 +145,7 @@ func resourceConflictCheck(c client.Interface, fr *FissionResources, specAllowCo
}
}
httptriggerList, err := getAllHTTPTriggers(c)
httptriggerList, err := getAllHTTPTriggers(c, namespace)
if err != nil {
return errors.Errorf("Unable to get HTTPTrigger %v", err.Error())
}
@@ -146,7 +158,7 @@ func resourceConflictCheck(c client.Interface, fr *FissionResources, specAllowCo
}
}
mqtriggerList, err := getAllMessageQueueTriggers(c, "")
mqtriggerList, err := getAllMessageQueueTriggers(c, "", namespace)
if err != nil {
return errors.Errorf("Unable to get Message Queue Trigger %v", err.Error())
}
@@ -159,7 +171,7 @@ func resourceConflictCheck(c client.Interface, fr *FissionResources, specAllowCo
}
}
timetriggerList, err := getAllTimeTriggers(c)
timetriggerList, err := getAllTimeTriggers(c, namespace)
if err != nil {
return errors.Errorf("Unable to get Time Trigger %v", err.Error())
}
@@ -172,7 +184,7 @@ func resourceConflictCheck(c client.Interface, fr *FissionResources, specAllowCo
}
}
kubewatchtriggerList, err := getAllKubeWatchTriggers(c)
kubewatchtriggerList, err := getAllKubeWatchTriggers(c, namespace)
if err != nil {
return errors.Errorf("Unable to get Kubernetes Watch Trigger %v", err.Error())
}
+1 -1
View File
@@ -64,7 +64,7 @@ func Commands() *cobra.Command {
RunE: wrapper.Wrapper(List),
}
wrapper.SetFlags(listCmd, flag.FlagSet{
Optional: []flag.Flag{flag.NamespaceTrigger},
Optional: []flag.Flag{flag.NamespaceTrigger, flag.AllNamespaces},
})
showCmd := &cobra.Command{
+19 -7
View File
@@ -53,7 +53,7 @@ func (opts *CreateSubCommand) do(input cli.Input) error {
return opts.run(input)
}
func (opts *CreateSubCommand) complete(input cli.Input) error {
func (opts *CreateSubCommand) complete(input cli.Input) (err error) {
name := input.String(flagkey.TtName)
if len(name) == 0 {
id, err := uuid.NewV4()
@@ -68,7 +68,10 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
return errors.New("Need a function name to create a trigger, use --function")
}
fnNamespace := input.String(flagkey.NamespaceFunction)
userProvidedNS, fnNamespace, err := util.GetResourceNamespace(input, flagkey.NamespaceFunction)
if err != nil {
return errors.Wrap(err, "error in deleting function ")
}
cronSpec := input.String(flagkey.TtCron)
if len(cronSpec) == 0 {
@@ -86,7 +89,7 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
exists, err := fr.ExistsInSpecs(fv1.Function{
ObjectMeta: metav1.ObjectMeta{
Name: fnName,
Namespace: fnNamespace,
Namespace: userProvidedNS,
},
})
if err != nil {
@@ -98,11 +101,20 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
}
}
opts.trigger = &fv1.TimeTrigger{
ObjectMeta: metav1.ObjectMeta{
m := metav1.ObjectMeta{
Name: name,
Namespace: fnNamespace,
}
if input.Bool(flagkey.SpecSave) || input.Bool(flagkey.SpecDry) {
m = metav1.ObjectMeta{
Name: name,
Namespace: fnNamespace,
},
Namespace: userProvidedNS,
}
}
opts.trigger = &fv1.TimeTrigger{
ObjectMeta: m,
Spec: fv1.TimeTriggerSpec{
Cron: cronSpec,
FunctionReference: fv1.FunctionReference{
+8 -3
View File
@@ -36,13 +36,18 @@ func Delete(input cli.Input) error {
return (&DeleteSubCommand{}).do(input)
}
func (opts *DeleteSubCommand) do(input cli.Input) error {
func (opts *DeleteSubCommand) do(input cli.Input) (err error) {
_, namespace, err := util.GetResourceNamespace(input, flagkey.NamespaceTrigger)
if err != nil {
return errors.Wrap(err, "error in deleting function ")
}
m := &metav1.ObjectMeta{
Name: input.String(flagkey.TtName),
Namespace: input.String(flagkey.NamespaceTrigger),
Namespace: namespace,
}
err := opts.Client().V1().TimeTrigger().Delete(m)
err = opts.Client().V1().TimeTrigger().Delete(m)
if err != nil {
if input.Bool(flagkey.IgnoreNotFound) && util.IsNotFound(err) {
return nil
+15 -3
View File
@@ -23,9 +23,11 @@ import (
"github.com/pkg/errors"
v1 "github.com/fission/fission/pkg/apis/core/v1"
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
"github.com/fission/fission/pkg/fission-cli/cmd"
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
"github.com/fission/fission/pkg/fission-cli/util"
)
type ListSubCommand struct {
@@ -36,9 +38,19 @@ func List(input cli.Input) error {
return (&ListSubCommand{}).do(input)
}
func (opts *ListSubCommand) do(input cli.Input) error {
ttNs := input.String(flagkey.NamespaceTrigger)
tts, err := opts.Client().V1().TimeTrigger().List(ttNs)
func (opts *ListSubCommand) do(input cli.Input) (err error) {
_, ttNs, err := util.GetResourceNamespace(input, flagkey.NamespaceTrigger)
if err != nil {
return errors.Wrap(err, "error in deleting function ")
}
var tts []v1.TimeTrigger
if input.Bool(flagkey.AllNamespaces) {
tts, err = opts.Client().V1().TimeTrigger().List("")
} else {
tts, err = opts.Client().V1().TimeTrigger().List(ttNs)
}
if err != nil {
return errors.Wrap(err, "list Time triggers")
}
+12 -4
View File
@@ -25,7 +25,9 @@ import (
fv1 "github.com/fission/fission/pkg/apis/core/v1"
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
"github.com/fission/fission/pkg/fission-cli/cmd"
"github.com/fission/fission/pkg/fission-cli/console"
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
"github.com/fission/fission/pkg/fission-cli/util"
)
type UpdateSubCommand struct {
@@ -46,9 +48,13 @@ func (opts *UpdateSubCommand) do(input cli.Input) error {
}
func (opts *UpdateSubCommand) complete(input cli.Input) error {
_, namespace, err := util.GetResourceNamespace(input, flagkey.NamespaceTrigger)
if err != nil {
return errors.Wrap(err, "error in deleting function ")
}
tt, err := opts.Client().V1().TimeTrigger().Get(&metav1.ObjectMeta{
Name: input.String(flagkey.TtName),
Namespace: input.String(flagkey.NamespaceTrigger),
Namespace: namespace,
})
if err != nil {
return errors.Wrap(err, "error getting time trigger")
@@ -61,11 +67,13 @@ func (opts *UpdateSubCommand) complete(input cli.Input) error {
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 := input.String("function")
if len(fnName) > 0 {
functionList := []string{fnName}
err := util.CheckFunctionExistence(opts.Client(), functionList, namespace)
if err != nil {
console.Warn(err.Error())
}
tt.Spec.FunctionReference.Name = fnName
updated = true
}
+15 -13
View File
@@ -21,8 +21,6 @@ import (
"net/http"
"time"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
fv1 "github.com/fission/fission/pkg/apis/core/v1"
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
"github.com/fission/fission/pkg/fission-cli/util"
@@ -83,17 +81,21 @@ var (
Labels = Flag{Type: String, Name: flagkey.Labels, Usage: "Comma separated labels to apply to the function. E.g. --labels=\"environment=dev,application=analytics\""}
Annotation = Flag{Type: StringSlice, Name: flagkey.Annotation, Usage: "Annotation to apply to the function. To mention multiple annotations --annotation=\"abc.com/team=dev\" --annotation=\"foo=bar\""}
NamespaceFunction = Flag{Type: String, Name: flagkey.NamespaceFunction, Aliases: []string{"fns"}, Usage: "Namespace for function object", DefaultValue: metav1.NamespaceDefault}
NamespaceEnvironment = Flag{Type: String, Name: flagkey.NamespaceEnvironment, Aliases: []string{"envns"}, Usage: "Namespace for environment object", DefaultValue: metav1.NamespaceDefault}
NamespacePackage = Flag{Type: String, Name: flagkey.NamespacePackage, Aliases: []string{"pkgns"}, Usage: "Namespace for package object", DefaultValue: metav1.NamespaceDefault}
NamespaceTrigger = Flag{Type: String, Name: flagkey.NamespaceTrigger, Aliases: []string{"triggerns"}, Usage: "Namespace for trigger object", DefaultValue: metav1.NamespaceDefault}
NamespaceCanary = Flag{Type: String, Name: flagkey.NamespaceCanary, Aliases: []string{"canaryns"}, Usage: "Namespace for canary config object", DefaultValue: metav1.NamespaceDefault}
Namespace = Flag{Type: String, Name: flagkey.Namespace, Short: "n", Usage: "If present, the namespace scope for this CLI request"}
RunTimeMinCPU = Flag{Type: Int, Name: flagkey.RuntimeMincpu, Usage: "Minimum CPU to be assigned to pod (In millicore, minimum 1)"}
RunTimeMaxCPU = Flag{Type: Int, Name: flagkey.RuntimeMaxcpu, Usage: "Maximum CPU to be assigned to pod (In millicore, minimum 1)"}
RunTimeTargetCPU = Flag{Type: Int, Name: flagkey.RuntimeTargetcpu, Usage: "Target average CPU usage percentage across pods for scaling", DefaultValue: 80}
RunTimeMinMemory = Flag{Type: Int, Name: flagkey.RuntimeMinmemory, Usage: "Minimum memory to be assigned to pod (In megabyte)"}
RunTimeMaxMemory = Flag{Type: Int, Name: flagkey.RuntimeMaxmemory, Usage: "Maximum memory to be assigned to pod (In megabyte)"}
NamespaceFunction = Flag{Type: String, Name: flagkey.NamespaceFunction, Aliases: []string{"fns"}, Usage: "Namespace for function object", Deprecated: true, Substitute: flagkey.Namespace}
NamespaceEnvironment = Flag{Type: String, Name: flagkey.NamespaceEnvironment, Aliases: []string{"envns"}, Usage: "Namespace for environment object", Deprecated: true, Substitute: flagkey.Namespace}
NamespacePackage = Flag{Type: String, Name: flagkey.NamespacePackage, Aliases: []string{"pkgns"}, Usage: "Namespace for package object", Deprecated: true, Substitute: flagkey.Namespace}
NamespaceTrigger = Flag{Type: String, Name: flagkey.NamespaceTrigger, Aliases: []string{"triggerns"}, Usage: "Namespace for trigger object", Deprecated: true, Substitute: flagkey.Namespace}
NamespaceCanary = Flag{Type: String, Name: flagkey.NamespaceCanary, Aliases: []string{"canaryns"}, Usage: "Namespace for canary config object", Deprecated: true, Substitute: flagkey.Namespace}
ForceNamespace = Flag{Type: Bool, Name: flagkey.ForceNamespace, Aliases: []string{"force"}, Usage: "If true, resources will be created in namespace provided by (--namespace flag ) even if spec file contains some other namespace", DefaultValue: false}
ForceDelete = Flag{Type: Bool, Name: flagkey.ForceDelete, Aliases: []string{"force"}, Usage: "Delete all resources across all namespaces present in spec"}
AllNamespaces = Flag{Type: Bool, Name: flagkey.AllNamespaces, Short: "A", Usage: "Fetch resources from all namespaces"}
RunTimeMinCPU = Flag{Type: Int, Name: flagkey.RuntimeMincpu, Usage: "Minimum CPU to be assigned to pod (In millicore, minimum 1)"}
RunTimeMaxCPU = Flag{Type: Int, Name: flagkey.RuntimeMaxcpu, Usage: "Maximum CPU to be assigned to pod (In millicore, minimum 1)"}
RunTimeTargetCPU = Flag{Type: Int, Name: flagkey.RuntimeTargetcpu, Usage: "Target average CPU usage percentage across pods for scaling", DefaultValue: 80}
RunTimeMinMemory = Flag{Type: Int, Name: flagkey.RuntimeMinmemory, Usage: "Minimum memory to be assigned to pod (In megabyte)"}
RunTimeMaxMemory = Flag{Type: Int, Name: flagkey.RuntimeMaxmemory, Usage: "Maximum memory to be assigned to pod (In megabyte)"}
ReplicasMin = Flag{Type: Int, Name: flagkey.ReplicasMinscale, Usage: "Minimum number of pods (Uses resource inputs to configure HPA)", DefaultValue: 1}
ReplicasMax = Flag{Type: Int, Name: flagkey.ReplicasMaxscale, Usage: "Maximum number of pods (Uses resource inputs to configure HPA)", DefaultValue: 1}
@@ -186,7 +188,7 @@ var (
KwName = Flag{Type: String, Name: flagkey.KwName, Usage: "Watch name"}
KwFnName = Flag{Type: String, Name: flagkey.KwFnName, Usage: "Function name"}
KwNamespace = Flag{Type: String, Name: flagkey.KwNamespace, Aliases: []string{"ns"}, Usage: "Namespace of resource to watch", DefaultValue: metav1.NamespaceDefault}
KwNamespace = Flag{Type: String, Name: flagkey.KwNamespace, Aliases: []string{"ns"}, Usage: "Namespace of resource to watch"}
KwObjType = Flag{Type: String, Name: flagkey.KwObjType, Usage: "Type of resource to watch (Pod, Service, etc.)", DefaultValue: "pod"}
KwLabels = Flag{Type: String, Name: flagkey.KwLabels, Usage: "Label selector of the form a=b,c=d"}
+4
View File
@@ -38,6 +38,10 @@ const (
NamespacePackage = "pkgNamespace"
NamespaceTrigger = "triggerNamespace"
NamespaceCanary = "canaryNamespace"
Namespace = "namespace"
ForceNamespace = "force-namespace"
AllNamespaces = "all-namespaces"
ForceDelete = "force"
RuntimeMincpu = "mincpu"
RuntimeMaxcpu = "maxcpu"
+64 -6
View File
@@ -104,11 +104,8 @@ func KubifyName(old string) string {
return newName
}
// GetKubernetesClient builds a new kubernetes client. If the KUBECONFIG
// environment variable is empty or doesn't exist, ~/.kube/config is used for
// the kube config path
func GetKubernetesClient(kubeContext string) (*restclient.Config, kubernetes.Interface, error) {
loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
func getLoadingRules() (loadingRules *clientcmd.ClientConfigLoadingRules, err error) {
loadingRules = clientcmd.NewDefaultClientConfigLoadingRules()
kubeConfigPath := os.Getenv("KUBECONFIG")
if len(kubeConfigPath) == 0 {
@@ -126,7 +123,7 @@ func GetKubernetesClient(kubeContext string) (*restclient.Config, kubernetes.Int
kubeConfigPath = filepath.Join(homeDir, ".kube", "config")
if _, err := os.Stat(kubeConfigPath); os.IsNotExist(err) {
return nil, nil, errors.New("Couldn't find kubeconfig file. " +
return nil, errors.New("Couldn't find kubeconfig file. " +
"Set the KUBECONFIG environment variable to your kubeconfig's path.")
}
loadingRules.ExplicitPath = kubeConfigPath
@@ -134,6 +131,17 @@ func GetKubernetesClient(kubeContext string) (*restclient.Config, kubernetes.Int
} else {
console.Verbose(2, "Using kubeconfig from environment %q", kubeConfigPath)
}
return loadingRules, nil
}
// GetKubernetesClient builds a new kubernetes client. If the KUBECONFIG
// environment variable is empty or doesn't exist, ~/.kube/config is used for
// the kube config path
func GetKubernetesClient(kubeContext string) (*restclient.Config, kubernetes.Interface, error) {
loadingRules, err := getLoadingRules()
if err != nil {
return nil, nil, err
}
config, err := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
loadingRules, &clientcmd.ConfigOverrides{CurrentContext: kubeContext}).ClientConfig()
@@ -149,6 +157,25 @@ func GetKubernetesClient(kubeContext string) (*restclient.Config, kubernetes.Int
return config, clientset, nil
}
// GetKubernetesNamespace builds a new kubernetes client. If the KUBECONFIG
// environment variable is empty or doesn't exist, ~/.kube/config is used for
// the kube config path
func GetKubernetesNamespace(kubeContext string) (currentNS string, err error) {
loadingRules, err := getLoadingRules()
if err != nil {
return "", err
}
config1, err := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
loadingRules, &clientcmd.ConfigOverrides{CurrentContext: kubeContext}).RawConfig()
if err != nil {
return "", errors.Wrap(err, "Failed to build Kubernetes config")
}
currentNS = config1.Contexts[config1.CurrentContext].Namespace
return currentNS, nil
}
// given a list of functions, this checks if the functions actually exist on the cluster
func CheckFunctionExistence(client client.Interface, functions []string, fnNamespace string) (err error) {
fnMissing := make([]string, 0)
@@ -459,3 +486,34 @@ func GetStorageURL(ctx context.Context, kubeContext string) (*url.URL, error) {
return serverURL, nil
}
func GetResourceNamespace(input cli.Input, deprecatedFlag string) (namespace, currentNS string, err error) {
namespace = input.String(deprecatedFlag)
currentNS = namespace
if input.String(flagkey.Namespace) != "" {
namespace = input.String(flagkey.Namespace)
currentNS = namespace
return namespace, currentNS, err
}
console.Verbose(2, "Namespace from user %s ", namespace)
if namespace == "" {
if os.Getenv("FISSION_DEFAULT_NAMESPACE") != "" {
currentNS = os.Getenv("FISSION_DEFAULT_NAMESPACE")
} else {
kubeContext := input.String(flagkey.KubeContext)
currentNS, err = GetKubernetesNamespace(kubeContext)
if err != nil {
return namespace, currentNS, err
}
}
if currentNS == "" {
return namespace, currentNS, errors.Errorf("either set current-context or provide namespace with --namespace flag")
}
}
console.Verbose(2, "Namespace final %s ", currentNS)
return namespace, currentNS, nil
}
+8
View File
@@ -64,3 +64,11 @@ func TestGetEnvVarFromStringSlice(t *testing.T) {
})
}
}
func TestGetConfig(t *testing.T) {
response, err := GetKubernetesNamespace("")
if err != nil {
t.Log(err)
}
t.Log("Current NS: ", response)
}
+4
View File
@@ -101,6 +101,10 @@ main() {
$ROOT/test/tests/test_fn_update/test_secret_update.sh \
$ROOT/test/tests/test_fn_update/test_nd_pkg_update.sh \
$ROOT/test/tests/test_fn_update/test_poolmgr_nd.sh
$ROOT/test/tests/test_namespace/test_ns_current_context.sh
$ROOT/test/tests/test_namespace/test_ns_flag.sh
$ROOT/test/tests/test_namespace/test_ns_env.sh
$ROOT/test/tests/test_namespace/test_ns_deprecated_flag.sh
set -e
+39
View File
@@ -0,0 +1,39 @@
#!/bin/bash
set -euo pipefail
source $(dirname $0)/../../utils.sh
TEST_ID=$(generate_test_id)
echo "TEST_ID = $TEST_ID"
tmp_dir="/tmp/test-$TEST_ID"
mkdir -p $tmp_dir
ROOT=$(dirname $0)/../../..
cleanup() {
echo "previous response" $?
log "Cleaning up..."
clean_resource_by_id $TEST_ID
rm -rf $tmp_dir
}
if [ -z "${TEST_NOCLEANUP:-}" ]; then
trap cleanup EXIT
else
log "TEST_NOCLEANUP is set; not cleaning up test artifacts afterwards."
fi
httptrigger=http-$TEST_ID
httptriggerurl=/url-$TEST_ID
fn_n=nbuilderhello-$TEST_ID
cd $ROOT/examples/go/hello-world
log "Creating httptrigger using default namespace"
fission httptrigger create --function $fn_n --url /$httptriggerurl --name $httptrigger
log "verify trigger exists"
fission httptrigger list --namespace default | grep $httptrigger
log "Test PASSED"
+43
View File
@@ -0,0 +1,43 @@
#!/bin/bash
set -euo pipefail
source $(dirname $0)/../../utils.sh
TEST_ID=$(generate_test_id)
echo "TEST_ID = $TEST_ID"
tmp_dir="/tmp/test-$TEST_ID"
mkdir -p $tmp_dir
TEST_NS=ns-$TEST_ID
ROOT=$(dirname $0)/../../..
cleanup() {
echo "previous response" $?
log "Cleaning up..."
clean_resource_by_id_for_namespace $TEST_ID $TEST_NS
rm -rf $tmp_dir
}
if [ -z "${TEST_NOCLEANUP:-}" ]; then
trap cleanup EXIT
else
log "TEST_NOCLEANUP is set; not cleaning up test artifacts afterwards."
fi
httptrigger=http-$TEST_ID
httptriggerurl=/url-$TEST_ID
fn_n=nbuilderhello-$TEST_ID
cd $ROOT/examples/go/hello-world
kubectl create namespace $TEST_NS
log "Creating httptrigger using deprecating flag"
fission httptrigger create --function $fn_n --url /$httptriggerurl --name $httptrigger --fnNamespace $TEST_NS
log "verify trigger exists"
fission httptrigger list --namespace $TEST_NS | grep $httptrigger
log "Test PASSED"
+45
View File
@@ -0,0 +1,45 @@
#!/bin/bash
set -euo pipefail
source $(dirname $0)/../../utils.sh
TEST_ID=$(generate_test_id)
echo "TEST_ID = $TEST_ID"
tmp_dir="/tmp/test-$TEST_ID"
mkdir -p $tmp_dir
TEST_NS=ns-$TEST_ID
export FISSION_DEFAULT_NAMESPACE=$TEST_NS
ROOT=$(dirname $0)/../../..
cleanup() {
echo "previous response" $?
log "Cleaning up..."
clean_resource_by_id_for_namespace $TEST_ID $TEST_NS
rm -rf $tmp_dir
}
if [ -z "${TEST_NOCLEANUP:-}" ]; then
trap cleanup EXIT
else
log "TEST_NOCLEANUP is set; not cleaning up test artifacts afterwards."
fi
httptrigger=http-$TEST_ID
httptriggerurl=/url-$TEST_ID
fn_n=nbuilderhello-$TEST_ID
cd $ROOT/examples/go/hello-world
kubectl create namespace $TEST_NS
log "Creating httptrigger in namespace using env var"
fission httptrigger create --function $fn_n --url /$httptriggerurl --name $httptrigger
log "verify trigger exists"
fission httptrigger list --namespace $TEST_NS | grep $httptrigger
log "Test PASSED"
+43
View File
@@ -0,0 +1,43 @@
#!/bin/bash
set -euo pipefail
source $(dirname $0)/../../utils.sh
TEST_ID=$(generate_test_id)
echo "TEST_ID = $TEST_ID"
tmp_dir="/tmp/test-$TEST_ID"
mkdir -p $tmp_dir
TEST_NS=ns-$TEST_ID
ROOT=$(dirname $0)/../../..
cleanup() {
echo "previous response" $?
log "Cleaning up..."
clean_resource_by_id_for_namespace $TEST_ID $TEST_NS
rm -rf $tmp_dir
}
if [ -z "${TEST_NOCLEANUP:-}" ]; then
trap cleanup EXIT
else
log "TEST_NOCLEANUP is set; not cleaning up test artifacts afterwards."
fi
httptrigger=http-$TEST_ID
httptriggerurl=/url-$TEST_ID
fn_n=nbuilderhello-$TEST_ID
cd $ROOT/examples/go/hello-world
kubectl create namespace $TEST_NS
log "Creating httptrigger in namespace provided by flag"
fission httptrigger create --function $fn_n --url /$httptriggerurl --name $httptrigger --namespace $TEST_NS
log "verify trigger exists"
fission httptrigger list --namespace $TEST_NS | grep $httptrigger
log "Test PASSED"
+32
View File
@@ -43,6 +43,38 @@ clean_resource_by_id() {
set -e
}
clean_resource_by_id_for_namespace() {
test_id=$1
namespace=$2
KUBECTL="kubectl --namespace $namespace"
set +e
echo test_id
fn_list=$(fission function list | grep $test_id | awk '{print $1}')
for fn in $fn_list; do
fission fn delete --name $fn
done
pkg_list=$(fission package list | grep $test_id | awk '{print $1}')
for pkg in $pkg_list; do
fission pkg info --name $pkg
fission pkg delete -f --name $pkg
done
route_list=$(fission route list | grep $test_id | awk '{print $1}')
for route in $route_list; do
fission route delete --name $route
done
crds=$($KUBECTL get crd | grep "fission.io" | awk '{print $1}')
crds="$crds configmaps secrets"
for crd in $crds; do
$KUBECTL get $crd -o name | grep $test_id | xargs --no-run-if-empty $KUBECTL delete
done
set -e
}
test_fn() {
if [ -z $FISSION_ROUTER ]; then
log "Environment FISSION_ROUTER not set"