Skip to content

Commit 4bf526c

Browse files
Add tests for clusterctl image overrides functionality
Signed-off-by: Danil-Grigorev <[email protected]>
1 parent c40d35f commit 4bf526c

File tree

2 files changed

+168
-6
lines changed

2 files changed

+168
-6
lines changed
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
/*
2+
Copyright 2024 The Kubernetes Authors.
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+
package controller
18+
19+
import (
20+
"fmt"
21+
"testing"
22+
23+
. "github.com/onsi/gomega"
24+
appsv1 "k8s.io/api/apps/v1"
25+
corev1 "k8s.io/api/core/v1"
26+
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
27+
"k8s.io/client-go/kubernetes/scheme"
28+
)
29+
30+
// inspectImages identifies the container images required to install the objects defined in the objs.
31+
// NB. The implemented approach is specific for the provider components YAML & for the cert-manager manifest; it is not
32+
// intended to cover all the possible objects used to deploy containers existing in Kubernetes.
33+
func inspectImages(objs []unstructured.Unstructured) ([]string, error) {
34+
images := []string{}
35+
36+
for i := range objs {
37+
o := objs[i]
38+
39+
var podSpec corev1.PodSpec
40+
41+
switch o.GetKind() {
42+
case deploymentKind:
43+
d := &appsv1.Deployment{}
44+
if err := scheme.Scheme.Convert(&o, d, nil); err != nil {
45+
return nil, err
46+
}
47+
podSpec = d.Spec.Template.Spec
48+
case daemonSetKind:
49+
d := &appsv1.DaemonSet{}
50+
if err := scheme.Scheme.Convert(&o, d, nil); err != nil {
51+
return nil, err
52+
}
53+
podSpec = d.Spec.Template.Spec
54+
default:
55+
continue
56+
}
57+
58+
for _, c := range podSpec.Containers {
59+
images = append(images, c.Image)
60+
}
61+
62+
for _, c := range podSpec.InitContainers {
63+
images = append(images, c.Image)
64+
}
65+
}
66+
67+
return images, nil
68+
}
69+
70+
func TestFixImages(t *testing.T) {
71+
type args struct {
72+
objs []unstructured.Unstructured
73+
alterImageFunc func(image string) (string, error)
74+
}
75+
tests := []struct {
76+
name string
77+
args args
78+
want []string
79+
wantErr bool
80+
}{
81+
{
82+
name: "fix deployment containers images",
83+
args: args{
84+
objs: []unstructured.Unstructured{
85+
{
86+
Object: map[string]interface{}{
87+
"apiVersion": "apps/v1",
88+
"kind": deploymentKind,
89+
"spec": map[string]interface{}{
90+
"template": map[string]interface{}{
91+
"spec": map[string]interface{}{
92+
"containers": []map[string]interface{}{
93+
{
94+
"image": "container-image",
95+
},
96+
},
97+
"initContainers": []map[string]interface{}{
98+
{
99+
"image": "init-container-image",
100+
},
101+
},
102+
},
103+
},
104+
},
105+
},
106+
},
107+
},
108+
alterImageFunc: func(image string) (string, error) {
109+
return fmt.Sprintf("foo-%s", image), nil
110+
},
111+
},
112+
want: []string{"foo-container-image", "foo-init-container-image"},
113+
wantErr: false,
114+
},
115+
{
116+
name: "fix daemonSet containers images",
117+
args: args{
118+
objs: []unstructured.Unstructured{
119+
{
120+
Object: map[string]interface{}{
121+
"apiVersion": "apps/v1",
122+
"kind": daemonSetKind,
123+
"spec": map[string]interface{}{
124+
"template": map[string]interface{}{
125+
"spec": map[string]interface{}{
126+
"containers": []map[string]interface{}{
127+
{
128+
"image": "container-image",
129+
},
130+
},
131+
"initContainers": []map[string]interface{}{
132+
{
133+
"image": "init-container-image",
134+
},
135+
},
136+
},
137+
},
138+
},
139+
},
140+
},
141+
},
142+
alterImageFunc: func(image string) (string, error) {
143+
return fmt.Sprintf("foo-%s", image), nil
144+
},
145+
},
146+
want: []string{"foo-container-image", "foo-init-container-image"},
147+
wantErr: false,
148+
},
149+
}
150+
for _, tt := range tests {
151+
t.Run(tt.name, func(t *testing.T) {
152+
g := NewWithT(t)
153+
154+
got, err := fixImages(tt.args.objs, tt.args.alterImageFunc)
155+
if tt.wantErr {
156+
g.Expect(err).To(HaveOccurred())
157+
return
158+
}
159+
160+
g.Expect(err).ToNot(HaveOccurred())
161+
162+
gotImages, err := inspectImages(got)
163+
g.Expect(err).ToNot(HaveOccurred())
164+
g.Expect(gotImages).To(Equal(tt.want))
165+
})
166+
}
167+
}

internal/controller/manifests_downloader_test.go

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,6 @@ func TestProviderDownloadWithOverrides(t *testing.T) {
8282
overridesClient, err := configclient.New(ctx, "", configclient.InjectReader(reader))
8383
g.Expect(err).ToNot(HaveOccurred())
8484

85-
overridesClient.Variables().Set("images", `
86-
all:
87-
repository: "myorg.io/local-repo"
88-
`)
89-
9085
p := &phaseReconciler{
9186
ctrlClient: fakeclient,
9287
provider: &operatorv1.CoreProvider{
@@ -111,6 +106,6 @@ all:
111106
_, err = p.fetch(ctx)
112107
g.Expect(err).ToNot(HaveOccurred())
113108

114-
g.Expect(p.components.Images()).To(HaveExactElements([]string{"myorg.io/local-repo/cluster-api-controller:v1.4.3"}))
109+
g.Expect(p.components.Images()).To(HaveExactElements([]string{"registry.k8s.io/cluster-api/cluster-api-controller:v1.4.3"}))
115110
g.Expect(p.components.Version()).To(Equal("v1.4.3"))
116111
}

0 commit comments

Comments
 (0)