This is an automated email from the ASF dual-hosted git repository.
gyfora pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/flink-kubernetes-operator.git
The following commit(s) were added to refs/heads/main by this push:
new 24b0d998 [FLINK-39509][flink-kubernetes-webhook] Fix mutating webhook
producing spurious object modifications on no-op patches
24b0d998 is described below
commit 24b0d998278b8ce8a579927ea292b9f4eb1b5a60
Author: Dennis-Mircea Ciupitu <[email protected]>
AuthorDate: Tue Apr 21 16:20:55 2026 +0300
[FLINK-39509][flink-kubernetes-webhook] Fix mutating webhook producing
spurious object modifications on no-op patches
---
.../operator/admission/mutator/FlinkMutator.java | 28 ++++++++++++++++++----
1 file changed, 24 insertions(+), 4 deletions(-)
diff --git
a/flink-kubernetes-webhook/src/main/java/org/apache/flink/kubernetes/operator/admission/mutator/FlinkMutator.java
b/flink-kubernetes-webhook/src/main/java/org/apache/flink/kubernetes/operator/admission/mutator/FlinkMutator.java
index 28199614..f9d4f878 100644
---
a/flink-kubernetes-webhook/src/main/java/org/apache/flink/kubernetes/operator/admission/mutator/FlinkMutator.java
+++
b/flink-kubernetes-webhook/src/main/java/org/apache/flink/kubernetes/operator/admission/mutator/FlinkMutator.java
@@ -66,9 +66,10 @@ public class FlinkMutator implements Mutator<HasMetadata> {
return resource;
}
- private FlinkSessionJob mutateSessionJob(HasMetadata resource) {
+ private HasMetadata mutateSessionJob(HasMetadata resource) {
try {
var sessionJob = mapper.convertValue(resource,
FlinkSessionJob.class);
+ var originalSessionJob = mapper.valueToTree(sessionJob);
var namespace = sessionJob.getMetadata().getNamespace();
var deploymentName = sessionJob.getSpec().getDeploymentName();
var key = Cache.namespaceKeyFunc(namespace, deploymentName);
@@ -78,31 +79,50 @@ public class FlinkMutator implements Mutator<HasMetadata> {
for (FlinkResourceMutator mutator : mutators) {
sessionJob = mutator.mutateSessionJob(sessionJob,
Optional.ofNullable(deployment));
}
-
+ // Return the original resource if no mutation was applied to avoid
+ // the serialization round-trip producing a different object,
which causes
+ // kubectl to inconsistently omit the "(no change)" suffix on
patch responses
+ if (originalSessionJob.equals(mapper.valueToTree(sessionJob))) {
+ return resource;
+ }
return sessionJob;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
- private FlinkDeployment mutateDeployment(HasMetadata resource) {
+ private HasMetadata mutateDeployment(HasMetadata resource) {
try {
var flinkDeployment = mapper.convertValue(resource,
FlinkDeployment.class);
+ var originalFlinkDeployment = mapper.valueToTree(flinkDeployment);
for (FlinkResourceMutator mutator : mutators) {
flinkDeployment = mutator.mutateDeployment(flinkDeployment);
}
+ // Return the original resource if no mutation was applied to avoid
+ // the serialization round-trip producing a different object,
which causes
+ // kubectl to inconsistently omit the "(no change)" suffix on
patch responses
+ if
(originalFlinkDeployment.equals(mapper.valueToTree(flinkDeployment))) {
+ return resource;
+ }
return flinkDeployment;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
- private FlinkStateSnapshot mutateStateSnapshot(HasMetadata resource) {
+ private HasMetadata mutateStateSnapshot(HasMetadata resource) {
try {
var snapshot = mapper.convertValue(resource,
FlinkStateSnapshot.class);
+ var originalSnapshot = mapper.valueToTree(snapshot);
for (var mutator : mutators) {
snapshot = mutator.mutateStateSnapshot(snapshot);
}
+ // Return the original resource if no mutation was applied to avoid
+ // the serialization round-trip producing a different object,
which causes
+ // kubectl to inconsistently omit the "(no change)" suffix on
patch responses
+ if (originalSnapshot.equals(mapper.valueToTree(snapshot))) {
+ return resource;
+ }
return snapshot;
} catch (Exception e) {
throw new RuntimeException(e);