@@ -22,24 +22,17 @@ import (
22
22
"k8s.io/client-go/dynamic"
23
23
"k8s.io/klog"
24
24
"k8s.io/kubectl/pkg/cmd/util"
25
- "k8s.io/kubectl/pkg/validation"
26
25
"sigs.k8s.io/cli-utils/pkg/apply/event"
27
26
"sigs.k8s.io/cli-utils/pkg/common"
28
27
"sigs.k8s.io/cli-utils/pkg/inventory"
29
- "sigs.k8s.io/cli-utils/pkg/object"
30
28
)
31
29
32
30
// PruneOptions encapsulates the necessary information to
33
31
// implement the prune functionality.
34
32
type PruneOptions struct {
35
- client dynamic.Interface
36
- builder * resource.Builder
37
- mapper meta.RESTMapper
38
- // The currently applied objects (as Infos), including the
39
- // current inventory object. These objects are used to
40
- // calculate the prune set after retrieving the previous
41
- // inventory objects.
42
- currentInventoryObject * resource.Info
33
+ invClient inventory.InventoryClient
34
+ client dynamic.Interface
35
+ mapper meta.RESTMapper
43
36
// Stores the UID for each of the currently applied objects.
44
37
// These UID's are written during the apply, and this data
45
38
// structure is shared. IMPORTANT: the apply task must
@@ -49,9 +42,7 @@ type PruneOptions struct {
49
42
// by the inventory label. This set should also include the
50
43
// current inventory object. Stored here to make testing
51
44
// easier by manually setting the retrieved inventory infos.
52
- pastInventoryObjects []* resource.Info
53
- retrievedInventoryObjects bool
54
- validator validation.Schema
45
+
55
46
// InventoryFactoryFunc wraps and returns an interface for the
56
47
// object which will load and store the inventory.
57
48
InventoryFactoryFunc func (* resource.Info ) inventory.Inventory
@@ -66,134 +57,21 @@ func NewPruneOptions(currentUids sets.String) *PruneOptions {
66
57
return po
67
58
}
68
59
69
- func (po * PruneOptions ) Initialize (factory util.Factory ) error {
60
+ func (po * PruneOptions ) Initialize (factory util.Factory , invClient inventory. InventoryClient ) error {
70
61
var err error
62
+ po .invClient = invClient
71
63
// Client/Builder fields from the Factory.
72
64
po .client , err = factory .DynamicClient ()
73
65
if err != nil {
74
66
return err
75
67
}
76
- po .builder = factory .NewBuilder ()
77
68
po .mapper , err = factory .ToRESTMapper ()
78
69
if err != nil {
79
70
return err
80
71
}
81
- po .validator , err = factory .Validator (false )
82
- if err != nil {
83
- return err
84
- }
85
- // Initialize past inventory objects as empty.
86
- po .pastInventoryObjects = []* resource.Info {}
87
- po .retrievedInventoryObjects = false
88
72
return nil
89
73
}
90
74
91
- // GetPreviousInventoryObjects returns the set of inventory objects
92
- // that have the same label as the current inventory object. Removes
93
- // the current inventory object from this set. Returns an error
94
- // if there is a problem retrieving the inventory objects.
95
- func (po * PruneOptions ) GetPreviousInventoryObjects (currentInv * resource.Info ) ([]inventory.Inventory , error ) {
96
- current , err := infoToObjMetadata (currentInv )
97
- if err != nil {
98
- return nil , err
99
- }
100
- label , err := inventory .RetrieveInventoryLabel (currentInv .Object )
101
- if err != nil {
102
- return nil , err
103
- }
104
- if _ , err := po .retrievePreviousInventoryObjects (current , label ); err != nil {
105
- return nil , err
106
- }
107
- // Remove the current inventory info from the previous inventory infos.
108
- pastInventoryInfos := []* resource.Info {}
109
- pastInventories := []inventory.Inventory {}
110
- for _ , pastInfo := range po .pastInventoryObjects {
111
- past , err := infoToObjMetadata (pastInfo )
112
- if err != nil {
113
- return nil , err
114
- }
115
- if ! current .Equals (past ) {
116
- pastInv := po .InventoryFactoryFunc (pastInfo )
117
- pastInventories = append (pastInventories , pastInv )
118
- pastInventoryInfos = append (pastInventoryInfos , pastInfo )
119
- }
120
- }
121
- po .pastInventoryObjects = pastInventoryInfos
122
- return pastInventories , nil
123
- }
124
-
125
- // retrievePreviousInventoryObjects requests the previous inventory objects
126
- // using the inventory label from the current inventory object. Sets
127
- // the field "pastInventoryObjects". Returns an error if the inventory
128
- // label doesn't exist for the current currentInventoryObject does not
129
- // exist or if the call to retrieve the past inventory objects fails.
130
- func (po * PruneOptions ) retrievePreviousInventoryObjects (current * object.ObjMetadata , label string ) ([]* resource.Info , error ) {
131
- if po .retrievedInventoryObjects {
132
- return po .pastInventoryObjects , nil
133
- }
134
- mapping , err := po .mapper .RESTMapping (current .GroupKind )
135
- if err != nil {
136
- return nil , err
137
- }
138
- groupResource := mapping .Resource .GroupResource ().String ()
139
- namespace := current .Namespace
140
- labelSelector := fmt .Sprintf ("%s=%s" , common .InventoryLabel , label )
141
- klog .V (4 ).Infof ("prune inventory object fetch: %s/%s/%s" , groupResource , namespace , labelSelector )
142
- retrievedInventoryInfos , err := po .builder .
143
- Unstructured ().
144
- // TODO: Check if this validator is necessary.
145
- Schema (po .validator ).
146
- ContinueOnError ().
147
- NamespaceParam (namespace ).DefaultNamespace ().
148
- ResourceTypes (groupResource ).
149
- LabelSelectorParam (labelSelector ).
150
- Flatten ().
151
- Do ().
152
- Infos ()
153
- if err != nil {
154
- return nil , err
155
- }
156
- po .pastInventoryObjects = retrievedInventoryInfos
157
- po .retrievedInventoryObjects = true
158
- klog .V (4 ).Infof ("prune %d inventory objects found" , len (po .pastInventoryObjects ))
159
- return retrievedInventoryInfos , nil
160
- }
161
-
162
- // infoToObjMetadata transforms the object represented by the passed "info"
163
- // into its Inventory representation. Returns error if the passed Info
164
- // is nil, or the Object in the Info is empty.
165
- func infoToObjMetadata (info * resource.Info ) (* object.ObjMetadata , error ) {
166
- if info == nil || info .Object == nil {
167
- return nil , fmt .Errorf ("empty resource.Info can not calculate as inventory" )
168
- }
169
- obj := info .Object
170
- gk := obj .GetObjectKind ().GroupVersionKind ().GroupKind ()
171
- return object .CreateObjMetadata (info .Namespace , info .Name , gk )
172
- }
173
-
174
- // UnionPastObjs takes a set of inventory objects (infos), returning the
175
- // union of the objects referenced by these inventory objects.
176
- // Returns an error if any of the passed objects are not inventory
177
- // objects, or if unable to retrieve the referenced objects from any
178
- // inventory object.
179
- func UnionPastObjs (pastInvs []inventory.Inventory ) ([]object.ObjMetadata , error ) {
180
- objSet := map [string ]object.ObjMetadata {}
181
- for _ , inv := range pastInvs {
182
- objs , err := inv .Load ()
183
- if err != nil {
184
- return nil , err
185
- }
186
- for _ , obj := range objs {
187
- objSet [obj .String ()] = obj // De-duping
188
- }
189
- }
190
- pastObjs := make ([]object.ObjMetadata , 0 , len (objSet ))
191
- for _ , obj := range objSet {
192
- pastObjs = append (pastObjs , obj )
193
- }
194
- return pastObjs , nil
195
- }
196
-
197
75
// Options defines a set of parameters that can be used to tune
198
76
// the behavior of the pruner.
199
77
type Options struct {
@@ -213,17 +91,12 @@ func (po *PruneOptions) Prune(currentObjects []*resource.Info, eventChannel chan
213
91
if ! found {
214
92
return fmt .Errorf ("current inventory object not found during prune" )
215
93
}
216
- po .currentInventoryObject = currentInventoryObject
217
94
klog .V (7 ).Infof ("prune current inventory object: %s/%s" ,
218
95
currentInventoryObject .Namespace , currentInventoryObject .Name )
219
96
220
97
// Retrieve previous inventory objects, and calculate the
221
98
// union of the previous applies as an inventory set.
222
- pastInventories , err := po .GetPreviousInventoryObjects (currentInventoryObject )
223
- if err != nil {
224
- return err
225
- }
226
- pastObjs , err := UnionPastObjs (pastInventories )
99
+ pastObjs , err := po .invClient .GetStoredObjRefs (currentInventoryObject )
227
100
if err != nil {
228
101
return err
229
102
}
@@ -287,7 +160,11 @@ func (po *PruneOptions) Prune(currentObjects []*resource.Info, eventChannel chan
287
160
}
288
161
}
289
162
// Delete previous inventory objects.
290
- for _ , pastGroupInfo := range po .pastInventoryObjects {
163
+ pastInventories , err := po .invClient .GetPreviousInventoryObjects (currentInventoryObject )
164
+ if err != nil {
165
+ return err
166
+ }
167
+ for _ , pastGroupInfo := range pastInventories {
291
168
if ! o .DryRun {
292
169
klog .V (7 ).Infof ("prune delete previous inventory object: %s/%s" ,
293
170
pastGroupInfo .Namespace , pastGroupInfo .Name )
0 commit comments