Skip to content

Commit 89e1603

Browse files
authored
Merge pull request #599 from mortent/DestoryerBuilder
Use builder for creating the destroyer
2 parents 1669bb3 + 5240fc4 commit 89e1603

File tree

8 files changed

+201
-115
lines changed

8 files changed

+201
-115
lines changed

cmd/destroy/cmddestroy.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,10 @@ func (r *Runner) RunE(cmd *cobra.Command, args []string) error {
118118
if err != nil {
119119
return err
120120
}
121-
d, err := apply.NewDestroyer(r.factory, invClient)
121+
d, err := apply.NewDestroyerBuilder().
122+
WithFactory(r.factory).
123+
WithInventoryClient(invClient).
124+
Build()
122125
if err != nil {
123126
return err
124127
}

cmd/preview/cmdpreview.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,10 @@ func (r *Runner) RunE(cmd *cobra.Command, args []string) error {
156156
InventoryPolicy: inventoryPolicy,
157157
})
158158
} else {
159-
d, err := apply.NewDestroyer(r.factory, invClient)
159+
d, err := apply.NewDestroyerBuilder().
160+
WithFactory(r.factory).
161+
WithInventoryClient(invClient).
162+
Build()
160163
if err != nil {
161164
return err
162165
}

pkg/apply/applier_builder.go

Lines changed: 1 addition & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@
44
package apply
55

66
import (
7-
"errors"
8-
"fmt"
9-
107
"k8s.io/apimachinery/pkg/api/meta"
118
"k8s.io/cli-runtime/pkg/resource"
129
"k8s.io/client-go/discovery"
@@ -20,15 +17,7 @@ import (
2017
)
2118

2219
type ApplierBuilder struct {
23-
// factory is only used to retrieve things that have not been provided explicitly.
24-
factory util.Factory
25-
invClient inventory.Client
26-
client dynamic.Interface
27-
discoClient discovery.CachedDiscoveryInterface
28-
mapper meta.RESTMapper
29-
restConfig *rest.Config
30-
unstructuredClientForMapping func(*meta.RESTMapping) (resource.RESTClient, error)
31-
statusWatcher watcher.StatusWatcher
20+
commonBuilder
3221
}
3322

3423
// NewApplierBuilder returns a new ApplierBuilder.
@@ -58,60 +47,6 @@ func (b *ApplierBuilder) Build() (*Applier, error) {
5847
}, nil
5948
}
6049

61-
func (b *ApplierBuilder) finalize() (*ApplierBuilder, error) {
62-
bx := *b // make a copy before mutating any fields. Shallow copy is good enough.
63-
var err error
64-
if bx.invClient == nil {
65-
return nil, errors.New("inventory client must be provided")
66-
}
67-
if bx.client == nil {
68-
if bx.factory == nil {
69-
return nil, fmt.Errorf("a factory must be provided or all other options: %v", err)
70-
}
71-
bx.client, err = bx.factory.DynamicClient()
72-
if err != nil {
73-
return nil, fmt.Errorf("error getting dynamic client: %v", err)
74-
}
75-
}
76-
if bx.discoClient == nil {
77-
if bx.factory == nil {
78-
return nil, fmt.Errorf("a factory must be provided or all other options: %v", err)
79-
}
80-
bx.discoClient, err = bx.factory.ToDiscoveryClient()
81-
if err != nil {
82-
return nil, fmt.Errorf("error getting discovery client: %v", err)
83-
}
84-
}
85-
if bx.mapper == nil {
86-
if bx.factory == nil {
87-
return nil, fmt.Errorf("a factory must be provided or all other options: %v", err)
88-
}
89-
bx.mapper, err = bx.factory.ToRESTMapper()
90-
if err != nil {
91-
return nil, fmt.Errorf("error getting rest mapper: %v", err)
92-
}
93-
}
94-
if bx.restConfig == nil {
95-
if bx.factory == nil {
96-
return nil, fmt.Errorf("a factory must be provided or all other options: %v", err)
97-
}
98-
bx.restConfig, err = bx.factory.ToRESTConfig()
99-
if err != nil {
100-
return nil, fmt.Errorf("error getting rest config: %v", err)
101-
}
102-
}
103-
if bx.unstructuredClientForMapping == nil {
104-
if bx.factory == nil {
105-
return nil, fmt.Errorf("a factory must be provided or all other options: %v", err)
106-
}
107-
bx.unstructuredClientForMapping = bx.factory.UnstructuredClientForMapping
108-
}
109-
if bx.statusWatcher == nil {
110-
bx.statusWatcher = watcher.NewDefaultStatusWatcher(bx.client, bx.mapper)
111-
}
112-
return &bx, nil
113-
}
114-
11550
func (b *ApplierBuilder) WithFactory(factory util.Factory) *ApplierBuilder {
11651
b.factory = factory
11752
return b

pkg/apply/builder.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// Copyright 2022 The Kubernetes Authors.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package apply
5+
6+
import (
7+
"errors"
8+
"fmt"
9+
10+
"k8s.io/apimachinery/pkg/api/meta"
11+
"k8s.io/cli-runtime/pkg/resource"
12+
"k8s.io/client-go/discovery"
13+
"k8s.io/client-go/dynamic"
14+
"k8s.io/client-go/rest"
15+
"k8s.io/kubectl/pkg/cmd/util"
16+
"sigs.k8s.io/cli-utils/pkg/inventory"
17+
"sigs.k8s.io/cli-utils/pkg/kstatus/watcher"
18+
)
19+
20+
type commonBuilder struct {
21+
// factory is only used to retrieve things that have not been provided explicitly.
22+
factory util.Factory
23+
invClient inventory.Client
24+
client dynamic.Interface
25+
discoClient discovery.CachedDiscoveryInterface
26+
mapper meta.RESTMapper
27+
restConfig *rest.Config
28+
unstructuredClientForMapping func(*meta.RESTMapping) (resource.RESTClient, error)
29+
statusWatcher watcher.StatusWatcher
30+
}
31+
32+
func (cb *commonBuilder) finalize() (*commonBuilder, error) {
33+
cx := *cb // make a copy before mutating any fields. Shallow copy is good enough.
34+
var err error
35+
if cx.invClient == nil {
36+
return nil, errors.New("inventory client must be provided")
37+
}
38+
if cx.client == nil {
39+
if cx.factory == nil {
40+
return nil, fmt.Errorf("a factory must be provided or all other options: %v", err)
41+
}
42+
cx.client, err = cx.factory.DynamicClient()
43+
if err != nil {
44+
return nil, fmt.Errorf("error getting dynamic client: %v", err)
45+
}
46+
}
47+
if cx.discoClient == nil {
48+
if cx.factory == nil {
49+
return nil, fmt.Errorf("a factory must be provided or all other options: %v", err)
50+
}
51+
cx.discoClient, err = cx.factory.ToDiscoveryClient()
52+
if err != nil {
53+
return nil, fmt.Errorf("error getting discovery client: %v", err)
54+
}
55+
}
56+
if cx.mapper == nil {
57+
if cx.factory == nil {
58+
return nil, fmt.Errorf("a factory must be provided or all other options: %v", err)
59+
}
60+
cx.mapper, err = cx.factory.ToRESTMapper()
61+
if err != nil {
62+
return nil, fmt.Errorf("error getting rest mapper: %v", err)
63+
}
64+
}
65+
if cx.restConfig == nil {
66+
if cx.factory == nil {
67+
return nil, fmt.Errorf("a factory must be provided or all other options: %v", err)
68+
}
69+
cx.restConfig, err = cx.factory.ToRESTConfig()
70+
if err != nil {
71+
return nil, fmt.Errorf("error getting rest config: %v", err)
72+
}
73+
}
74+
if cx.unstructuredClientForMapping == nil {
75+
if cx.factory == nil {
76+
return nil, fmt.Errorf("a factory must be provided or all other options: %v", err)
77+
}
78+
cx.unstructuredClientForMapping = cx.factory.UnstructuredClientForMapping
79+
}
80+
if cx.statusWatcher == nil {
81+
cx.statusWatcher = watcher.NewDefaultStatusWatcher(cx.client, cx.mapper)
82+
}
83+
return &cx, nil
84+
}

pkg/apply/common_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,10 @@ func newTestDestroyer(
109109

110110
invClient := newTestInventory(t, tf)
111111

112-
destroyer, err := NewDestroyer(tf, invClient)
112+
destroyer, err := NewDestroyerBuilder().
113+
WithFactory(tf).
114+
WithInventoryClient(invClient).
115+
Build()
113116
require.NoError(t, err)
114117
destroyer.statusWatcher = statusWatcher
115118

pkg/apply/destroyer.go

Lines changed: 12 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ import (
88
"fmt"
99
"time"
1010

11+
"k8s.io/apimachinery/pkg/api/meta"
1112
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
13+
"k8s.io/client-go/discovery"
14+
"k8s.io/client-go/dynamic"
1215
"k8s.io/klog/v2"
13-
cmdutil "k8s.io/kubectl/pkg/cmd/util"
1416
"sigs.k8s.io/cli-utils/pkg/apis/actuation"
1517
"sigs.k8s.io/cli-utils/pkg/apply/cache"
1618
"sigs.k8s.io/cli-utils/pkg/apply/event"
@@ -26,41 +28,16 @@ import (
2628
"sigs.k8s.io/cli-utils/pkg/object/validation"
2729
)
2830

29-
// NewDestroyer returns a new destroyer. It will set up the ApplyOptions and
30-
// PruneOptions which are responsible for capturing any command line flags.
31-
// It currently requires IOStreams, but this is a legacy from when
32-
// the ApplyOptions were responsible for printing progress. This is now
33-
// handled by a separate printer with the KubectlPrinterAdapter bridging
34-
// between the two.
35-
func NewDestroyer(factory cmdutil.Factory, invClient inventory.Client) (*Destroyer, error) {
36-
pruner, err := prune.NewPruner(factory, invClient)
37-
if err != nil {
38-
return nil, fmt.Errorf("error setting up PruneOptions: %w", err)
39-
}
40-
client, err := factory.DynamicClient()
41-
if err != nil {
42-
return nil, err
43-
}
44-
mapper, err := factory.ToRESTMapper()
45-
if err != nil {
46-
return nil, err
47-
}
48-
statusWatcher := watcher.NewDefaultStatusWatcher(client, mapper)
49-
return &Destroyer{
50-
pruner: pruner,
51-
statusWatcher: statusWatcher,
52-
factory: factory,
53-
invClient: invClient,
54-
}, nil
55-
}
56-
5731
// Destroyer performs the step of grabbing all the previous inventory objects and
5832
// prune them. This also deletes all the previous inventory objects
5933
type Destroyer struct {
6034
pruner *prune.Pruner
6135
statusWatcher watcher.StatusWatcher
62-
factory cmdutil.Factory
6336
invClient inventory.Client
37+
mapper meta.RESTMapper
38+
client dynamic.Interface
39+
openAPIGetter discovery.OpenAPISchemaInterface
40+
infoHelper info.Helper
6441
}
6542

6643
type DestroyerOptions struct {
@@ -112,18 +89,13 @@ func (d *Destroyer) Run(ctx context.Context, invInfo inventory.Info, options Des
11289
handleError(eventChannel, err)
11390
return
11491
}
115-
mapper, err := d.factory.ToRESTMapper()
116-
if err != nil {
117-
handleError(eventChannel, err)
118-
return
119-
}
12092

12193
// Validate the resources to make sure we catch those problems early
12294
// before anything has been updated in the cluster.
12395
vCollector := &validation.Collector{}
12496
validator := &validation.Validator{
12597
Collector: vCollector,
126-
Mapper: mapper,
98+
Mapper: d.mapper,
12799
}
128100
validator.Validate(deleteObjs)
129101

@@ -132,11 +104,6 @@ func (d *Destroyer) Run(ctx context.Context, invInfo inventory.Info, options Des
132104
taskContext := taskrunner.NewTaskContext(eventChannel, resourceCache)
133105

134106
klog.V(4).Infoln("destroyer building task queue...")
135-
dynamicClient, err := d.factory.DynamicClient()
136-
if err != nil {
137-
handleError(eventChannel, err)
138-
return
139-
}
140107
deleteFilters := []filter.ValidationFilter{
141108
filter.PreventRemoveFilter{},
142109
filter.InventoryPolicyPruneFilter{
@@ -151,10 +118,10 @@ func (d *Destroyer) Run(ctx context.Context, invInfo inventory.Info, options Des
151118
}
152119
taskBuilder := &solver.TaskQueueBuilder{
153120
Pruner: d.pruner,
154-
DynamicClient: dynamicClient,
155-
OpenAPIGetter: d.factory.OpenAPIGetter(),
156-
InfoHelper: info.NewHelper(mapper, d.factory.UnstructuredClientForMapping),
157-
Mapper: mapper,
121+
DynamicClient: d.client,
122+
OpenAPIGetter: d.openAPIGetter,
123+
InfoHelper: d.infoHelper,
124+
Mapper: d.mapper,
158125
InvClient: d.invClient,
159126
Collector: vCollector,
160127
PruneFilters: deleteFilters,

0 commit comments

Comments
 (0)