diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/diff/diff.go b/staging/src/k8s.io/kubectl/pkg/cmd/diff/diff.go index d33e95cf96d..4f1f37f434f 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/diff/diff.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/diff/diff.go @@ -114,7 +114,9 @@ type DiffOptions struct { EnforceNamespace bool Builder *resource.Builder Diff *DiffProgram - pruner *pruner + + pruner *pruner + tracker *tracker } func NewDiffOptions(ioStreams genericclioptions.IOStreams) *DiffOptions { @@ -659,6 +661,7 @@ func (o *DiffOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []str if err != nil { return err } + o.tracker = newTracker() o.pruner = newPruner(o.DynamicClient, mapper, resources, o.Selector) } @@ -723,8 +726,8 @@ func (o *DiffOptions) Run() error { IOStreams: o.Diff.IOStreams, } - if o.pruner != nil { - o.pruner.MarkVisited(info) + if o.tracker != nil { + o.tracker.MarkVisited(info) } err = differ.Diff(obj, printer, o.ShowManagedFields) @@ -739,7 +742,7 @@ func (o *DiffOptions) Run() error { }) if o.pruner != nil { - prunedObjs, err := o.pruner.pruneAll(o.CmdNamespace != "") + prunedObjs, err := o.pruner.pruneAll(o.tracker, o.CmdNamespace != "") if err != nil { klog.Warningf("pruning failed and could not be evaluated err: %v", err) } diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/diff/prune.go b/staging/src/k8s.io/kubectl/pkg/cmd/diff/prune.go index e3ec06a70ce..6b1e04446c2 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/diff/prune.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/diff/prune.go @@ -31,37 +31,45 @@ import ( "k8s.io/kubectl/pkg/util/prune" ) +type tracker struct { + visitedUids sets.Set[types.UID] + visitedNamespaces sets.Set[string] +} + +func newTracker() *tracker { + return &tracker{ + visitedUids: sets.New[types.UID](), + visitedNamespaces: sets.New[string](), + } +} + type pruner struct { mapper meta.RESTMapper dynamicClient dynamic.Interface - visitedUids sets.Set[types.UID] - visitedNamespaces sets.Set[string] - labelSelector string - resources []prune.Resource + labelSelector string + resources []prune.Resource } func newPruner(dc dynamic.Interface, m meta.RESTMapper, r []prune.Resource, selector string) *pruner { return &pruner{ - visitedUids: sets.New[types.UID](), - visitedNamespaces: sets.New[string](), - dynamicClient: dc, - mapper: m, - resources: r, - labelSelector: selector, + dynamicClient: dc, + mapper: m, + resources: r, + labelSelector: selector, } } -func (p *pruner) pruneAll(namespaceSpecified bool) ([]runtime.Object, error) { +func (p *pruner) pruneAll(tracker *tracker, namespaceSpecified bool) ([]runtime.Object, error) { var allPruned []runtime.Object namespacedRESTMappings, nonNamespacedRESTMappings, err := prune.GetRESTMappings(p.mapper, p.resources, namespaceSpecified) if err != nil { return allPruned, fmt.Errorf("error retrieving RESTMappings to prune: %v", err) } - for n := range p.visitedNamespaces { + for n := range tracker.visitedNamespaces { for _, m := range namespacedRESTMappings { - if pobjs, err := p.prune(n, m); err != nil { + if pobjs, err := p.prune(tracker, n, m); err != nil { return pobjs, fmt.Errorf("error pruning namespaced object %v: %v", m.GroupVersionKind, err) } else { allPruned = append(allPruned, pobjs...) @@ -69,7 +77,7 @@ func (p *pruner) pruneAll(namespaceSpecified bool) ([]runtime.Object, error) { } } for _, m := range nonNamespacedRESTMappings { - if pobjs, err := p.prune(metav1.NamespaceNone, m); err != nil { + if pobjs, err := p.prune(tracker, metav1.NamespaceNone, m); err != nil { return allPruned, fmt.Errorf("error pruning nonNamespaced object %v: %v", m.GroupVersionKind, err) } else { allPruned = append(allPruned, pobjs...) @@ -79,7 +87,7 @@ func (p *pruner) pruneAll(namespaceSpecified bool) ([]runtime.Object, error) { return allPruned, nil } -func (p *pruner) prune(namespace string, mapping *meta.RESTMapping) ([]runtime.Object, error) { +func (p *pruner) prune(tracker *tracker, namespace string, mapping *meta.RESTMapping) ([]runtime.Object, error) { objList, err := p.dynamicClient.Resource(mapping.Resource). Namespace(namespace). List(context.TODO(), metav1.ListOptions{ @@ -105,7 +113,7 @@ func (p *pruner) prune(namespace string, mapping *meta.RESTMapping) ([]runtime.O continue } uid := metadata.GetUID() - if p.visitedUids.Has(uid) { + if tracker.visitedUids.Has(uid) { continue } @@ -115,14 +123,14 @@ func (p *pruner) prune(namespace string, mapping *meta.RESTMapping) ([]runtime.O } // MarkVisited marks visited namespaces and uids -func (p *pruner) MarkVisited(info *resource.Info) { +func (t *tracker) MarkVisited(info *resource.Info) { if info.Namespaced() { - p.visitedNamespaces.Insert(info.Namespace) + t.visitedNamespaces.Insert(info.Namespace) } metadata, err := meta.Accessor(info.Object) if err != nil { return } - p.visitedUids.Insert(metadata.GetUID()) + t.visitedUids.Insert(metadata.GetUID()) }