mirror of https://github.com/fluxcd/cli-utils.git
132 lines
3.8 KiB
Go
132 lines
3.8 KiB
Go
// Copyright 2020 The Kubernetes Authors.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package list
|
|
|
|
import (
|
|
"sigs.k8s.io/cli-utils/pkg/apply/event"
|
|
"sigs.k8s.io/cli-utils/pkg/common"
|
|
"sigs.k8s.io/cli-utils/pkg/object"
|
|
printcommon "sigs.k8s.io/cli-utils/pkg/print/common"
|
|
"sigs.k8s.io/cli-utils/pkg/print/stats"
|
|
)
|
|
|
|
type Formatter interface {
|
|
FormatValidationEvent(ve event.ValidationEvent) error
|
|
FormatApplyEvent(ae event.ApplyEvent) error
|
|
FormatStatusEvent(se event.StatusEvent) error
|
|
FormatPruneEvent(pe event.PruneEvent) error
|
|
FormatDeleteEvent(de event.DeleteEvent) error
|
|
FormatWaitEvent(we event.WaitEvent) error
|
|
FormatErrorEvent(ee event.ErrorEvent) error
|
|
FormatActionGroupEvent(
|
|
age event.ActionGroupEvent,
|
|
ags []event.ActionGroup,
|
|
s stats.Stats,
|
|
c Collector,
|
|
) error
|
|
}
|
|
|
|
type FormatterFactory func(previewStrategy common.DryRunStrategy) Formatter
|
|
|
|
type BaseListPrinter struct {
|
|
FormatterFactory FormatterFactory
|
|
}
|
|
|
|
type Collector interface {
|
|
LatestStatus() map[object.ObjMetadata]event.StatusEvent
|
|
}
|
|
|
|
type StatusCollector struct {
|
|
latestStatus map[object.ObjMetadata]event.StatusEvent
|
|
}
|
|
|
|
func (sc *StatusCollector) updateStatus(id object.ObjMetadata, se event.StatusEvent) {
|
|
sc.latestStatus[id] = se
|
|
}
|
|
|
|
func (sc *StatusCollector) LatestStatus() map[object.ObjMetadata]event.StatusEvent {
|
|
return sc.latestStatus
|
|
}
|
|
|
|
// Print outputs the events from the provided channel in a simple
|
|
// format on StdOut. As we support other printer implementations
|
|
// this should probably be an interface.
|
|
// This function will block until the channel is closed.
|
|
//nolint:gocyclo
|
|
func (b *BaseListPrinter) Print(ch <-chan event.Event, previewStrategy common.DryRunStrategy, printStatus bool) error {
|
|
var actionGroups []event.ActionGroup
|
|
var statsCollector stats.Stats
|
|
statusCollector := &StatusCollector{
|
|
latestStatus: make(map[object.ObjMetadata]event.StatusEvent),
|
|
}
|
|
formatter := b.FormatterFactory(previewStrategy)
|
|
for e := range ch {
|
|
statsCollector.Handle(e)
|
|
switch e.Type {
|
|
case event.InitType:
|
|
actionGroups = e.InitEvent.ActionGroups
|
|
case event.ErrorType:
|
|
_ = formatter.FormatErrorEvent(e.ErrorEvent)
|
|
return e.ErrorEvent.Err
|
|
case event.ValidationType:
|
|
if err := formatter.FormatValidationEvent(e.ValidationEvent); err != nil {
|
|
return err
|
|
}
|
|
case event.ApplyType:
|
|
if err := formatter.FormatApplyEvent(e.ApplyEvent); err != nil {
|
|
return err
|
|
}
|
|
case event.StatusType:
|
|
statusCollector.updateStatus(e.StatusEvent.Identifier, e.StatusEvent)
|
|
if printStatus {
|
|
if err := formatter.FormatStatusEvent(e.StatusEvent); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
case event.PruneType:
|
|
if err := formatter.FormatPruneEvent(e.PruneEvent); err != nil {
|
|
return err
|
|
}
|
|
case event.DeleteType:
|
|
if err := formatter.FormatDeleteEvent(e.DeleteEvent); err != nil {
|
|
return err
|
|
}
|
|
case event.WaitType:
|
|
if err := formatter.FormatWaitEvent(e.WaitEvent); err != nil {
|
|
return err
|
|
}
|
|
case event.ActionGroupType:
|
|
if err := formatter.FormatActionGroupEvent(
|
|
e.ActionGroupEvent,
|
|
actionGroups,
|
|
statsCollector,
|
|
statusCollector,
|
|
); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
return printcommon.ResultErrorFromStats(statsCollector)
|
|
}
|
|
|
|
// IsLastActionGroup returns true if the passed ActionGroupEvent is the
|
|
// last of its type in the slice of ActionGroup; false otherwise. For example,
|
|
// this function will determine if an ApplyAction is the last ApplyAction in
|
|
// the initialized task queue. This functionality is current used to determine
|
|
// when to print stats.
|
|
func IsLastActionGroup(age event.ActionGroupEvent, ags []event.ActionGroup) bool {
|
|
var found bool
|
|
var action event.ResourceAction
|
|
for _, ag := range ags {
|
|
if found && (action == ag.Action) {
|
|
return false
|
|
}
|
|
if age.GroupName == ag.Name {
|
|
found = true
|
|
action = age.Action
|
|
}
|
|
}
|
|
return true
|
|
}
|