Skip to content

Commit c30b06b

Browse files
authored
Merge pull request #446 from fanminshi/impl_tls_ca_not_app
*: implement and test the case where CA exists but App secret doesn't
2 parents e476f34 + fb40804 commit c30b06b

File tree

8 files changed

+235
-10
lines changed

8 files changed

+235
-10
lines changed

pkg/tlsutil/tls.go

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,8 @@ func (scg *SDKCertGenerator) GenerateCert(cr runtime.Object, service *v1.Service
152152
if err != nil {
153153
return nil, nil, nil, err
154154
}
155-
appSecret, err := getAppSecretInCluster(scg.KubeClient, ToAppSecretName(k, n, config.CertName), ns)
155+
appSecretName := ToAppSecretName(k, n, config.CertName)
156+
appSecret, err := getAppSecretInCluster(scg.KubeClient, appSecretName, ns)
156157
if err != nil {
157158
return nil, nil, nil, err
158159
}
@@ -169,9 +170,29 @@ func (scg *SDKCertGenerator) GenerateCert(cr runtime.Object, service *v1.Service
169170
} else if hasAppSecret && !hasCASecretAndConfigMap {
170171
return nil, nil, nil, ErrCANotFound
171172
} else if !hasAppSecret && hasCASecretAndConfigMap {
172-
// TODO
173+
caKey, err := parsePEMEncodedPrivateKey(caSecret.Data[TLSPrivateCAKeyKey])
174+
if err != nil {
175+
return nil, nil, nil, err
176+
}
177+
caCert, err := parsePEMEncodedCert([]byte(caConfigMap.Data[TLSCACertKey]))
178+
if err != nil {
179+
return nil, nil, nil, err
180+
}
181+
key, err := newPrivateKey()
182+
if err != nil {
183+
return nil, nil, nil, err
184+
}
185+
cert, err := newSignedCertificate(config, service, key, caCert, caKey)
186+
if err != nil {
187+
return nil, nil, nil, err
188+
}
189+
appSecret, err := scg.KubeClient.CoreV1().Secrets(ns).Create(toTLSSecret(key, cert, appSecretName, ns))
190+
if err != nil {
191+
return nil, nil, nil, err
192+
}
193+
return appSecret, caConfigMap, caSecret, nil
173194
} else {
174-
// TODO
195+
// TODO: handle the case where both CA and Application TLS assets don't exist.
175196
}
176197
return nil, nil, nil, nil
177198
}

test/e2e/testdata/ca-csr.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"key": {
3+
"algo": "rsa",
4+
"size": 2048
5+
},
6+
"names": [
7+
{
8+
"L": "San Francisco",
9+
"ST": "California",
10+
"C": "USA"
11+
}
12+
],
13+
"CN": "ca",
14+
"ca": {
15+
"expiry": "87600h"
16+
}
17+
}

test/e2e/testdata/ca.crt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIDhDCCAmygAwIBAgIUJCpEclRVqfgYKUIyrk6m46BqH0EwDQYJKoZIhvcNAQEL
3+
BQAwSDEMMAoGA1UEBhMDVVNBMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQH
4+
Ew1TYW4gRnJhbmNpc2NvMQswCQYDVQQDEwJjYTAeFw0xODA4MzAyMDEyMDBaFw0y
5+
ODA4MjcyMDEyMDBaMEgxDDAKBgNVBAYTA1VTQTETMBEGA1UECBMKQ2FsaWZvcm5p
6+
YTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzELMAkGA1UEAxMCY2EwggEiMA0GCSqG
7+
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDwSnTyS56xvTRBNbkNNoYBfOJNGzSNCtF/
8+
u2NrYUQW9YOCCceuhl8q4g8H6/+HTV9RlRiTAY7DSFSZUK/C3x4uFhY1emXjzgqT
9+
Z19FKEKwkVhqo7XSkGrqb37U0vgdO2eyGWqVt2gS50wNimo4Z3HcfsziDtqFZpxb
10+
9ZuCiWmGpnkx+NuH9Qq2LBHSdOHI+HWw7E/91ZAaTmW/QA9W9HvxKNC9pmFFBRtd
11+
WDjGvHsTmpgPZ2Pce/jcJ6SAaO82KXM0ksW4LmaK4OTUPN+c3KODA/gSau77DNNG
12+
bnjQ6CkyKKOfInGDVhpG57p+LuIbt724bCxmNRkvjYwrr+dEL4SpAgMBAAGjZjBk
13+
MA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgECMB0GA1UdDgQWBBSN
14+
6FinnI4qg4IeK9PGzzufD6usjDAfBgNVHSMEGDAWgBSN6FinnI4qg4IeK9PGzzuf
15+
D6usjDANBgkqhkiG9w0BAQsFAAOCAQEAy6sn3xyNcQ/HzD1Ii7p4toc5qbgDONnq
16+
9YkbIoNFxFj8DTQ86r6jcj94PnylIhBe1I1k70tVVal7nM+4wnNaTktAfiQN/mYJ
17+
RyvMTXN6+Vsl93AeBMo7DIGElz2sL2EkOTct1QmTr7hr/3u4SfBvppFnxYqJKiI3
18+
GX3V0kV1iuAllyHR787hkWq28LQ3WXtqnybAR23SMVtQNrHw1t1ia5eStK4Gbfl/
19+
FN/BNwkV6i8Q/5B2obCUJWpzt4UqB4hXv3TmhYCeA8ddq7LYjjil11Ed21o95QyK
20+
FooF2jEmda+zivmB/XKC+5+DfL00x0G1QqbME6ilGkpRx2gDFg03cg==
21+
-----END CERTIFICATE-----

test/e2e/testdata/ca.csr

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
-----BEGIN CERTIFICATE REQUEST-----
2+
MIICjTCCAXUCAQAwSDEMMAoGA1UEBhMDVVNBMRMwEQYDVQQIEwpDYWxpZm9ybmlh
3+
MRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMQswCQYDVQQDEwJjYTCCASIwDQYJKoZI
4+
hvcNAQEBBQADggEPADCCAQoCggEBAPBKdPJLnrG9NEE1uQ02hgF84k0bNI0K0X+7
5+
Y2thRBb1g4IJx66GXyriDwfr/4dNX1GVGJMBjsNIVJlQr8LfHi4WFjV6ZePOCpNn
6+
X0UoQrCRWGqjtdKQaupvftTS+B07Z7IZapW3aBLnTA2Kajhncdx+zOIO2oVmnFv1
7+
m4KJaYameTH424f1CrYsEdJ04cj4dbDsT/3VkBpOZb9AD1b0e/Eo0L2mYUUFG11Y
8+
OMa8exOamA9nY9x7+NwnpIBo7zYpczSSxbguZorg5NQ835zco4MD+BJq7vsM00Zu
9+
eNDoKTIoo58icYNWGkbnun4u4hu3vbhsLGY1GS+NjCuv50QvhKkCAwEAAaAAMA0G
10+
CSqGSIb3DQEBCwUAA4IBAQDDqdtWrOmptqpQNDG6nt1EW6KLwSPhZBx+wwGVpPtb
11+
cXVSvjQkmIzK0G22XtDnIIix+D65hvFIPyVvKYVhDm5LhRvcguyRAV2SkrDlhBka
12+
tZG03yvvUE4hbdWjJtk7CAUoKOZ1Sl47zdf0Rn1b/LZd9gQ6Ew08YRfdZ9VLQdOm
13+
j/o6owGqIpU/dCaMZZ/8jzccmqt6QkiTSlyrA2ws38S0wcEsILp8vppLQc056Qiw
14+
AcqwwUw1jp8omqozPCKir12gNjkWxLnZ56ka1PwUJr0cj8QYUqHC0q/xl2eNw2lU
15+
W8qZn+2N43F3KvJ5BPUbuu+69G8EQhhMKHq69G6WSGhQ
16+
-----END CERTIFICATE REQUEST-----

test/e2e/testdata/ca.key

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
-----BEGIN RSA PRIVATE KEY-----
2+
MIIEpAIBAAKCAQEA8Ep08kuesb00QTW5DTaGAXziTRs0jQrRf7tja2FEFvWDggnH
3+
roZfKuIPB+v/h01fUZUYkwGOw0hUmVCvwt8eLhYWNXpl484Kk2dfRShCsJFYaqO1
4+
0pBq6m9+1NL4HTtnshlqlbdoEudMDYpqOGdx3H7M4g7ahWacW/WbgolphqZ5Mfjb
5+
h/UKtiwR0nThyPh1sOxP/dWQGk5lv0APVvR78SjQvaZhRQUbXVg4xrx7E5qYD2dj
6+
3Hv43CekgGjvNilzNJLFuC5miuDk1DzfnNyjgwP4Emru+wzTRm540OgpMiijnyJx
7+
g1YaRue6fi7iG7e9uGwsZjUZL42MK6/nRC+EqQIDAQABAoIBAAbaSL2ENJFjEPNv
8+
IcjjriyqsBV82iHPlivrXyl3y6ZP+CEkQEKU6G/jpIQYUeA876P2+Y1vtO+Sx37b
9+
0zdef5DW5mk+BVvay2hqwUfKnyRD8N6RrqTDo5jt9xMAtTy4LfvhR63fXiNz3zJf
10+
qSnUoWWlZBhqTgcR5xGkTnwJiS3i0Vk9/xU1zNL7OZpSSSuefXuq2qQtG+Gayrps
11+
KAp1essnKnNRyiQH2yOn3pXs5Mj+ytWCV7C9eL1TAg0ZSIjuV+S/CNpCHsVLv5p6
12+
yj/CWjzV7NOhsdHoo5t1FsALhQaov0bb6hv96ZbTwkPoegr1SLQnYx63kOo//AmK
13+
uCgZgxECgYEA/qmFoBlRNm2AJ/vRp0t6JoERF9LhsUWSYRmcSho2xG5fLwzSxCjR
14+
YOxFEdZl3hzkH/rhY7+Vg6rOH5rhjL4hBKnrCkZcC88J7WCTI4mJDwTP/iViahAg
15+
RVEvJ6T51qI8N1wojumuQIhbUmVcWiZA49QRC/5DqIgZ1lRDWycqTeUCgYEA8Y2b
16+
mCI5zvjPci/1WBbPqA9ZDdbi4MmvO/RG+ik4RZnN7poxg2JU/Ta5RAFB1UY21bo8
17+
JTiL2pRqLaGLi0HPEJEaS6K5a+9oK5tUtmJp6CgpnNiNmALUyaoXbg3lrv5ajo74
18+
G94AZEIha0r9ReECvtk/sdsK1IgZaBtCIJ2Lj3UCgYEAjo+4DngdzqpeJAQEyfKm
19+
3wdB2mRjlCmuWE1OAO3L2wsundg/5TA0hl2+DM5JGJ5z1rNLmduWh68G1QqPWYrW
20+
URYOTiI1RScSF6EIvcwwvgejqFKlVVrRtfxMuZTRiCYqL5OX4OlQcy/ib63ulUj0
21+
6pW9NUmR9ra6QBHL4yt5s0ECgYEAsAJpX/+AdAnkzuWXNqrYgTM9xtHP28/aOiuT
22+
FHG4qS6bWcNNVNjv6NpZQO5RlCBnkHD1poF/lrQSclGGJuC7Cu1QZdCan8WA+FVk
23+
8sjfNuUc/UbmVd+qQZAJJo5F0K9SORKAQ34Odv+g7ldkGekNYRdYTDa5u4e4S52h
24+
H7bsnIkCgYAJZRkDWjhPhWX7hv9HcLcyW/yOe9tEys/2UoYBr+j3X0eraKR1+EUr
25+
Xli+yuPBbRo5+bEzAXI/gbZGu3J6vZm0J9qHc1ybqLvcTcOweTBU7xs4aeJsSK5O
26+
w0BnNOc/05hLf2Ow02ZlZBELMXpp1Y187+FKEmkwxTrgaGB3rZanVA==
27+
-----END RSA PRIVATE KEY-----

test/e2e/testdata/gencert.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"signing": {
3+
"default": {
4+
"usages": [
5+
"signing",
6+
"key encipherment",
7+
"server auth",
8+
"client auth"
9+
],
10+
"expiry": "87600h"
11+
}
12+
}
13+
}

test/e2e/testdata/gencert.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/bin/bash
2+
3+
if ! [[ "$0" =~ "./gencert.sh" ]]; then
4+
echo "must be run from 'testdata'"
5+
exit 255
6+
fi
7+
8+
if ! which cfssl; then
9+
echo "cfssl is not installed"
10+
exit 255
11+
fi
12+
13+
cfssl gencert --initca=true ./ca-csr.json | cfssljson --bare ca -
14+
mv ca.pem ca.crt
15+
mv ca-key.pem ca.key
16+
if which openssl >/dev/null; then
17+
openssl x509 -in ca.crt -noout -text
18+
fi

test/e2e/tls_util_test.go

Lines changed: 99 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package e2e
1616

1717
import (
18+
"io/ioutil"
1819
"reflect"
1920
"testing"
2021

@@ -27,32 +28,53 @@ import (
2728

2829
var (
2930
// TLS test variables.
30-
crKind = "Pod"
31-
crName = "example-pod"
32-
certName = "app-cert"
33-
31+
crKind = "Pod"
32+
crName = "example-pod"
33+
certName = "app-cert"
3434
caConfigMapAndSecretName = tlsutil.ToCASecretAndConfigMapName(crKind, crName)
35-
caConfigMap = &v1.ConfigMap{
35+
appSecretName = tlsutil.ToAppSecretName(crKind, crName, certName)
36+
37+
caConfigMap *v1.ConfigMap
38+
caSecret *v1.Secret
39+
appSecret *v1.Secret
40+
41+
ccfg *tlsutil.CertConfig
42+
)
43+
44+
// setup test variables.
45+
func init() {
46+
caCertBytes, err := ioutil.ReadFile("./testdata/ca.crt")
47+
if err != nil {
48+
panic(err)
49+
}
50+
caConfigMap = &v1.ConfigMap{
3651
ObjectMeta: metav1.ObjectMeta{
3752
Name: caConfigMapAndSecretName,
3853
},
54+
Data: map[string]string{tlsutil.TLSCACertKey: string(caCertBytes)},
55+
}
56+
57+
caKeyBytes, err := ioutil.ReadFile("./testdata/ca.key")
58+
if err != nil {
59+
panic(err)
3960
}
4061
caSecret = &v1.Secret{
4162
ObjectMeta: metav1.ObjectMeta{
4263
Name: caConfigMapAndSecretName,
4364
},
65+
Data: map[string][]byte{tlsutil.TLSPrivateCAKeyKey: caKeyBytes},
4466
}
4567

4668
appSecret = &v1.Secret{
4769
ObjectMeta: metav1.ObjectMeta{
48-
Name: tlsutil.ToAppSecretName(crKind, crName, certName),
70+
Name: appSecretName,
4971
},
5072
}
5173

5274
ccfg = &tlsutil.CertConfig{
5375
CertName: certName,
5476
}
55-
)
77+
}
5678

5779
// TestBothAppAndCATLSAssetsExist ensures that when both application
5880
// and CA TLS assets exist in the k8s cluster for a given cr,
@@ -142,3 +164,73 @@ func TestOnlyAppSecretExist(t *testing.T) {
142164
t.Fatalf("expect %v, but got %v", tlsutil.ErrCANotFound.Error(), err.Error())
143165
}
144166
}
167+
168+
// TestOnlyCAExist ensures that at the case where only the CA exists in the cluster;
169+
// GenerateCert can retrieve the CA and uses it to create a new application secret.
170+
func TestOnlyCAExist(t *testing.T) {
171+
f := framework.Global
172+
ctx := f.NewTestCtx(t)
173+
defer ctx.Cleanup(t)
174+
namespace, err := ctx.GetNamespace()
175+
if err != nil {
176+
t.Fatal(err)
177+
}
178+
179+
_, err = f.KubeClient.CoreV1().ConfigMaps(namespace).Create(caConfigMap)
180+
if err != nil {
181+
t.Fatal(err)
182+
}
183+
_, err = f.KubeClient.CoreV1().Secrets(namespace).Create(caSecret)
184+
if err != nil {
185+
t.Fatal(err)
186+
}
187+
188+
cg := tlsutil.NewSDKCertGenerator(f.KubeClient)
189+
// Use Pod as a dummy runtime object for the CR input of GenerateCert().
190+
mCR := &v1.Pod{
191+
TypeMeta: metav1.TypeMeta{
192+
Kind: crKind,
193+
},
194+
ObjectMeta: metav1.ObjectMeta{
195+
Name: crName,
196+
Namespace: namespace,
197+
},
198+
}
199+
appSvc := &v1.Service{
200+
ObjectMeta: metav1.ObjectMeta{
201+
Name: "app-service",
202+
Namespace: namespace,
203+
},
204+
}
205+
appSecret, _, _, err := cg.GenerateCert(mCR, appSvc, ccfg)
206+
if err != nil {
207+
t.Fatal(err)
208+
}
209+
210+
// check if appSecret has the correct fields.
211+
if appSecretName != appSecret.Name {
212+
t.Fatalf("expect the secret name %v, but got %v", appSecretName, appSecret.Name)
213+
}
214+
if namespace != appSecret.Namespace {
215+
t.Fatalf("expect the secret namespace %v, but got %v", namespace, appSecret.Namespace)
216+
}
217+
if v1.SecretTypeTLS != appSecret.Type {
218+
t.Fatalf("expect the secret type %v, but got %v", v1.SecretTypeTLS, appSecret.Type)
219+
}
220+
if _, ok := appSecret.Data[v1.TLSCertKey]; !ok {
221+
t.Fatalf("expect the secret to have the data field %v, but got none", v1.TLSCertKey)
222+
}
223+
if _, ok := appSecret.Data[v1.TLSPrivateKeyKey]; !ok {
224+
t.Fatalf("expect the secret to have the data field %v, but got none", v1.TLSPrivateKeyKey)
225+
}
226+
227+
// check if appSecret exists in k8s cluster.
228+
appSecretFromCluster, err := f.KubeClient.CoreV1().Secrets(namespace).Get(appSecretName, metav1.GetOptions{})
229+
if err != nil {
230+
t.Fatal(err)
231+
}
232+
// check if appSecret returned from GenerateCert is the same as the one that exists in the k8s.
233+
if !reflect.DeepEqual(appSecret, appSecretFromCluster) {
234+
t.Fatalf("expect %+v, but got %+v", appSecret, appSecretFromCluster)
235+
}
236+
}

0 commit comments

Comments
 (0)