From f26ea8dfb6047f7f16e1eacf5b6f62c26de126b6 Mon Sep 17 00:00:00 2001 From: JoshVanL Date: Mon, 22 Jul 2019 15:44:23 +0100 Subject: [PATCH] Adds selfsigned certificaterequest e2e tests Signed-off-by: JoshVanL --- .../selfsigned/selfsigned.go | 9 +- .../selfsigned/selfsigned_test.go | 9 +- .../selfsigned/util_test.go | 9 +- test/e2e/suite/issuers/selfsigned/BUILD.bazel | 7 +- .../suite/issuers/selfsigned/certificate.go | 2 +- .../issuers/selfsigned/certificaterequest.go | 151 ++++++++++++++++++ test/e2e/suite/issuers/selfsigned/fixtures.go | 61 +++++++ test/unit/gen/certificaterequest.go | 14 ++ 8 files changed, 251 insertions(+), 11 deletions(-) create mode 100644 test/e2e/suite/issuers/selfsigned/certificaterequest.go create mode 100644 test/e2e/suite/issuers/selfsigned/fixtures.go diff --git a/pkg/controller/certificaterequests/selfsigned/selfsigned.go b/pkg/controller/certificaterequests/selfsigned/selfsigned.go index b289bb493..72a9a1dff 100644 --- a/pkg/controller/certificaterequests/selfsigned/selfsigned.go +++ b/pkg/controller/certificaterequests/selfsigned/selfsigned.go @@ -1,10 +1,13 @@ /* Copyright 2019 The Jetstack cert-manager contributors. - Licensed under the Apache License, Version 2.0 (the "License"); + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, software + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and diff --git a/pkg/controller/certificaterequests/selfsigned/selfsigned_test.go b/pkg/controller/certificaterequests/selfsigned/selfsigned_test.go index 434abf5b7..54d13277c 100644 --- a/pkg/controller/certificaterequests/selfsigned/selfsigned_test.go +++ b/pkg/controller/certificaterequests/selfsigned/selfsigned_test.go @@ -1,10 +1,13 @@ /* Copyright 2019 The Jetstack cert-manager contributors. - Licensed under the Apache License, Version 2.0 (the "License"); + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, software + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and diff --git a/pkg/controller/certificaterequests/selfsigned/util_test.go b/pkg/controller/certificaterequests/selfsigned/util_test.go index 182754437..8b92cb3eb 100644 --- a/pkg/controller/certificaterequests/selfsigned/util_test.go +++ b/pkg/controller/certificaterequests/selfsigned/util_test.go @@ -1,10 +1,13 @@ /* Copyright 2019 The Jetstack cert-manager contributors. - Licensed under the Apache License, Version 2.0 (the "License"); + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, software + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and diff --git a/test/e2e/suite/issuers/selfsigned/BUILD.bazel b/test/e2e/suite/issuers/selfsigned/BUILD.bazel index b82d5c995..9b57f0399 100644 --- a/test/e2e/suite/issuers/selfsigned/BUILD.bazel +++ b/test/e2e/suite/issuers/selfsigned/BUILD.bazel @@ -2,7 +2,11 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") go_library( name = "go_default_library", - srcs = ["certificate.go"], + srcs = [ + "certificate.go", + "certificaterequest.go", + "fixtures.go", + ], importpath = "github.com/jetstack/cert-manager/test/e2e/suite/issuers/selfsigned", tags = ["manual"], visibility = ["//visibility:public"], @@ -12,6 +16,7 @@ go_library( "//test/e2e/util:go_default_library", "//vendor/github.com/onsi/ginkgo:go_default_library", "//vendor/github.com/onsi/gomega:go_default_library", + "//vendor/k8s.io/api/core/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", ], ) diff --git a/test/e2e/suite/issuers/selfsigned/certificate.go b/test/e2e/suite/issuers/selfsigned/certificate.go index 57bb51404..732fdd35a 100644 --- a/test/e2e/suite/issuers/selfsigned/certificate.go +++ b/test/e2e/suite/issuers/selfsigned/certificate.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package certificate +package selfsigned import ( "fmt" diff --git a/test/e2e/suite/issuers/selfsigned/certificaterequest.go b/test/e2e/suite/issuers/selfsigned/certificaterequest.go new file mode 100644 index 000000000..b14901cad --- /dev/null +++ b/test/e2e/suite/issuers/selfsigned/certificaterequest.go @@ -0,0 +1,151 @@ +/* +Copyright 2019 The Jetstack cert-manager contributors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package selfsigned + +import ( + "crypto/x509" + "net" + "time" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1alpha1" + "github.com/jetstack/cert-manager/test/e2e/framework" + "github.com/jetstack/cert-manager/test/e2e/util" +) + +var _ = framework.CertManagerDescribe("SelfSigned CertificateRequest", func() { + f := framework.NewDefaultFramework("create-selfsigned-certificaterequest") + h := f.Helper() + + issuerName := "test-selfsigned-issuer" + certificateRequestName := "test-selfsigned-certificaterequest" + certificateRequestSecretName := "test-selfsigned-private-key" + + exampleDNSNames := []string{"dnsName1.co", "dnsName2.ninja"} + exampleIPAddresses := []net.IP{ + []byte{8, 8, 8, 8}, + []byte{1, 1, 1, 1}, + } + exampleURIs := []string{"spiffe://foo.foo.example.net", "spiffe://foo.bar.example.net"} + + JustBeforeEach(func() { + By("Creating an Issuer") + _, err := f.CertManagerClientSet.CertmanagerV1alpha1().Issuers(f.Namespace.Name).Create(util.NewCertManagerSelfSignedIssuer(issuerName)) + Expect(err).NotTo(HaveOccurred()) + By("Waiting for Issuer to become Ready") + err = util.WaitForIssuerCondition(f.CertManagerClientSet.CertmanagerV1alpha1().Issuers(f.Namespace.Name), + issuerName, + v1alpha1.IssuerCondition{ + Type: v1alpha1.IssuerConditionReady, + Status: v1alpha1.ConditionTrue, + }) + Expect(err).NotTo(HaveOccurred()) + }) + + AfterEach(func() { + By("Cleaning up") + f.KubeClientSet.CoreV1().Secrets(f.Namespace.Name).Delete(certificateRequestSecretName, nil) + f.CertManagerClientSet.CertmanagerV1alpha1().Issuers(f.Namespace.Name).Delete(issuerName, nil) + }) + + Context("Self Signed and private key", func() { + + BeforeEach(func() { + By("Creating a signing keypair fixture") + _, err := f.KubeClientSet.CoreV1().Secrets(f.Namespace.Name).Create(newPrivateKeySecret(certificateRequestSecretName)) + Expect(err).NotTo(HaveOccurred()) + }) + + It("should generate a valid certificate from CSR", func() { + certRequestClient := f.CertManagerClientSet.CertmanagerV1alpha1().CertificateRequests(f.Namespace.Name) + + By("Creating a CertificateRequest") + cr, key, err := util.NewCertManagerBasicCertificateRequest(certificateRequestName, issuerName, v1alpha1.IssuerKind, + &metav1.Duration{ + Duration: time.Hour * 24 * 90, + }, + exampleDNSNames, exampleIPAddresses, exampleURIs, x509.RSA) + Expect(err).NotTo(HaveOccurred()) + cr.Annotations[v1alpha1.CRPrivateKeyAnnotationKey] = certificateRequestSecretName + _, err = certRequestClient.Create(cr) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying the Certificate is valid") + err = h.WaitCertificateRequestIssuedValid(f.Namespace.Name, certificateRequestName, time.Second*30, key) + Expect(err).NotTo(HaveOccurred()) + }) + + It("should be able to obtain an ECDSA key from a RSA backed issuer", func() { + certRequestClient := f.CertManagerClientSet.CertmanagerV1alpha1().CertificateRequests(f.Namespace.Name) + + By("Creating a CertificateRequest") + cr, key, err := util.NewCertManagerBasicCertificateRequest(certificateRequestName, issuerName, v1alpha1.IssuerKind, + &metav1.Duration{ + Duration: time.Hour * 24 * 90, + }, + exampleDNSNames, exampleIPAddresses, exampleURIs, x509.ECDSA) + Expect(err).NotTo(HaveOccurred()) + cr.Annotations[v1alpha1.CRPrivateKeyAnnotationKey] = certificateRequestSecretName + _, err = certRequestClient.Create(cr) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying the Certificate is valid") + err = h.WaitCertificateRequestIssuedValid(f.Namespace.Name, certificateRequestName, time.Second*30, key) + Expect(err).NotTo(HaveOccurred()) + }) + + cases := []struct { + inputDuration *metav1.Duration + expectedDuration time.Duration + label string + }{ + { + inputDuration: &metav1.Duration{time.Hour * 24 * 35}, + expectedDuration: time.Hour * 24 * 35, + label: "35 days", + }, + { + inputDuration: nil, + expectedDuration: time.Hour * 24 * 90, + label: "the default duration (90 days)", + }, + } + for _, v := range cases { + It("should generate a signed certificate valid for "+v.label, func() { + crClient := f.CertManagerClientSet.CertmanagerV1alpha1().CertificateRequests(f.Namespace.Name) + + By("Creating a CertificateRequest") + cr, key, err := util.NewCertManagerBasicCertificateRequest(certificateRequestName, issuerName, v1alpha1.IssuerKind, v.inputDuration, + exampleDNSNames, exampleIPAddresses, exampleURIs, x509.RSA) + Expect(err).NotTo(HaveOccurred()) + cr.Annotations[v1alpha1.CRPrivateKeyAnnotationKey] = certificateRequestSecretName + cr, err = crClient.Create(cr) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying the CertificateRequest is valid") + err = h.WaitCertificateRequestIssuedValid(f.Namespace.Name, certificateRequestName, time.Second*30, key) + Expect(err).NotTo(HaveOccurred()) + cr, err = crClient.Get(cr.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + f.CertificateRequestDurationValid(cr, v.expectedDuration) + }) + } + }) +}) diff --git a/test/e2e/suite/issuers/selfsigned/fixtures.go b/test/e2e/suite/issuers/selfsigned/fixtures.go new file mode 100644 index 000000000..28a45ff94 --- /dev/null +++ b/test/e2e/suite/issuers/selfsigned/fixtures.go @@ -0,0 +1,61 @@ +/* +Copyright 2019 The Jetstack cert-manager contributors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package selfsigned + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const rootKey = `-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAz5DYA7iEBFq/SrCOTsjiYSHlHbTUdLyzselos5cE2++Huon3 +InPqMupiDoS8/Qr9srnoKnah7aKB3sY7GlXdg85zcIbQIKocymsRy/GPbEEpfTRG +1yfihUuEM+EBvQFX9Hs0Ut5bHOH6CC88jVebWotpZiphkQnlsGxhcPe091LgYYg1 +HPxm+KHjp/RnbBWQIahOmxtfwc7vixrYNrJSPMCxYaU7ltkaIxIeMMSd/3J6TZNy +MTJWiiGg4tpCD+eDbVPlFbN5kpOXVzOfC4ZWv21l8cWrFDmp5oh37UgK3E2+QSNt +OdmXpbL0K2GfR3HA55LlOowntIU1fLWCniN/8wIDAQABAoIBAQCYvGvIKSG0FpbG +vi6pmLbEZO20s1jW4fiUxT2PUWR49sR4pocdahB/EOvA5TowNcNDnftSK+Ox+q/4 +HwRkt6R+Fg/qULmcH7F53dnFqeYw8a42/J3YOvg7v7rzdfISg4eWVobFJ+wBz+Nt +3FyBYWLm+MlBLZSH5rGG5em59/zJNHWIhH+oQPfCxAkYEvd8tXOTUzjhqvEfjaJy +FZghnT9xto4MwDdNCPbtzdNjTMhiv0AHkcZGGtRJfkehXX2qhXOQ2UzzO9XrMZnv +5KgYf+bXKJsyS3SPl6TTl7vg2gKBciRvsdFhMy5I5GyIADrEDJnNNmXQRtiaFLfd +k/aqfPT5AoGBAPquMouZUbVS/Qh+qbls7G4zAuznfCiqdctcKmUGPRP4sTTjWdUp +fjI+UTt1e8hncmr4RY7Oa9kUV/kDwzS5spUZZ+u0PczS3XKxOwNOleoH00dfc9vt +cxctHdPdDTndRi8Z4k3m931jIX7jB/Pyx8qeNYB3pj0k3ThktwMbAVLnAoGBANP4 +beI5zpbvtAdExJcuxx2mRDGF0lIdKC0bvQaeqM3Lwqnmc0Fz1dbP7KXDa+SdJWPd +res+NHPZoEPeEJuDTSngXOLNECZe4Ja9frn1TeY858vMJBwIkyc8zu+sgXxjQUM+ +TWUlTUhtXyybkRnxAEny4OT2TTgmXITJaKOmV1UVAoGAHaXSlo4YitB42rNYUXTf +dZ0U4H30Qj7+1YFeBjq5qI4GL1IgQsS4hyq1osmfTTFm593bJCunt7HfQbU/NhIs +W9P4ZXkYwgvCYxkw+JAnzNkGFO/mHQG1Ve1hFLiVIt3XuiRejoYdiTfbM02YmDKD +jKQvgbUk9SBSBaRrvLNJ8csCgYAYnrZEnGo+ZcEHRxl+ZdSCwRkSl3SCTRiphJtD +9ZGttYj6quWgKJAhzyyxZC1X9FivbMQSmrsE6bYPq+9J4MpJnuGrBh5mFocHeyMI +/lD5+QEDTsay6twMpqdydxrjE7Q01zuuD9MWIn33dGo6FR/vduJgNatqZipA0hPx +ThS+sQKBgQDh0+cVo1mfYiCkp3IQPB8QYiJ/g2/UBk6pH8ZZDZ+A5td6NveiWO1y +wTEUWkX2qyz9SLxWDGOhdKqxNrLCUSYSOV/5/JQEtBm6K50ArFtrY40JP/T/5KvM +tSK2ayFX1wQ3PuEmewAogy/20tWo80cr556AXA62Utl2PzLK30Db8w== +-----END RSA PRIVATE KEY-----` + +func newPrivateKeySecret(name string) *corev1.Secret { + return &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + StringData: map[string]string{ + corev1.TLSPrivateKeyKey: rootKey, + }, + } +} diff --git a/test/unit/gen/certificaterequest.go b/test/unit/gen/certificaterequest.go index ba7d887df..df78ac4a3 100644 --- a/test/unit/gen/certificaterequest.go +++ b/test/unit/gen/certificaterequest.go @@ -106,3 +106,17 @@ func SetCertificateRequestName(name string) CertificateRequestModifier { cr.ObjectMeta.Name = name } } + +func AddCertificateRequestAnnotations(annotations map[string]string) CertificateRequestModifier { + return func(cr *v1alpha1.CertificateRequest) { + // Make sure to do a merge here with new annotations overriding. + annotationsNew := cr.GetAnnotations() + if annotationsNew == nil { + annotationsNew = make(map[string]string) + } + for k, v := range annotations { + annotationsNew[k] = v + } + cr.SetAnnotations(annotationsNew) + } +}