From 2d0f4303f1ff9c02a090b4fe81f15a13dd1b3090 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arda=20G=C3=BC=C3=A7l=C3=BC?= Date: Wed, 6 Oct 2021 17:01:19 +0300 Subject: [PATCH] Get object name correctly for pruned resources Kubernetes-commit: a19bd5e47436c1f0a2aea20c4a992da18f8ba480 --- pkg/cmd/diff/diff.go | 37 +++++++++++++++--------------------- pkg/cmd/diff/prune.go | 44 +++++++++++++++++++++++++++++++++++++------ 2 files changed, 53 insertions(+), 28 deletions(-) diff --git a/pkg/cmd/diff/diff.go b/pkg/cmd/diff/diff.go index f0a48976..0315afce 100644 --- a/pkg/cmd/diff/diff.go +++ b/pkg/cmd/diff/diff.go @@ -118,7 +118,6 @@ type DiffOptions struct { EnforceNamespace bool Builder *resource.Builder Diff *DiffProgram - Prune bool pruner *pruner } @@ -135,7 +134,6 @@ func NewDiffOptions(ioStreams genericclioptions.IOStreams) *DiffOptions { Exec: exec.New(), IOStreams: ioStreams, }, - pruner: newPruner(), } } @@ -176,7 +174,7 @@ func NewCmdDiff(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.C usage := "contains the configuration to diff" cmd.Flags().StringVarP(&options.Selector, "selector", "l", options.Selector, "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)") cmd.Flags().StringArray("prunewhitelist", []string{}, "Overwrite the default whitelist with for --prune") - cmd.Flags().BoolVar(&options.Prune, "prune", options.Prune, "Include resources that would be deleted by pruning. Can be used with -l and default shows all would be pruned resources") + cmd.Flags().Bool("prune", false, "Include resources that would be deleted by pruning. Can be used with -l and default shows all resources would be pruned") cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage) cmdutil.AddServerSideApplyFlags(cmd) cmdutil.AddFieldManagerFlagVar(cmd, &options.FieldManager, apply.FieldManagerClientSideApply) @@ -649,17 +647,17 @@ func (o *DiffOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error { return err } - if o.Prune { - o.pruner.dynamicClient = o.DynamicClient - o.pruner.mapper, err = f.ToRESTMapper() + if cmdutil.GetFlagBool(cmd, "prune") { + mapper, err := f.ToRESTMapper() if err != nil { return err } - o.pruner.resources, err = prune.ParseResources(o.pruner.mapper, cmdutil.GetFlagStringArray(cmd, "prunewhitelist")) + resources, err := prune.ParseResources(mapper, cmdutil.GetFlagStringArray(cmd, "prunewhitelist")) if err != nil { return err } + o.pruner = newPruner(o.DynamicClient, mapper, resources) } o.Builder = f.NewBuilder() @@ -727,7 +725,9 @@ func (o *DiffOptions) Run() error { IOStreams: o.Diff.IOStreams, } - o.markVisited(info) + if o.pruner != nil { + o.pruner.MarkVisited(info) + } err = differ.Diff(obj, printer) if !isConflict(err) { @@ -740,7 +740,7 @@ func (o *DiffOptions) Run() error { return err }) - if o.Prune { + if o.pruner != nil { prunedObjs, err := o.pruner.pruneAll() if err != nil { klog.Warningf("pruning failed and could not be evaluated err: %v", err) @@ -749,7 +749,12 @@ func (o *DiffOptions) Run() error { // Print pruned objects into old file and thus, diff // command will show them as pruned. for _, p := range prunedObjs { - if err := differ.From.Print(o.pruner.GetObjectName(p), p, printer); err != nil { + name, err := o.pruner.GetObjectName(p) + if err != nil { + klog.Warningf("pruning failed and object name could not be retrieved: %v", err) + continue + } + if err := differ.From.Print(name, p, printer); err != nil { return err } } @@ -761,15 +766,3 @@ func (o *DiffOptions) Run() error { return differ.Run(o.Diff) } - -func (o *DiffOptions) markVisited(info *resource.Info) { - if info.Namespaced() { - o.pruner.visitedNamespaces.Insert(info.Namespace) - } - - metadata, err := meta.Accessor(info.Object) - if err != nil { - return - } - o.pruner.visitedUids.Insert(string(metadata.GetUID())) -} diff --git a/pkg/cmd/diff/prune.go b/pkg/cmd/diff/prune.go index fff6db11..d7d5d288 100644 --- a/pkg/cmd/diff/prune.go +++ b/pkg/cmd/diff/prune.go @@ -20,7 +20,7 @@ import ( "context" "fmt" - "k8s.io/apimachinery/pkg/util/uuid" + "k8s.io/cli-runtime/pkg/resource" "k8s.io/apimachinery/pkg/runtime" @@ -43,10 +43,13 @@ type pruner struct { resources []prune.Resource } -func newPruner() *pruner { +func newPruner(dc dynamic.Interface, m meta.RESTMapper, r []prune.Resource) *pruner { return &pruner{ visitedUids: sets.NewString(), visitedNamespaces: sets.NewString(), + dynamicClient: dc, + mapper: m, + resources: r, } } @@ -112,8 +115,37 @@ func (p *pruner) prune(namespace string, mapping *meta.RESTMapping) ([]runtime.O return pobjs, nil } -func (p *pruner) GetObjectName(obj runtime.Object) string { - // Not compare anything, it is safe to assign random - // object name. - return string(uuid.NewUUID()) +func (p *pruner) GetObjectName(obj runtime.Object) (string, error) { + gvk := obj.GetObjectKind().GroupVersionKind() + metadata, err := meta.Accessor(obj) + if err != nil { + return "", err + } + name := metadata.GetName() + ns := metadata.GetNamespace() + + group := "" + if gvk.Group != "" { + group = fmt.Sprintf("%v.", gvk.Group) + } + return group + fmt.Sprintf( + "%v.%v.%v.%v", + gvk.Version, + gvk.Kind, + ns, + name, + ), nil +} + +// MarkVisited marks visited namespaces and uids +func (p *pruner) MarkVisited(info *resource.Info) { + if info.Namespaced() { + p.visitedNamespaces.Insert(info.Namespace) + } + + metadata, err := meta.Accessor(info.Object) + if err != nil { + return + } + p.visitedUids.Insert(string(metadata.GetUID())) }