@@ -41,6 +41,10 @@ public class SSABasedGenericKubernetesResourceMatcher<R extends HasMetadata> {
4141 public static final String APPLY_OPERATION = "Apply" ;
4242 public static final String DOT_KEY = "." ;
4343
44+ private static final List <String > IGNORED_METADATA =
45+ Arrays .asList ("creationTimestamp" , "deletionTimestamp" ,
46+ "generation" , "selfLink" , "uid" );
47+
4448 @ SuppressWarnings ("unchecked" )
4549 public static <L extends HasMetadata > SSABasedGenericKubernetesResourceMatcher <L > getInstance () {
4650 return INSTANCE ;
@@ -58,11 +62,10 @@ public static <L extends HasMetadata> SSABasedGenericKubernetesResourceMatcher<L
5862 private static final Logger log =
5963 LoggerFactory .getLogger (SSABasedGenericKubernetesResourceMatcher .class );
6064
61-
6265 @ SuppressWarnings ("unchecked" )
6366 public boolean matches (R actual , R desired , Context <?> context ) {
64- var optionalManagedFieldsEntry =
65- checkIfFieldManagerExists ( actual , context .getControllerConfiguration ().fieldManager ());
67+ var optionalManagedFieldsEntry = checkIfFieldManagerExists ( actual ,
68+ context .getControllerConfiguration ().fieldManager ());
6669 // If no field is managed by our controller, that means the controller hasn't touched the
6770 // resource yet and the resource probably doesn't match the desired state. Not matching here
6871 // means that the resource will need to be updated and since this will be done using SSA, the
@@ -86,7 +89,8 @@ public boolean matches(R actual, R desired, Context<?> context) {
8689
8790 var prunedActual = new HashMap <String , Object >(actualMap .size ());
8891 keepOnlyManagedFields (prunedActual , actualMap ,
89- managedFieldsEntry .getFieldsV1 ().getAdditionalProperties (), objectMapper );
92+ managedFieldsEntry .getFieldsV1 ().getAdditionalProperties (),
93+ objectMapper );
9094
9195 removeIrrelevantValues (desiredMap );
9296
@@ -110,9 +114,8 @@ private void sanitizeState(R actual, R desired, Map<String, Object> actualMap) {
110114 for (int i = 0 ; i < claims ; i ++) {
111115 if (desiredStatefulSet .getSpec ().getVolumeClaimTemplates ().get (i ).getSpec ()
112116 .getVolumeMode () == null ) {
113- Optional
114- .ofNullable (GenericKubernetesResource .get (actualMap , "spec" , "volumeClaimTemplates" ,
115- i , "spec" ))
117+ Optional .ofNullable (
118+ GenericKubernetesResource .get (actualMap , "spec" , "volumeClaimTemplates" , i , "spec" ))
116119 .map (Map .class ::cast ).ifPresent (m -> m .remove ("volumeMode" ));
117120 }
118121 if (desiredStatefulSet .getSpec ().getVolumeClaimTemplates ().get (i ).getStatus () == null ) {
@@ -131,6 +134,7 @@ private static void removeIrrelevantValues(Map<String, Object> desiredMap) {
131134 var metadata = (Map <String , Object >) desiredMap .get (METADATA_KEY );
132135 metadata .remove (NAME_KEY );
133136 metadata .remove (NAMESPACE_KEY );
137+ IGNORED_METADATA .forEach (metadata ::remove );
134138 if (metadata .isEmpty ()) {
135139 desiredMap .remove (METADATA_KEY );
136140 }
@@ -163,7 +167,8 @@ private static void keepOnlyManagedFields(Map<String, Object> result,
163167 } else {
164168 // basically if we should traverse further
165169 fillResultsAndTraverseFurther (result , actualMap , managedFields , objectMapper , key ,
166- keyInActual , managedFieldValue );
170+ keyInActual ,
171+ managedFieldValue );
167172 }
168173 } else {
169174 // this should handle the case when the value is complex in the actual map (not just a
@@ -181,8 +186,9 @@ private static void keepOnlyManagedFields(Map<String, Object> result,
181186
182187 @ SuppressWarnings ("unchecked" )
183188 private static void fillResultsAndTraverseFurther (Map <String , Object > result ,
184- Map <String , Object > actualMap , Map <String , Object > managedFields ,
185- KubernetesSerialization objectMapper , String key , String keyInActual ,
189+ Map <String , Object > actualMap ,
190+ Map <String , Object > managedFields , KubernetesSerialization objectMapper , String key ,
191+ String keyInActual ,
186192 Object managedFieldValue ) {
187193 var emptyMapValue = new HashMap <String , Object >();
188194 result .put (keyInActual , emptyMapValue );
@@ -223,8 +229,9 @@ private static void handleListKeyEntrySet(Map<String, Object> result,
223229 if (DOT_KEY .equals (listEntry .getKey ())) {
224230 continue ;
225231 }
226- var actualListEntry = selectListEntryBasedOnKey (keyWithoutPrefix (listEntry .getKey ()),
227- actualValueList , objectMapper );
232+ var actualListEntry =
233+ selectListEntryBasedOnKey (keyWithoutPrefix (listEntry .getKey ()), actualValueList ,
234+ objectMapper );
228235 targetValuesByIndex .put (actualListEntry .getKey (), actualListEntry .getValue ());
229236 managedEntryByIndex .put (actualListEntry .getKey (), (Map <String , Object >) listEntry .getValue ());
230237 }
@@ -301,8 +308,7 @@ private static boolean isKeyPrefixedSkippingDotKey(Set<Map.Entry<String, Object>
301308 @ SuppressWarnings ("unchecked" )
302309 private static java .util .Map .Entry <Integer , Map <String , Object >> selectListEntryBasedOnKey (
303310 String key ,
304- List <Map <String , Object >> values ,
305- KubernetesSerialization objectMapper ) {
311+ List <Map <String , Object >> values , KubernetesSerialization objectMapper ) {
306312 Map <String , Object > ids = objectMapper .unmarshal (key , Map .class );
307313 List <Map <String , Object >> possibleTargets = new ArrayList <>(1 );
308314 int index = -1 ;
@@ -314,9 +320,8 @@ private static java.util.Map.Entry<Integer, Map<String, Object>> selectListEntry
314320 }
315321 }
316322 if (possibleTargets .isEmpty ()) {
317- throw new IllegalStateException (
318- "Cannot find list element for key:" + key + ", in map: "
319- + values .stream ().map (Map ::keySet ).collect (Collectors .toList ()));
323+ throw new IllegalStateException ("Cannot find list element for key:" + key + ", in map: "
324+ + values .stream ().map (Map ::keySet ).collect (Collectors .toList ()));
320325 }
321326 if (possibleTargets .size () > 1 ) {
322327 throw new IllegalStateException (
@@ -327,7 +332,6 @@ private static java.util.Map.Entry<Integer, Map<String, Object>> selectListEntry
327332 return new AbstractMap .SimpleEntry <>(finalIndex , possibleTargets .get (0 ));
328333 }
329334
330-
331335 private Optional <ManagedFieldsEntry > checkIfFieldManagerExists (R actual , String fieldManager ) {
332336 var targetManagedFields = actual .getMetadata ().getManagedFields ().stream ()
333337 // Only the apply operations are interesting for us since those were created properly be SSA
@@ -338,14 +342,14 @@ private Optional<ManagedFieldsEntry> checkIfFieldManagerExists(R actual, String
338342 .collect (Collectors .toList ());
339343 if (targetManagedFields .isEmpty ()) {
340344 log .debug ("No field manager exists for resource {} with name: {} and operation Apply " ,
341- actual .getKind (), actual .getMetadata ().getName ());
345+ actual .getKind (),
346+ actual .getMetadata ().getName ());
342347 return Optional .empty ();
343348 }
344349 // this should not happen in theory
345350 if (targetManagedFields .size () > 1 ) {
346- throw new OperatorException (
347- "More than one field manager exists with name: " + fieldManager + "in resource: " +
348- actual .getKind () + " with name: " + actual .getMetadata ().getName ());
351+ throw new OperatorException ("More than one field manager exists with name: " + fieldManager
352+ + "in resource: " + actual .getKind () + " with name: " + actual .getMetadata ().getName ());
349353 }
350354 return Optional .of (targetManagedFields .get (0 ));
351355 }
0 commit comments