@@ -29,11 +29,40 @@ static <R extends HasMetadata, P extends HasMetadata> Matcher<R, P> matcherFor(
29
29
@ Override
30
30
public Result <R > match (R actualResource , P primary , Context <P > context ) {
31
31
var desired = dependentResource .desired (primary , context );
32
- return match (desired , actualResource , false );
32
+ return match (desired , actualResource , false , false );
33
33
}
34
34
35
35
public static <R extends HasMetadata > Result <R > match (R desired , R actualResource ,
36
36
boolean considerMetadata ) {
37
+ return match (desired , actualResource , considerMetadata , false );
38
+ }
39
+
40
+ /**
41
+ * Determines whether the specified actual resource matches the specified desired resource,
42
+ * possibly considering metadata and deeper equality checks.
43
+ *
44
+ * @param desired the desired resource
45
+ * @param actualResource the actual resource
46
+ * @param considerMetadata {@code true} if labels and annotations will be checked for equality,
47
+ * {@code false} otherwise (meaning that metadata changes will be ignored for matching
48
+ * purposes)
49
+ * @param equality if {@code false}, the algorithm checks if the properties in the desired
50
+ * resource spec are same as in the actual resource spec. The reason is that admission
51
+ * controllers and default Kubernetes controllers might add default values to some
52
+ * properties which are not set in the desired resources' spec and comparing it with simple
53
+ * equality check would mean that such resource will not match (while conceptually should).
54
+ * However, there is an issue with this for example if desired spec contains a list of
55
+ * values and a value is removed, this still will match the actual state from previous
56
+ * reconciliation. Setting this parameter to {@code true}, will match the resources only if
57
+ * all properties and values are equal. This could be implemented also by overriding equals
58
+ * method of spec, should be done as an optimization - this implementation does not require
59
+ * that.
60
+ *
61
+ * @return results of matching
62
+ * @param <R> resource
63
+ */
64
+ public static <R extends HasMetadata > Result <R > match (R desired , R actualResource ,
65
+ boolean considerMetadata , boolean equality ) {
37
66
if (considerMetadata ) {
38
67
final var desiredMetadata = desired .getMetadata ();
39
68
final var actualMetadata = actualResource .getMetadata ();
@@ -61,6 +90,12 @@ public static <R extends HasMetadata> Result<R> match(R desired, R actualResourc
61
90
var desiredSpecNode = objectMapper .valueToTree (ReconcilerUtils .getSpec (desired ));
62
91
var actualSpecNode = objectMapper .valueToTree (ReconcilerUtils .getSpec (actualResource ));
63
92
var diffJsonPatch = JsonDiff .asJson (desiredSpecNode , actualSpecNode );
93
+ // In case of equality is set to true, no diffs are allowed, so we return early if diffs exist
94
+ // On contrary (if equality is false), "add" is allowed for cases when for some
95
+ // resources Kubernetes fills-in values into spec.
96
+ if (equality && diffJsonPatch .size () > 0 ) {
97
+ return Result .computed (false , desired );
98
+ }
64
99
for (int i = 0 ; i < diffJsonPatch .size (); i ++) {
65
100
String operation = diffJsonPatch .get (i ).get ("op" ).asText ();
66
101
if (!operation .equals ("add" )) {
@@ -90,10 +125,17 @@ public static <R extends HasMetadata> Result<R> match(R desired, R actualResourc
90
125
* @param <P> the type of primary resources associated with the secondary resources we want to
91
126
* match
92
127
*/
128
+ public static <R extends HasMetadata , P extends HasMetadata > Result <R > match (
129
+ KubernetesDependentResource <R , P > dependentResource , R actualResource , P primary ,
130
+ Context <P > context , boolean considerMetadata , boolean strongEquality ) {
131
+ final var desired = dependentResource .desired (primary , context );
132
+ return match (desired , actualResource , considerMetadata , strongEquality );
133
+ }
134
+
93
135
public static <R extends HasMetadata , P extends HasMetadata > Result <R > match (
94
136
KubernetesDependentResource <R , P > dependentResource , R actualResource , P primary ,
95
137
Context <P > context , boolean considerMetadata ) {
96
138
final var desired = dependentResource .desired (primary , context );
97
- return match (desired , actualResource , considerMetadata );
139
+ return match (desired , actualResource , considerMetadata , false );
98
140
}
99
141
}
0 commit comments