mirror of https://github.com/fluxcd/cli-utils.git
Integrate prune with the applier
This commit is contained in:
parent
34cab2ddb3
commit
1026b4ce1a
|
|
@ -32,6 +32,7 @@ func NewApplier(factory util.Factory, ioStreams genericclioptions.IOStreams) *Ap
|
|||
return &Applier{
|
||||
ApplyOptions: apply.NewApplyOptions(ioStreams),
|
||||
StatusOptions: NewStatusOptions(),
|
||||
PruneOptions: prune.NewPruneOptions(),
|
||||
factory: factory,
|
||||
ioStreams: ioStreams,
|
||||
}
|
||||
|
|
@ -51,6 +52,7 @@ type Applier struct {
|
|||
|
||||
ApplyOptions *apply.ApplyOptions
|
||||
StatusOptions *StatusOptions
|
||||
PruneOptions *prune.PruneOptions
|
||||
resolver resolver
|
||||
}
|
||||
|
||||
|
|
@ -63,9 +65,10 @@ func (a *Applier) Initialize(cmd *cobra.Command) error {
|
|||
if err != nil {
|
||||
return errors.WrapPrefix(err, "error setting up ApplyOptions", 1)
|
||||
}
|
||||
// Default PostProcessor is configured in "Complete" function,
|
||||
// so the prune must happen after "Complete".
|
||||
a.ApplyOptions.PostProcessorFn = pruneExec(a.factory, a.ApplyOptions)
|
||||
err = a.PruneOptions.Initialize(a.factory, a.ApplyOptions.Namespace)
|
||||
if err != nil {
|
||||
return errors.WrapPrefix(err, "error setting up PruntOptions", 1)
|
||||
}
|
||||
|
||||
resolver, err := a.newResolver(a.StatusOptions.period)
|
||||
if err != nil {
|
||||
|
|
@ -126,6 +129,7 @@ func (a *Applier) Run(ctx context.Context) <-chan Event {
|
|||
// The adapter is used to intercept what is meant to be printing
|
||||
// in the ApplyOptions, and instead turn those into events.
|
||||
a.ApplyOptions.ToPrinter = adapter.toPrinterFunc()
|
||||
a.PruneOptions.ToPrinter = adapter.toPrinterFunc()
|
||||
// This provides us with a slice of all the objects that will be
|
||||
// applied to the cluster.
|
||||
infos, _ := a.ApplyOptions.GetObjects()
|
||||
|
|
@ -154,6 +158,20 @@ func (a *Applier) Run(ctx context.Context) <-chan Event {
|
|||
}
|
||||
}
|
||||
}
|
||||
infos, _ = a.ApplyOptions.GetObjects()
|
||||
err = a.PruneOptions.Prune(infos)
|
||||
if err != nil {
|
||||
// If we see an error here we just report it on the channel and then
|
||||
// give up. Eventually we might be able to determine which errors
|
||||
// are fatal and which might allow us to continue.
|
||||
ch <- Event{
|
||||
EventType: ErrorEventType,
|
||||
ErrorEvent: ErrorEvent{
|
||||
Err: errors.WrapPrefix(err, "error pruning resources", 1),
|
||||
},
|
||||
}
|
||||
return
|
||||
}
|
||||
}()
|
||||
return ch
|
||||
}
|
||||
|
|
@ -228,16 +246,3 @@ func prependGroupingObject(o *apply.ApplyOptions) func() error {
|
|||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Prune deletes previously applied objects that have been
|
||||
// omitted in the current apply. The previously applied objects
|
||||
// are reached through ConfigMap grouping objects.
|
||||
func pruneExec(f util.Factory, o *apply.ApplyOptions) func() error {
|
||||
return func() error {
|
||||
po, err := prune.NewPruneOptions(f, o)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return po.Prune()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,14 +14,12 @@ package prune
|
|||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/cli-runtime/pkg/printers"
|
||||
"k8s.io/cli-runtime/pkg/resource"
|
||||
"k8s.io/client-go/dynamic"
|
||||
"k8s.io/kubectl/pkg/cmd/apply"
|
||||
"k8s.io/kubectl/pkg/cmd/util"
|
||||
"k8s.io/kubectl/pkg/validation"
|
||||
)
|
||||
|
|
@ -45,7 +43,7 @@ type PruneOptions struct {
|
|||
pastGroupingObjects []*resource.Info
|
||||
retrievedGroupingObjects bool
|
||||
|
||||
toPrinter func(string) (printers.ResourcePrinter, error)
|
||||
ToPrinter func(string) (printers.ResourcePrinter, error)
|
||||
out io.Writer
|
||||
|
||||
validator validation.Schema
|
||||
|
|
@ -57,42 +55,30 @@ type PruneOptions struct {
|
|||
// information to run the prune. Returns an error if an error occurs
|
||||
// gathering this information.
|
||||
// TODO: Add dry-run options.
|
||||
func NewPruneOptions(f util.Factory, ao *apply.ApplyOptions) (*PruneOptions, error) {
|
||||
func NewPruneOptions() *PruneOptions {
|
||||
po := &PruneOptions{}
|
||||
return po
|
||||
}
|
||||
|
||||
func (po *PruneOptions) Initialize(factory util.Factory, namespace string) error {
|
||||
var err error
|
||||
// Fields copied from ApplyOptions.
|
||||
po.namespace = ao.Namespace
|
||||
po.toPrinter = ao.ToPrinter
|
||||
po.out = ao.Out
|
||||
po.namespace = namespace
|
||||
// Client/Builder fields from the Factory.
|
||||
po.client, err = f.DynamicClient()
|
||||
po.client, err = factory.DynamicClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
po.builder = f.NewBuilder()
|
||||
po.mapper, err = f.ToRESTMapper()
|
||||
po.builder = factory.NewBuilder()
|
||||
po.mapper, err = factory.ToRESTMapper()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
po.validator, err = f.Validator(false)
|
||||
po.validator, err = factory.Validator(false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
// Retrieve/store the grouping object for current apply.
|
||||
currentObjects, err := ao.GetObjects()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
currentGroupingObject, found := FindGroupingObject(currentObjects)
|
||||
if !found {
|
||||
return nil, fmt.Errorf("current grouping object not found during prune")
|
||||
}
|
||||
po.currentGroupingObject = currentGroupingObject
|
||||
// Initialize past grouping objects as empty.
|
||||
po.pastGroupingObjects = []*resource.Info{}
|
||||
po.retrievedGroupingObjects = false
|
||||
|
||||
return po, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// getPreviousGroupingObjects returns the set of grouping objects
|
||||
|
|
@ -216,7 +202,16 @@ func (po *PruneOptions) calcPruneSet(pastGroupingInfos []*resource.Info) (*Inven
|
|||
// (retrieved from previous grouping objects) but omitted in
|
||||
// the current apply. Prune also delete all previous grouping
|
||||
// objects. Returns an error if there was a problem.
|
||||
func (po *PruneOptions) Prune() error {
|
||||
func (po *PruneOptions) Prune(currentObjects []*resource.Info) error {
|
||||
currentGroupingObject, found := FindGroupingObject(currentObjects)
|
||||
if !found {
|
||||
return fmt.Errorf("current grouping object not found during prune")
|
||||
}
|
||||
po.currentGroupingObject = currentGroupingObject
|
||||
// Initialize past grouping objects as empty.
|
||||
po.pastGroupingObjects = []*resource.Info{}
|
||||
po.retrievedGroupingObjects = false
|
||||
|
||||
// Retrieve previous grouping objects, and calculate the
|
||||
// union of the previous applies as an inventory set.
|
||||
pastGroupingInfos, err := po.getPreviousGroupingObjects()
|
||||
|
|
@ -233,11 +228,24 @@ func (po *PruneOptions) Prune() error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = po.client.Resource(mapping.Resource).Namespace(inv.Namespace).Delete(inv.Name, &metav1.DeleteOptions{})
|
||||
// Fetching the resource here before deletion seems a bit unnecessary, but
|
||||
// it allows us to work with the ResourcePrinter.
|
||||
namespacedClient := po.client.Resource(mapping.Resource).Namespace(inv.Namespace)
|
||||
obj, err := namespacedClient.Get(inv.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintf(po.out, "%s/%s deleted\n", strings.ToLower(inv.GroupKind.Kind), inv.Name)
|
||||
err = namespacedClient.Delete(inv.Name, &metav1.DeleteOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printer, err := po.ToPrinter("deleted")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = printer.PrintObj(obj, po.out); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// Delete previous grouping objects.
|
||||
for _, pastGroupInfo := range pastGroupingInfos {
|
||||
|
|
@ -247,7 +255,7 @@ func (po *PruneOptions) Prune() error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printer, err := po.toPrinter("deleted")
|
||||
printer, err := po.ToPrinter("deleted")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue