...

Source file src/sigs.k8s.io/cli-utils/cmd/status/printers/event/printer.go

Documentation: sigs.k8s.io/cli-utils/cmd/status/printers/event

     1  // Copyright 2020 The Kubernetes Authors.
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package event
     5  
     6  import (
     7  	"fmt"
     8  	"strings"
     9  
    10  	"k8s.io/cli-runtime/pkg/genericclioptions"
    11  	"sigs.k8s.io/cli-utils/cmd/status/printers/printer"
    12  	"sigs.k8s.io/cli-utils/pkg/apply/event"
    13  	"sigs.k8s.io/cli-utils/pkg/common"
    14  	"sigs.k8s.io/cli-utils/pkg/kstatus/polling/collector"
    15  	pollevent "sigs.k8s.io/cli-utils/pkg/kstatus/polling/event"
    16  	"sigs.k8s.io/cli-utils/pkg/object"
    17  	"sigs.k8s.io/cli-utils/pkg/print/list"
    18  	"sigs.k8s.io/cli-utils/pkg/printers/events"
    19  )
    20  
    21  // Printer implements the Printer interface and outputs the resource
    22  // status information as a list of events as they happen.
    23  type Printer struct {
    24  	Formatter list.Formatter
    25  	IOStreams genericclioptions.IOStreams
    26  	Data      *printer.PrintData
    27  }
    28  
    29  // NewPrinter returns a new instance of the eventPrinter.
    30  func NewPrinter(ioStreams genericclioptions.IOStreams, printData *printer.PrintData) *Printer {
    31  	return &Printer{
    32  		Formatter: events.NewFormatter(ioStreams, common.DryRunNone),
    33  		IOStreams: ioStreams,
    34  		Data:      printData,
    35  	}
    36  }
    37  
    38  // Print takes an event channel and outputs the status events on the channel
    39  // until the channel is closed. The provided cancelFunc is consulted on
    40  // every event and is responsible for stopping the poller when appropriate.
    41  // This function will block.
    42  func (ep *Printer) Print(ch <-chan pollevent.Event, identifiers object.ObjMetadataSet,
    43  	cancelFunc collector.ObserverFunc) error {
    44  	coll := collector.NewResourceStatusCollector(identifiers)
    45  	// The actual work is done by the collector, which will invoke the
    46  	// callback on every event. In the callback we print the status
    47  	// information and call the cancelFunc which is responsible for
    48  	// stopping the poller at the correct time.
    49  	done := coll.ListenWithObserver(ch, collector.ObserverFunc(
    50  		func(statusCollector *collector.ResourceStatusCollector, e pollevent.Event) {
    51  			err := ep.printStatusEvent(e)
    52  			if err != nil {
    53  				panic(err)
    54  			}
    55  			cancelFunc(statusCollector, e)
    56  		}),
    57  	)
    58  	// Listen to the channel until it is closed.
    59  	var err error
    60  	for msg := range done {
    61  		err = msg.Err
    62  	}
    63  	return err
    64  }
    65  
    66  func (ep *Printer) printStatusEvent(se pollevent.Event) error {
    67  	switch se.Type {
    68  	case pollevent.ResourceUpdateEvent:
    69  		id := se.Resource.Identifier
    70  		var invName string
    71  		var ok bool
    72  		if invName, ok = ep.Data.InvNameMap[id]; !ok {
    73  			return fmt.Errorf("%s: resource not found", id)
    74  		}
    75  		// filter out status that are not assigned
    76  		statusString := se.Resource.Status.String()
    77  		if _, ok := ep.Data.StatusSet[strings.ToLower(statusString)]; len(ep.Data.StatusSet) != 0 && !ok {
    78  			return nil
    79  		}
    80  		_, err := fmt.Fprintf(ep.IOStreams.Out, "%s/%s/%s/%s is %s: %s\n", invName,
    81  			strings.ToLower(id.GroupKind.String()), id.Namespace, id.Name, statusString, se.Resource.Message)
    82  		return err
    83  	case pollevent.ErrorEvent:
    84  		return ep.Formatter.FormatErrorEvent(event.ErrorEvent{
    85  			Err: se.Error,
    86  		})
    87  	}
    88  	return nil
    89  }
    90  

View as plain text