From 4d8a9c1a0574c6674242d5432063e2b92fa9844b Mon Sep 17 00:00:00 2001 From: Lorenzo Fontana Date: Sun, 25 Nov 2018 03:38:19 +0100 Subject: [PATCH] feat(cmd/delete): delete command in reorg Signed-off-by: Lorenzo Fontana --- pkg/cmd/delete.go | 110 ++++++++++++++++++++++++++++++++------------ pkg/cmd/get.go | 3 +- pkg/cmd/run.go | 3 +- pkg/tracejob/job.go | 23 ++++++++- 4 files changed, 106 insertions(+), 33 deletions(-) diff --git a/pkg/cmd/delete.go b/pkg/cmd/delete.go index 741dce7c..795f2d60 100644 --- a/pkg/cmd/delete.go +++ b/pkg/cmd/delete.go @@ -3,10 +3,15 @@ package cmd import ( "fmt" - "github.com/davecgh/go-spew/spew" "github.com/fntlnz/kubectl-trace/pkg/factory" + "github.com/fntlnz/kubectl-trace/pkg/meta" + "github.com/fntlnz/kubectl-trace/pkg/tracejob" "github.com/spf13/cobra" + "k8s.io/apimachinery/pkg/types" "k8s.io/cli-runtime/pkg/genericclioptions" + batchv1client "k8s.io/client-go/kubernetes/typed/batch/v1" + corev1client "k8s.io/client-go/kubernetes/typed/core/v1" + "k8s.io/client-go/rest" ) var ( @@ -28,25 +33,64 @@ var ( // DeleteOptions ... type DeleteOptions struct { genericclioptions.IOStreams - traceID string - traceName string - namespace string + traceID *types.UID + traceName *string + namespace string + clientConfig *rest.Config + all bool } // NewDeleteOptions provides an instance of DeleteOptions with default values. func NewDeleteOptions(streams genericclioptions.IOStreams) *DeleteOptions { return &DeleteOptions{ IOStreams: streams, + all: false, } } +// NewDeleteCommand provides the delete command wrapping DeleteOptions. +func NewDeleteCommand(factory factory.Factory, streams genericclioptions.IOStreams) *cobra.Command { + o := NewDeleteOptions(streams) + + cmd := &cobra.Command{ + Use: "delete [TRACE_ID] [--all]", + Short: deleteShort, + Long: deleteLong, // Wrap with templates.LongDesc() + Example: fmt.Sprintf(deleteExamples, "kubectl"), // Wrap with templates.Examples() + PreRunE: func(c *cobra.Command, args []string) error { + return o.Validate(c, args) + }, + RunE: func(c *cobra.Command, args []string) error { + if err := o.Complete(factory, c, args); err != nil { + return err + } + if err := o.Run(); err != nil { + fmt.Fprintln(o.ErrOut, err.Error()) + return nil + } + return nil + }, + } + + cmd.Flags().BoolVar(&o.all, "all", o.all, "Delete all trace jobs in the provided namespace") + + return cmd +} + func (o *DeleteOptions) Validate(cmd *cobra.Command, args []string) error { switch len(args) { case 1: - o.traceID = args[0] + if meta.IsObjectName(args[0]) { + o.traceName = &args[0] + } else { + tid := types.UID(args[0]) + o.traceID = &tid + } break default: - return fmt.Errorf(requiredArgErrString) + if o.all == false { + return fmt.Errorf("--all=true must be specified to delete all the trace programs in a namespace\n%s", requiredArgErrString) + } } return nil @@ -61,35 +105,41 @@ func (o *DeleteOptions) Complete(factory factory.Factory, cmd *cobra.Command, ar } //// Prepare client - //clientConfig, err := factory.ToRESTConfig() - //if err != nil { - //return err - //} - //o.client, err = batchv1client.NewForConfig(clientConfig) - //if err != nil { - //return err - //} + o.clientConfig, err = factory.ToRESTConfig() + if err != nil { + return err + } return nil } -// NewDeleteCommand provides the delete command wrapping DeleteOptions. -func NewDeleteCommand(factory factory.Factory, streams genericclioptions.IOStreams) *cobra.Command { - o := NewDeleteOptions(streams) +func (o *DeleteOptions) Run() error { + jobsClient, err := batchv1client.NewForConfig(o.clientConfig) + if err != nil { + return err + } - cmd := &cobra.Command{ - Use: "delete TRACE_ID", - Short: deleteShort, - Long: deleteLong, // Wrap with templates.LongDesc() - Example: fmt.Sprintf(deleteExamples, "kubectl"), // Wrap with templates.Examples() - PreRunE: func(c *cobra.Command, args []string) error { - return o.Validate(c, args) - }, - Run: func(c *cobra.Command, args []string) { - fmt.Println("delete") - spew.Dump(o) - }, + coreClient, err := corev1client.NewForConfig(o.clientConfig) + if err != nil { + return err } - return cmd + tc := &tracejob.TraceJobClient{ + JobClient: jobsClient.Jobs(o.namespace), + ConfigClient: coreClient.ConfigMaps(o.namespace), + } + + tc.WithOutStream(o.Out) + + tf := tracejob.TraceJobFilter{ + Name: o.traceName, + ID: o.traceID, + } + + err = tc.DeleteJobs(tf) + if err != nil { + return err + } + + return nil } diff --git a/pkg/cmd/get.go b/pkg/cmd/get.go index 1d47e80f..544a22ae 100644 --- a/pkg/cmd/get.go +++ b/pkg/cmd/get.go @@ -75,7 +75,8 @@ func NewGetCommand(factory factory.Factory, streams genericclioptions.IOStreams) return err } if err := o.Run(); err != nil { - return err + fmt.Fprintln(o.ErrOut, err.Error()) + return nil } return nil }, diff --git a/pkg/cmd/run.go b/pkg/cmd/run.go index 9fa8df07..f084e4ee 100644 --- a/pkg/cmd/run.go +++ b/pkg/cmd/run.go @@ -90,7 +90,8 @@ func NewRunCommand(factory factory.Factory, streams genericclioptions.IOStreams) return err } if err := o.Run(); err != nil { - return err + fmt.Fprintln(o.ErrOut, err.Error()) + return nil } return nil }, diff --git a/pkg/tracejob/job.go b/pkg/tracejob/job.go index a90ba44c..87dd6a90 100644 --- a/pkg/tracejob/job.go +++ b/pkg/tracejob/job.go @@ -3,6 +3,9 @@ package tracejob import ( "fmt" + "io" + "io/ioutil" + "github.com/fntlnz/kubectl-trace/pkg/meta" batchv1 "k8s.io/api/batch/v1" apiv1 "k8s.io/api/core/v1" @@ -15,6 +18,7 @@ import ( type TraceJobClient struct { JobClient batchv1typed.JobInterface ConfigClient corev1typed.ConfigMapInterface + outStream io.Writer } type TraceJob struct { @@ -25,6 +29,14 @@ type TraceJob struct { Program string } +// WithOutStream setup a file stream to output trace job operation information +func (t *TraceJobClient) WithOutStream(o io.Writer) { + if o == nil { + t.outStream = ioutil.Discard + } + t.outStream = o +} + type TraceJobFilter struct { Name *string ID *types.UID @@ -110,7 +122,8 @@ func (t *TraceJobClient) GetJob(nf TraceJobFilter) ([]TraceJob, error) { return tjobs, nil } -func (t *TraceJobClient) DeleteJob(nf TraceJobFilter) error { +func (t *TraceJobClient) DeleteJobs(nf TraceJobFilter) error { + nothingDeleted := true jl, err := t.findJobsWithFilter(nf) if err != nil { return err @@ -124,6 +137,8 @@ func (t *TraceJobClient) DeleteJob(nf TraceJobFilter) error { if err != nil { return err } + fmt.Fprintf(t.outStream, "trace job %s deleted\n", j.Name) + nothingDeleted = false } cl, err := t.findConfigMapsWithFilter(nf) @@ -137,6 +152,12 @@ func (t *TraceJobClient) DeleteJob(nf TraceJobFilter) error { if err != nil { return err } + fmt.Fprintf(t.outStream, "trace configuration %s deleted\n", c.Name) + nothingDeleted = false + } + + if nothingDeleted { + fmt.Fprintf(t.outStream, "error: no trace found to be deleted\n") } return nil }