Skip to content

Commit ad47274

Browse files
authored
Merge pull request kubernetes#75185 from ereslibre/certs-integration
kubeadm: add integration tests for certs transfer
2 parents 3adae6c + 8737720 commit ad47274

File tree

2 files changed

+135
-7
lines changed

2 files changed

+135
-7
lines changed

cmd/kubeadm/app/phases/copycerts/BUILD

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,14 @@ go_test(
4747
deps = [
4848
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
4949
"//cmd/kubeadm/app/constants:go_default_library",
50+
"//cmd/kubeadm/app/phases/certs:go_default_library",
5051
"//cmd/kubeadm/app/util/crypto:go_default_library",
5152
"//cmd/kubeadm/test:go_default_library",
53+
"//staging/src/k8s.io/api/core/v1:go_default_library",
54+
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
55+
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
56+
"//staging/src/k8s.io/client-go/util/cert:go_default_library",
57+
"//staging/src/k8s.io/client-go/util/keyutil:go_default_library",
5258
"//vendor/github.com/lithammer/dedent:go_default_library",
5359
],
5460
)

cmd/kubeadm/app/phases/copycerts/copycerts_test.go

Lines changed: 129 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,18 @@ import (
2525
"testing"
2626

2727
"github.com/lithammer/dedent"
28+
v1 "k8s.io/api/core/v1"
29+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
30+
fakeclient "k8s.io/client-go/kubernetes/fake"
31+
certutil "k8s.io/client-go/util/cert"
32+
keyutil "k8s.io/client-go/util/keyutil"
2833
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
2934
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
35+
"k8s.io/kubernetes/cmd/kubeadm/app/phases/certs"
3036
cryptoutil "k8s.io/kubernetes/cmd/kubeadm/app/util/crypto"
3137
testutil "k8s.io/kubernetes/cmd/kubeadm/test"
3238
)
3339

34-
func TestUploadCerts(t *testing.T) {
35-
tmpdir := testutil.SetupTempDir(t)
36-
defer os.RemoveAll(tmpdir)
37-
38-
}
39-
40-
//teste cert name, teste cert can be decrypted
4140
func TestGetDataFromInitConfig(t *testing.T) {
4241
certData := []byte("cert-data")
4342
tmpdir := testutil.SetupTempDir(t)
@@ -156,3 +155,126 @@ func TestCertOrKeyNameToSecretName(t *testing.T) {
156155
}
157156
}
158157
}
158+
159+
func TestUploadCerts(t *testing.T) {
160+
tmpdir := testutil.SetupTempDir(t)
161+
defer os.RemoveAll(tmpdir)
162+
163+
secretKey, err := CreateCertificateKey()
164+
if err != nil {
165+
t.Fatalf("could not create certificate key: %v", err)
166+
}
167+
168+
initConfiguration := testutil.GetDefaultInternalConfig(t)
169+
initConfiguration.ClusterConfiguration.CertificatesDir = tmpdir
170+
171+
if err := certs.CreatePKIAssets(initConfiguration); err != nil {
172+
t.Fatalf("error creating PKI assets: %v", err)
173+
}
174+
175+
cs := fakeclient.NewSimpleClientset()
176+
if err := UploadCerts(cs, initConfiguration, secretKey); err != nil {
177+
t.Fatalf("error uploading certs: %v", err)
178+
}
179+
rawSecretKey, err := hex.DecodeString(secretKey)
180+
if err != nil {
181+
t.Fatalf("error decoding key: %v", err)
182+
}
183+
secretMap, err := cs.CoreV1().Secrets(metav1.NamespaceSystem).Get(kubeadmconstants.KubeadmCertsSecret, metav1.GetOptions{})
184+
if err != nil {
185+
t.Fatalf("could not fetch secret: %v", err)
186+
}
187+
for certName, certPath := range certsToTransfer(initConfiguration) {
188+
secretCertData, err := cryptoutil.DecryptBytes(secretMap.Data[certOrKeyNameToSecretName(certName)], rawSecretKey)
189+
if err != nil {
190+
t.Fatalf("error decrypting secret data: %v", err)
191+
}
192+
diskCertData, err := ioutil.ReadFile(certPath)
193+
if err != nil {
194+
t.Fatalf("error reading certificate from disk: %v", err)
195+
}
196+
// Check that the encrypted contents on the secret match the contents on disk, and that all
197+
// the expected certificates are in the secret
198+
if string(secretCertData) != string(diskCertData) {
199+
t.Fatalf("cert %s does not have the expected contents. contents: %q; expected contents: %q", certName, string(secretCertData), string(diskCertData))
200+
}
201+
}
202+
}
203+
204+
func TestDownloadCerts(t *testing.T) {
205+
secretKey, err := CreateCertificateKey()
206+
if err != nil {
207+
t.Fatalf("could not create certificate key: %v", err)
208+
}
209+
210+
// Temporary directory where certificates will be generated
211+
tmpdir := testutil.SetupTempDir(t)
212+
defer os.RemoveAll(tmpdir)
213+
initConfiguration := testutil.GetDefaultInternalConfig(t)
214+
initConfiguration.ClusterConfiguration.CertificatesDir = tmpdir
215+
216+
// Temporary directory where certificates will be downloaded to
217+
targetTmpdir := testutil.SetupTempDir(t)
218+
defer os.RemoveAll(targetTmpdir)
219+
initForDownloadConfiguration := testutil.GetDefaultInternalConfig(t)
220+
initForDownloadConfiguration.ClusterConfiguration.CertificatesDir = targetTmpdir
221+
222+
if err := certs.CreatePKIAssets(initConfiguration); err != nil {
223+
t.Fatalf("error creating PKI assets: %v", err)
224+
}
225+
226+
kubeadmCertsSecret := createKubeadmCertsSecret(t, initConfiguration, secretKey)
227+
cs := fakeclient.NewSimpleClientset(kubeadmCertsSecret)
228+
if err := DownloadCerts(cs, initForDownloadConfiguration, secretKey); err != nil {
229+
t.Fatalf("error downloading certs: %v", err)
230+
}
231+
232+
const keyFileMode = 0600
233+
const certFileMode = 0644
234+
235+
for certName, certPath := range certsToTransfer(initForDownloadConfiguration) {
236+
diskCertData, err := ioutil.ReadFile(certPath)
237+
if err != nil {
238+
t.Errorf("error reading certificate from disk: %v", err)
239+
}
240+
// Check that the written files are either certificates or keys, and that they have
241+
// the expected permissions
242+
if _, err := keyutil.ParsePublicKeysPEM(diskCertData); err == nil {
243+
if stat, err := os.Stat(certPath); err == nil {
244+
if stat.Mode() != keyFileMode {
245+
t.Errorf("key %q should have mode %#o, has %#o", certName, keyFileMode, stat.Mode())
246+
}
247+
} else {
248+
t.Errorf("could not stat key %q: %v", certName, err)
249+
}
250+
} else if _, err := certutil.ParseCertsPEM(diskCertData); err == nil {
251+
if stat, err := os.Stat(certPath); err == nil {
252+
if stat.Mode() != certFileMode {
253+
t.Errorf("cert %q should have mode %#o, has %#o", certName, certFileMode, stat.Mode())
254+
}
255+
} else {
256+
t.Errorf("could not stat cert %q: %v", certName, err)
257+
}
258+
} else {
259+
t.Errorf("secret %q was not identified as a cert or as a key", certName)
260+
}
261+
}
262+
}
263+
264+
func createKubeadmCertsSecret(t *testing.T, cfg *kubeadmapi.InitConfiguration, secretKey string) *v1.Secret {
265+
decodedKey, err := hex.DecodeString(secretKey)
266+
if err != nil {
267+
t.Fatalf("error decoding key: %v", err)
268+
}
269+
secretData, err := getDataFromDisk(cfg, decodedKey)
270+
if err != nil {
271+
t.Fatalf("error creating secret data: %v", err)
272+
}
273+
return &v1.Secret{
274+
ObjectMeta: metav1.ObjectMeta{
275+
Name: kubeadmconstants.KubeadmCertsSecret,
276+
Namespace: metav1.NamespaceSystem,
277+
},
278+
Data: secretData,
279+
}
280+
}

0 commit comments

Comments
 (0)