Skip to content
This repository has been archived by the owner on Oct 22, 2021. It is now read-only.

Commit

Permalink
Add more integration tests around secret rotation (#28)
Browse files Browse the repository at this point in the history
* Integration tests use catalog helpers

* dry up tests
* remove unecessary setup from 'csr' test

* Add rotation tests for ssh, rsa and basic-auth

* Add rotation tests for different certificate options
  • Loading branch information
Mario Manno authored Aug 5, 2020
1 parent db2d625 commit c33d29d
Show file tree
Hide file tree
Showing 4 changed files with 273 additions and 173 deletions.
28 changes: 28 additions & 0 deletions integration/environment/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@ import (
"context"

"github.com/pkg/errors"
"go.uber.org/zap"

corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/wait"

"code.cloudfoundry.org/quarks-secret/pkg/credsgen"
inmemorygenerator "code.cloudfoundry.org/quarks-secret/pkg/credsgen/in_memory_generator"
qsv1a1 "code.cloudfoundry.org/quarks-secret/pkg/kube/apis/quarkssecret/v1alpha1"
"code.cloudfoundry.org/quarks-secret/pkg/kube/client/clientset/versioned"
"code.cloudfoundry.org/quarks-utils/testing/machine"
Expand Down Expand Up @@ -61,3 +65,27 @@ func (m *Machine) WaitForQuarksSecretChange(namespace string, name string, chang
return changed(*qs), nil
})
}

// CreateCASecret creates a CA and stores it in a secret
func (m *Machine) CreateCASecret(log *zap.SugaredLogger, namespace string, name string) (machine.TearDownFunc, error) {
generator := inmemorygenerator.NewInMemoryGenerator(log)
ca, err := generator.GenerateCertificate("default-ca", credsgen.CertificateGenerationRequest{
CommonName: "Fake CA",
IsCA: true,
})
if err != nil {
return nil, err
}

casecret := corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
Data: map[string][]byte{
"ca": ca.Certificate,
"key": ca.PrivateKey,
},
}
return m.CreateSecret(namespace, casecret)
}
89 changes: 75 additions & 14 deletions integration/quarks_secret_rotation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@ var _ = Describe("QuarksSecretRotation", func() {
qsecName = "test.qsec"
)

notGenerated := func(status qsv1a1.QuarksSecretStatus) bool {
return status.Generated == nil || (status.Generated != nil && !*status.Generated)
}

JustBeforeEach(func() {
By("Creating the quarks secret", func() {
_, tearDown, err := env.CreateQuarksSecret(env.Namespace, qsec)
Expand Down Expand Up @@ -60,13 +56,8 @@ var _ = Describe("QuarksSecretRotation", func() {
})

It("modifies quarks secret and a a new password is generated", func() {
err := env.WaitForQuarksSecretChange(env.Namespace, qsecName, func(qs qsv1a1.QuarksSecret) bool {
return notGenerated(qs.Status)
})
Expect(err).NotTo(HaveOccurred())

oldPassword = oldSecret.Data["password"]
err = env.WaitForSecretChange(env.Namespace, qsec.Spec.SecretName, func(s corev1.Secret) bool {
err := env.WaitForSecretChange(env.Namespace, qsec.Spec.SecretName, func(s corev1.Secret) bool {
return !bytes.Equal(oldPassword, s.Data["password"])
})
Expect(err).NotTo(HaveOccurred())
Expand All @@ -75,21 +66,91 @@ var _ = Describe("QuarksSecretRotation", func() {

When("rotating a certificate", func() {
BeforeEach(func() {
qsec = env.CertificateQuarksSecret(qsecName, "mysecret", "ca", "key")
qsec = env.CertificateQuarksSecret(qsecName, "my-ca", "ca", "key")

By("creating the CA and storing it in a secret")
tearDown, err := env.CreateCASecret(env.Log, env.Namespace, "my-ca")
Expect(err).NotTo(HaveOccurred())
tearDowns = append(tearDowns, tearDown)
})

It("modifies quarks secret and updates certificate and key", func() {
err := env.WaitForSecretChange(env.Namespace, qsec.Spec.SecretName, func(s corev1.Secret) bool {
return !bytes.Equal(oldSecret.Data["certificate"], s.Data["certificate"]) &&
!bytes.Equal(oldSecret.Data["private_key"], s.Data["private_key"])
})
Expect(err).NotTo(HaveOccurred())
})
})

When("rotating a cluster signed certificate", func() {
BeforeEach(func() {
qsec = env.CertificateQuarksSecret(qsecName, "", "", "")
qsec.Spec.Request.CertificateRequest.SignerType = qsv1a1.ClusterSigner
})

It("modifies quarks secret and updates certificate and key", func() {
err := env.WaitForQuarksSecretChange(env.Namespace, qsecName, func(qs qsv1a1.QuarksSecret) bool {
return notGenerated(qs.Status)
err := env.WaitForSecretChange(env.Namespace, qsec.Spec.SecretName, func(s corev1.Secret) bool {
return !bytes.Equal(oldSecret.Data["certificate"], s.Data["certificate"]) &&
!bytes.Equal(oldSecret.Data["private_key"], s.Data["private_key"])
})
Expect(err).NotTo(HaveOccurred())
})
})

When("rotating a CA certificate", func() {
BeforeEach(func() {
qsec = env.CACertificateQuarksSecret(qsecName, "", "", "")
})

err = env.WaitForSecretChange(env.Namespace, qsec.Spec.SecretName, func(s corev1.Secret) bool {
It("modifies quarks secret and updates certificate and key", func() {
err := env.WaitForSecretChange(env.Namespace, qsec.Spec.SecretName, func(s corev1.Secret) bool {
return !bytes.Equal(oldSecret.Data["certificate"], s.Data["certificate"]) &&
!bytes.Equal(oldSecret.Data["private_key"], s.Data["private_key"])
})
Expect(err).NotTo(HaveOccurred())
})
})

When("rotating a ssh secret", func() {
BeforeEach(func() {
qsec = env.SSHQuarksSecret(qsecName)
})

It("modifies quarks secret and the secret is updated", func() {
err := env.WaitForSecretChange(env.Namespace, qsec.Spec.SecretName, func(s corev1.Secret) bool {
return !bytes.Equal(oldSecret.Data["private_key"], s.Data["private_key"]) &&
!bytes.Equal(oldSecret.Data["public_key_fingerprint"], s.Data["public_key_fingerprint"])
})
Expect(err).NotTo(HaveOccurred())
})
})

When("rotating a rsa secret", func() {
BeforeEach(func() {
qsec = env.RSAQuarksSecret(qsecName)
})

It("modifies quarks secret and the secret is updated", func() {
err := env.WaitForSecretChange(env.Namespace, qsec.Spec.SecretName, func(s corev1.Secret) bool {
return !bytes.Equal(oldSecret.Data["private_key"], s.Data["private_key"]) &&
!bytes.Equal(oldSecret.Data["public_key"], s.Data["public_key"])
})
Expect(err).NotTo(HaveOccurred())
})
})

When("rotating a basic-auth secret", func() {
BeforeEach(func() {
qsec = env.BasicAuthQuarksSecret(qsecName)
})

It("modifies quarks secret and the secret is updated", func() {
err := env.WaitForSecretChange(env.Namespace, qsec.Spec.SecretName, func(s corev1.Secret) bool {
return !bytes.Equal(oldSecret.Data["password"], s.Data["password"]) &&
bytes.Equal(oldSecret.Data["username"], s.Data["username"])
})
Expect(err).NotTo(HaveOccurred())
})
})
})
Loading

0 comments on commit c33d29d

Please sign in to comment.