diff --git a/pkg/fission-cli/cli.go b/pkg/fission-cli/cli.go index 1ad8db56..be4b7f30 100644 --- a/pkg/fission-cli/cli.go +++ b/pkg/fission-cli/cli.go @@ -30,6 +30,7 @@ import ( "github.com/fission/fission/pkg/fission-cli/cliwrapper/driver/urfavecli" "github.com/fission/fission/pkg/fission-cli/cmd" "github.com/fission/fission/pkg/fission-cli/cmd/environment" + "github.com/fission/fission/pkg/fission-cli/cmd/kubewatch" _package "github.com/fission/fission/pkg/fission-cli/cmd/package" plugincmd "github.com/fission/fission/pkg/fission-cli/cmd/plugin" "github.com/fission/fission/pkg/fission-cli/cmd/spec" @@ -246,11 +247,10 @@ func NewCliApp() *cli.App { wObjTypeFlag := cli.StringFlag{Name: "type", Usage: "Type of resource to watch (Pod, Service, etc.)"} wLabelsFlag := cli.StringFlag{Name: "labels", Usage: "Label selector of the form a=b,c=d"} wSubCommands := []cli.Command{ - {Name: "create", Aliases: []string{"add"}, Usage: "Create a watch", Flags: []cli.Flag{wFnNameFlag, fnNamespaceFlag, wNamespaceFlag, wObjTypeFlag, wLabelsFlag, specSaveFlag}, Action: wCreate}, - {Name: "get", Usage: "Get details about a watch", Flags: []cli.Flag{wNameFlag, triggerNamespaceFlag}, Action: wGet}, + {Name: "create", Aliases: []string{"add"}, Usage: "Create a watch", Flags: []cli.Flag{wFnNameFlag, fnNamespaceFlag, wNamespaceFlag, wObjTypeFlag, wLabelsFlag, specSaveFlag}, Action: urfavecli.Wrapper(kubewatch.Create)}, // TODO add update flag when supported - {Name: "delete", Usage: "Delete watch", Flags: []cli.Flag{wNameFlag, triggerNamespaceFlag}, Action: wDelete}, - {Name: "list", Usage: "List all watches", Flags: []cli.Flag{triggerNamespaceFlag}, Action: wList}, + {Name: "delete", Usage: "Delete watch", Flags: []cli.Flag{wNameFlag, triggerNamespaceFlag}, Action: urfavecli.Wrapper(kubewatch.Delete)}, + {Name: "list", Usage: "List all watches", Flags: []cli.Flag{triggerNamespaceFlag}, Action: urfavecli.Wrapper(kubewatch.List)}, } // packages diff --git a/pkg/fission-cli/watch.go b/pkg/fission-cli/cmd/kubewatch/create.go similarity index 51% rename from pkg/fission-cli/watch.go rename to pkg/fission-cli/cmd/kubewatch/create.go index c5ee5f96..f2e1b01c 100644 --- a/pkg/fission-cli/watch.go +++ b/pkg/fission-cli/cmd/kubewatch/create.go @@ -1,5 +1,5 @@ /* -Copyright 2016 The Fission Authors. +Copyright 2019 The Fission Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,45 +14,63 @@ See the License for the specific language governing permissions and limitations under the License. */ -package fission_cli +package kubewatch import ( "fmt" - "os" - "text/tabwriter" - "github.com/satori/go.uuid" - "github.com/urfave/cli" + "github.com/pkg/errors" + uuid "github.com/satori/go.uuid" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" fv1 "github.com/fission/fission/pkg/apis/fission.io/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/cmd/spec" "github.com/fission/fission/pkg/fission-cli/log" - "github.com/fission/fission/pkg/fission-cli/util" ) -func wCreate(c *cli.Context) error { - client := util.GetApiClient(c.GlobalString("server")) +type CreateSubCommand struct { + client *client.Client + watcher *fv1.KubernetesWatchTrigger +} - fnName := c.String("function") +func Create(flags cli.Input) error { + opts := CreateSubCommand{ + client: cmd.GetServer(flags), + } + return opts.do(flags) +} + +func (opts *CreateSubCommand) do(flags cli.Input) error { + err := opts.complete(flags) + if err != nil { + return err + } + return opts.run(flags) +} + +func (opts *CreateSubCommand) complete(flags cli.Input) error { + fnName := flags.String("function") if len(fnName) == 0 { log.Fatal("Need a function name to create a watch, use --function") } - fnNamespace := c.String("fnNamespace") + fnNamespace := flags.String("fnNamespace") - namespace := c.String("ns") + namespace := flags.String("ns") if len(namespace) == 0 { fmt.Println("Watch 'default' namespace. Use --ns to override.") namespace = "default" } - objType := c.String("type") + objType := flags.String("type") if len(objType) == 0 { fmt.Println("Object type unspecified, will watch pods. Use --type to override.") objType = "pod" } - labels := c.String("labels") + labels := flags.String("labels") // empty 'labels' selects everything if len(labels) == 0 { fmt.Printf("Watching all objects of type '%v', use --labels to refine selection.\n", objType) @@ -64,7 +82,7 @@ func wCreate(c *cli.Context) error { // automatically name watches watchName := uuid.NewV4().String() - w := &fv1.KubernetesWatchTrigger{ + opts.watcher = &fv1.KubernetesWatchTrigger{ Metadata: metav1.ObjectMeta{ Name: watchName, Namespace: fnNamespace, @@ -80,63 +98,25 @@ func wCreate(c *cli.Context) error { }, } + return nil +} + +func (opts *CreateSubCommand) run(flags cli.Input) error { // if we're writing a spec, don't call the API - if c.Bool("spec") { - specFile := fmt.Sprintf("kubewatch-%v.yaml", watchName) - err := spec.SpecSave(*w, specFile) - util.CheckErr(err, "create kubernetes watch spec") + if flags.Bool("spec") { + specFile := fmt.Sprintf("kubewatch-%v.yaml", opts.watcher.Metadata.Name) + err := spec.SpecSave(*opts.watcher, specFile) + if err != nil { + return errors.Wrap(err, "error creating kubewatch spec") + } return nil } - _, err := client.WatchCreate(w) - util.CheckErr(err, "create watch") - - fmt.Printf("watch '%v' created\n", w.Metadata.Name) - return err -} - -func wGet(c *cli.Context) error { - // TODO - log.Fatal("Not implemented") - return nil -} - -func wDelete(c *cli.Context) error { - client := util.GetApiClient(c.GlobalString("server")) - - wName := c.String("name") - if len(wName) == 0 { - log.Fatal("Need name of watch to delete, use --name") + _, err := opts.client.WatchCreate(opts.watcher) + if err != nil { + return errors.Wrap(err, "error creating kubewatch") } - wNs := c.String("triggerns") - - err := client.WatchDelete(&metav1.ObjectMeta{ - Name: wName, - Namespace: wNs, - }) - util.CheckErr(err, "delete watch") - - fmt.Printf("watch '%v' deleted\n", wName) - return nil -} - -func wList(c *cli.Context) error { - client := util.GetApiClient(c.GlobalString("server")) - - wNs := c.String("triggerns") - - ws, err := client.WatchList(wNs) - util.CheckErr(err, "list watches") - - w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0) - - fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\n", - "NAME", "NAMESPACE", "OBJTYPE", "LABELS", "FUNCTION_NAME") - for _, wa := range ws { - fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\n", - wa.Metadata.Name, wa.Spec.Namespace, wa.Spec.Type, wa.Spec.LabelSelector, wa.Spec.FunctionReference.Name) - } - w.Flush() + fmt.Printf("kubewatch '%v' created\n", opts.watcher.Metadata.Name) return nil } diff --git a/pkg/fission-cli/cmd/kubewatch/delete.go b/pkg/fission-cli/cmd/kubewatch/delete.go new file mode 100644 index 00000000..780559e3 --- /dev/null +++ b/pkg/fission-cli/cmd/kubewatch/delete.go @@ -0,0 +1,71 @@ +/* +Copyright 2019 The Fission Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package kubewatch + +import ( + "fmt" + + "github.com/pkg/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/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" +) + +type DeleteSubCommand struct { + client *client.Client + name string + namespace string +} + +func Delete(flags cli.Input) error { + opts := DeleteSubCommand{ + client: cmd.GetServer(flags), + } + return opts.do(flags) +} + +func (opts *DeleteSubCommand) do(flags cli.Input) error { + err := opts.complete(flags) + if err != nil { + return err + } + return opts.run(flags) +} + +func (opts *DeleteSubCommand) complete(flags cli.Input) error { + opts.name = flags.String("name") + if len(opts.name) == 0 { + return errors.New("need name of watch to delete, use --name") + } + opts.namespace = flags.String("triggerns") + return nil +} + +func (opts *DeleteSubCommand) run(flags cli.Input) error { + err := opts.client.WatchDelete(&metav1.ObjectMeta{ + Name: opts.name, + Namespace: opts.namespace, + }) + if err != nil { + return errors.Wrap(err, "error deleting kubewatch") + } + + fmt.Printf("watch '%v' deleted\n", opts.name) + return nil +} diff --git a/pkg/fission-cli/cmd/kubewatch/list.go b/pkg/fission-cli/cmd/kubewatch/list.go new file mode 100644 index 00000000..e4ca9191 --- /dev/null +++ b/pkg/fission-cli/cmd/kubewatch/list.go @@ -0,0 +1,73 @@ +/* +Copyright 2019 The Fission Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package kubewatch + +import ( + "fmt" + "os" + "text/tabwriter" + + "github.com/pkg/errors" + + "github.com/fission/fission/pkg/controller/client" + "github.com/fission/fission/pkg/fission-cli/cliwrapper/cli" + "github.com/fission/fission/pkg/fission-cli/cmd" +) + +type ListSubCommand struct { + client *client.Client + namespace string +} + +func List(flags cli.Input) error { + opts := ListSubCommand{ + client: cmd.GetServer(flags), + } + return opts.do(flags) +} + +func (opts *ListSubCommand) do(flags cli.Input) error { + err := opts.complete(flags) + if err != nil { + return err + } + return opts.run(flags) +} + +func (opts *ListSubCommand) complete(flags cli.Input) error { + opts.namespace = flags.String("triggerns") + return nil +} + +func (opts *ListSubCommand) run(flags cli.Input) error { + ws, err := opts.client.WatchList(opts.namespace) + if err != nil { + return errors.Wrap(err, "error listing kubewatches") + } + + w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0) + + fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\n", + "NAME", "NAMESPACE", "OBJTYPE", "LABELS", "FUNCTION_NAME") + for _, wa := range ws { + fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\n", + wa.Metadata.Name, wa.Spec.Namespace, wa.Spec.Type, wa.Spec.LabelSelector, wa.Spec.FunctionReference.Name) + } + w.Flush() + + return nil +} diff --git a/pkg/fission-cli/cmd/package/create.go b/pkg/fission-cli/cmd/package/create.go index 5d0acdac..f1869343 100644 --- a/pkg/fission-cli/cmd/package/create.go +++ b/pkg/fission-cli/cmd/package/create.go @@ -56,7 +56,6 @@ func (opts *CreateSubCommand) do(flags cli.Input) error { return nil } -// complete creates a environment objects and populates it with default value and CLI inputs. func (opts *CreateSubCommand) complete(flags cli.Input) error { pkgNamespace := flags.String("pkgNamespace") envName := flags.String("env")