From a5030ffd180fef6c1570d80ddec5eca2398930db Mon Sep 17 00:00:00 2001 From: Karl Isenberg Date: Tue, 19 Oct 2021 16:11:23 -0700 Subject: [PATCH] Clean up prune package - Rename PruneOptions to Pruner (it does the work itself) - Rename variables and internal methods for clarity/consistency - Extract deleteObject method to improve readability - Rename GetObject to getObject (only used internally and by test) - Modify log messages for readability - Add log support for prune tests - Make log messages more consistent --- pkg/apply/applier.go | 20 ++-- pkg/apply/destroyer.go | 18 ++-- pkg/apply/prune/main_test.go | 19 ++++ pkg/apply/prune/prune.go | 159 ++++++++++++++++---------------- pkg/apply/prune/prune_test.go | 26 +++--- pkg/apply/solver/solver.go | 12 +-- pkg/apply/solver/solver_test.go | 16 ++-- pkg/apply/task/prune_task.go | 4 +- 8 files changed, 146 insertions(+), 128 deletions(-) create mode 100644 pkg/apply/prune/main_test.go diff --git a/pkg/apply/applier.go b/pkg/apply/applier.go index a19abd83..f32c149a 100644 --- a/pkg/apply/applier.go +++ b/pkg/apply/applier.go @@ -31,7 +31,7 @@ import ( // NewApplier returns a new Applier. func NewApplier(factory cmdutil.Factory, invClient inventory.InventoryClient, statusPoller poller.Poller) (*Applier, error) { - pruneOpts, err := prune.NewPruneOptions(factory, invClient) + pruner, err := prune.NewPruner(factory, invClient) if err != nil { return nil, err } @@ -40,7 +40,7 @@ func NewApplier(factory cmdutil.Factory, invClient inventory.InventoryClient, st return nil, err } return &Applier{ - pruneOptions: pruneOpts, + pruner: pruner, statusPoller: statusPoller, factory: factory, invClient: invClient, @@ -59,7 +59,7 @@ func NewApplier(factory cmdutil.Factory, invClient inventory.InventoryClient, st // parameters and/or the set of resources that needs to be applied to the // cluster, different sets of tasks might be needed. type Applier struct { - pruneOptions *prune.PruneOptions + pruner *prune.Pruner statusPoller poller.Poller factory cmdutil.Factory invClient inventory.InventoryClient @@ -100,7 +100,7 @@ func (a *Applier) prepareObjects(localInv inventory.InventoryInfo, localObjs obj } } } - pruneObjs, err := a.pruneOptions.GetPruneObjs(localInv, localObjs, prune.Options{ + pruneObjs, err := a.pruner.GetPruneObjs(localInv, localObjs, prune.Options{ DryRunStrategy: o.DryRunStrategy, }) if err != nil { @@ -155,12 +155,12 @@ func (a *Applier) Run(ctx context.Context, invInfo inventory.InventoryInfo, obje // Fetch the queue (channel) of tasks that should be executed. klog.V(4).Infoln("applier building task queue...") taskBuilder := &solver.TaskQueueBuilder{ - PruneOptions: a.pruneOptions, - Factory: a.factory, - InfoHelper: a.infoHelper, - Mapper: mapper, - InvClient: a.invClient, - Destroy: false, + Pruner: a.pruner, + Factory: a.factory, + InfoHelper: a.infoHelper, + Mapper: mapper, + InvClient: a.invClient, + Destroy: false, } opts := solver.Options{ ServerSideOptions: options.ServerSideOptions, diff --git a/pkg/apply/destroyer.go b/pkg/apply/destroyer.go index 151415f0..3a0a1c16 100644 --- a/pkg/apply/destroyer.go +++ b/pkg/apply/destroyer.go @@ -30,12 +30,12 @@ import ( // handled by a separate printer with the KubectlPrinterAdapter bridging // between the two. func NewDestroyer(factory cmdutil.Factory, invClient inventory.InventoryClient, statusPoller poller.Poller) (*Destroyer, error) { - pruneOpts, err := prune.NewPruneOptions(factory, invClient) + pruner, err := prune.NewPruner(factory, invClient) if err != nil { return nil, fmt.Errorf("error setting up PruneOptions: %w", err) } return &Destroyer{ - pruneOptions: pruneOpts, + pruner: pruner, statusPoller: statusPoller, factory: factory, invClient: invClient, @@ -45,7 +45,7 @@ func NewDestroyer(factory cmdutil.Factory, invClient inventory.InventoryClient, // Destroyer performs the step of grabbing all the previous inventory objects and // prune them. This also deletes all the previous inventory objects type Destroyer struct { - pruneOptions *prune.PruneOptions + pruner *prune.Pruner statusPoller poller.Poller factory cmdutil.Factory invClient inventory.InventoryClient @@ -97,7 +97,7 @@ func (d *Destroyer) Run(ctx context.Context, inv inventory.InventoryInfo, option // Retrieve the objects to be deleted from the cluster. Second parameter is empty // because no local objects returns all inventory objects for deletion. emptyLocalObjs := object.UnstructuredSet{} - deleteObjs, err := d.pruneOptions.GetPruneObjs(inv, emptyLocalObjs, prune.Options{ + deleteObjs, err := d.pruner.GetPruneObjs(inv, emptyLocalObjs, prune.Options{ DryRunStrategy: options.DryRunStrategy, }) if err != nil { @@ -111,11 +111,11 @@ func (d *Destroyer) Run(ctx context.Context, inv inventory.InventoryInfo, option } klog.V(4).Infoln("destroyer building task queue...") taskBuilder := &solver.TaskQueueBuilder{ - PruneOptions: d.pruneOptions, - Factory: d.factory, - Mapper: mapper, - InvClient: d.invClient, - Destroy: true, + Pruner: d.pruner, + Factory: d.factory, + Mapper: mapper, + InvClient: d.invClient, + Destroy: true, } opts := solver.Options{ Prune: true, diff --git a/pkg/apply/prune/main_test.go b/pkg/apply/prune/main_test.go new file mode 100644 index 00000000..0602ed2f --- /dev/null +++ b/pkg/apply/prune/main_test.go @@ -0,0 +1,19 @@ +// Copyright 2021 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +package prune + +import ( + "os" + "testing" + + "k8s.io/klog/v2" +) + +// TestMain executes the tests for this package, with optional logging. +// To see all logs, use: +// go test sigs.k8s.io/cli-utils/pkg/apply/prune -v -args -v=5 +func TestMain(m *testing.M) { + klog.InitFlags(nil) + os.Exit(m.Run()) +} diff --git a/pkg/apply/prune/prune.go b/pkg/apply/prune/prune.go index 4c869d11..89e047a7 100644 --- a/pkg/apply/prune/prune.go +++ b/pkg/apply/prune/prune.go @@ -30,18 +30,17 @@ import ( "sigs.k8s.io/cli-utils/pkg/ordering" ) -// PruneOptions encapsulates the necessary information to -// implement the prune functionality. -type PruneOptions struct { +// Pruner implements GetPruneObjs to calculate which objects to prune and Prune +// to delete them. +type Pruner struct { InvClient inventory.InventoryClient Client dynamic.Interface Mapper meta.RESTMapper } -// NewPruneOptions returns a struct (PruneOptions) encapsulating the necessary -// information to run the prune. Returns an error if an error occurs -// gathering this information. -func NewPruneOptions(factory util.Factory, invClient inventory.InventoryClient) (*PruneOptions, error) { +// NewPruner returns a new Pruner. +// Returns an error if dependency injection fails using the factory. +func NewPruner(factory util.Factory, invClient inventory.InventoryClient) (*Pruner, error) { // Client/Builder fields from the Factory. client, err := factory.DynamicClient() if err != nil { @@ -51,7 +50,7 @@ func NewPruneOptions(factory util.Factory, invClient inventory.InventoryClient) if err != nil { return nil, err } - return &PruneOptions{ + return &Pruner{ InvClient: invClient, Client: client, Mapper: mapper, @@ -72,7 +71,7 @@ type Options struct { Destroy bool } -// Prune deletes the set of passed pruneObjs. A prune skip/failure is +// Prune deletes the set of passed objects. A prune skip/failure is // captured in the TaskContext, so we do not lose track of these // objects from the inventory. The passed prune filters are used to // determine if permission exists to delete the object. An example @@ -82,62 +81,63 @@ type Options struct { // automatically prune/delete). // // Parameters: -// pruneObjs - objects to prune (delete) +// objs - objects to prune (delete) // pruneFilters - list of filters for deletion permission // taskContext - task for apply/prune // taskName - name of the parent task group, for events -// o - options for dry-run -func (po *PruneOptions) Prune(pruneObjs object.UnstructuredSet, +// opts - options for dry-run +func (p *Pruner) Prune( + objs object.UnstructuredSet, pruneFilters []filter.ValidationFilter, taskContext *taskrunner.TaskContext, taskName string, - o Options, + opts Options, ) error { - eventFactory := CreateEventFactory(o.Destroy, taskName) + eventFactory := CreateEventFactory(opts.Destroy, taskName) // Iterate through objects to prune (delete). If an object is not pruned // and we need to keep it in the inventory, we must capture the prune failure. - for _, pruneObj := range pruneObjs { - pruneID := object.UnstructuredToObjMetaOrDie(pruneObj) - klog.V(5).Infof("attempting prune: %s", pruneID) + for _, obj := range objs { + id := object.UnstructuredToObjMetaOrDie(obj) + klog.V(5).Infof("evaluating prune filters (object: %q)", id) // Check filters to see if we're prevented from pruning/deleting object. var filtered bool var reason string var err error for _, pruneFilter := range pruneFilters { - klog.V(6).Infof("prune filter %s: %s", pruneFilter.Name(), pruneID) - filtered, reason, err = pruneFilter.Filter(pruneObj) + klog.V(6).Infof("evaluating prune filter (object: %q, filter: %q)", id, pruneFilter.Name()) + filtered, reason, err = pruneFilter.Filter(obj) if err != nil { if klog.V(5).Enabled() { - klog.Errorf("error during %s, (%s): %s", pruneFilter.Name(), pruneID, err) + klog.Errorf("error during %s, (%s): %v", pruneFilter.Name(), id, err) } - taskContext.EventChannel() <- eventFactory.CreateFailedEvent(pruneID, err) - taskContext.CapturePruneFailure(pruneID) + taskContext.EventChannel() <- eventFactory.CreateFailedEvent(id, err) + taskContext.CapturePruneFailure(id) break } if filtered { - klog.V(4).Infof("prune filtered (filter: %q, resource: %q, reason: %q)", pruneFilter.Name(), pruneID, reason) + klog.V(4).Infof("prune skipped (object: %q, filter: %q): %v", id, pruneFilter.Name(), reason) // pruneFailure indicates whether `taskContext.CapturePruneFailure` should be called. pruneFailure := true if pruneFilter.Name() == filter.PreventRemoveFilterName { - if o.DryRunStrategy.ClientOrServerDryRun() { + if opts.DryRunStrategy.ClientOrServerDryRun() { pruneFailure = false } else { - err := po.handleDeletePrevention(pruneObj) + err := p.removeInventoryAnnotation(obj) if err != nil { if klog.V(4).Enabled() { - klog.Errorf("Failed to remove the %q annotation from %s: %v", inventory.OwningInventoryKey, pruneID, err) + klog.Errorf("error removing annotation (object: %q, annotation: %q): %v", id, inventory.OwningInventoryKey, err) } - taskContext.EventChannel() <- eventFactory.CreateFailedEvent(pruneID, err) - taskContext.CapturePruneFailure(pruneID) + taskContext.EventChannel() <- eventFactory.CreateFailedEvent(id, err) + taskContext.CapturePruneFailure(id) break } else { pruneFailure = false } } } - taskContext.EventChannel() <- eventFactory.CreateSkippedEvent(pruneObj, reason) + taskContext.EventChannel() <- eventFactory.CreateSkippedEvent(obj, reason) if pruneFailure { - taskContext.CapturePruneFailure(pruneID) + taskContext.CapturePruneFailure(id) } break } @@ -146,48 +146,39 @@ func (po *PruneOptions) Prune(pruneObjs object.UnstructuredSet, continue } // Filters passed--actually delete object if not dry run. - if !o.DryRunStrategy.ClientOrServerDryRun() { - klog.V(4).Infof("prune object delete: %s", pruneID) - namespacedClient, err := po.namespacedClient(pruneID) - if err != nil { - if klog.V(4).Enabled() { - klog.Errorf("prune failed for %s (%s)", pruneID, err) - } - taskContext.EventChannel() <- eventFactory.CreateFailedEvent(pruneID, err) - taskContext.CapturePruneFailure(pruneID) - continue - } - err = namespacedClient.Delete(context.TODO(), pruneID.Name, metav1.DeleteOptions{ - PropagationPolicy: &o.PropagationPolicy, + if !opts.DryRunStrategy.ClientOrServerDryRun() { + klog.V(4).Infof("deleting object (object: %q)", id) + err := p.deleteObject(id, metav1.DeleteOptions{ + PropagationPolicy: &opts.PropagationPolicy, }) if err != nil { if klog.V(4).Enabled() { - klog.Errorf("prune failed for %s (%s)", pruneID, err) + klog.Errorf("error deleting object (object: %q): %v", id, err) } - taskContext.EventChannel() <- eventFactory.CreateFailedEvent(pruneID, err) - taskContext.CapturePruneFailure(pruneID) + taskContext.EventChannel() <- eventFactory.CreateFailedEvent(id, err) + taskContext.CapturePruneFailure(id) continue } } - taskContext.EventChannel() <- eventFactory.CreateSuccessEvent(pruneObj) + taskContext.EventChannel() <- eventFactory.CreateSuccessEvent(obj) } return nil } -// handleDeletePrevention removes the `config.k8s.io/owning-inventory` annotation from pruneObj. -func (po *PruneOptions) handleDeletePrevention(pruneObj *unstructured.Unstructured) error { - pruneID := object.UnstructuredToObjMetaOrDie(pruneObj) - annotations := pruneObj.GetAnnotations() +// removeInventoryAnnotation removes the `config.k8s.io/owning-inventory` annotation from pruneObj. +func (p *Pruner) removeInventoryAnnotation(obj *unstructured.Unstructured) error { + id := object.UnstructuredToObjMetaOrDie(obj) + annotations := obj.GetAnnotations() if annotations != nil { if _, ok := annotations[inventory.OwningInventoryKey]; ok { - klog.V(4).Infof("remove the %q annotation from the object %s", inventory.OwningInventoryKey, pruneID) + klog.V(4).Infof("removing annotation (object: %q, annotation: %q)", id, inventory.OwningInventoryKey) delete(annotations, inventory.OwningInventoryKey) - pruneObj.SetAnnotations(annotations) - namespacedClient, err := po.namespacedClient(pruneID) + obj.SetAnnotations(annotations) + namespacedClient, err := p.namespacedClient(id) if err != nil { return err } - _, err = namespacedClient.Update(context.TODO(), pruneObj, metav1.UpdateOptions{}) + _, err = namespacedClient.Update(context.TODO(), obj, metav1.UpdateOptions{}) return err } } @@ -198,50 +189,58 @@ func (po *PruneOptions) handleDeletePrevention(pruneObj *unstructured.Unstructur // from the cluster. Set of prune objects equals the set of inventory // objects minus the set of currently applied objects. Returns an error // if one occurs. -func (po *PruneOptions) GetPruneObjs(inv inventory.InventoryInfo, - localObjs object.UnstructuredSet, o Options) (object.UnstructuredSet, error) { - localIds := object.UnstructuredsToObjMetasOrDie(localObjs) - prevInvIds, err := po.InvClient.GetClusterObjs(inv, o.DryRunStrategy) +func (p *Pruner) GetPruneObjs( + inv inventory.InventoryInfo, + objs object.UnstructuredSet, + opts Options, +) (object.UnstructuredSet, error) { + ids := object.UnstructuredsToObjMetasOrDie(objs) + invIDs, err := p.InvClient.GetClusterObjs(inv, opts.DryRunStrategy) if err != nil { return nil, err } - pruneIds := prevInvIds.Diff(localIds) - pruneObjs := object.UnstructuredSet{} - for _, pruneID := range pruneIds { - pruneObj, err := po.GetObject(pruneID) + // only return objects that were in the inventory but not in the object set + ids = invIDs.Diff(ids) + objs = object.UnstructuredSet{} + for _, id := range ids { + pruneObj, err := p.getObject(id) if err != nil { if meta.IsNoMatchError(err) { - klog.V(4).Infof("skip pruning obj %s/%s: the resource type is unrecognized by the cluster (kind: %s, group %s)", - pruneID.Namespace, pruneID.Name, pruneID.GroupKind.Kind, pruneID.GroupKind.Group) + klog.V(4).Infof("skip pruning (object: %q): resource type not registered", id) continue - } else if apierrors.IsNotFound(err) { - // If prune object is not in cluster, no need to prune it--skip. - klog.V(4).Infof("skip pruning obj %s/%s: not found in the cluster", - pruneID.Namespace, pruneID.Name) + } + if apierrors.IsNotFound(err) { + klog.V(4).Infof("skip pruning (object: %q): resource not found", id) continue } return nil, err } - pruneObjs = append(pruneObjs, pruneObj) + objs = append(objs, pruneObj) } - sort.Sort(sort.Reverse(ordering.SortableUnstructureds(pruneObjs))) - return pruneObjs, nil + sort.Sort(sort.Reverse(ordering.SortableUnstructureds(objs))) + return objs, nil } -// GetObject uses the passed object data to retrieve the object -// from the cluster (or an error if one occurs). -func (po *PruneOptions) GetObject(obj object.ObjMetadata) (*unstructured.Unstructured, error) { - namespacedClient, err := po.namespacedClient(obj) +func (p *Pruner) getObject(id object.ObjMetadata) (*unstructured.Unstructured, error) { + namespacedClient, err := p.namespacedClient(id) if err != nil { return nil, err } - return namespacedClient.Get(context.TODO(), obj.Name, metav1.GetOptions{}) + return namespacedClient.Get(context.TODO(), id.Name, metav1.GetOptions{}) +} + +func (p *Pruner) deleteObject(id object.ObjMetadata, opts metav1.DeleteOptions) error { + namespacedClient, err := p.namespacedClient(id) + if err != nil { + return err + } + return namespacedClient.Delete(context.TODO(), id.Name, opts) } -func (po *PruneOptions) namespacedClient(obj object.ObjMetadata) (dynamic.ResourceInterface, error) { - mapping, err := po.Mapper.RESTMapping(obj.GroupKind) +func (p *Pruner) namespacedClient(id object.ObjMetadata) (dynamic.ResourceInterface, error) { + mapping, err := p.Mapper.RESTMapping(id.GroupKind) if err != nil { return nil, err } - return po.Client.Resource(mapping.Resource).Namespace(obj.Namespace), nil + return p.Client.Resource(mapping.Resource).Namespace(id.Namespace), nil } diff --git a/pkg/apply/prune/prune_test.go b/pkg/apply/prune/prune_test.go index 8b3c27a3..0c00ec6c 100644 --- a/pkg/apply/prune/prune_test.go +++ b/pkg/apply/prune/prune_test.go @@ -422,7 +422,7 @@ func TestPrune(t *testing.T) { pruneIds, err := object.UnstructuredsToObjMetas(tc.pruneObjs) require.NoError(t, err) - po := PruneOptions{ + po := Pruner{ InvClient: inventory.NewFakeInventoryClient(pruneIds), Client: fake.NewSimpleDynamicClient(scheme.Scheme, objs...), Mapper: testrestmapper.TestOnlyStaticRESTMapper(scheme.Scheme, @@ -480,7 +480,7 @@ func TestPruneDeletionPrevention(t *testing.T) { pruneID, err := object.UnstructuredToObjMeta(tc.pruneObj) require.NoError(t, err) - po := PruneOptions{ + po := Pruner{ InvClient: inventory.NewFakeInventoryClient(object.ObjMetadataSet{pruneID}), Client: fake.NewSimpleDynamicClient(scheme.Scheme, tc.pruneObj), Mapper: testrestmapper.TestOnlyStaticRESTMapper(scheme.Scheme, @@ -501,7 +501,7 @@ func TestPruneDeletionPrevention(t *testing.T) { t.Fatalf("Unexpected error during Prune(): %#v", err) } // verify that the object no longer has the annotation - obj, err := po.GetObject(pruneID) + obj, err := po.getObject(pruneID) if err != nil { t.Fatalf("Unexpected error: %#v", err) } @@ -576,7 +576,7 @@ func TestPruneWithErrors(t *testing.T) { t.Run(name, func(t *testing.T) { pruneIds, err := object.UnstructuredsToObjMetas(tc.pruneObjs) require.NoError(t, err) - po := PruneOptions{ + po := Pruner{ InvClient: inventory.NewFakeInventoryClient(pruneIds), // Set up the fake dynamic client to recognize all objects, and the RESTMapper. Client: &fakeDynamicClient{ @@ -667,7 +667,7 @@ func TestGetPruneObjs(t *testing.T) { for _, obj := range tc.prevInventory { objs = append(objs, obj) } - po := PruneOptions{ + po := Pruner{ InvClient: inventory.NewFakeInventoryClient(object.UnstructuredsToObjMetasOrDie(tc.prevInventory)), Client: fake.NewSimpleDynamicClient(scheme.Scheme, objs...), Mapper: testrestmapper.TestOnlyStaticRESTMapper(scheme.Scheme, @@ -695,12 +695,12 @@ func TestGetPruneObjs(t *testing.T) { } func TestGetObject_NoMatchError(t *testing.T) { - po := PruneOptions{ + po := Pruner{ Client: fake.NewSimpleDynamicClient(scheme.Scheme, pod, namespace), Mapper: testrestmapper.TestOnlyStaticRESTMapper(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...), } - _, err := po.GetObject(testutil.ToIdentifier(t, crontabCRManifest)) + _, err := po.getObject(testutil.ToIdentifier(t, crontabCRManifest)) if err == nil { t.Fatalf("expected GetObject() to return a NoKindMatchError, got nil") } @@ -710,7 +710,7 @@ func TestGetObject_NoMatchError(t *testing.T) { } func TestGetObject_NotFoundError(t *testing.T) { - po := PruneOptions{ + po := Pruner{ Client: fake.NewSimpleDynamicClient(scheme.Scheme, pod, namespace), Mapper: testrestmapper.TestOnlyStaticRESTMapper(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...), @@ -719,7 +719,7 @@ func TestGetObject_NotFoundError(t *testing.T) { if err != nil { t.Fatalf("unexpected error %s returned", err) } - _, err = po.GetObject(objMeta) + _, err = po.getObject(objMeta) if err == nil { t.Fatalf("expected GetObject() to return a NotFound error, got nil") } @@ -730,17 +730,17 @@ func TestGetObject_NotFoundError(t *testing.T) { func TestHandleDeletePrevention(t *testing.T) { obj := testutil.Unstructured(t, pdbDeletePreventionManifest) - po := PruneOptions{ + po := Pruner{ Client: fake.NewSimpleDynamicClient(scheme.Scheme, obj, namespace), Mapper: testrestmapper.TestOnlyStaticRESTMapper(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...), } - if err := po.handleDeletePrevention(obj); err != nil { + if err := po.removeInventoryAnnotation(obj); err != nil { t.Fatalf("unexpected error %s returned", err) } // Get the object from the cluster and verify that the `config.k8s.io/owning-inventory` annotation is removed from the object. - liveObj, err := po.GetObject(testutil.ToIdentifier(t, pdbDeletePreventionManifest)) + liveObj, err := po.getObject(testutil.ToIdentifier(t, pdbDeletePreventionManifest)) if err != nil { t.Fatalf("unexpected error %s returned", err) } @@ -778,7 +778,7 @@ func TestPrune_PropagationPolicy(t *testing.T) { for name, tc := range testCases { t.Run(name, func(t *testing.T) { captureClient := &optionsCaptureNamespaceClient{} - po := PruneOptions{ + po := Pruner{ InvClient: inventory.NewFakeInventoryClient(object.ObjMetadataSet{}), Client: &fakeDynamicClient{ resourceInterface: captureClient, diff --git a/pkg/apply/solver/solver.go b/pkg/apply/solver/solver.go index 8344045d..2ce6d794 100644 --- a/pkg/apply/solver/solver.go +++ b/pkg/apply/solver/solver.go @@ -38,11 +38,11 @@ import ( const defaultWaitTimeout = 1 * time.Minute type TaskQueueBuilder struct { - PruneOptions *prune.PruneOptions - InfoHelper info.InfoHelper - Factory util.Factory - Mapper meta.RESTMapper - InvClient inventory.InventoryClient + Pruner *prune.Pruner + InfoHelper info.InfoHelper + Factory util.Factory + Mapper meta.RESTMapper + InvClient inventory.InventoryClient // True if we are destroying, which deletes the inventory object // as well (possibly) the inventory namespace. Destroy bool @@ -200,7 +200,7 @@ func (t *TaskQueueBuilder) AppendPruneTask(pruneObjs object.UnstructuredSet, TaskName: fmt.Sprintf("prune-%d", t.pruneCounter), Objects: pruneObjs, Filters: pruneFilters, - PruneOptions: t.PruneOptions, + Pruner: t.Pruner, PropagationPolicy: o.PrunePropagationPolicy, DryRunStrategy: o.DryRunStrategy, Destroy: t.Destroy, diff --git a/pkg/apply/solver/solver_test.go b/pkg/apply/solver/solver_test.go index fb2745a8..e448af0f 100644 --- a/pkg/apply/solver/solver_test.go +++ b/pkg/apply/solver/solver_test.go @@ -22,8 +22,8 @@ import ( ) var ( - pruneOptions = &prune.PruneOptions{} - resources = map[string]string{ + pruner = &prune.Pruner{} + resources = map[string]string{ "pod": ` kind: Pod apiVersion: v1 @@ -353,9 +353,9 @@ func TestTaskQueueBuilder_AppendApplyWaitTasks(t *testing.T) { applyIds := object.UnstructuredsToObjMetasOrDie(tc.applyObjs) fakeInvClient := inventory.NewFakeInventoryClient(applyIds) tqb := TaskQueueBuilder{ - PruneOptions: pruneOptions, - Mapper: testutil.NewFakeRESTMapper(), - InvClient: fakeInvClient, + Pruner: pruner, + Mapper: testutil.NewFakeRESTMapper(), + InvClient: fakeInvClient, } tq, err := tqb.AppendApplyWaitTasks( tc.applyObjs, @@ -651,9 +651,9 @@ func TestTaskQueueBuilder_AppendPruneWaitTasks(t *testing.T) { pruneIds := object.UnstructuredsToObjMetasOrDie(tc.pruneObjs) fakeInvClient := inventory.NewFakeInventoryClient(pruneIds) tqb := TaskQueueBuilder{ - PruneOptions: pruneOptions, - Mapper: testutil.NewFakeRESTMapper(), - InvClient: fakeInvClient, + Pruner: pruner, + Mapper: testutil.NewFakeRESTMapper(), + InvClient: fakeInvClient, } emptyPruneFilters := []filter.ValidationFilter{} tq, err := tqb.AppendPruneWaitTasks(tc.pruneObjs, emptyPruneFilters, tc.options).Build() diff --git a/pkg/apply/task/prune_task.go b/pkg/apply/task/prune_task.go index cb0ea336..2679b3ea 100644 --- a/pkg/apply/task/prune_task.go +++ b/pkg/apply/task/prune_task.go @@ -20,7 +20,7 @@ import ( type PruneTask struct { TaskName string - PruneOptions *prune.PruneOptions + Pruner *prune.Pruner Objects object.UnstructuredSet Filters []filter.ValidationFilter DryRunStrategy common.DryRunStrategy @@ -59,7 +59,7 @@ func (p *PruneTask) Start(taskContext *taskrunner.TaskContext) { CurrentUIDs: taskContext.AppliedResourceUIDs(), } p.Filters = append(p.Filters, uidFilter) - err := p.PruneOptions.Prune( + err := p.Pruner.Prune( p.Objects, p.Filters, taskContext,