Skip to content

Commit fa288d1

Browse files
authored
Improve PodTemplateSpec sanitizer for GKE Autopilot compatibility (#3012)
* test: update type parameters in SSABasedGenericKubernetesResourceMatcherTest for better type safety * fix: improve PodTemplateSpec sanitizer for GKE Autopilot compatibility Signed-off-by: David Sondermann <david.sondermann@hivemq.com>
1 parent d6e76d2 commit fa288d1

File tree

3 files changed

+62
-26
lines changed

3 files changed

+62
-26
lines changed

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/PodTemplateSpecSanitizer.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,6 @@ private static void sanitizeQuantities(
124124
"resources",
125125
quantityPath))
126126
.map(Map.class::cast)
127-
.filter(m -> m.size() == desiredResource.size())
128127
.ifPresent(
129128
m ->
130129
actualResource.forEach(

operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/PodTemplateSpecSanitizerTest.java

Lines changed: 56 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -132,19 +132,6 @@ void testSanitizePodTemplateSpec_whenResourceIsNull_doNothing() {
132132
verifyNoInteractions(actualMap);
133133
}
134134

135-
@Test
136-
void testSanitizeResourceRequirements_whenResourceSizeMismatch_doNothing() {
137-
final var actualMap =
138-
sanitizeRequestsAndLimits(
139-
ContainerType.CONTAINER,
140-
Map.of("cpu", new Quantity("2")),
141-
Map.of(),
142-
Map.of("cpu", new Quantity("4")),
143-
Map.of("cpu", new Quantity("4"), "memory", new Quantity("4Gi")));
144-
assertContainerResources(actualMap, "requests").hasSize(1).containsEntry("cpu", "2");
145-
assertContainerResources(actualMap, "limits").hasSize(1).containsEntry("cpu", "4");
146-
}
147-
148135
@Test
149136
void testSanitizeResourceRequirements_whenResourceKeyMismatch_doNothing() {
150137
final var actualMap =
@@ -187,6 +174,34 @@ void testSanitizePodTemplateSpec_whenResourcesHaveNumericalAmountMismatch_doNoth
187174
assertInitContainerResources(actualMap, "limits").hasSize(1).containsEntry("cpu", "2");
188175
}
189176

177+
@Test
178+
void
179+
testSanitizePodTemplateSpec_whenResourcesHaveNumericalAmountMismatch_withEphemeralStorageAddedByOtherOperator_doNothing() {
180+
// mimics an environment like GKE Autopilot that enforces ephemeral-storage requests and limits
181+
final var actualMap =
182+
sanitizeRequestsAndLimits(
183+
ContainerType.INIT_CONTAINER,
184+
Map.of(
185+
"cpu",
186+
new Quantity("2"),
187+
"memory",
188+
new Quantity("4Gi"),
189+
"ephemeral-storage",
190+
new Quantity("1Gi")),
191+
Map.of("cpu", new Quantity("4"), "memory", new Quantity("4Ti")),
192+
Map.of("cpu", new Quantity("2"), "ephemeral-storage", new Quantity("1Gi")),
193+
Map.of("cpu", new Quantity("4000m")));
194+
assertInitContainerResources(actualMap, "requests")
195+
.hasSize(3)
196+
.containsEntry("cpu", "2")
197+
.containsEntry("memory", "4Gi")
198+
.containsEntry("ephemeral-storage", "1Gi");
199+
assertInitContainerResources(actualMap, "limits")
200+
.hasSize(2)
201+
.containsEntry("cpu", "2")
202+
.containsEntry("ephemeral-storage", "1Gi");
203+
}
204+
190205
@Test
191206
void
192207
testSanitizeResourceRequirements_whenResourcesHaveAmountAndFormatMismatchWithSameNumericalAmount_thenSanitizeActualMap() {
@@ -204,6 +219,34 @@ void testSanitizePodTemplateSpec_whenResourcesHaveNumericalAmountMismatch_doNoth
204219
assertContainerResources(actualMap, "limits").hasSize(1).containsEntry("cpu", "4000m");
205220
}
206221

222+
@Test
223+
void
224+
testSanitizeResourceRequirements_whenResourcesHaveAmountAndFormatMismatchWithSameNumericalAmount_withEphemeralStorageAddedByOtherOperator_thenSanitizeActualMap() {
225+
// mimics an environment like GKE Autopilot that enforces ephemeral-storage requests and limits
226+
final var actualMap =
227+
sanitizeRequestsAndLimits(
228+
ContainerType.CONTAINER,
229+
Map.of(
230+
"cpu",
231+
new Quantity("2"),
232+
"memory",
233+
new Quantity("4Gi"),
234+
"ephemeral-storage",
235+
new Quantity("1Gi")),
236+
Map.of("cpu", new Quantity("2000m"), "memory", new Quantity("4096Mi")),
237+
Map.of("cpu", new Quantity("4"), "ephemeral-storage", new Quantity("1Gi")),
238+
Map.of("cpu", new Quantity("4000m")));
239+
assertContainerResources(actualMap, "requests")
240+
.hasSize(3)
241+
.containsEntry("cpu", "2000m")
242+
.containsEntry("memory", "4096Mi")
243+
.containsEntry("ephemeral-storage", "1Gi");
244+
assertContainerResources(actualMap, "limits")
245+
.hasSize(2)
246+
.containsEntry("cpu", "4000m")
247+
.containsEntry("ephemeral-storage", "1Gi");
248+
}
249+
207250
@Test
208251
void testSanitizePodTemplateSpec_whenEnvVarsIsEmpty_doNothing() {
209252
final var template =

operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/SSABasedGenericKubernetesResourceMatcherTest.java

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030

3131
class SSABasedGenericKubernetesResourceMatcherTest {
3232

33-
private final Context<?> mockedContext = mock();
33+
private final Context<HasMetadata> mockedContext = mock();
3434

3535
private final SSABasedGenericKubernetesResourceMatcher<HasMetadata> matcher =
3636
SSABasedGenericKubernetesResourceMatcher.getInstance();
@@ -325,23 +325,17 @@ void testSanitizeState_daemonSet_withResourceTypeMismatch() {
325325
void testCustomMatcher_returnsExpectedMatchBasedOnReadOnlyLabel(boolean readOnly) {
326326
var dr = new ConfigMapDR();
327327
dr.configureWith(
328-
new KubernetesDependentResourceConfigBuilder()
329-
.withSSAMatcher(new ReadOnlyAwareMatcher())
328+
new KubernetesDependentResourceConfigBuilder<ConfigMap>()
329+
.withSSAMatcher(new ReadOnlyAwareMatcher<>())
330330
.build());
331331
var desiredConfigMap =
332332
loadResource("configmap.empty-owner-reference-desired.yaml", ConfigMap.class);
333333
desiredConfigMap.getData().put("key1", "another value");
334334
var actualConfigMap = loadResource("configmap.empty-owner-reference.yaml", ConfigMap.class);
335335
actualConfigMap.getMetadata().getLabels().put("readonly", Boolean.toString(readOnly));
336336

337-
ConfigMap ignoredPrimary = null;
338-
assertThat(
339-
dr.match(
340-
actualConfigMap,
341-
desiredConfigMap,
342-
ignoredPrimary,
343-
(Context<ConfigMap>) mockedContext)
344-
.matched())
337+
HasMetadata primary = mock();
338+
assertThat(dr.match(actualConfigMap, desiredConfigMap, primary, mockedContext).matched())
345339
.isEqualTo(readOnly);
346340
}
347341

@@ -391,7 +385,7 @@ private static <R> R loadResource(String fileName, Class<R> clazz) {
391385
clazz, SSABasedGenericKubernetesResourceMatcherTest.class, fileName);
392386
}
393387

394-
private static class ConfigMapDR extends KubernetesDependentResource<ConfigMap, ConfigMap> {
388+
private static class ConfigMapDR extends KubernetesDependentResource<ConfigMap, HasMetadata> {
395389
public ConfigMapDR() {
396390
super(ConfigMap.class);
397391
}

0 commit comments

Comments
 (0)