Skip to content

Commit 919d3f6

Browse files
author
Danil-Grigorev
committed
Implement image substitution for Pod and generalise the approach for other objects
1 parent b0fb4b3 commit 919d3f6

2 files changed

Lines changed: 87 additions & 88 deletions

File tree

pkg/substitution/substitution.go

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ package substitution
22

33
import (
44
"github.com/openshift/cluster-cloud-controller-manager-operator/pkg/config"
5-
v1 "k8s.io/api/apps/v1"
5+
appsv1 "k8s.io/api/apps/v1"
6+
corev1 "k8s.io/api/core/v1"
67
"k8s.io/klog/v2"
78
"sigs.k8s.io/controller-runtime/pkg/client"
89
)
@@ -14,27 +15,27 @@ const (
1415
cloudNodeManagerName = "cloud-node-manager"
1516
)
1617

17-
// setDeploymentImages substitutes controller containers in Deployment with correct image
18-
func setDeploymentImages(config config.OperatorConfig, d *v1.Deployment) {
19-
for i, container := range d.Spec.Template.Spec.Containers {
20-
if container.Name != cloudControllerManagerName {
18+
// setCloudControllerImage substitutes controller containers in provided pod specs with correct image
19+
func setCloudControllerImage(config config.OperatorConfig, p corev1.PodSpec) corev1.PodSpec {
20+
updatedPod := *p.DeepCopy()
21+
for i, container := range p.Containers {
22+
substituteName := ""
23+
switch container.Name {
24+
case cloudControllerManagerName:
25+
substituteName = config.ControllerImage
26+
case cloudNodeManagerName:
27+
substituteName = config.CloudNodeImage
28+
default:
2129
continue
2230
}
2331

24-
klog.Infof("Substituting %q in Deployment %q with %s", container.Name, d.Name, config.ControllerImage)
25-
d.Spec.Template.Spec.Containers[i].Image = config.ControllerImage
26-
}
27-
}
28-
29-
func setDaemonSetImage(config config.OperatorConfig, d *v1.DaemonSet) {
30-
for i, container := range d.Spec.Template.Spec.Containers {
31-
if container.Name != cloudNodeManagerName {
32-
continue
32+
if substituteName != "" {
33+
klog.Infof("Substituting container image for container %q with %q", container.Name, substituteName)
34+
updatedPod.Containers[i].Image = substituteName
3335
}
34-
35-
klog.Infof("Substituting %q in DaemonSet %q with %s", container.Name, d.Name, config.ControllerImage)
36-
d.Spec.Template.Spec.Containers[i].Image = config.CloudNodeImage
3736
}
37+
38+
return updatedPod
3839
}
3940

4041
func FillConfigValues(config config.OperatorConfig, templates []client.Object) []client.Object {
@@ -46,10 +47,12 @@ func FillConfigValues(config config.OperatorConfig, templates []client.Object) [
4647
templateCopy.SetNamespace(config.ManagedNamespace)
4748

4849
switch obj := templateCopy.(type) {
49-
case *v1.Deployment:
50-
setDeploymentImages(config, obj)
51-
case *v1.DaemonSet:
52-
setDaemonSetImage(config, obj)
50+
case *appsv1.Deployment:
51+
obj.Spec.Template.Spec = setCloudControllerImage(config, obj.Spec.Template.Spec)
52+
case *appsv1.DaemonSet:
53+
obj.Spec.Template.Spec = setCloudControllerImage(config, obj.Spec.Template.Spec)
54+
case *corev1.Pod:
55+
obj.Spec = setCloudControllerImage(config, obj.Spec)
5356
}
5457
objects[i] = templateCopy
5558
}

pkg/substitution/substitution_test.go

Lines changed: 63 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111
"sigs.k8s.io/controller-runtime/pkg/client"
1212
)
1313

14-
func TestSetDeploymentImages(t *testing.T) {
14+
func TestSetCloudControllerImage(t *testing.T) {
1515
tc := []struct {
1616
name string
1717
containers []corev1.Container
@@ -43,6 +43,19 @@ func TestSetDeploymentImages(t *testing.T) {
4343
config: config.OperatorConfig{
4444
ControllerImage: "correct_image:tag",
4545
},
46+
}, {
47+
name: "Substitute cloud-node-manager container image",
48+
containers: []corev1.Container{{
49+
Name: cloudNodeManagerName,
50+
Image: "expect_change",
51+
}},
52+
expectedContainers: []corev1.Container{{
53+
Name: cloudNodeManagerName,
54+
Image: "correct_node_image:tag",
55+
}},
56+
config: config.OperatorConfig{
57+
CloudNodeImage: "correct_node_image:tag",
58+
},
4659
}, {
4760
name: "Combination of container image names",
4861
containers: []corev1.Container{{
@@ -76,69 +89,6 @@ func TestSetDeploymentImages(t *testing.T) {
7689
},
7790
}
7891

79-
setDeploymentImages(tc.config, deploy)
80-
81-
assert.EqualValues(t, deploy.Spec.Template.Spec.Containers, tc.expectedContainers)
82-
})
83-
}
84-
85-
}
86-
87-
func TestSetDaemonsetImages(t *testing.T) {
88-
tc := []struct {
89-
name string
90-
containers []corev1.Container
91-
config config.OperatorConfig
92-
expectedContainers []corev1.Container
93-
}{{
94-
name: "Unknown container name",
95-
containers: []corev1.Container{{
96-
Name: "different_name",
97-
Image: "no_change",
98-
}},
99-
expectedContainers: []corev1.Container{{
100-
Name: "different_name",
101-
Image: "no_change",
102-
}},
103-
config: config.OperatorConfig{
104-
CloudNodeImage: "correct_image:tag",
105-
},
106-
}, {
107-
name: "Substitute cloud-node-manager container image",
108-
containers: []corev1.Container{{
109-
Name: cloudNodeManagerName,
110-
Image: "expect_change",
111-
}},
112-
expectedContainers: []corev1.Container{{
113-
Name: cloudNodeManagerName,
114-
Image: "correct_image:tag",
115-
}},
116-
config: config.OperatorConfig{
117-
CloudNodeImage: "correct_image:tag",
118-
},
119-
}, {
120-
name: "Combination of container image names",
121-
containers: []corev1.Container{{
122-
Name: cloudNodeManagerName,
123-
Image: "expect_change",
124-
}, {
125-
Name: "some-stuff-there",
126-
Image: "no_change",
127-
}},
128-
expectedContainers: []corev1.Container{{
129-
Name: cloudNodeManagerName,
130-
Image: "correct_image:tag",
131-
}, {
132-
Name: "some-stuff-there",
133-
Image: "no_change",
134-
}},
135-
config: config.OperatorConfig{
136-
CloudNodeImage: "correct_image:tag",
137-
},
138-
}}
139-
140-
for _, tc := range tc {
141-
t.Run(tc.name, func(t *testing.T) {
14292
ds := &v1.DaemonSet{
14393
Spec: v1.DaemonSetSpec{
14494
Template: corev1.PodTemplateSpec{
@@ -149,11 +99,23 @@ func TestSetDaemonsetImages(t *testing.T) {
14999
},
150100
}
151101

152-
setDaemonSetImage(tc.config, ds)
102+
pod := &corev1.Pod{
103+
Spec: corev1.PodSpec{
104+
Containers: tc.containers,
105+
},
106+
}
107+
108+
spec := setCloudControllerImage(tc.config, deploy.Spec.Template.Spec)
109+
assert.EqualValues(t, spec.Containers, tc.expectedContainers)
153110

154-
assert.EqualValues(t, ds.Spec.Template.Spec.Containers, tc.expectedContainers)
111+
spec = setCloudControllerImage(tc.config, ds.Spec.Template.Spec)
112+
assert.EqualValues(t, spec.Containers, tc.expectedContainers)
113+
114+
spec = setCloudControllerImage(tc.config, pod.Spec)
115+
assert.EqualValues(t, spec.Containers, tc.expectedContainers)
155116
})
156117
}
118+
157119
}
158120

159121
func TestFillConfigValues(t *testing.T) {
@@ -247,7 +209,7 @@ func TestFillConfigValues(t *testing.T) {
247209
ManagedNamespace: testManagementNamespace,
248210
},
249211
}, {
250-
name: "Substitute image and namespace for more deployment and daemonset",
212+
name: "Substitute image and namespace for deployment, daemonset and pod",
251213
objects: []client.Object{&v1.DaemonSet{
252214
Spec: v1.DaemonSetSpec{
253215
Template: corev1.PodTemplateSpec{
@@ -259,6 +221,20 @@ func TestFillConfigValues(t *testing.T) {
259221
},
260222
},
261223
},
224+
}, &corev1.Pod{
225+
Spec: corev1.PodSpec{
226+
Containers: []corev1.Container{{
227+
Name: cloudControllerManagerName,
228+
Image: "expect_change",
229+
}},
230+
},
231+
}, &corev1.Pod{
232+
Spec: corev1.PodSpec{
233+
Containers: []corev1.Container{{
234+
Name: cloudNodeManagerName,
235+
Image: "expect_change",
236+
}},
237+
},
262238
}, &v1.Deployment{
263239
Spec: v1.DeploymentSpec{
264240
Template: corev1.PodTemplateSpec{
@@ -286,6 +262,26 @@ func TestFillConfigValues(t *testing.T) {
286262
},
287263
},
288264
},
265+
}, &corev1.Pod{
266+
ObjectMeta: metav1.ObjectMeta{
267+
Namespace: testManagementNamespace,
268+
},
269+
Spec: corev1.PodSpec{
270+
Containers: []corev1.Container{{
271+
Name: cloudControllerManagerName,
272+
Image: "correct_image:tag",
273+
}},
274+
},
275+
}, &corev1.Pod{
276+
ObjectMeta: metav1.ObjectMeta{
277+
Namespace: testManagementNamespace,
278+
},
279+
Spec: corev1.PodSpec{
280+
Containers: []corev1.Container{{
281+
Name: cloudNodeManagerName,
282+
Image: "correct_cloud_node_image:tag",
283+
}},
284+
},
289285
}, &v1.Deployment{
290286
ObjectMeta: metav1.ObjectMeta{
291287
Namespace: testManagementNamespace,

0 commit comments

Comments
 (0)