Skip to content

Commit e38e320

Browse files
committed
Moved prune functionality into its own file.
1 parent 07cb2fd commit e38e320

File tree

3 files changed

+254
-214
lines changed

3 files changed

+254
-214
lines changed

staging/src/k8s.io/kubectl/pkg/cmd/apply/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ go_library(
77
"apply_edit_last_applied.go",
88
"apply_set_last_applied.go",
99
"apply_view_last_applied.go",
10+
"prune.go",
1011
],
1112
importmap = "k8s.io/kubernetes/vendor/k8s.io/kubectl/pkg/cmd/apply",
1213
importpath = "k8s.io/kubectl/pkg/cmd/apply",

staging/src/k8s.io/kubectl/pkg/cmd/apply/apply.go

Lines changed: 10 additions & 214 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import (
2121
"fmt"
2222
"io"
2323
"net/http"
24-
"strings"
2524
"time"
2625

2726
"github.com/jonboulle/clockwork"
@@ -282,6 +281,13 @@ func (o *ApplyOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error {
282281
return err
283282
}
284283

284+
if o.Prune {
285+
o.PruneResources, err = parsePruneResources(o.Mapper, o.PruneWhitelist)
286+
if err != nil {
287+
return err
288+
}
289+
}
290+
285291
return nil
286292
}
287293

@@ -302,37 +308,6 @@ func validatePruneAll(prune, all bool, selector string) error {
302308
return nil
303309
}
304310

305-
func parsePruneResources(mapper meta.RESTMapper, gvks []string) ([]pruneResource, error) {
306-
pruneResources := []pruneResource{}
307-
for _, groupVersionKind := range gvks {
308-
gvk := strings.Split(groupVersionKind, "/")
309-
if len(gvk) != 3 {
310-
return nil, fmt.Errorf("invalid GroupVersionKind format: %v, please follow <group/version/kind>", groupVersionKind)
311-
}
312-
313-
if gvk[0] == "core" {
314-
gvk[0] = ""
315-
}
316-
mapping, err := mapper.RESTMapping(schema.GroupKind{Group: gvk[0], Kind: gvk[2]}, gvk[1])
317-
if err != nil {
318-
return pruneResources, err
319-
}
320-
var namespaced bool
321-
namespaceScope := mapping.Scope.Name()
322-
switch namespaceScope {
323-
case meta.RESTScopeNameNamespace:
324-
namespaced = true
325-
case meta.RESTScopeNameRoot:
326-
namespaced = false
327-
default:
328-
return pruneResources, fmt.Errorf("Unknown namespace scope: %q", namespaceScope)
329-
}
330-
331-
pruneResources = append(pruneResources, pruneResource{gvk[0], gvk[1], gvk[2], namespaced})
332-
}
333-
return pruneResources, nil
334-
}
335-
336311
func isIncompatibleServerError(err error) bool {
337312
// 415: Unsupported media type means we're talking to a server which doesn't
338313
// support server-side apply.
@@ -387,14 +362,6 @@ func (o *ApplyOptions) Run() error {
387362
OpenAPIGetter: o.DiscoveryClient,
388363
}
389364

390-
var err error
391-
if o.Prune {
392-
o.PruneResources, err = parsePruneResources(o.Mapper, o.PruneWhitelist)
393-
if err != nil {
394-
return err
395-
}
396-
}
397-
398365
visitedUids := sets.NewString()
399366
visitedNamespaces := sets.NewString()
400367

@@ -606,46 +573,9 @@ See http://k8s.io/docs/reference/using-api/api-concepts/#conflicts`, err)
606573
return err
607574
}
608575

609-
if !o.Prune {
610-
return nil
611-
}
612-
613-
p := pruner{
614-
mapper: o.Mapper,
615-
dynamicClient: o.DynamicClient,
616-
617-
labelSelector: o.Selector,
618-
visitedUids: visitedUids,
619-
620-
cascade: o.DeleteOptions.Cascade,
621-
dryRun: o.DryRun,
622-
serverDryRun: o.ServerDryRun,
623-
gracePeriod: o.DeleteOptions.GracePeriod,
624-
625-
toPrinter: o.ToPrinter,
626-
627-
out: o.Out,
628-
}
629-
630-
namespacedRESTMappings, nonNamespacedRESTMappings, err := getRESTMappings(o.Mapper, &(o.PruneResources))
631-
if err != nil {
632-
return fmt.Errorf("error retrieving RESTMappings to prune: %v", err)
633-
}
634-
635-
for n := range visitedNamespaces {
636-
if len(o.Namespace) != 0 && n != o.Namespace {
637-
continue
638-
}
639-
for _, m := range namespacedRESTMappings {
640-
if err := p.prune(n, m); err != nil {
641-
return fmt.Errorf("error pruning namespaced object %v: %v", m.GroupVersionKind, err)
642-
}
643-
}
644-
}
645-
for _, m := range nonNamespacedRESTMappings {
646-
if err := p.prune(metav1.NamespaceNone, m); err != nil {
647-
return fmt.Errorf("error pruning nonNamespaced object %v: %v", m.GroupVersionKind, err)
648-
}
576+
if o.Prune {
577+
p := newPruner(o, visitedUids, visitedNamespaces)
578+
return p.pruneAll(o)
649579
}
650580

651581
return nil
@@ -706,140 +636,6 @@ func (o *ApplyOptions) printObjects() error {
706636
return nil
707637
}
708638

709-
type pruneResource struct {
710-
group string
711-
version string
712-
kind string
713-
namespaced bool
714-
}
715-
716-
func (pr pruneResource) String() string {
717-
return fmt.Sprintf("%v/%v, Kind=%v, Namespaced=%v", pr.group, pr.version, pr.kind, pr.namespaced)
718-
}
719-
720-
func getRESTMappings(mapper meta.RESTMapper, pruneResources *[]pruneResource) (namespaced, nonNamespaced []*meta.RESTMapping, err error) {
721-
if len(*pruneResources) == 0 {
722-
// default whitelist
723-
// TODO: need to handle the older api versions - e.g. v1beta1 jobs. Github issue: #35991
724-
*pruneResources = []pruneResource{
725-
{"", "v1", "ConfigMap", true},
726-
{"", "v1", "Endpoints", true},
727-
{"", "v1", "Namespace", false},
728-
{"", "v1", "PersistentVolumeClaim", true},
729-
{"", "v1", "PersistentVolume", false},
730-
{"", "v1", "Pod", true},
731-
{"", "v1", "ReplicationController", true},
732-
{"", "v1", "Secret", true},
733-
{"", "v1", "Service", true},
734-
{"batch", "v1", "Job", true},
735-
{"batch", "v1beta1", "CronJob", true},
736-
{"extensions", "v1beta1", "Ingress", true},
737-
{"apps", "v1", "DaemonSet", true},
738-
{"apps", "v1", "Deployment", true},
739-
{"apps", "v1", "ReplicaSet", true},
740-
{"apps", "v1", "StatefulSet", true},
741-
}
742-
}
743-
744-
for _, resource := range *pruneResources {
745-
addedMapping, err := mapper.RESTMapping(schema.GroupKind{Group: resource.group, Kind: resource.kind}, resource.version)
746-
if err != nil {
747-
return nil, nil, fmt.Errorf("invalid resource %v: %v", resource, err)
748-
}
749-
if resource.namespaced {
750-
namespaced = append(namespaced, addedMapping)
751-
} else {
752-
nonNamespaced = append(nonNamespaced, addedMapping)
753-
}
754-
}
755-
756-
return namespaced, nonNamespaced, nil
757-
}
758-
759-
type pruner struct {
760-
mapper meta.RESTMapper
761-
dynamicClient dynamic.Interface
762-
763-
visitedUids sets.String
764-
labelSelector string
765-
fieldSelector string
766-
767-
cascade bool
768-
serverDryRun bool
769-
dryRun bool
770-
gracePeriod int
771-
772-
toPrinter func(string) (printers.ResourcePrinter, error)
773-
774-
out io.Writer
775-
}
776-
777-
func (p *pruner) prune(namespace string, mapping *meta.RESTMapping) error {
778-
objList, err := p.dynamicClient.Resource(mapping.Resource).
779-
Namespace(namespace).
780-
List(metav1.ListOptions{
781-
LabelSelector: p.labelSelector,
782-
FieldSelector: p.fieldSelector,
783-
})
784-
if err != nil {
785-
return err
786-
}
787-
788-
objs, err := meta.ExtractList(objList)
789-
if err != nil {
790-
return err
791-
}
792-
793-
for _, obj := range objs {
794-
metadata, err := meta.Accessor(obj)
795-
if err != nil {
796-
return err
797-
}
798-
annots := metadata.GetAnnotations()
799-
if _, ok := annots[corev1.LastAppliedConfigAnnotation]; !ok {
800-
// don't prune resources not created with apply
801-
continue
802-
}
803-
uid := metadata.GetUID()
804-
if p.visitedUids.Has(string(uid)) {
805-
continue
806-
}
807-
name := metadata.GetName()
808-
if !p.dryRun {
809-
if err := p.delete(namespace, name, mapping); err != nil {
810-
return err
811-
}
812-
}
813-
814-
printer, err := p.toPrinter("pruned")
815-
if err != nil {
816-
return err
817-
}
818-
printer.PrintObj(obj, p.out)
819-
}
820-
return nil
821-
}
822-
823-
func (p *pruner) delete(namespace, name string, mapping *meta.RESTMapping) error {
824-
return runDelete(namespace, name, mapping, p.dynamicClient, p.cascade, p.gracePeriod, p.serverDryRun)
825-
}
826-
827-
func runDelete(namespace, name string, mapping *meta.RESTMapping, c dynamic.Interface, cascade bool, gracePeriod int, serverDryRun bool) error {
828-
options := &metav1.DeleteOptions{}
829-
if gracePeriod >= 0 {
830-
options = metav1.NewDeleteOptions(int64(gracePeriod))
831-
}
832-
if serverDryRun {
833-
options.DryRun = []string{metav1.DryRunAll}
834-
}
835-
policy := metav1.DeletePropagationForeground
836-
if !cascade {
837-
policy = metav1.DeletePropagationOrphan
838-
}
839-
options.PropagationPolicy = &policy
840-
return c.Resource(mapping.Resource).Namespace(namespace).Delete(name, options)
841-
}
842-
843639
func (p *Patcher) delete(namespace, name string) error {
844640
return runDelete(namespace, name, p.Mapping, p.DynamicClient, p.Cascade, p.GracePeriod, p.ServerDryRun)
845641
}

0 commit comments

Comments
 (0)