diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GenericKubernetesResourceMatcher.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GenericKubernetesResourceMatcher.java index 23fb29151f..668ed409ab 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GenericKubernetesResourceMatcher.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GenericKubernetesResourceMatcher.java @@ -183,7 +183,9 @@ public static Matcher.Result m final var kubernetesSerialization = context.getClient().getKubernetesSerialization(); var desiredNode = kubernetesSerialization.convertValue(desired, JsonNode.class); var actualNode = kubernetesSerialization.convertValue(actualResource, JsonNode.class); - var wholeDiffJsonPatch = JsonDiff.asJson(desiredNode, actualNode); + // move and copy operations would hide additions and removals from the checks below + var wholeDiffJsonPatch = + JsonDiff.asJson(desiredNode, actualNode, DiffFlags.dontNormalizeOpIntoMoveAndCopy()); boolean matched = true; for (int i = 0; i < wholeDiffJsonPatch.size() && matched; i++) { diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GenericKubernetesResourceMatcherTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GenericKubernetesResourceMatcherTest.java index 0c2583d594..529b76425e 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GenericKubernetesResourceMatcherTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GenericKubernetesResourceMatcherTest.java @@ -77,6 +77,47 @@ void matchesAdditiveOnlyChanges() { .isTrue(); } + @Test + void matchesAdditiveChangesWithValueEqualToAnExistingValue() { + var desired = + new ServiceBuilder() + .withNewMetadata() + .withName("test") + .endMetadata() + .withNewSpec() + .addNewPort() + .withPort(80) + .endPort() + .endSpec() + .build(); + // the API server defaults targetPort to the value of port + var actual = + new ServiceBuilder(desired) + .editSpec() + .editFirstPort() + .withTargetPort(new IntOrString(80)) + .endPort() + .endSpec() + .build(); + assertThat(GenericKubernetesResourceMatcher.match(desired, actual, context).matched()) + .withFailMessage( + "Additive changes should not cause a mismatch even if the added value equals an" + + " existing one") + .isTrue(); + } + + @Test + void doesNotMatchRemovedValueAddedBackUnderIgnoredPath() { + actual = createDeployment(); + // revisionHistoryLimit is 10 in desired, the added priority has the same value + actual.getSpec().setRevisionHistoryLimit(null); + actual.getSpec().getTemplate().getSpec().setPriority(10); + assertThat( + match(dependentResource, actual, null, context, false, "/spec/template/spec").matched()) + .withFailMessage("Removing values outside of ignored paths should lead to a mismatch") + .isFalse(); + } + @Test void matchesWithStrongSpecEquality() { actual.getSpec().getTemplate().getMetadata().getLabels().put("new-key", "val");