Skip to content

Commit 7534df7

Browse files
committed
Expose PodAffinity and PodAntiAffinity struct and build overrides
This patch introduces a very basic struct to expose Pod Affinity/Antiaffinity interfaces as part of the Topology CR spec and allows to patch the (opinionated) default that is currently applied to the services. Signed-off-by: Francesco Pantano <[email protected]>
1 parent d172b3a commit 7534df7

File tree

4 files changed

+136
-4
lines changed

4 files changed

+136
-4
lines changed

modules/common/affinity/affinity.go

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@ limitations under the License.
1717
package affinity
1818

1919
import (
20+
"encoding/json"
21+
"fmt"
2022
corev1 "k8s.io/api/core/v1"
23+
v1 "k8s.io/api/core/v1"
2124
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
25+
"k8s.io/apimachinery/pkg/util/strategicpatch"
2226
)
2327

2428
// DistributePods - returns rule to ensure that two replicas of the same selector
@@ -27,8 +31,9 @@ func DistributePods(
2731
selectorKey string,
2832
selectorValues []string,
2933
topologyKey string,
34+
overrides *OverrideSpec,
3035
) *corev1.Affinity {
31-
return &corev1.Affinity{
36+
defaultAffinity := &corev1.Affinity{
3237
PodAntiAffinity: &corev1.PodAntiAffinity{
3338
// This rule ensures that two replicas of the same selector
3439
// should not run if possible on the same worker node
@@ -53,4 +58,46 @@ func DistributePods(
5358
},
5459
},
5560
}
61+
// patch the default affinity Object with the data passed as input
62+
if overrides != nil {
63+
patchedAffinity, _ := toCoreAffinity(defaultAffinity, overrides)
64+
return patchedAffinity
65+
}
66+
return defaultAffinity
67+
}
68+
69+
func toCoreAffinity(
70+
affinity *v1.Affinity,
71+
override *OverrideSpec,
72+
) (*v1.Affinity, error) {
73+
74+
aff := &v1.Affinity{
75+
PodAntiAffinity: affinity.PodAntiAffinity,
76+
PodAffinity: affinity.PodAffinity,
77+
}
78+
if override != nil {
79+
if override != nil {
80+
origAffinit, err := json.Marshal(affinity)
81+
if err != nil {
82+
return aff, fmt.Errorf("error marshalling Affinity Spec: %w", err)
83+
}
84+
patch, err := json.Marshal(override)
85+
if err != nil {
86+
return aff, fmt.Errorf("error marshalling Affinity Spec: %w", err)
87+
}
88+
89+
patchedJSON, err := strategicpatch.StrategicMergePatch(origAffinit, patch, v1.Affinity{})
90+
if err != nil {
91+
return aff, fmt.Errorf("error patching Affinity Spec: %w", err)
92+
}
93+
94+
patchedSpec := v1.Affinity{}
95+
err = json.Unmarshal(patchedJSON, &patchedSpec)
96+
if err != nil {
97+
return aff, fmt.Errorf("error unmarshalling patched Service Spec: %w", err)
98+
}
99+
aff = &patchedSpec
100+
}
101+
}
102+
return aff, nil
56103
}

modules/common/affinity/affinity_test.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,7 @@ func TestDistributePods(t *testing.T) {
5151

5252
t.Run("Default pod distribution", func(t *testing.T) {
5353
g := NewWithT(t)
54-
55-
d := DistributePods("ThisSelector", []string{"selectorValue1", "selectorValue2"}, "ThisTopologyKey")
56-
54+
d := DistributePods("ThisSelector", []string{"selectorValue1", "selectorValue2"}, "ThisTopologyKey", nil)
5755
g.Expect(d).To(BeEquivalentTo(affinityObj))
5856
})
5957
}

modules/common/affinity/types.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
Copyright 2024 Red Hat
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
// +kubebuilder:object:generate:=true
18+
19+
package affinity
20+
21+
import (
22+
corev1 "k8s.io/api/core/v1"
23+
)
24+
25+
// OverrideSpec -
26+
type OverrideSpec struct {
27+
// Describes pod affinity scheduling rules (e.g. co-locate this pod in the same node, zone, etc. as some other pod(s)).
28+
// +optional
29+
PodAffinity *corev1.PodAffinity `json:"podAffinity,omitempty" protobuf:"bytes,2,opt,name=podAffinity"`
30+
// Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod in the same node, zone, etc. as some other pod(s)).
31+
// +optional
32+
PodAntiAffinity *corev1.PodAntiAffinity `json:"podAntiAffinity,omitempty" protobuf:"bytes,3,opt,name=podAntiAffinity"`
33+
// Describes node affinity scheduling rules for the pod.
34+
// +optional
35+
NodeAffinity *corev1.NodeAffinity `json:"nodeAffinity,omitempty" protobuf:"bytes,1,opt,name=nodeAffinity"`
36+
}

modules/common/affinity/zz_generated.deepcopy.go

Lines changed: 51 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)