1
16
17 package componentconfigs
18
19 import (
20 "testing"
21
22 v1 "k8s.io/api/core/v1"
23 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
24
25 "k8s.io/kubernetes/cmd/kubeadm/app/constants"
26 )
27
28 var checksumTestCases = []struct {
29 desc string
30 configMap *v1.ConfigMap
31 checksum string
32 }{
33 {
34 desc: "checksum is calculated using both data and binaryData",
35 checksum: "sha256:c8f8b724728a6d6684106e5e64e94ce811c9965d19dd44dd073cf86cf43bc238",
36 configMap: &v1.ConfigMap{
37 Data: map[string]string{
38 "foo": "bar",
39 },
40 BinaryData: map[string][]byte{
41 "bar": []byte("baz"),
42 },
43 },
44 },
45 {
46 desc: "config keys have no effect on the checksum",
47 checksum: "sha256:c8f8b724728a6d6684106e5e64e94ce811c9965d19dd44dd073cf86cf43bc238",
48 configMap: &v1.ConfigMap{
49 Data: map[string]string{
50 "foo2": "bar",
51 },
52 BinaryData: map[string][]byte{
53 "bar2": []byte("baz"),
54 },
55 },
56 },
57 {
58 desc: "metadata fields have no effect on the checksum",
59 checksum: "sha256:c8f8b724728a6d6684106e5e64e94ce811c9965d19dd44dd073cf86cf43bc238",
60 configMap: &v1.ConfigMap{
61 ObjectMeta: metav1.ObjectMeta{
62 Name: "le-config",
63 Namespace: "le-namespace",
64 Labels: map[string]string{
65 "label1": "value1",
66 "label2": "value2",
67 },
68 Annotations: map[string]string{
69 "annotation1": "value1",
70 "annotation2": "value2",
71 },
72 },
73 Data: map[string]string{
74 "foo": "bar",
75 },
76 BinaryData: map[string][]byte{
77 "bar": []byte("baz"),
78 },
79 },
80 },
81 {
82 desc: "checksum can be calculated without binaryData",
83 checksum: "sha256:fcde2b2edba56bf408601fb721fe9b5c338d10ee429ea04fae5511b68fbf8fb9",
84 configMap: &v1.ConfigMap{
85 Data: map[string]string{
86 "foo": "bar",
87 },
88 },
89 },
90 {
91 desc: "checksum can be calculated without data",
92 checksum: "sha256:baa5a0964d3320fbc0c6a922140453c8513ea24ab8fd0577034804a967248096",
93 configMap: &v1.ConfigMap{
94 BinaryData: map[string][]byte{
95 "bar": []byte("baz"),
96 },
97 },
98 },
99 }
100
101 func TestChecksumForConfigMap(t *testing.T) {
102 for _, test := range checksumTestCases {
103 t.Run(test.desc, func(t *testing.T) {
104 got := ChecksumForConfigMap(test.configMap)
105 if got != test.checksum {
106 t.Errorf("checksum mismatch - got %q, expected %q", got, test.checksum)
107 }
108 })
109 }
110 }
111
112 func TestSignConfigMap(t *testing.T) {
113 for _, test := range checksumTestCases {
114 t.Run(test.desc, func(t *testing.T) {
115 target := test.configMap.DeepCopy()
116 SignConfigMap(target)
117
118
119 signature, ok := target.Annotations[constants.ComponentConfigHashAnnotationKey]
120 if !ok {
121 t.Errorf("no %s annotation found in the config map", constants.ComponentConfigHashAnnotationKey)
122 } else {
123 if signature != test.checksum {
124 t.Errorf("unexpected checksum - got %q, expected %q", signature, test.checksum)
125 }
126 }
127
128
129 expectedAnnotationCount := 1 + len(test.configMap.Annotations)
130 if len(target.Annotations) != expectedAnnotationCount {
131 t.Errorf("unexpected number of annotations - got %d, expected %d", len(target.Annotations), expectedAnnotationCount)
132 }
133 })
134 }
135 }
136
137 func TestVerifyConfigMapSignature(t *testing.T) {
138 tests := []struct {
139 desc string
140 configMap *v1.ConfigMap
141 expectErr bool
142 }{
143 {
144 desc: "correct signature is acknowledged",
145 configMap: &v1.ConfigMap{
146 ObjectMeta: metav1.ObjectMeta{
147 Name: "le-config",
148 Namespace: "le-namespace",
149 Labels: map[string]string{
150 "label1": "value1",
151 "label2": "value2",
152 },
153 Annotations: map[string]string{
154 "annotation1": "value1",
155 "annotation2": "value2",
156 constants.ComponentConfigHashAnnotationKey: "sha256:c8f8b724728a6d6684106e5e64e94ce811c9965d19dd44dd073cf86cf43bc238",
157 },
158 },
159 Data: map[string]string{
160 "foo": "bar",
161 },
162 BinaryData: map[string][]byte{
163 "bar": []byte("baz"),
164 },
165 },
166 },
167 {
168 desc: "wrong checksum leads to failure",
169 configMap: &v1.ConfigMap{
170 ObjectMeta: metav1.ObjectMeta{
171 Name: "le-config",
172 Namespace: "le-namespace",
173 Labels: map[string]string{
174 "label1": "value1",
175 "label2": "value2",
176 },
177 Annotations: map[string]string{
178 "annotation1": "value1",
179 "annotation2": "value2",
180 constants.ComponentConfigHashAnnotationKey: "sha256:832cb34fc68fc370dd44dd91d5699c118ec49e46e5e6014866d6a827427b8f8c",
181 },
182 },
183 Data: map[string]string{
184 "foo": "bar",
185 },
186 BinaryData: map[string][]byte{
187 "bar": []byte("baz"),
188 },
189 },
190 expectErr: true,
191 },
192 {
193 desc: "missing signature means error",
194 configMap: &v1.ConfigMap{
195 ObjectMeta: metav1.ObjectMeta{
196 Name: "le-config",
197 Namespace: "le-namespace",
198 Labels: map[string]string{
199 "label1": "value1",
200 "label2": "value2",
201 },
202 Annotations: map[string]string{
203 "annotation1": "value1",
204 "annotation2": "value2",
205 },
206 },
207 Data: map[string]string{
208 "foo": "bar",
209 },
210 BinaryData: map[string][]byte{
211 "bar": []byte("baz"),
212 },
213 },
214 expectErr: true,
215 },
216 }
217 for _, test := range tests {
218 t.Run(test.desc, func(t *testing.T) {
219 result := VerifyConfigMapSignature(test.configMap)
220 if result != !test.expectErr {
221 t.Errorf("unexpected result - got %t, expected %t", result, !test.expectErr)
222 }
223 })
224 }
225 }
226
View as plain text