Skip to content

Commit f20fd10

Browse files
committed
Enhance/fix e2e tests for cert-manager
Signed-off-by: ArkaSaha30 <[email protected]>
1 parent 52c387e commit f20fd10

File tree

1 file changed

+243
-36
lines changed

1 file changed

+243
-36
lines changed

test/e2e/certmanager_test.go

+243-36
Original file line numberDiff line numberDiff line change
@@ -2,76 +2,283 @@ package e2e
22

33
import (
44
"context"
5+
"fmt"
6+
"net"
57
"testing"
8+
"time"
69

10+
certv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
711
"github.com/stretchr/testify/assert"
8-
"k8s.io/apimachinery/pkg/api/errors"
12+
appsv1 "k8s.io/api/apps/v1"
13+
corev1 "k8s.io/api/core/v1"
14+
k8serrors "k8s.io/apimachinery/pkg/api/errors"
15+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
16+
"sigs.k8s.io/e2e-framework/klient"
17+
"sigs.k8s.io/e2e-framework/klient/k8s"
18+
"sigs.k8s.io/e2e-framework/klient/k8s/resources"
19+
"sigs.k8s.io/e2e-framework/klient/wait"
20+
"sigs.k8s.io/e2e-framework/klient/wait/conditions"
921
"sigs.k8s.io/e2e-framework/pkg/envconf"
1022
"sigs.k8s.io/e2e-framework/pkg/features"
1123

24+
apiextensionsV1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
25+
26+
ecv1alpha1 "go.etcd.io/etcd-operator/api/v1alpha1"
1227
"go.etcd.io/etcd-operator/pkg/certificate/cert_manager"
1328
interfaces "go.etcd.io/etcd-operator/pkg/certificate/interfaces"
1429
)
1530

31+
const cmIssuerName = "selfsigned"
32+
const etcdClusterName = "etcd-cluster-test"
33+
const size = 3
34+
1635
func TestCertManagerProvider(t *testing.T) {
1736
feature := features.New("Cert-Manager Certificate").WithLabel("app", "cert-manager")
1837

38+
// TODO: pick these from testdata yamls
39+
etcdCluster := &ecv1alpha1.EtcdCluster{
40+
TypeMeta: metav1.TypeMeta{
41+
APIVersion: "operator.etcd.io/v1alpha1",
42+
Kind: "EtcdCluster",
43+
},
44+
ObjectMeta: metav1.ObjectMeta{
45+
Name: etcdClusterName,
46+
Namespace: namespace,
47+
},
48+
Spec: ecv1alpha1.EtcdClusterSpec{
49+
Size: size,
50+
Version: "v3.5.18",
51+
TLS: &ecv1alpha1.TLSCertificate{
52+
Provider: "cert-manager",
53+
ProviderCfg: &ecv1alpha1.ProviderConfig{
54+
CertManagerCfg: &ecv1alpha1.ProviderCertManagerConfig{
55+
CommonName: "etcd.etcd-operator-system",
56+
Organization: []string{"etcd-operator"},
57+
DNSNames: []string{"etcd.etcd-operator-system"},
58+
IPs: []net.IP{net.ParseIP("192.168.0.5")},
59+
Duration: 2160,
60+
IssuerName: "selfsigned",
61+
IssuerKind: "ClusterIssuer",
62+
},
63+
},
64+
},
65+
},
66+
}
67+
68+
cmIssuer := &certv1.ClusterIssuer{
69+
TypeMeta: metav1.TypeMeta{
70+
Kind: "ClusterIssuer",
71+
},
72+
ObjectMeta: metav1.ObjectMeta{
73+
Name: "selfsigned",
74+
},
75+
Spec: certv1.IssuerSpec{
76+
IssuerConfig: certv1.IssuerConfig{
77+
SelfSigned: &certv1.SelfSignedIssuer{},
78+
}},
79+
}
80+
1981
feature.Setup(
2082
func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context {
2183
client := cfg.Client()
22-
cmProvider := cert_manager.New(client.Resources().GetControllerRuntimeClient())
23-
_, getCertConfigErr := cmProvider.GetCertificateConfig(ctx, "test-cert-secret", cfg.Namespace())
24-
if errors.IsNotFound(getCertConfigErr) {
25-
t.Log(getCertConfigErr)
26-
} else {
27-
t.Fatal(getCertConfigErr)
84+
_ = appsv1.AddToScheme(client.Resources().GetScheme())
85+
_ = corev1.AddToScheme(client.Resources().GetScheme())
86+
_ = certv1.AddToScheme(client.Resources().GetScheme())
87+
_ = apiextensionsV1.AddToScheme(client.Resources().GetScheme())
88+
_ = ecv1alpha1.AddToScheme(client.Resources().GetScheme())
89+
90+
var issuer certv1.ClusterIssuer
91+
if err := client.Resources().Get(ctx, cmIssuerName, "", &issuer); err != nil {
92+
if k8serrors.IsNotFound(err) {
93+
t.Logf("No cert-manager selfsigned issuer found, creating clusterIssuer: %s", cmIssuerName)
94+
// Create cert-manager issuer
95+
if err := client.Resources().Create(ctx, cmIssuer); err != nil {
96+
t.Fatalf("unable to craete cert-manager selfsigned issuer: %s", err)
97+
}
98+
} else {
99+
t.Fatalf("Failed to get cert-manager selfsigned issuer: %s", cmIssuerName)
100+
}
28101
}
29-
cmConfig := &interfaces.Config{
30-
AltNames: interfaces.AltNames{
31-
DNSNames: []string{"test.com"},
32-
},
33-
ExtraConfig: map[string]interface{}{
34-
"issuerName": "test-issuer",
35-
"issuerKind": "Issuer",
36-
},
102+
103+
name := "etcdclusters.operator.etcd.io"
104+
var crd apiextensionsV1.CustomResourceDefinition
105+
if err := client.Resources().Get(ctx, name, "", &crd); err != nil {
106+
t.Fatalf("Failed due to error: %s", err)
107+
}
108+
109+
if crd.Spec.Group != "operator.etcd.io" {
110+
t.Fatalf("Expected crd group to be operator.etcd.io, got %s", crd.Spec.Group)
37111
}
38-
err := cmProvider.EnsureCertificateSecret(ctx, "test-cert-secret", cfg.Namespace(), cmConfig)
39-
if err != nil {
112+
113+
// Create the etcd cluster resource
114+
if err := client.Resources().Create(ctx, etcdCluster); err != nil {
115+
t.Fatalf("unable to create an etcd cluster resource of size 1: %s", err)
116+
}
117+
118+
if err := wait.For(
119+
conditions.New(client.Resources()).ResourceMatch(etcdCluster, func(object k8s.Object) bool {
120+
return true
121+
}),
122+
wait.WithTimeout(3*time.Minute),
123+
wait.WithInterval(30*time.Second),
124+
); err != nil {
40125
t.Fatal(err)
41126
}
42127
return ctx
43128
})
44129

45-
feature.Assess("Validate certificate secret",
130+
feature.Assess("Check for client certificates",
46131
func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context {
47132
client := cfg.Client()
48-
cmProvider := cert_manager.New(client.Resources().GetControllerRuntimeClient())
49-
valid, err := cmProvider.ValidateCertificateSecret(ctx, "test-cert-secret", cfg.Namespace(), &interfaces.Config{})
50-
if err != nil {
51-
t.Fatal(err)
52-
}
53-
assert.True(t, valid)
133+
validateCertificates(ctx, client, t, "client")
134+
return ctx
135+
})
136+
137+
feature.Assess("Check for server certificates",
138+
func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context {
139+
client := cfg.Client()
140+
validateCertificates(ctx, client, t, "server")
141+
return ctx
142+
})
143+
144+
feature.Assess("Check for peer certificates",
145+
func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context {
146+
client := cfg.Client()
147+
validateCertificates(ctx, client, t, "peer")
54148
return ctx
55149
})
56150

57151
feature.Teardown(
58152
func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context {
59153
client := cfg.Client()
60-
cmProvider := cert_manager.New(client.Resources().GetControllerRuntimeClient())
61-
deleteSecretErr := cmProvider.DeleteCertificateSecret(ctx, "test-cert-secret", cfg.Namespace())
62-
if errors.IsNotFound(deleteSecretErr) {
63-
t.Log(deleteSecretErr)
154+
deleteCertificates(ctx, client, t, "client")
155+
deleteCertificates(ctx, client, t, "server")
156+
deleteCertificates(ctx, client, t, "peer")
157+
return ctx
158+
})
159+
160+
_ = testEnv.Test(t, feature.Feature())
161+
}
162+
163+
func validateCertificates(ctx context.Context, client klient.Client, t *testing.T, certType string) {
164+
cmProvider := cert_manager.New(client.Resources().GetControllerRuntimeClient())
165+
podList := corev1.PodList{}
166+
cmCert := certv1.Certificate{}
167+
// Check if the certificate type is Client
168+
if certType == "client" {
169+
cmCertName := fmt.Sprintf("%s-%s-tls", etcdClusterName, certType)
170+
certErr := client.Resources().Get(ctx, cmCertName, namespace, &cmCert)
171+
if certErr != nil {
172+
if k8serrors.IsNotFound(certErr) {
173+
t.Fatalf("No %s certificate found: %s", cmCertName, certErr)
64174
} else {
65-
t.Fatal(deleteSecretErr)
175+
t.Logf("Failed to get %s certificate: %s", certErr, cmCertName)
176+
t.Fatal(certErr)
177+
}
178+
}
179+
// Check if the secret created is a valid secret
180+
valid, secretErr := cmProvider.ValidateCertificateSecret(ctx, cmCertName, namespace, &interfaces.Config{})
181+
if secretErr != nil {
182+
t.Logf("Invalid secret: %s", cmCertName)
183+
t.Fatal(secretErr)
184+
} else {
185+
if !valid {
186+
t.Fatalf("No secret %s found", cmCertName)
187+
}
188+
}
189+
} else {
190+
// If the certificate type is Server or Peer, check for each member
191+
labelSelector := fmt.Sprintf("app=%s", etcdClusterName)
192+
err := client.Resources().List(ctx, &podList, resources.WithLabelSelector(labelSelector))
193+
if err != nil {
194+
t.Log("Failed to get StatefulSet pods")
195+
t.Fatal(err)
196+
}
197+
for _, pod := range podList.Items {
198+
cmCertName := fmt.Sprintf("%s-%s-tls", pod.Name, certType)
199+
certErr := client.Resources().Get(ctx, cmCertName, namespace, &cmCert)
200+
if certErr != nil {
201+
if k8serrors.IsNotFound(certErr) {
202+
t.Fatalf("No %s certificate found: %s", cmCertName, certErr)
203+
} else {
204+
t.Logf("Failed to get %s certificate: %s", certType, cmCertName)
205+
t.Fatal(certErr)
206+
}
66207
}
67-
deleteCertErr := cmProvider.RevokeCertificate(ctx, "test-cert-secret", cfg.Namespace())
68-
if errors.IsNotFound(deleteCertErr) {
69-
t.Log(deleteCertErr)
208+
valid, secretErr := cmProvider.ValidateCertificateSecret(ctx, cmCertName, namespace, &interfaces.Config{})
209+
if secretErr != nil {
210+
t.Logf("Invalid secret: %s", cmCertName)
211+
t.Fatal(secretErr)
70212
} else {
71-
t.Fatal(deleteCertErr)
213+
if !valid {
214+
t.Fatalf("No secret %s found", cmCertName)
215+
}
72216
}
73-
return ctx
74-
})
217+
assert.True(t, valid)
218+
}
219+
}
220+
}
75221

76-
_ = testEnv.Test(t, feature.Feature())
222+
func deleteCertificates(ctx context.Context, client klient.Client, t *testing.T, certType string) {
223+
cmProvider := cert_manager.New(client.Resources().GetControllerRuntimeClient())
224+
podList := corev1.PodList{}
225+
cmCert := certv1.Certificate{}
226+
cmSecret := corev1.Secret{}
227+
// Check if the certificate type is Client
228+
if certType == "client" {
229+
cmCertName := fmt.Sprintf("%s-%s-tls", etcdClusterName, certType)
230+
deleteErr := cmProvider.RevokeCertificate(ctx, cmCertName, namespace)
231+
if deleteErr != nil {
232+
t.Fatalf("Failed to remvoke certificate: %s", deleteErr)
233+
}
234+
// Check if certificate has been deleted successfully
235+
certErr := client.Resources().Get(ctx, cmCertName, namespace, &cmCert)
236+
if certErr != nil {
237+
if k8serrors.IsNotFound(certErr) {
238+
t.Logf("No %s certificate to delete: %s", cmCertName, certErr)
239+
} else {
240+
t.Logf("Failed to get %s certificate for deletion: %s", certErr, cmCertName)
241+
}
242+
}
243+
// Check if secret has been deleted successfully
244+
secretErr := client.Resources().Get(ctx, cmCertName, namespace, &cmSecret)
245+
if secretErr != nil {
246+
if k8serrors.IsNotFound(secretErr) {
247+
t.Logf("No %s secret to delete: %s", cmCertName, secretErr)
248+
} else {
249+
t.Logf("Failed to get %s secret for deletion: %s", secretErr, cmCertName)
250+
}
251+
}
252+
} else {
253+
// If the certificate type is Server or Peer, check for each member
254+
labelSelector := fmt.Sprintf("app=%s", etcdClusterName)
255+
err := client.Resources().List(ctx, &podList, resources.WithLabelSelector(labelSelector))
256+
if err != nil {
257+
t.Log("Failed to get StatefulSet pods")
258+
}
259+
for _, pod := range podList.Items {
260+
cmCertName := fmt.Sprintf("%s-%s-tls", pod.Name, certType)
261+
deleteErr := cmProvider.RevokeCertificate(ctx, cmCertName, namespace)
262+
if deleteErr != nil {
263+
t.Fatalf("Failed to remvoke certificate: %s", deleteErr)
264+
}
265+
// Check if certificate has been deleted successfully
266+
certErr := client.Resources().Get(ctx, cmCertName, namespace, &cmCert)
267+
if certErr != nil {
268+
if k8serrors.IsNotFound(certErr) {
269+
t.Logf("No %s certificate to delete: %s", cmCertName, certErr)
270+
}
271+
t.Logf("Failed to get %s certificate for deletion: %s", certType, cmCertName)
272+
}
273+
// Check if secret has been deleted successfully
274+
secretErr := client.Resources().Get(ctx, cmCertName, namespace, &cmSecret)
275+
if secretErr != nil {
276+
if k8serrors.IsNotFound(secretErr) {
277+
t.Logf("No %s secret to delete: %s", cmCertName, secretErr)
278+
} else {
279+
t.Logf("Failed to get %s secret for deletion: %s", secretErr, cmCertName)
280+
}
281+
}
282+
}
283+
}
77284
}

0 commit comments

Comments
 (0)