@@ -17,10 +17,6 @@ limitations under the License.
17
17
package ssa
18
18
19
19
import (
20
- "fmt"
21
- "reflect"
22
- "strings"
23
-
24
20
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
25
21
26
22
"sigs.k8s.io/cluster-api/internal/contract"
@@ -36,43 +32,26 @@ type FilterObjectInput struct {
36
32
// spec.ControlPlaneEndpoint.
37
33
// NOTE: ignore paths which point to an array are not supported by the current implementation.
38
34
IgnorePaths []contract.Path
39
-
40
- // DropEmptyStructAndNil instructs the Helper to drop all fields with values equal to empty struct or nil.
41
- // NOTE: This is required when using typed objects, because the DefaultUnstructuredConverter does
42
- // not handle omitzero (yet).
43
- DropEmptyStructAndNil bool
44
35
}
45
36
46
37
// FilterObject filter out changes not relevant for the controller.
47
38
func FilterObject (obj * unstructured.Unstructured , input * FilterObjectInput ) {
48
39
// filter out changes not in the allowed paths (fields to not consider, e.g. status);
49
- // also drop empty struct if required.
50
40
if len (input .AllowedPaths ) > 0 {
51
41
FilterIntent (& FilterIntentInput {
52
- Path : contract.Path {},
53
- Value : obj .Object ,
54
- ShouldFilter : IsPathNotAllowed (input .AllowedPaths ),
55
- DropEmptyStructAndNil : input .DropEmptyStructAndNil ,
42
+ Path : contract.Path {},
43
+ Value : obj .Object ,
44
+ ShouldFilter : IsPathNotAllowed (input .AllowedPaths ),
56
45
})
57
46
}
58
47
59
48
// filter out changes for ignore paths (well known fields owned by other controllers, e.g.
60
- // spec.controlPlaneEndpoint in the InfrastructureCluster object); also drop empty struct if required.
49
+ // spec.controlPlaneEndpoint in the InfrastructureCluster object);
61
50
if len (input .IgnorePaths ) > 0 {
62
51
FilterIntent (& FilterIntentInput {
63
- Path : contract.Path {},
64
- Value : obj .Object ,
65
- ShouldFilter : IsPathIgnored (input .IgnorePaths ),
66
- DropEmptyStructAndNil : input .DropEmptyStructAndNil ,
67
- })
68
- }
69
-
70
- // DropEmptyStructAndNil if not already done above.
71
- if input .DropEmptyStructAndNil && len (input .AllowedPaths ) == 0 && len (input .IgnorePaths ) == 0 {
72
- FilterIntent (& FilterIntentInput {
73
- Path : contract.Path {},
74
- Value : obj .Object ,
75
- DropEmptyStructAndNil : input .DropEmptyStructAndNil ,
52
+ Path : contract.Path {},
53
+ Value : obj .Object ,
54
+ ShouldFilter : IsPathIgnored (input .IgnorePaths ),
76
55
})
77
56
}
78
57
}
@@ -84,71 +63,38 @@ func FilterObject(obj *unstructured.Unstructured, input *FilterObjectInput) {
84
63
// all of them are defined in reconcile_state.go and are targeting well-known fields inside nested maps.
85
64
// Allowed paths / ignore paths which point to an array are not supported by the current implementation.
86
65
func FilterIntent (ctx * FilterIntentInput ) bool {
66
+ value , ok := ctx .Value .(map [string ]interface {})
67
+ if ! ok {
68
+ return false
69
+ }
70
+
87
71
gotDeletions := false
72
+ for field := range value {
73
+ fieldCtx := & FilterIntentInput {
74
+ // Compose the Path for the nested field.
75
+ Path : ctx .Path .Append (field ),
76
+ // Gets the original and the modified Value for the field.
77
+ Value : value [field ],
78
+ // Carry over global values from the context.
79
+ ShouldFilter : ctx .ShouldFilter ,
80
+ }
88
81
89
- switch value := ctx .Value .(type ) {
90
- case map [string ]interface {}:
91
- for field := range value {
92
- fieldCtx := & FilterIntentInput {
93
- // Compose the Path for the nested field.
94
- Path : ctx .Path .Append (field ),
95
- // Gets the original and the modified Value for the field.
96
- Value : value [field ],
97
- // Carry over global values from the context.
98
- ShouldFilter : ctx .ShouldFilter ,
99
- DropEmptyStructAndNil : ctx .DropEmptyStructAndNil ,
100
- }
82
+ // If the field should be filtered out, delete it from the modified object.
83
+ if fieldCtx .ShouldFilter != nil && fieldCtx .ShouldFilter (fieldCtx .Path ) {
84
+ delete (value , field )
85
+ gotDeletions = true
86
+ continue
87
+ }
101
88
102
- // If the field should be filtered out, delete it from the modified object.
103
- if fieldCtx .ShouldFilter != nil && fieldCtx .ShouldFilter (fieldCtx .Path ) {
89
+ // Process nested fields and get in return if FilterIntent removed fields.
90
+ if FilterIntent (fieldCtx ) {
91
+ gotDeletions = true
92
+ // Ensure we are not leaving empty maps around.
93
+ if v , ok := fieldCtx .Value .(map [string ]interface {}); ok && len (v ) == 0 {
104
94
delete (value , field )
105
- gotDeletions = true
106
- continue
107
- }
108
-
109
- // TODO: Can be removed once we bumped to k8s.io v0.34 because the DefaultUnstructuredConverter will then handle omitzero
110
- if strings .HasPrefix (fieldCtx .Path .String (), "spec" ) && fieldCtx .DropEmptyStructAndNil {
111
- // If empty struct should be dropped and the value is a empty struct, delete it from the modified object.
112
- if reflect .DeepEqual (fieldCtx .Value , map [string ]interface {}{}) {
113
- delete (value , field )
114
- gotDeletions = true
115
- continue
116
- }
117
- // If nil should be dropped and the value is nil, delete it from the modified object.
118
- if reflect .DeepEqual (fieldCtx .Value , nil ) {
119
- delete (value , field )
120
- gotDeletions = true
121
- continue
122
- }
123
- }
124
-
125
- // Process nested fields and get in return if FilterIntent removed fields.
126
- if FilterIntent (fieldCtx ) {
127
- gotDeletions = true
128
- // Ensure we are not leaving empty maps around.
129
- if v , ok := fieldCtx .Value .(map [string ]interface {}); ok && len (v ) == 0 {
130
- delete (value , field )
131
- }
132
- }
133
- }
134
- case []interface {}:
135
- // TODO: Can be removed once we bumped to k8s.io v0.34 because the DefaultUnstructuredConverter will then handle omitzero
136
- if strings .HasPrefix (ctx .Path .String (), "spec" ) && ctx .DropEmptyStructAndNil {
137
- for i , v := range value {
138
- fieldCtx := & FilterIntentInput {
139
- // Compose the Path for the nested field.
140
- Path : ctx .Path .Append (fmt .Sprintf ("[%d]" , i )),
141
- // Not supporting ShouldFilter within arrays, so not setting it.
142
- Value : v ,
143
- DropEmptyStructAndNil : ctx .DropEmptyStructAndNil ,
144
- }
145
- if FilterIntent (fieldCtx ) {
146
- gotDeletions = true
147
- }
148
95
}
149
96
}
150
97
}
151
-
152
98
return gotDeletions
153
99
}
154
100
@@ -163,8 +109,6 @@ type FilterIntentInput struct {
163
109
164
110
// ShouldFilter handle the func that determine if the current Path should be dropped or not.
165
111
ShouldFilter func (path contract.Path ) bool
166
-
167
- DropEmptyStructAndNil bool
168
112
}
169
113
170
114
// IsPathAllowed returns true when the Path is one of the AllowedPaths.
0 commit comments