Skip to content

Commit 63629e7

Browse files
committed
Backport affinity merging
1 parent 8df532a commit 63629e7

File tree

3 files changed

+143
-48
lines changed

3 files changed

+143
-48
lines changed

operator/src/main/java/oracle/kubernetes/weblogic/domain/model/ServerPod.java

Lines changed: 51 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,20 @@
2222
import io.kubernetes.client.openapi.models.V1HostPathVolumeSource;
2323
import io.kubernetes.client.openapi.models.V1NodeAffinity;
2424
import io.kubernetes.client.openapi.models.V1NodeSelector;
25+
import io.kubernetes.client.openapi.models.V1NodeSelectorTerm;
2526
import io.kubernetes.client.openapi.models.V1PersistentVolumeClaimVolumeSource;
2627
import io.kubernetes.client.openapi.models.V1PodAffinity;
28+
import io.kubernetes.client.openapi.models.V1PodAffinityTerm;
2729
import io.kubernetes.client.openapi.models.V1PodAntiAffinity;
2830
import io.kubernetes.client.openapi.models.V1PodReadinessGate;
2931
import io.kubernetes.client.openapi.models.V1PodSecurityContext;
32+
import io.kubernetes.client.openapi.models.V1PreferredSchedulingTerm;
3033
import io.kubernetes.client.openapi.models.V1ResourceRequirements;
3134
import io.kubernetes.client.openapi.models.V1SecurityContext;
3235
import io.kubernetes.client.openapi.models.V1Toleration;
3336
import io.kubernetes.client.openapi.models.V1Volume;
3437
import io.kubernetes.client.openapi.models.V1VolumeMount;
38+
import io.kubernetes.client.openapi.models.V1WeightedPodAffinityTerm;
3539
import oracle.kubernetes.json.Description;
3640
import org.apache.commons.lang3.builder.EqualsBuilder;
3741
import org.apache.commons.lang3.builder.HashCodeBuilder;
@@ -266,25 +270,15 @@ private void copyValues(V1SecurityContext to, V1SecurityContext from) {
266270

267271
private void copyValues(V1Capabilities to, V1Capabilities from) {
268272
if (from.getAdd() != null) {
269-
List<String> allAddCapabilities = new ArrayList<>();
270-
if (to.getAdd() != null) {
271-
allAddCapabilities =
272-
Stream.concat(to.getAdd().stream(), from.getAdd().stream())
273-
.distinct()
274-
.collect(Collectors.toList());
275-
}
276-
to.setAdd(allAddCapabilities);
273+
Stream<String> stream = (to.getAdd() != null)
274+
? Stream.concat(to.getAdd().stream(), from.getAdd().stream()) : from.getAdd().stream();
275+
to.setAdd(stream.distinct().collect(Collectors.toList()));
277276
}
278277

279278
if (from.getDrop() != null) {
280-
List<String> allDropCapabilities = new ArrayList<>();
281-
if (to.getDrop() != null) {
282-
allDropCapabilities =
283-
Stream.concat(to.getDrop().stream(), from.getDrop().stream())
284-
.distinct()
285-
.collect(Collectors.toList());
286-
}
287-
to.setDrop(allDropCapabilities);
279+
Stream<String> stream = (to.getDrop() != null)
280+
? Stream.concat(to.getDrop().stream(), from.getDrop().stream()) : from.getDrop().stream();
281+
to.setDrop(stream.distinct().collect(Collectors.toList()));
288282
}
289283
}
290284

@@ -307,12 +301,14 @@ private void copyValues(V1Affinity to, V1Affinity from) {
307301
}
308302

309303
private void copyValues(V1NodeAffinity to, V1NodeAffinity from) {
310-
if (to.getPreferredDuringSchedulingIgnoredDuringExecution() == null) {
311-
to.setPreferredDuringSchedulingIgnoredDuringExecution(from.getPreferredDuringSchedulingIgnoredDuringExecution());
312-
} else if (from.getPreferredDuringSchedulingIgnoredDuringExecution() != null) {
313-
from.getPreferredDuringSchedulingIgnoredDuringExecution()
314-
.forEach(to::addPreferredDuringSchedulingIgnoredDuringExecutionItem);
304+
if (from.getPreferredDuringSchedulingIgnoredDuringExecution() != null) {
305+
Stream<V1PreferredSchedulingTerm> stream = (to.getPreferredDuringSchedulingIgnoredDuringExecution() != null)
306+
? Stream.concat(to.getPreferredDuringSchedulingIgnoredDuringExecution().stream(),
307+
from.getPreferredDuringSchedulingIgnoredDuringExecution().stream())
308+
: from.getPreferredDuringSchedulingIgnoredDuringExecution().stream();
309+
to.setPreferredDuringSchedulingIgnoredDuringExecution(stream.distinct().collect(Collectors.toList()));
315310
}
311+
316312
if (to.getRequiredDuringSchedulingIgnoredDuringExecution() == null) {
317313
to.setRequiredDuringSchedulingIgnoredDuringExecution(from.getRequiredDuringSchedulingIgnoredDuringExecution());
318314
} else if (from.getRequiredDuringSchedulingIgnoredDuringExecution() != null) {
@@ -321,41 +317,49 @@ private void copyValues(V1NodeAffinity to, V1NodeAffinity from) {
321317
}
322318
}
323319

324-
private void copyValues(V1NodeSelector to,V1NodeSelector from) {
325-
if (to.getNodeSelectorTerms() == null) {
326-
to.setNodeSelectorTerms(from.getNodeSelectorTerms());
327-
} else if (from.getNodeSelectorTerms() != null) {
328-
from.getNodeSelectorTerms().forEach(to::addNodeSelectorTermsItem);
320+
private void copyValues(V1NodeSelector to, V1NodeSelector from) {
321+
if (from.getNodeSelectorTerms() != null) {
322+
Stream<V1NodeSelectorTerm> stream = (to.getNodeSelectorTerms() != null)
323+
? Stream.concat(to.getNodeSelectorTerms().stream(),
324+
from.getNodeSelectorTerms().stream())
325+
: from.getNodeSelectorTerms().stream();
326+
to.setNodeSelectorTerms(stream.distinct().collect(Collectors.toList()));
329327
}
330328
}
331329

332330
private void copyValues(V1PodAffinity to, V1PodAffinity from) {
333-
if (to.getPreferredDuringSchedulingIgnoredDuringExecution() == null) {
334-
to.setPreferredDuringSchedulingIgnoredDuringExecution(from.getPreferredDuringSchedulingIgnoredDuringExecution());
335-
} else if (from.getPreferredDuringSchedulingIgnoredDuringExecution() != null) {
336-
from.getPreferredDuringSchedulingIgnoredDuringExecution()
337-
.forEach(to::addPreferredDuringSchedulingIgnoredDuringExecutionItem);
331+
if (from.getPreferredDuringSchedulingIgnoredDuringExecution() != null) {
332+
Stream<V1WeightedPodAffinityTerm> stream = (to.getPreferredDuringSchedulingIgnoredDuringExecution() != null)
333+
? Stream.concat(to.getPreferredDuringSchedulingIgnoredDuringExecution().stream(),
334+
from.getPreferredDuringSchedulingIgnoredDuringExecution().stream())
335+
: from.getPreferredDuringSchedulingIgnoredDuringExecution().stream();
336+
to.setPreferredDuringSchedulingIgnoredDuringExecution(stream.distinct().collect(Collectors.toList()));
338337
}
339-
if (to.getRequiredDuringSchedulingIgnoredDuringExecution() == null) {
340-
to.setRequiredDuringSchedulingIgnoredDuringExecution(from.getRequiredDuringSchedulingIgnoredDuringExecution());
341-
} else if (from.getRequiredDuringSchedulingIgnoredDuringExecution() != null) {
342-
from.getRequiredDuringSchedulingIgnoredDuringExecution()
343-
.forEach(to::addRequiredDuringSchedulingIgnoredDuringExecutionItem);
338+
339+
if (from.getRequiredDuringSchedulingIgnoredDuringExecution() != null) {
340+
Stream<V1PodAffinityTerm> stream = (to.getRequiredDuringSchedulingIgnoredDuringExecution() != null)
341+
? Stream.concat(to.getRequiredDuringSchedulingIgnoredDuringExecution().stream(),
342+
from.getRequiredDuringSchedulingIgnoredDuringExecution().stream())
343+
: from.getRequiredDuringSchedulingIgnoredDuringExecution().stream();
344+
to.setRequiredDuringSchedulingIgnoredDuringExecution(stream.distinct().collect(Collectors.toList()));
344345
}
345346
}
346347

347348
private void copyValues(V1PodAntiAffinity to, V1PodAntiAffinity from) {
348-
if (to.getPreferredDuringSchedulingIgnoredDuringExecution() == null) {
349-
to.setPreferredDuringSchedulingIgnoredDuringExecution(from.getPreferredDuringSchedulingIgnoredDuringExecution());
350-
} else if (from.getPreferredDuringSchedulingIgnoredDuringExecution() != null) {
351-
from.getPreferredDuringSchedulingIgnoredDuringExecution()
352-
.forEach(to::addPreferredDuringSchedulingIgnoredDuringExecutionItem);
349+
if (from.getPreferredDuringSchedulingIgnoredDuringExecution() != null) {
350+
Stream<V1WeightedPodAffinityTerm> stream = (to.getPreferredDuringSchedulingIgnoredDuringExecution() != null)
351+
? Stream.concat(to.getPreferredDuringSchedulingIgnoredDuringExecution().stream(),
352+
from.getPreferredDuringSchedulingIgnoredDuringExecution().stream())
353+
: from.getPreferredDuringSchedulingIgnoredDuringExecution().stream();
354+
to.setPreferredDuringSchedulingIgnoredDuringExecution(stream.distinct().collect(Collectors.toList()));
353355
}
354-
if (to.getRequiredDuringSchedulingIgnoredDuringExecution() == null) {
355-
to.setRequiredDuringSchedulingIgnoredDuringExecution(from.getRequiredDuringSchedulingIgnoredDuringExecution());
356-
} else if (from.getRequiredDuringSchedulingIgnoredDuringExecution() != null) {
357-
from.getRequiredDuringSchedulingIgnoredDuringExecution()
358-
.forEach(to::addRequiredDuringSchedulingIgnoredDuringExecutionItem);
356+
357+
if (from.getRequiredDuringSchedulingIgnoredDuringExecution() != null) {
358+
Stream<V1PodAffinityTerm> stream = (to.getRequiredDuringSchedulingIgnoredDuringExecution() != null)
359+
? Stream.concat(to.getRequiredDuringSchedulingIgnoredDuringExecution().stream(),
360+
from.getRequiredDuringSchedulingIgnoredDuringExecution().stream())
361+
: from.getRequiredDuringSchedulingIgnoredDuringExecution().stream();
362+
to.setRequiredDuringSchedulingIgnoredDuringExecution(stream.distinct().collect(Collectors.toList()));
359363
}
360364
}
361365

@@ -811,4 +815,4 @@ public int hashCode() {
811815
.append(serviceAccountName)
812816
.toHashCode();
813817
}
814-
}
818+
}

operator/src/test/java/oracle/kubernetes/operator/helpers/ManagedPodHelperTest.java

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,15 @@
1010
import java.util.Map;
1111
import java.util.Optional;
1212

13+
import io.kubernetes.client.openapi.models.V1Affinity;
1314
import io.kubernetes.client.openapi.models.V1Container;
1415
import io.kubernetes.client.openapi.models.V1EnvVar;
16+
import io.kubernetes.client.openapi.models.V1LabelSelector;
17+
import io.kubernetes.client.openapi.models.V1LabelSelectorRequirement;
1518
import io.kubernetes.client.openapi.models.V1Pod;
19+
import io.kubernetes.client.openapi.models.V1PodAffinityTerm;
20+
import io.kubernetes.client.openapi.models.V1PodAntiAffinity;
21+
import io.kubernetes.client.openapi.models.V1WeightedPodAffinityTerm;
1622
import oracle.kubernetes.operator.LabelConstants;
1723
import oracle.kubernetes.operator.ProcessingConstants;
1824
import oracle.kubernetes.operator.VersionConstants;
@@ -906,6 +912,91 @@ public void whenClusterHasResources_createContainersWithThem() {
906912
containers.forEach(c -> assertThat(c.getResources().getRequests(), hasResourceQuantity("memory", "250m")));
907913
}
908914

915+
@Test
916+
public void whenClusterHasAffinityWithVariables_createManagedPodWithSubstitutions() {
917+
testSupport.addToPacket(ProcessingConstants.CLUSTER_NAME, CLUSTER_NAME);
918+
getConfigurator()
919+
.configureCluster(CLUSTER_NAME)
920+
.withAffinity(
921+
new V1Affinity().podAntiAffinity(
922+
new V1PodAntiAffinity().preferredDuringSchedulingIgnoredDuringExecution(
923+
Collections.singletonList(new V1WeightedPodAffinityTerm().weight(100).podAffinityTerm(
924+
new V1PodAffinityTerm().labelSelector(
925+
new V1LabelSelector().matchExpressions(
926+
Collections.singletonList(new V1LabelSelectorRequirement()
927+
.key("weblogic.clusterName")
928+
.operator("In")
929+
.addValuesItem("$(CLUSTER_NAME)"))))
930+
.topologyKey("kubernetes.io/hostname"))))));
931+
932+
V1Affinity expectedValue = new V1Affinity().podAntiAffinity(
933+
new V1PodAntiAffinity().preferredDuringSchedulingIgnoredDuringExecution(
934+
Collections.singletonList(new V1WeightedPodAffinityTerm().weight(100).podAffinityTerm(
935+
new V1PodAffinityTerm().labelSelector(
936+
new V1LabelSelector().matchExpressions(
937+
Collections.singletonList(new V1LabelSelectorRequirement()
938+
.key("weblogic.clusterName")
939+
.operator("In")
940+
.addValuesItem(CLUSTER_NAME))))
941+
.topologyKey("kubernetes.io/hostname")))));
942+
943+
assertThat(
944+
getCreatedPod().getSpec().getAffinity(),
945+
is(expectedValue));
946+
}
947+
948+
@Test
949+
public void whenDomainAndClusterBothHaveAffinityWithVariables_createManagedPodWithSubstitutions() {
950+
testSupport.addToPacket(ProcessingConstants.CLUSTER_NAME, CLUSTER_NAME);
951+
getConfigurator()
952+
.withAffinity(
953+
new V1Affinity().podAntiAffinity(
954+
new V1PodAntiAffinity().preferredDuringSchedulingIgnoredDuringExecution(
955+
Collections.singletonList(new V1WeightedPodAffinityTerm().weight(100).podAffinityTerm(
956+
new V1PodAffinityTerm().labelSelector(
957+
new V1LabelSelector().matchExpressions(
958+
Collections.singletonList(new V1LabelSelectorRequirement()
959+
.key("weblogic.domainUID")
960+
.operator("In")
961+
.addValuesItem("$(DOMAIN_UID)"))))
962+
.topologyKey("kubernetes.io/hostname"))))))
963+
.configureCluster(CLUSTER_NAME)
964+
.withAffinity(
965+
new V1Affinity().podAntiAffinity(
966+
new V1PodAntiAffinity().preferredDuringSchedulingIgnoredDuringExecution(
967+
Collections.singletonList(new V1WeightedPodAffinityTerm().weight(100).podAffinityTerm(
968+
new V1PodAffinityTerm().labelSelector(
969+
new V1LabelSelector().matchExpressions(
970+
Collections.singletonList(new V1LabelSelectorRequirement()
971+
.key("weblogic.clusterName")
972+
.operator("In")
973+
.addValuesItem("$(CLUSTER_NAME)"))))
974+
.topologyKey("kubernetes.io/hostname"))))));
975+
976+
V1Affinity expectedValue = new V1Affinity().podAntiAffinity(
977+
new V1PodAntiAffinity().preferredDuringSchedulingIgnoredDuringExecution(
978+
Arrays.asList(
979+
new V1WeightedPodAffinityTerm().weight(100).podAffinityTerm(
980+
new V1PodAffinityTerm().labelSelector(
981+
new V1LabelSelector().matchExpressions(
982+
Collections.singletonList(new V1LabelSelectorRequirement()
983+
.key("weblogic.clusterName")
984+
.operator("In")
985+
.addValuesItem(CLUSTER_NAME))))
986+
.topologyKey("kubernetes.io/hostname")),
987+
new V1WeightedPodAffinityTerm().weight(100).podAffinityTerm(
988+
new V1PodAffinityTerm().labelSelector(
989+
new V1LabelSelector().matchExpressions(
990+
Collections.singletonList(new V1LabelSelectorRequirement()
991+
.key("weblogic.domainUID")
992+
.operator("In")
993+
.addValuesItem(UID))))
994+
.topologyKey("kubernetes.io/hostname")))));
995+
996+
assertThat(
997+
getCreatedPod().getSpec().getAffinity(),
998+
is(expectedValue));
999+
}
9091000

9101001
@Override
9111002
void setServerPort(int port) {

operator/src/test/java/oracle/kubernetes/operator/helpers/PodHelperTestBase.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ public abstract class PodHelperTestBase {
121121
static final String NS = "namespace";
122122
static final String ADMIN_SERVER = "ADMIN_SERVER";
123123
static final Integer ADMIN_PORT = 7001;
124-
private static final String DOMAIN_NAME = "domain1";
124+
protected static final String DOMAIN_NAME = "domain1";
125125
protected static final String UID = "uid1";
126126
private static final boolean INCLUDE_SERVER_OUT_IN_POD_LOG = true;
127127

0 commit comments

Comments
 (0)