1
16
17 package renewal
18
19 import (
20 "crypto"
21 "crypto/x509"
22 "fmt"
23 "net"
24 "os"
25 "path/filepath"
26 "testing"
27
28 "k8s.io/client-go/tools/clientcmd"
29 certutil "k8s.io/client-go/util/cert"
30 "k8s.io/client-go/util/keyutil"
31 netutils "k8s.io/utils/net"
32
33 kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
34 kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
35 "k8s.io/kubernetes/cmd/kubeadm/app/util/pkiutil"
36 testutil "k8s.io/kubernetes/cmd/kubeadm/test"
37 )
38
39 func TestPKICertificateReadWriter(t *testing.T) {
40
41 dir := testutil.SetupTempDir(t)
42 defer os.RemoveAll(dir)
43
44
45 cert := writeTestCertificate(t, dir, "test", testCACert, testCAKey, testCertOrganization)
46
47
48 pkiReadWriter := newPKICertificateReadWriter(dir, "test")
49
50
51 readCert, err := pkiReadWriter.Read()
52 if err != nil {
53 t.Fatalf("couldn't read certificate: %v", err)
54 }
55
56
57 if !cert.Equal(readCert) {
58 t.Errorf("read cert does not match with expected cert")
59 }
60
61
62 newCert, newkey, err := pkiutil.NewCertAndKey(testCACert, testCAKey, testCertCfg)
63 if err != nil {
64 t.Fatalf("couldn't generate certificate: %v", err)
65 }
66
67
68 err = pkiReadWriter.Write(newCert, newkey)
69 if err != nil {
70 t.Fatalf("couldn't write new certificate: %v", err)
71 }
72
73
74 readCert, err = pkiReadWriter.Read()
75 if err != nil {
76 t.Fatalf("couldn't read new certificate: %v", err)
77 }
78
79
80 if !newCert.Equal(readCert) {
81 t.Error("read cert does not match with expected new cert")
82 }
83 }
84
85 func TestKubeconfigReadWriter(t *testing.T) {
86
87 dirKubernetes := testutil.SetupTempDir(t)
88 defer os.RemoveAll(dirKubernetes)
89 dirPKI := testutil.SetupTempDir(t)
90 defer os.RemoveAll(dirPKI)
91
92
93 caName := kubeadmconstants.CACertAndKeyBaseName
94 if err := pkiutil.WriteCertAndKey(
95 dirPKI,
96 caName,
97 testCACert,
98 testCAKey); err != nil {
99 t.Fatalf("couldn't write out certificate %s to %s", caName, dirPKI)
100 }
101
102
103 cert := writeTestKubeconfig(t, dirKubernetes, "test", testCACert, testCAKey)
104
105
106 kubeconfigReadWriter := newKubeconfigReadWriter(dirKubernetes, "test", dirPKI, caName)
107
108
109 readCert, err := kubeconfigReadWriter.Read()
110 if err != nil {
111 t.Fatalf("couldn't read embedded certificate: %v", err)
112 }
113
114
115 if !cert.Equal(readCert) {
116 t.Errorf("read cert does not match with expected cert")
117 }
118
119
120 newCert, newkey, err := pkiutil.NewCertAndKey(testCACert, testCAKey, testCertCfg)
121 if err != nil {
122 t.Fatalf("couldn't generate certificate: %v", err)
123 }
124
125
126 err = kubeconfigReadWriter.Write(newCert, newkey)
127 if err != nil {
128 t.Fatalf("couldn't write new embedded certificate: %v", err)
129 }
130
131
132
133 _, caKeyPath := pkiutil.PathsForCertAndKey(dirPKI, caName)
134 os.Remove(caKeyPath)
135
136
137 readCert, err = kubeconfigReadWriter.Read()
138 if err != nil {
139 t.Fatalf("couldn't read new embedded certificate: %v", err)
140 }
141
142
143 if !newCert.Equal(readCert) {
144 t.Errorf("read cert does not match with expected new cert")
145 }
146 }
147
148
149 func writeTestCertificate(t *testing.T, dir, name string, caCert *x509.Certificate, caKey crypto.Signer, organization []string) *x509.Certificate {
150 cert, key, err := pkiutil.NewCertAndKey(caCert, caKey, makeTestCertConfig(organization))
151 if err != nil {
152 t.Fatalf("couldn't generate certificate: %v", err)
153 }
154
155 if err := pkiutil.WriteCertAndKey(dir, name, cert, key); err != nil {
156 t.Fatalf("couldn't write out certificate %s to %s", name, dir)
157 }
158
159 return cert
160 }
161
162
163 func writeTestKubeconfig(t *testing.T, dir, name string, caCert *x509.Certificate, caKey crypto.Signer) *x509.Certificate {
164
165 cfg := &pkiutil.CertConfig{
166 Config: certutil.Config{
167 CommonName: "test-common-name",
168 Organization: testCertOrganization,
169 Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
170 AltNames: certutil.AltNames{
171 IPs: []net.IP{netutils.ParseIPSloppy("10.100.0.1")},
172 DNSNames: []string{"test-domain.space"},
173 },
174 },
175 }
176 cert, key, err := pkiutil.NewCertAndKey(caCert, caKey, cfg)
177 if err != nil {
178 t.Fatalf("couldn't generate certificate: %v", err)
179 }
180
181 encodedClientKey, err := keyutil.MarshalPrivateKeyToPEM(key)
182 if err != nil {
183 t.Fatalf("failed to marshal private key to PEM: %v", err)
184 }
185
186 certificateAuthorityData := pkiutil.EncodeCertPEM(caCert)
187
188 config := kubeconfigutil.CreateWithCerts(
189 "https://localhost:1234",
190 "kubernetes-test",
191 "user-test",
192 certificateAuthorityData,
193 encodedClientKey,
194 pkiutil.EncodeCertPEM(cert),
195 )
196
197 if err := clientcmd.WriteToFile(*config, filepath.Join(dir, name)); err != nil {
198 t.Fatalf("couldn't write out certificate")
199 }
200
201 return cert
202 }
203
204 func TestFileExists(t *testing.T) {
205 tmpdir, err := os.MkdirTemp("", "")
206 if err != nil {
207 t.Fatalf("Couldn't create tmpdir: %v", err)
208 }
209 defer func() {
210 err = os.RemoveAll(tmpdir)
211 if err != nil {
212 t.Fatalf("Fail to remove tmpdir: %v", err)
213 }
214 }()
215 tmpfile, err := os.CreateTemp(tmpdir, "")
216 if err != nil {
217 t.Fatalf("Couldn't create tmpfile: %v", err)
218 }
219 tests := []struct {
220 name string
221 filename string
222 want bool
223 }{
224 {
225 name: "file exist",
226 filename: tmpfile.Name(),
227 want: true,
228 },
229 {
230 name: "file does not exist",
231 filename: "foo",
232 want: false,
233 },
234 {
235 name: "file path is a dir",
236 filename: tmpdir,
237 want: false,
238 },
239 }
240 for _, tt := range tests {
241 t.Run(tt.name, func(t *testing.T) {
242 if got, _ := fileExists(tt.filename); got != tt.want {
243 t.Errorf("fileExists() = %v, want %v", got, tt.want)
244 }
245 })
246 }
247 }
248
249 func TestPKICertificateReadWriterExists(t *testing.T) {
250 tmpdir, err := os.MkdirTemp("", "")
251 if err != nil {
252 t.Fatalf("Couldn't create tmpdir: %v", err)
253 }
254 defer func() {
255 err = os.RemoveAll(tmpdir)
256 if err != nil {
257 t.Fatalf("Fail to remove tmpdir: %v", err)
258 }
259 }()
260 filename := "testfile"
261 tmpfilepath := filepath.Join(tmpdir, fmt.Sprintf(filename+".crt"))
262 err = os.WriteFile(tmpfilepath, nil, 0644)
263 if err != nil {
264 t.Fatalf("Couldn't write file: %v", err)
265 }
266 type fields struct {
267 baseName string
268 certificateDir string
269 }
270 tests := []struct {
271 name string
272 fields fields
273 want bool
274 }{
275 {
276 name: "cert file exists",
277 fields: fields{
278 baseName: filename,
279 certificateDir: tmpdir,
280 },
281 want: true,
282 },
283 {
284 name: "cert file does not exist",
285 fields: fields{
286 baseName: "foo",
287 certificateDir: tmpdir,
288 },
289 want: false,
290 },
291 }
292 for _, tt := range tests {
293 t.Run(tt.name, func(t *testing.T) {
294 rw := &pkiCertificateReadWriter{
295 baseName: tt.fields.baseName,
296 certificateDir: tt.fields.certificateDir,
297 }
298 if got, _ := rw.Exists(); got != tt.want {
299 t.Errorf("pkiCertificateReadWriter.Exists() = %v, want %v", got, tt.want)
300 }
301 })
302 }
303 }
304
305 func TestKubeConfigReadWriterExists(t *testing.T) {
306 tmpdir, err := os.MkdirTemp("", "")
307 if err != nil {
308 t.Fatalf("Couldn't create tmpdir: %v", err)
309 }
310 defer func() {
311 err = os.RemoveAll(tmpdir)
312 if err != nil {
313 t.Fatalf("Fail to remove tmpdir: %v", err)
314 }
315 }()
316 tmpfile, err := os.CreateTemp(tmpdir, "")
317 if err != nil {
318 t.Fatalf("Couldn't create tmpfile: %v", err)
319 }
320 tests := []struct {
321 name string
322 kubeConfigFilePath string
323 want bool
324 }{
325 {
326 name: "file exists",
327 kubeConfigFilePath: tmpfile.Name(),
328 want: true,
329 },
330 {
331 name: "file does not exist",
332 kubeConfigFilePath: "foo",
333 want: false,
334 },
335 }
336 for _, tt := range tests {
337 t.Run(tt.name, func(t *testing.T) {
338 rw := &kubeConfigReadWriter{
339 kubeConfigFilePath: tt.kubeConfigFilePath,
340 }
341 if got, _ := rw.Exists(); got != tt.want {
342 t.Errorf("kubeConfigReadWriter.Exists() = %v, want %v", got, tt.want)
343 }
344 })
345 }
346 }
347
View as plain text