-
Notifications
You must be signed in to change notification settings - Fork 78
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #500 from mortent/ApplyReconcileFailedError
feat: Return a specific error type from the printers when resources fail to apply/delete/reconcile
- Loading branch information
Showing
12 changed files
with
562 additions
and
187 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// Copyright 2022 The Kubernetes Authors. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package common | ||
|
||
import ( | ||
"fmt" | ||
|
||
"sigs.k8s.io/cli-utils/pkg/print/stats" | ||
) | ||
|
||
// ResultErrorFromStats takes a stats object and returns either a ResultError or | ||
// nil depending on whether the stats reports that resources failed apply/prune/delete | ||
// or reconciliation. | ||
func ResultErrorFromStats(s stats.Stats) error { | ||
if s.FailedActuationSum() > 0 || s.FailedReconciliationSum() > 0 { | ||
return &ResultError{ | ||
Stats: s, | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
// ResultError is returned from printers when the apply/destroy operations completed, but one or | ||
// more resources either failed apply/prune/delete, or failed to reconcile. | ||
type ResultError struct { | ||
Stats stats.Stats | ||
} | ||
|
||
func (a *ResultError) Error() string { | ||
switch { | ||
case a.Stats.FailedActuationSum() > 0 && a.Stats.FailedReconciliationSum() > 0: | ||
return fmt.Sprintf("%d resources failed, %d resources failed to reconcile before timeout", | ||
a.Stats.FailedActuationSum(), a.Stats.FailedReconciliationSum()) | ||
case a.Stats.FailedActuationSum() > 0: | ||
return fmt.Sprintf("%d resources failed", a.Stats.FailedActuationSum()) | ||
case a.Stats.FailedReconciliationSum() > 0: | ||
return fmt.Sprintf("%d resources failed to reconcile before timeout", | ||
a.Stats.FailedReconciliationSum()) | ||
default: | ||
// Should not happen as this error is only used when at least one resource | ||
// either failed to apply/prune/delete or reconcile. | ||
return "unknown error" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
// Copyright 2022 The Kubernetes Authors. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package list | ||
|
||
import ( | ||
"testing" | ||
|
||
"sigs.k8s.io/cli-utils/pkg/apply/event" | ||
"sigs.k8s.io/cli-utils/pkg/common" | ||
"sigs.k8s.io/cli-utils/pkg/print/stats" | ||
"sigs.k8s.io/cli-utils/pkg/printers/printer" | ||
printertesting "sigs.k8s.io/cli-utils/pkg/printers/testutil" | ||
) | ||
|
||
func TestPrint(t *testing.T) { | ||
printertesting.PrintResultErrorTest(t, func() printer.Printer { | ||
return &BaseListPrinter{ | ||
FormatterFactory: func(previewStrategy common.DryRunStrategy) Formatter { | ||
return newCountingFormatter() | ||
}, | ||
} | ||
}) | ||
} | ||
|
||
func newCountingFormatter() *countingFormatter { | ||
return &countingFormatter{} | ||
} | ||
|
||
type countingFormatter struct { | ||
applyEvents []event.ApplyEvent | ||
statusEvents []event.StatusEvent | ||
pruneEvents []event.PruneEvent | ||
deleteEvents []event.DeleteEvent | ||
waitEvents []event.WaitEvent | ||
errorEvent event.ErrorEvent | ||
actionGroupEvent []event.ActionGroupEvent | ||
} | ||
|
||
func (c *countingFormatter) FormatApplyEvent(e event.ApplyEvent) error { | ||
c.applyEvents = append(c.applyEvents, e) | ||
return nil | ||
} | ||
|
||
func (c *countingFormatter) FormatStatusEvent(e event.StatusEvent) error { | ||
c.statusEvents = append(c.statusEvents, e) | ||
return nil | ||
} | ||
|
||
func (c *countingFormatter) FormatPruneEvent(e event.PruneEvent) error { | ||
c.pruneEvents = append(c.pruneEvents, e) | ||
return nil | ||
} | ||
|
||
func (c *countingFormatter) FormatDeleteEvent(e event.DeleteEvent) error { | ||
c.deleteEvents = append(c.deleteEvents, e) | ||
return nil | ||
} | ||
|
||
func (c *countingFormatter) FormatWaitEvent(e event.WaitEvent) error { | ||
c.waitEvents = append(c.waitEvents, e) | ||
return nil | ||
} | ||
|
||
func (c *countingFormatter) FormatErrorEvent(e event.ErrorEvent) error { | ||
c.errorEvent = e | ||
return nil | ||
} | ||
|
||
func (c *countingFormatter) FormatActionGroupEvent(e event.ActionGroupEvent, _ []event.ActionGroup, _ stats.Stats, | ||
_ Collector) error { | ||
c.actionGroupEvent = append(c.actionGroupEvent, e) | ||
return nil | ||
} |
Oops, something went wrong.