16
16
import java .util .Map ;
17
17
import java .util .Objects ;
18
18
import java .util .Optional ;
19
- import java .util .regex .Pattern ;
20
19
import java .util .stream .Collectors ;
21
20
import javax .annotation .Nonnull ;
22
21
@@ -69,7 +68,7 @@ public class ConfigMapHelper {
69
68
70
69
private static final String SCRIPT_LOCATION = "/scripts" ;
71
70
private static final String UPDATEDOMAINRESULT = "UPDATEDOMAINRESULT" ;
72
- private static final ConfigMapComparator COMPARATOR = new ConfigMapComparatorImpl ();
71
+ private static final ConfigMapComparator COMPARATOR = new ConfigMapComparator ();
73
72
74
73
private static final FileGroupReader scriptReader = new FileGroupReader (SCRIPT_LOCATION );
75
74
@@ -82,12 +81,8 @@ private ConfigMapHelper() {
82
81
* @param domainNamespace the domain's namespace
83
82
* @return Step for creating config map containing scripts
84
83
*/
85
- public static Step createScriptConfigMapStep (String domainNamespace ) {
86
- return new ScriptConfigMapStep (domainNamespace );
87
- }
88
-
89
- static FileGroupReader getScriptReader () {
90
- return scriptReader ;
84
+ public static Step createScriptConfigMapStep (String domainNamespace , SemanticVersion productVersion ) {
85
+ return new ScriptConfigMapStep (domainNamespace , productVersion );
91
86
}
92
87
93
88
static Map <String , String > parseIntrospectorResult (String text , String domainUid ) {
@@ -162,23 +157,25 @@ public static String getIntrospectorConfigMapName(String domainUid) {
162
157
return IntrospectorConfigMapConstants .getIntrospectorConfigMapName (domainUid , 0 );
163
158
}
164
159
165
- abstract static class ConfigMapComparator {
166
- boolean containsAll (V1ConfigMap actual , V1ConfigMap expected ) {
167
- return containsAllData (getData (actual ), getData (expected ));
168
- }
160
+ static class ConfigMapComparator {
161
+ boolean isOutdated (SemanticVersion productVersion , V1ConfigMap actual , V1ConfigMap expected ) {
162
+ // Check product version label
163
+ if (productVersion != null ) {
164
+ SemanticVersion currentVersion = KubernetesUtils .getProductVersionFromMetadata (actual .getMetadata ());
165
+ if (currentVersion == null || productVersion .compareTo (currentVersion ) > 0 ) {
166
+ return true ;
167
+ }
168
+ }
169
169
170
- private Map <String ,String > getData (V1ConfigMap map ) {
171
- return Optional .ofNullable (map ).map (V1ConfigMap ::getData ).orElse (Collections .emptyMap ());
170
+ return !AnnotationHelper .getHash (expected ).equals (AnnotationHelper .getHash (actual ));
172
171
}
173
-
174
- abstract boolean containsAllData (Map <String , String > actual , Map <String , String > expected );
175
172
}
176
173
177
174
static class ScriptConfigMapStep extends Step {
178
175
final ConfigMapContext context ;
179
176
180
- ScriptConfigMapStep (String domainNamespace ) {
181
- context = new ScriptConfigMapContext (this , domainNamespace );
177
+ ScriptConfigMapStep (String domainNamespace , SemanticVersion productVersion ) {
178
+ context = new ScriptConfigMapContext (this , domainNamespace , productVersion );
182
179
}
183
180
184
181
@ Override
@@ -188,25 +185,23 @@ public NextAction apply(Packet packet) {
188
185
}
189
186
190
187
static class ScriptConfigMapContext extends ConfigMapContext {
191
-
192
- ScriptConfigMapContext ( Step conflictStep , String domainNamespace ) {
193
- super ( conflictStep , SCRIPT_CONFIG_MAP_NAME , domainNamespace , loadScriptsFromClasspath (domainNamespace ), null );
188
+ ScriptConfigMapContext ( Step conflictStep , String domainNamespace , SemanticVersion productVersion ) {
189
+ super ( conflictStep , SCRIPT_CONFIG_MAP_NAME , domainNamespace ,
190
+ loadScriptsFromClasspath (domainNamespace ), null , productVersion );
194
191
195
192
addLabel (LabelConstants .OPERATORNAME_LABEL , getOperatorNamespace ());
196
193
}
197
194
198
- private static synchronized Map <String , String > loadScriptsFromClasspath (String domainNamespace ) {
199
- Map <String , String > scripts = scriptReader .loadFilesFromClasspath ();
200
- LOGGER .fine (MessageKeys .SCRIPT_LOADED , domainNamespace );
201
- return scripts ;
202
- }
203
-
204
195
@ Override
205
196
void recordCurrentMap (Packet packet , V1ConfigMap configMap ) {
206
197
packet .put (ProcessingConstants .SCRIPT_CONFIG_MAP , configMap );
207
198
}
199
+ }
208
200
209
-
201
+ static synchronized Map <String , String > loadScriptsFromClasspath (String domainNamespace ) {
202
+ Map <String , String > scripts = scriptReader .loadFilesFromClasspath ();
203
+ LOGGER .fine (MessageKeys .SCRIPT_LOADED , domainNamespace );
204
+ return scripts ;
210
205
}
211
206
212
207
abstract static class ConfigMapContext extends StepContextBase {
@@ -216,14 +211,21 @@ abstract static class ConfigMapContext extends StepContextBase {
216
211
private final String namespace ;
217
212
private V1ConfigMap model ;
218
213
private final Map <String , String > labels = new HashMap <>();
214
+ protected final SemanticVersion productVersion ;
219
215
220
216
ConfigMapContext (Step conflictStep , String name , String namespace , Map <String , String > contents ,
221
217
DomainPresenceInfo info ) {
218
+ this (conflictStep , name , namespace , contents , info , null );
219
+ }
220
+
221
+ ConfigMapContext (Step conflictStep , String name , String namespace , Map <String , String > contents ,
222
+ DomainPresenceInfo info , SemanticVersion productVersion ) {
222
223
super (info );
223
224
this .conflictStep = conflictStep ;
224
225
this .name = name ;
225
226
this .namespace = namespace ;
226
227
this .contents = contents ;
228
+ this .productVersion = productVersion ;
227
229
228
230
addLabel (LabelConstants .CREATEDBYOPERATOR_LABEL , "true" );
229
231
}
@@ -253,15 +255,22 @@ protected V1ConfigMap getModel() {
253
255
}
254
256
255
257
protected final V1ConfigMap createModel (Map <String , String > data ) {
256
- return new V1ConfigMap ().kind ("ConfigMap" ).apiVersion ("v1" ).metadata (createMetadata ()).data (data );
258
+ return AnnotationHelper .withSha256Hash (
259
+ new V1ConfigMap ().kind ("ConfigMap" ).apiVersion ("v1" ).metadata (createMetadata ()).data (data ), data );
257
260
}
258
261
259
262
private V1ObjectMeta createMetadata () {
260
- return updateForOwnerReference (
263
+ V1ObjectMeta metadata = updateForOwnerReference (
261
264
new V1ObjectMeta ()
262
265
.name (name )
263
266
.namespace (namespace )
264
267
.labels (labels ));
268
+
269
+ if (productVersion != null ) {
270
+ metadata .putLabelsItem (LabelConstants .OPERATOR_VERSION , productVersion .toString ());
271
+ }
272
+
273
+ return metadata ;
265
274
}
266
275
267
276
@ SuppressWarnings ("SameParameterValue" )
@@ -283,8 +292,8 @@ Step verifyConfigMap(Step next) {
283
292
return new CallBuilder ().readConfigMapAsync (getName (), namespace , null , new ReadResponseStep (next ));
284
293
}
285
294
286
- boolean isIncompatibleMap (V1ConfigMap existingMap ) {
287
- return ! COMPARATOR .containsAll ( existingMap , getModel ());
295
+ boolean isOutdated (V1ConfigMap existingMap ) {
296
+ return COMPARATOR .isOutdated ( productVersion , existingMap , getModel ());
288
297
}
289
298
290
299
V1ConfigMap withoutTransientData (V1ConfigMap originalMap ) {
@@ -315,8 +324,8 @@ public NextAction onSuccess(Packet packet, CallResponse<V1ConfigMap> callRespons
315
324
V1ConfigMap existingMap = withoutTransientData (callResponse .getResult ());
316
325
if (existingMap == null ) {
317
326
return doNext (createConfigMap (getNext ()), packet );
318
- } else if (isIncompatibleMap (existingMap )) {
319
- return doNext (updateConfigMap (getNext (), existingMap ), packet );
327
+ } else if (isOutdated (existingMap )) {
328
+ return doNext (replaceConfigMap (getNext ()), packet );
320
329
} else if (mustPatchCurrentMap (existingMap )) {
321
330
return doNext (patchCurrentMap (existingMap , getNext ()), packet );
322
331
} else {
@@ -335,9 +344,9 @@ private void logConfigMapExists() {
335
344
LOGGER .fine (MessageKeys .CM_EXISTS , getName (), namespace );
336
345
}
337
346
338
- private Step updateConfigMap (Step next , V1ConfigMap existingConfigMap ) {
347
+ private Step replaceConfigMap (Step next ) {
339
348
return new CallBuilder ().replaceConfigMapAsync (name , namespace ,
340
- createModel ( getCombinedData ( existingConfigMap )) ,
349
+ model ,
341
350
createReplaceResponseStep (next ));
342
351
}
343
352
@@ -370,12 +379,6 @@ private boolean labelsNotDefined(V1ConfigMap currentMap) {
370
379
}
371
380
}
372
381
373
- private Map <String , String > getCombinedData (V1ConfigMap existingConfigMap ) {
374
- Map <String , String > updated = Objects .requireNonNull (existingConfigMap .getData ());
375
- updated .putAll (contents );
376
- return updated ;
377
- }
378
-
379
382
private ResponseStep <V1ConfigMap > createCreateResponseStep (Step next ) {
380
383
return new CreateResponseStep (next );
381
384
}
@@ -440,15 +443,6 @@ public NextAction onSuccess(Packet packet, CallResponse<V1ConfigMap> callRespons
440
443
441
444
}
442
445
443
- /** Returns true if the actual map contains all of the entries from the expected map. */
444
- static class ConfigMapComparatorImpl extends ConfigMapComparator {
445
-
446
- @ Override
447
- boolean containsAllData (Map <String , String > actual , Map <String , String > expected ) {
448
- return actual .entrySet ().containsAll (expected .entrySet ());
449
- }
450
- }
451
-
452
446
/**
453
447
* Factory for a step that creates or updates the generated domain config map from introspection results.
454
448
* Reads the following packet fields:
@@ -596,7 +590,8 @@ private IntrospectorConfigMapContext createIntrospectorConfigMapContext() {
596
590
return createIntrospectorConfigMapContext (data , 0 );
597
591
}
598
592
599
- private IntrospectorConfigMapContext createIntrospectorConfigMapContext (Map <String , String > data , int index ) {
593
+ private IntrospectorConfigMapContext createIntrospectorConfigMapContext (
594
+ Map <String , String > data , int index ) {
600
595
return new IntrospectorConfigMapContext (conflictStep , info , data , index );
601
596
}
602
597
@@ -662,11 +657,10 @@ private String perLine(List<String> errors) {
662
657
663
658
public static class IntrospectorConfigMapContext extends ConfigMapContext implements SplitterTarget {
664
659
665
- private static final Pattern ENCODED_ZIP_PATTERN = Pattern .compile ("([A-Za-z_]+)\\ .secure" );
666
-
667
660
private boolean patchOnly ;
668
661
669
- IntrospectorConfigMapContext (Step conflictStep , DomainPresenceInfo info , Map <String , String > data , int index ) {
662
+ IntrospectorConfigMapContext (Step conflictStep , DomainPresenceInfo info ,
663
+ Map <String , String > data , int index ) {
670
664
super (conflictStep , getConfigMapName (info , index ), info .getNamespace (), data , info );
671
665
672
666
addLabel (LabelConstants .DOMAINUID_LABEL , info .getDomainUid ());
@@ -687,8 +681,8 @@ IntrospectorConfigMapContext patchOnly() {
687
681
}
688
682
689
683
@ Override
690
- boolean isIncompatibleMap (V1ConfigMap existingMap ) {
691
- return !patchOnly && super .isIncompatibleMap (existingMap );
684
+ boolean isOutdated (V1ConfigMap existingMap ) {
685
+ return !patchOnly && super .isOutdated (existingMap );
692
686
}
693
687
694
688
@ Override
0 commit comments