Merge pull request #601 from chunglu-chou/kpt-event

Change printing functions to support the status output for other inventory types
This commit is contained in:
Kubernetes Prow Robot 2022-08-09 04:36:50 -07:00 committed by GitHub
commit 2cd8a3ab45
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 67 additions and 34 deletions

View File

@ -13,6 +13,7 @@ import (
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"sigs.k8s.io/cli-utils/cmd/flagutils"
"sigs.k8s.io/cli-utils/cmd/status/printers"
"sigs.k8s.io/cli-utils/cmd/status/printers/printer"
"sigs.k8s.io/cli-utils/pkg/apply/poller"
"sigs.k8s.io/cli-utils/pkg/common"
"sigs.k8s.io/cli-utils/pkg/inventory"
@ -22,6 +23,7 @@ import (
"sigs.k8s.io/cli-utils/pkg/kstatus/polling/event"
"sigs.k8s.io/cli-utils/pkg/kstatus/status"
"sigs.k8s.io/cli-utils/pkg/manifestreader"
"sigs.k8s.io/cli-utils/pkg/object"
)
func GetRunner(factory cmdutil.Factory, invFactory inventory.ClientFactory, loader manifestreader.ManifestLoader) *Runner {
@ -109,6 +111,18 @@ func (r *Runner) runE(cmd *cobra.Command, args []string) error {
return nil
}
// initialize maps in printData
printData := printer.PrintData{
InvNameMap: make(map[object.ObjMetadata]string),
StatusSet: make(map[string]bool),
}
for _, obj := range identifiers {
// add to the map for future reference
printData.InvNameMap[obj] = inv.Name()
// append to identifiers
printData.Identifiers = append(printData.Identifiers, obj)
}
statusPoller, err := r.pollerFactoryFunc(r.factory)
if err != nil {
return err
@ -120,7 +134,7 @@ func (r *Runner) runE(cmd *cobra.Command, args []string) error {
In: cmd.InOrStdin(),
Out: cmd.OutOrStdout(),
ErrOut: cmd.ErrOrStderr(),
})
}, &printData)
if err != nil {
return fmt.Errorf("error creating printer: %w", err)
}

View File

@ -99,8 +99,8 @@ func TestCommand(t *testing.T) {
},
},
expectedOutput: `
deployment.apps/foo is InProgress: inProgress
statefulset.apps/bar is Current: current
foo/deployment.apps/default/foo is InProgress: inProgress
foo/statefulset.apps/default/bar is Current: current
`,
},
"wait for all current": {
@ -146,10 +146,10 @@ statefulset.apps/bar is Current: current
},
},
expectedOutput: `
deployment.apps/foo is InProgress: inProgress
statefulset.apps/bar is InProgress: inProgress
statefulset.apps/bar is Current: current
deployment.apps/foo is Current: current
foo/deployment.apps/default/foo is InProgress: inProgress
foo/statefulset.apps/default/bar is InProgress: inProgress
foo/statefulset.apps/default/bar is Current: current
foo/deployment.apps/default/foo is Current: current
`,
},
"wait for all deleted": {
@ -179,8 +179,8 @@ deployment.apps/foo is Current: current
},
},
expectedOutput: `
statefulset.apps/bar is NotFound: notFound
deployment.apps/foo is NotFound: notFound
foo/statefulset.apps/default/bar is NotFound: notFound
foo/deployment.apps/default/foo is NotFound: notFound
`,
},
"forever with timeout": {
@ -211,8 +211,8 @@ deployment.apps/foo is NotFound: notFound
},
},
expectedOutput: `
statefulset.apps/bar is InProgress: inProgress
deployment.apps/foo is InProgress: inProgress
foo/statefulset.apps/default/bar is InProgress: inProgress
foo/deployment.apps/default/foo is InProgress: inProgress
`,
},
}

View File

@ -7,23 +7,31 @@ import (
"fmt"
"strings"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/cli-runtime/pkg/genericclioptions"
"sigs.k8s.io/cli-utils/cmd/status/printers/printer"
"sigs.k8s.io/cli-utils/pkg/apply/event"
"sigs.k8s.io/cli-utils/pkg/common"
"sigs.k8s.io/cli-utils/pkg/kstatus/polling/collector"
pollevent "sigs.k8s.io/cli-utils/pkg/kstatus/polling/event"
"sigs.k8s.io/cli-utils/pkg/object"
"sigs.k8s.io/cli-utils/pkg/print/list"
"sigs.k8s.io/cli-utils/pkg/printers/events"
)
// Printer implements the Printer interface and outputs the resource
// status information as a list of events as they happen.
type Printer struct {
Formatter list.Formatter
IOStreams genericclioptions.IOStreams
Data *printer.PrintData
}
// NewPrinter returns a new instance of the eventPrinter.
func NewPrinter(ioStreams genericclioptions.IOStreams) *Printer {
func NewPrinter(ioStreams genericclioptions.IOStreams, printData *printer.PrintData) *Printer {
return &Printer{
Formatter: events.NewFormatter(ioStreams, common.DryRunNone),
IOStreams: ioStreams,
Data: printData,
}
}
@ -40,7 +48,10 @@ func (ep *Printer) Print(ch <-chan pollevent.Event, identifiers object.ObjMetada
// stopping the poller at the correct time.
done := coll.ListenWithObserver(ch, collector.ObserverFunc(
func(statusCollector *collector.ResourceStatusCollector, e pollevent.Event) {
ep.printStatusEvent(e)
err := ep.printStatusEvent(e)
if err != nil {
panic(err)
}
cancelFunc(statusCollector, e)
}),
)
@ -52,25 +63,27 @@ func (ep *Printer) Print(ch <-chan pollevent.Event, identifiers object.ObjMetada
return err
}
func (ep *Printer) printStatusEvent(se pollevent.Event) {
func (ep *Printer) printStatusEvent(se pollevent.Event) error {
switch se.Type {
case pollevent.ResourceUpdateEvent:
id := se.Resource.Identifier
printResourceStatus(id, se, ep.IOStreams)
var invName string
var ok bool
if invName, ok = ep.Data.InvNameMap[id]; !ok {
return fmt.Errorf("%s: resource not found", id)
}
// filter out status that are not assigned
statusString := se.Resource.Status.String()
if _, ok := ep.Data.StatusSet[strings.ToLower(statusString)]; len(ep.Data.StatusSet) != 0 && !ok {
return nil
}
_, err := fmt.Fprintf(ep.IOStreams.Out, "%s/%s/%s/%s is %s: %s\n", invName,
strings.ToLower(id.GroupKind.String()), id.Namespace, id.Name, statusString, se.Resource.Message)
return err
case pollevent.ErrorEvent:
id := se.Resource.Identifier
gk := id.GroupKind
fmt.Fprintf(ep.IOStreams.Out, "%s error: %s\n", resourceIDToString(gk, id.Name),
se.Error.Error())
return ep.Formatter.FormatErrorEvent(event.ErrorEvent{
Err: se.Error,
})
}
}
// resourceIDToString returns the string representation of a GroupKind and a resource name.
func resourceIDToString(gk schema.GroupKind, name string) string {
return fmt.Sprintf("%s/%s", strings.ToLower(gk.String()), name)
}
func printResourceStatus(id object.ObjMetadata, se pollevent.Event, ioStreams genericclioptions.IOStreams) {
fmt.Fprintf(ioStreams.Out, "%s is %s: %s\n", resourceIDToString(id.GroupKind, id.Name),
se.Resource.Status.String(), se.Resource.Message)
return nil
}

View File

@ -9,6 +9,13 @@ import (
"sigs.k8s.io/cli-utils/pkg/object"
)
// PrintData records data required for printing
type PrintData struct {
Identifiers object.ObjMetadataSet
InvNameMap map[object.ObjMetadata]string
StatusSet map[string]bool
}
// Printer defines an interface for outputting information about status of
// resources. Different implementations allow output formats tailored to
// different use cases.

View File

@ -4,20 +4,19 @@
package printers
import (
"k8s.io/cli-runtime/pkg/genericclioptions"
"sigs.k8s.io/cli-utils/cmd/status/printers/event"
"sigs.k8s.io/cli-utils/cmd/status/printers/printer"
"sigs.k8s.io/cli-utils/cmd/status/printers/table"
"k8s.io/cli-runtime/pkg/genericclioptions"
)
// CreatePrinter return an implementation of the Printer interface. The
// actual implementation is based on the printerType requested.
func CreatePrinter(printerType string, ioStreams genericclioptions.IOStreams) (printer.Printer, error) {
func CreatePrinter(printerType string, ioStreams genericclioptions.IOStreams, printData *printer.PrintData) (printer.Printer, error) {
switch printerType {
case "table":
return table.NewPrinter(ioStreams), nil
default:
return event.NewPrinter(ioStreams), nil
return event.NewPrinter(ioStreams, printData), nil
}
}