diff --git a/Makefile b/Makefile index fc1669e..eb6a832 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ PORT := 5000 .PHONY: test-e2e test-e2e: @echo "Running e2e tests..." - @go test -v -race -count 1 ./test/ + @export COSIGN_E2E="42" && go test -v -race -count 1 ./test/ .PHONY: test-unit test-unit: diff --git a/test/framework/client.go b/test/framework/client.go index 0b2c073..301926c 100644 --- a/test/framework/client.go +++ b/test/framework/client.go @@ -18,9 +18,16 @@ import ( // the cosignwebhook in a k8s cluster type Framework struct { k8s *kubernetes.Clientset + t *testing.T + err error } -func New() (*Framework, error) { +// New creates a new Framework +func New(t *testing.T) (*Framework, error) { + if t == nil { + return nil, fmt.Errorf("test object must not be nil") + } + k8s, err := createClientSet() if err != nil { return nil, err @@ -28,6 +35,7 @@ func New() (*Framework, error) { return &Framework{ k8s: k8s, + t: t, }, nil } @@ -37,7 +45,6 @@ func createClientSet() (k8sClient *kubernetes.Clientset, err error) { kubeconfig = os.Getenv("HOME") + "/.kube/config" } - // create restconfig from kubeconfig config, err := clientcmd.BuildConfigFromFlags("", kubeconfig) if err != nil { return nil, err @@ -52,31 +59,33 @@ func createClientSet() (k8sClient *kubernetes.Clientset, err error) { // Cleanup removes all resources created by the framework // and cleans up the testing directory. -func (f *Framework) Cleanup(t testing.TB) { - cleanupKeys(t) - f.cleanupDeployments(t) - f.cleanupSecrets(t) +func (f *Framework) Cleanup() { + f.cleanupKeys() + f.cleanupDeployments() + f.cleanupSecrets() + if f.err != nil { + f.t.Fatal(f.err) + } } // cleanupDeployments removes all deployments from the testing namespace // if they exist -func (f *Framework) cleanupDeployments(t testing.TB) { +func (f *Framework) cleanupDeployments() { if f.k8s == nil { - t.Logf("k8s client is nil") return } - t.Logf("cleaning up deployments") + f.t.Logf("cleaning up deployments") deployments, err := f.k8s.AppsV1().Deployments("test-cases").List(context.Background(), metav1.ListOptions{}) if err != nil { - f.Cleanup(t) - t.Fatal(err) + f.err = err + return } for _, d := range deployments.Items { err = f.k8s.AppsV1().Deployments("test-cases").Delete(context.Background(), d.Name, metav1.DeleteOptions{}) if err != nil { - f.Cleanup(t) - t.Fatal(err) + f.err = err + return } } @@ -84,84 +93,102 @@ func (f *Framework) cleanupDeployments(t testing.TB) { for { select { case <-timeout: - f.Cleanup(t) + f.err = fmt.Errorf("timeout reached while waiting for deployments to be deleted") default: pods, err := f.k8s.CoreV1().Pods("test-cases").List(context.Background(), metav1.ListOptions{}) if err != nil { - f.Cleanup(t) - t.Fatal(err) + f.err = err + return } if len(pods.Items) == 0 { - t.Logf("All pods are deleted") + f.t.Logf("All pods are deleted") return } - time.Sleep(5 * time.Second) + time.Sleep(500 * time.Millisecond) } } } // cleanupSecrets removes all secrets from the testing namespace -func (f *Framework) cleanupSecrets(t testing.TB) { +func (f *Framework) cleanupSecrets() { if f.k8s == nil { - t.Logf("k8s client is nil") return } - t.Logf("cleaning up secrets") + f.t.Logf("cleaning up secrets") secrets, err := f.k8s.CoreV1().Secrets("test-cases").List(context.Background(), metav1.ListOptions{}) if err != nil { - f.Cleanup(t) - t.Fatal(err) + f.err = err + return } if len(secrets.Items) == 0 { + f.t.Log("no secrets to delete") return } for _, s := range secrets.Items { err = f.k8s.CoreV1().Secrets("test-cases").Delete(context.Background(), s.Name, metav1.DeleteOptions{}) if err != nil { - f.Cleanup(t) - t.Fatal(err) + f.err = err + return } } + f.t.Log("all secrets are deleted") } // GetPods returns the pod(s) of the deployment. The fetch is done by label selector (app=) // If the get request fails, the test will fail and the framework will be cleaned up -func (f *Framework) GetPods(t *testing.T, d appsv1.Deployment) *corev1.PodList { - pods, err := f.k8s.CoreV1().Pods("test-cases").List(context.Background(), metav1.ListOptions{ +func (f *Framework) GetPods(d appsv1.Deployment) *corev1.PodList { + if f.err != nil { + return nil + } + + pods, err := f.k8s.CoreV1().Pods(d.Namespace).List(context.Background(), metav1.ListOptions{ LabelSelector: fmt.Sprintf("app=%s", d.Name), }) if err != nil { - f.Cleanup(t) - t.Fatal(err) + f.err = err } return pods } // CreateDeployment creates a deployment in the testing namespace -func (f *Framework) CreateDeployment(t testing.TB, d appsv1.Deployment) { - _, err := f.k8s.AppsV1().Deployments("test-cases").Create(context.Background(), &d, metav1.CreateOptions{}) +func (f *Framework) CreateDeployment(d appsv1.Deployment) { + if f.err != nil { + return + } + + f.t.Logf("creating deployment %s", d.Name) + _, err := f.k8s.AppsV1().Deployments(d.Namespace).Create(context.Background(), &d, metav1.CreateOptions{}) if err != nil { - f.Cleanup(t) - t.Fatal(err) + f.err = err + return } + f.t.Logf("deployment %s created", d.Name) } // CreateSecret creates a secret in the testing namespace -func (f *Framework) CreateSecret(t *testing.T, secret corev1.Secret) { - t.Logf("creating secret %s", secret.Name) - s, err := f.k8s.CoreV1().Secrets("test-cases").Create(context.Background(), &secret, metav1.CreateOptions{}) +func (f *Framework) CreateSecret(s corev1.Secret) { + if f.err != nil { + return + } + + f.t.Logf("creating secret %s", s.Name) + _, err := f.k8s.CoreV1().Secrets(s.Namespace).Create(context.Background(), &s, metav1.CreateOptions{}) if err != nil { - f.Cleanup(t) - t.Fatal(err) + f.err = err + return } - t.Logf("created secret %s", s.Name) + f.t.Logf("secret %s created", s.Name) } // WaitForDeployment waits until the deployment is ready -func (f *Framework) WaitForDeployment(t *testing.T, d appsv1.Deployment) { - t.Logf("waiting for deployment %s to be ready", d.Name) +func (f *Framework) WaitForDeployment(d appsv1.Deployment) { + if f.err != nil { + return + } + + f.t.Logf("waiting for deployment %s to be ready", d.Name) // wait until the deployment is ready ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() @@ -169,39 +196,42 @@ func (f *Framework) WaitForDeployment(t *testing.T, d appsv1.Deployment) { FieldSelector: fmt.Sprintf("metadata.name=%s", d.Name), }) if err != nil { - f.Cleanup(t) - t.Fatal(err) + f.err = err + return } for { select { case <-ctx.Done(): - f.Cleanup(t) - t.Fatal("timeout reached while waiting for deployment to be ready") + f.err = fmt.Errorf("timeout reached while waiting for deployment to be ready") case event := <-w.ResultChan(): deployment, ok := event.Object.(*appsv1.Deployment) if !ok { - time.Sleep(5 * time.Second) + time.Sleep(500 * time.Millisecond) continue } if deployment.Status.ReadyReplicas == 1 { - t.Logf("deployment %s is ready", d.Name) + f.t.Logf("deployment %s is ready", d.Name) return } - time.Sleep(5 * time.Second) + time.Sleep(500 * time.Millisecond) } } } // waitForReplicaSetCreation waits for the replicaset of the given deployment to be created -func (f *Framework) waitForReplicaSetCreation(t *testing.T, d appsv1.Deployment) (string, error) { - rs, err := f.k8s.AppsV1().ReplicaSets("test-cases").Watch(context.Background(), metav1.ListOptions{ +func (f *Framework) waitForReplicaSetCreation(d appsv1.Deployment) string { + if f.err != nil { + return "" + } + + rs, err := f.k8s.AppsV1().ReplicaSets(d.Namespace).Watch(context.Background(), metav1.ListOptions{ LabelSelector: fmt.Sprintf("app=%s", d.Name), }) if err != nil { - f.Cleanup(t) - t.Fatal(err) + f.err = err + return "" } ctx, done := context.WithTimeout(context.Background(), 30*time.Second) @@ -210,37 +240,39 @@ func (f *Framework) waitForReplicaSetCreation(t *testing.T, d appsv1.Deployment) for { select { case <-ctx.Done(): - f.Cleanup(t) - t.Fatal("timeout reached while waiting for replicaset to be created") + f.err = fmt.Errorf("timeout reached while waiting for replicaset to be created") case event := <-rs.ResultChan(): rs, ok := event.Object.(*appsv1.ReplicaSet) if ok { - t.Logf("replicaset %s created", rs.Name) - return rs.Name, nil + f.t.Logf("replicaset %s created", rs.Name) + return rs.Name } - time.Sleep(5 * time.Second) + time.Sleep(500 * time.Millisecond) } } } // AssertDeploymentFailed asserts that the deployment cannot start -func (f *Framework) AssertDeploymentFailed(t *testing.T, d appsv1.Deployment) { - t.Logf("waiting for deployment %s to fail", d.Name) +func (f *Framework) AssertDeploymentFailed(d appsv1.Deployment) { + if f.err != nil { + return + } + + f.t.Logf("waiting for deployment %s to fail", d.Name) // watch for replicasets of the deployment - rsName, err := f.waitForReplicaSetCreation(t, d) - if err != nil { - f.Cleanup(t) - t.Fatal(err) + rsName := f.waitForReplicaSetCreation(d) + if rsName == "" { + return } // get warning events of deployment's namespace and check if the deployment failed - w, err := f.k8s.CoreV1().Events("test-cases").Watch(context.Background(), metav1.ListOptions{ + w, err := f.k8s.CoreV1().Events(d.Namespace).Watch(context.Background(), metav1.ListOptions{ FieldSelector: fmt.Sprintf("involvedObject.name=%s", rsName), }) if err != nil { - f.Cleanup(t) - t.Fatal(err) + f.err = err + return } ctx, done := context.WithTimeout(context.Background(), 30*time.Second) @@ -249,34 +281,37 @@ func (f *Framework) AssertDeploymentFailed(t *testing.T, d appsv1.Deployment) { for { select { case <-ctx.Done(): - f.Cleanup(t) - t.Fatal("timeout reached while waiting for deployment to fail") + f.err = fmt.Errorf("timeout reached while waiting for deployment to fail") case event := <-w.ResultChan(): e, ok := event.Object.(*corev1.Event) if !ok { - time.Sleep(5 * time.Second) + time.Sleep(500 * time.Millisecond) continue } if e.Reason == "FailedCreate" { - t.Logf("deployment %s failed: %s", d.Name, e.Message) + f.t.Logf("deployment %s failed: %s", d.Name, e.Message) return } - time.Sleep(5 * time.Second) + time.Sleep(500 * time.Millisecond) } } } // AssertEventForPod asserts that a PodVerified event is created -func (f *Framework) AssertEventForPod(t *testing.T, reason string, p corev1.Pod) { - t.Logf("waiting for %s event to be created for pod %s", reason, p.Name) +func (f *Framework) AssertEventForPod(reason string, p corev1.Pod) { + if f.err != nil { + return + } + + f.t.Logf("waiting for %s event to be created for pod %s", reason, p.Name) // watch for events of deployment's namespace and check if the podverified event is created - w, err := f.k8s.CoreV1().Events("test-cases").Watch(context.Background(), metav1.ListOptions{ + w, err := f.k8s.CoreV1().Events(p.Namespace).Watch(context.Background(), metav1.ListOptions{ FieldSelector: fmt.Sprintf("involvedObject.name=%s", p.Name), }) if err != nil { - f.Cleanup(t) - t.Fatal(err) + f.err = err + return } ctx, done := context.WithTimeout(context.Background(), 30*time.Second) @@ -285,19 +320,18 @@ func (f *Framework) AssertEventForPod(t *testing.T, reason string, p corev1.Pod) for { select { case <-ctx.Done(): - f.Cleanup(t) - t.Fatal("timeout reached while waiting for podverified event") + f.err = fmt.Errorf("timeout reached while waiting for event to be created") case event := <-w.ResultChan(): e, ok := event.Object.(*corev1.Event) if !ok { - time.Sleep(5 * time.Second) + time.Sleep(500 * time.Millisecond) continue } if e.Reason == reason { - t.Logf("%s event created for pod %s", reason, p.Name) + f.t.Logf("%s event created for pod %s", reason, p.Name) return } - time.Sleep(5 * time.Second) + time.Sleep(500 * time.Millisecond) } } } diff --git a/test/framework/cosign.go b/test/framework/cosign.go index dc05d4c..4a56beb 100644 --- a/test/framework/cosign.go +++ b/test/framework/cosign.go @@ -9,7 +9,6 @@ import ( "fmt" "os" "regexp" - "testing" "time" "github.com/sigstore/cosign/v2/cmd/cosign/cli/importkeypair" @@ -21,82 +20,123 @@ import ( const ImportKeySuffix = "imported" +// Pub contains the public key and its path +type Pub struct { + Key string + Path string +} + +// Priv contains the private key and its path +type Priv struct { + Key string + Path string +} + +// SignOptions is a struct to hold the options for signing a container +type SignOptions struct { + KeyPath string + Image string + SignatureRepo string +} + +// KeyFunc is a function that generates a keypair by using the testing framework +type KeyFunc func(f *Framework, name string) (Priv, Pub) + // cleanupKeys removes all keypair files from the testing directory -func cleanupKeys(t testing.TB) { - t.Logf("cleaning up keypair files") +func (f *Framework) cleanupKeys() { + f.t.Logf("cleaning up keypair files") files, err := os.ReadDir(".") if err != nil { - t.Fatalf("failed reading directory: %v", err) + f.err = fmt.Errorf("failed reading directory: %v", err) + return } - for _, f := range files { - if f.IsDir() { + for _, file := range files { + if file.IsDir() { continue } reKey := regexp.MustCompile(".*.key") rePub := regexp.MustCompile(".*.pub") - if reKey.MatchString(f.Name()) || rePub.MatchString(f.Name()) { - err = os.Remove(f.Name()) + if reKey.MatchString(file.Name()) || rePub.MatchString(file.Name()) { + err = os.Remove(file.Name()) if err != nil { - t.Fatalf("failed removing file %s: %v", f.Name(), err) + f.err = fmt.Errorf("failed to remove file: %v", err) + return } } } - t.Logf("cleaned up keypair files") + f.t.Logf("cleaned up keypair files") } -// CreateKeys creates a signing keypair for cosing with the provided name -func (f *Framework) CreateKeys(t testing.TB, name string) (private string, public string) { +// CreateECDSAKeyPair generates an ECDSA keypair and saves the keys to the current directory +func CreateECDSAKeyPair(f *Framework, name string) (Priv, Pub) { + if f.err != nil { + return Priv{}, Pub{} + } + args := []string{fmt.Sprintf("--output-key-prefix=%s", name)} err := os.Setenv("COSIGN_PASSWORD", "") if err != nil { - t.Fatalf("failed setting COSIGN_PASSWORD: %v", err) + f.err = err + return Priv{}, Pub{} } cmd := cli.GenerateKeyPair() cmd.SetArgs(args) err = cmd.Execute() if err != nil { - f.Cleanup(t) + f.err = err + return Priv{}, Pub{} } // read private key and public key from the current directory privateKey, err := os.ReadFile(fmt.Sprintf("%s.key", name)) if err != nil { - f.Cleanup(t) + f.err = err + return Priv{}, Pub{} } pubKey, err := os.ReadFile(fmt.Sprintf("%s.pub", name)) if err != nil { - f.Cleanup(t) + f.err = err + return Priv{}, Pub{} } - return string(privateKey), string(pubKey) + return Priv{ + Key: string(privateKey), + Path: fmt.Sprintf("%s.key", name), + }, Pub{ + Key: string(pubKey), + Path: fmt.Sprintf("%s.pub", name), + } } -// CreateRSAKeyPair creates an RSA keypair for signing with the provided name -func (f *Framework) CreateRSAKeyPair(t *testing.T, name string) (private string, public string) { - priv, err := rsa.GenerateKey(rand.Reader, 2048) - if err != nil { - f.Cleanup(t) - t.Fatal(err) +// CreateRSAKeyPair generates an RSA keypair and saves the keys to the current directory +func CreateRSAKeyPair(f *Framework, name string) (Priv, Pub) { + if f.err != nil { + return Priv{}, Pub{} } + pkey, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + f.err = fmt.Errorf("failed to generate RSA key: %v", err) + return Priv{}, Pub{} + } privBytes := pem.EncodeToMemory(&pem.Block{ Type: "RSA PRIVATE KEY", - Bytes: x509.MarshalPKCS1PrivateKey(priv), + Bytes: x509.MarshalPKCS1PrivateKey(pkey), }) err = os.WriteFile(fmt.Sprintf("%s.key", name), privBytes, 0o644) if err != nil { - t.Errorf("failed to write private key to file: %v", err) - return "", "" + f.err = fmt.Errorf("failed to write private key to file: %v", err) + return Priv{}, Pub{} } // Generate and save the public key to a PEM file - pub := &priv.PublicKey + pubKey := &pkey.PublicKey - pubASN1, err := x509.MarshalPKIXPublicKey(pub) + pubASN1, err := x509.MarshalPKIXPublicKey(pubKey) if err != nil { - f.Cleanup(t) - t.Fatal(err) + f.err = fmt.Errorf("failed to marshal public key: %v", err) + return Priv{}, Pub{} } pubBytes := pem.EncodeToMemory(&pem.Block{ Type: "PUBLIC KEY", @@ -104,53 +144,56 @@ func (f *Framework) CreateRSAKeyPair(t *testing.T, name string) (private string, }) err = os.WriteFile(fmt.Sprintf("%s.pub", name), pubBytes, 0o644) if err != nil { - t.Errorf("failed to write public key to file: %v", err) - return "", "" + f.err = fmt.Errorf("failed to write public key to file: %v", err) + return Priv{}, Pub{} } - t.Setenv("COSIGN_PASSWORD", "") + f.t.Setenv("COSIGN_PASSWORD", "") // import the keypair into cosign for signing err = importkeypair.ImportKeyPairCmd(context.Background(), options.ImportKeyPairOptions{ Key: fmt.Sprintf("%s.key", name), OutputKeyPrefix: fmt.Sprintf("%s-%s", name, ImportKeySuffix), }, []string{}) if err != nil { - t.Errorf("failed to import keypair to cosign: %v", err) - return "", "" + f.err = fmt.Errorf("failed to import keypair: %v", err) + return Priv{}, Pub{} } // read private key and public key from the current directory privBytes, err = os.ReadFile(fmt.Sprintf("%s-%s.key", name, ImportKeySuffix)) if err != nil { - f.Cleanup(t) - t.Fatal(err) + f.err = fmt.Errorf("failed reading private key: %v", err) + return Priv{}, Pub{} } pubBytes, err = os.ReadFile(fmt.Sprintf("%s-%s.pub", name, ImportKeySuffix)) if err != nil { - f.Cleanup(t) - t.Fatal(err) + f.err = fmt.Errorf("failed reading public key: %v", err) + return Priv{}, Pub{} } - return string(privBytes), string(pubBytes) + return Priv{ + Key: string(privBytes), + Path: fmt.Sprintf("%s-%s.key", name, ImportKeySuffix), + }, Pub{ + Key: string(pubBytes), + Path: fmt.Sprintf("%s-%s.pub", name, ImportKeySuffix), + } } -// SignOptions is a struct to hold the options for signing a container -type SignOptions struct { - KeyPath string - Image string - SignatureRepo string -} +// SignContainer signs the container using the provided SignOptions +func (f *Framework) SignContainer(opts SignOptions) { + if f.err != nil { + return + } -// SignContainer signs the container with the provided private key -func (f *Framework) SignContainer(t *testing.T, opts SignOptions) { // get SHA of the container image - t.Setenv("COSIGN_PASSWORD", "") + f.t.Setenv("COSIGN_PASSWORD", "") // if the signature repository is different from the image, set the COSIGN_REPOSITORY environment variable // to push the signature to the specified repository if opts.SignatureRepo != opts.Image { - t.Setenv("COSIGN_REPOSITORY", opts.SignatureRepo) + f.t.Setenv("COSIGN_REPOSITORY", opts.SignatureRepo) } err := sign.SignCmd( &options.RootOptions{ @@ -167,7 +210,6 @@ func (f *Framework) SignContainer(t *testing.T, opts SignOptions) { []string{opts.Image}, ) if err != nil { - f.Cleanup(t) - t.Fatal(err) + f.err = fmt.Errorf("failed to sign container: %v", err) } } diff --git a/test/framework/cosign_test.go b/test/framework/cosign_test.go index 83754fe..a156b99 100644 --- a/test/framework/cosign_test.go +++ b/test/framework/cosign_test.go @@ -16,11 +16,13 @@ func TestFramework_CreateRSAKeyPair(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - f := &Framework{} - priv, pub := f.CreateRSAKeyPair(t, tt.name) - defer f.Cleanup(t) + f := &Framework{ + t: t, + } + defer f.Cleanup() + private, public := CreateRSAKeyPair(f, tt.name) - if priv == "" || pub == "" { + if private.Key == "" || public.Key == "" { t.Fatal("failed to create RSA key pair") } @@ -67,11 +69,13 @@ func TestFramework_SignContainer_RSA(t *testing.T) { t.Skip() } - f := &Framework{} + f := &Framework{ + t: t, + } + defer f.Cleanup() name := "testkey" - priv, pub := f.CreateRSAKeyPair(t, name) - defer f.Cleanup(t) - if priv == "" || pub == "" { + private, public := CreateRSAKeyPair(f, name) + if private.Key == "" || public.Key == "" { t.Fatal("failed to create RSA key pair") } @@ -84,7 +88,7 @@ func TestFramework_SignContainer_RSA(t *testing.T) { t.Fatal("failed to create public key") } - f.SignContainer(t, SignOptions{ + f.SignContainer(SignOptions{ KeyPath: fmt.Sprintf("%s-%s.key", name, ImportKeySuffix), Image: "k3d-registry.localhost:5000/busybox:first", }) diff --git a/test/main_test.go b/test/main_test.go index 43aa93c..32fa1d0 100644 --- a/test/main_test.go +++ b/test/main_test.go @@ -1,13 +1,16 @@ package test import ( + "fmt" "testing" + + "github.com/eumel8/cosignwebhook/test/framework" ) -// TestPassingDeployments tests deployments that should pass signature verification -func TestPassingDeployments(t *testing.T) { - testFuncs := map[string]func(t *testing.T){ - "OneContainerSinglePubKeyEnvRef": testOneContainerSinglePubKeyEnvRef, +// TestPassECDSA tests deployments that should pass signature verification +func TestPassECDSA(t *testing.T) { + testFuncs := map[string]func(fw *framework.Framework, kf framework.KeyFunc, key string) func(t *testing.T){ + "OneContainerSinglePubKeyEnvRef": oneContainerSinglePubKeyEnvRef, "TwoContainersSinglePubKeyEnvRef": testTwoContainersSinglePubKeyEnvRef, "OneContainerSinglePubKeySecretRef": testOneContainerSinglePubKeySecretRef, "TwoContainersSinglePubKeyMixedRef": testTwoContainersSinglePubKeyMixedRef, @@ -16,25 +19,35 @@ func TestPassingDeployments(t *testing.T) { "EventEmittedOnSignatureVerification": testEventEmittedOnSignatureVerification, "EventEmittedOnNoSignatureVerification": testEventEmittedOnNoSignatureVerification, "OneContainerWIthCosignRepository": testOneContainerWithCosignRepository, - "OneContainerSinglePubKeyEnvRefRSA": testOneContainerSinglePubKeyEnvRefRSA, - "TwoContainersSinglePubKeyEnvRefRSA": TestTwoContainersSinglePubKeyEnvRefRSA, + } + + fw, err := framework.New(t) + if err != nil { + t.Fatal(err) } for name, tf := range testFuncs { - t.Run(name, tf) + t.Run(fmt.Sprintf("[%s] %s", "ECDSA", name), tf(fw, framework.CreateECDSAKeyPair, name)) + t.Run(fmt.Sprintf("[%s] %s", "RSA", name), tf(fw, framework.CreateRSAKeyPair, name)) } } // TestFailingDeployments tests deployments that should fail signature verification func TestFailingDeployments(t *testing.T) { - testFuncs := map[string]func(t *testing.T){ + testFuncs := map[string]func(fw *framework.Framework, kf framework.KeyFunc, key string) func(t *testing.T){ "OneContainerSinglePubKeyMalformedEnvRef": testOneContainerSinglePubKeyMalformedEnvRef, "TwoContainersSinglePubKeyMalformedEnvRef": testTwoContainersSinglePubKeyMalformedEnvRef, "OneContainerSinglePubKeyNoMatchEnvRef": testOneContainerSinglePubKeyNoMatchEnvRef, "OneContainerWithCosingRepoVariableMissing": testOneContainerWithCosingRepoVariableMissing, } + fw, err := framework.New(t) + if err != nil { + t.Fatal(err) + } + for name, tf := range testFuncs { - t.Run(name, tf) + t.Run(name, tf(fw, framework.CreateECDSAKeyPair, name)) + t.Run(name, tf(fw, framework.CreateRSAKeyPair, name)) } } diff --git a/test/webhook_test.go b/test/webhook_test.go index b2da4e7..ee4a8d7 100644 --- a/test/webhook_test.go +++ b/test/webhook_test.go @@ -1,7 +1,6 @@ package test import ( - "fmt" "testing" "github.com/eumel8/cosignwebhook/test/framework" @@ -20,17 +19,12 @@ const ( signatureRepo = "k3d-registry.localhost:5000/sigs" ) -// testOneContainerSinglePubKeyEnvRef tests that a deployment with a single signed container, +// oneContainerSinglePubKeyEnvRef tests that a deployment with a single signed container, // with a public key provided via an environment variable, succeeds. -func testOneContainerSinglePubKeyEnvRef(t *testing.T) { - fw, err := framework.New() - if err != nil { - t.Fatal(err) - } - - _, pub := fw.CreateKeys(t, "test") - fw.SignContainer(t, framework.SignOptions{ - KeyPath: "test.key", +func oneContainerSinglePubKeyEnvRef(fw *framework.Framework, keyFunc framework.KeyFunc, key string) func(t *testing.T) { + priv, pub := keyFunc(fw, key) + fw.SignContainer(framework.SignOptions{ + KeyPath: priv.Path, Image: busyboxOne, }) @@ -62,7 +56,7 @@ func testOneContainerSinglePubKeyEnvRef(t *testing.T) { Env: []corev1.EnvVar{ { Name: webhook.CosignEnvVar, - Value: pub, + Value: pub.Key, }, }, }, @@ -72,26 +66,23 @@ func testOneContainerSinglePubKeyEnvRef(t *testing.T) { }, } - fw.CreateDeployment(t, depl) - fw.WaitForDeployment(t, depl) - fw.Cleanup(t) + return func(t *testing.T) { + fw.CreateDeployment(depl) + fw.WaitForDeployment(depl) + fw.Cleanup() + } } // testTwoContainersSinglePubKeyEnvRef tests that a deployment with two signed containers, // with a public key provided via an environment variable, succeeds. -func testTwoContainersSinglePubKeyEnvRef(t *testing.T) { - fw, err := framework.New() - if err != nil { - t.Fatal(err) - } - - _, pub := fw.CreateKeys(t, "test") - fw.SignContainer(t, framework.SignOptions{ - KeyPath: "test.key", +func testTwoContainersSinglePubKeyEnvRef(fw *framework.Framework, kf framework.KeyFunc, key string) func(*testing.T) { + priv, pub := kf(fw, key) + fw.SignContainer(framework.SignOptions{ + KeyPath: priv.Path, Image: busyboxOne, }) - fw.SignContainer(t, framework.SignOptions{ - KeyPath: "test.key", + fw.SignContainer(framework.SignOptions{ + KeyPath: priv.Path, Image: busyboxTwo, }) @@ -123,7 +114,7 @@ func testTwoContainersSinglePubKeyEnvRef(t *testing.T) { Env: []corev1.EnvVar{ { Name: webhook.CosignEnvVar, - Value: pub, + Value: pub.Key, }, }, }, @@ -138,7 +129,7 @@ func testTwoContainersSinglePubKeyEnvRef(t *testing.T) { Env: []corev1.EnvVar{ { Name: webhook.CosignEnvVar, - Value: pub, + Value: pub.Key, }, }, }, @@ -148,22 +139,19 @@ func testTwoContainersSinglePubKeyEnvRef(t *testing.T) { }, } - fw.CreateDeployment(t, depl) - fw.WaitForDeployment(t, depl) - fw.Cleanup(t) + return func(*testing.T) { + fw.CreateDeployment(depl) + fw.WaitForDeployment(depl) + fw.Cleanup() + } } // testOneContainerPubKeySecret tests that a deployment with a single signed container, // with a public key provided via a secret, succeeds. -func testOneContainerSinglePubKeySecretRef(t *testing.T) { - fw, err := framework.New() - if err != nil { - t.Fatal(err) - } - - _, pub := fw.CreateKeys(t, "test") - fw.SignContainer(t, framework.SignOptions{ - KeyPath: "test.key", +func testOneContainerSinglePubKeySecretRef(fw *framework.Framework, kf framework.KeyFunc, key string) func(*testing.T) { + priv, pub := kf(fw, key) + fw.SignContainer(framework.SignOptions{ + KeyPath: priv.Path, Image: busyboxOne, }) @@ -174,7 +162,7 @@ func testOneContainerSinglePubKeySecretRef(t *testing.T) { Namespace: "test-cases", }, StringData: map[string]string{ - "cosign.pub": pub, + "cosign.pub": pub.Key, }, } @@ -223,28 +211,25 @@ func testOneContainerSinglePubKeySecretRef(t *testing.T) { }, } - fw.CreateSecret(t, secret) - fw.CreateDeployment(t, depl) - fw.WaitForDeployment(t, depl) - fw.Cleanup(t) + return func(*testing.T) { + fw.CreateSecret(secret) + fw.CreateDeployment(depl) + fw.WaitForDeployment(depl) + fw.Cleanup() + } } // testTwoContainersMixedPubKeyMixedRef tests that a deployment with two signed containers with two different public keys, // with the keys provided by a secret and an environment variable, succeeds. -func testTwoContainersMixedPubKeyMixedRef(t *testing.T) { - fw, err := framework.New() - if err != nil { - t.Fatal(err) - } - - _, pub1 := fw.CreateKeys(t, "test1") - _, pub2 := fw.CreateKeys(t, "test2") - fw.SignContainer(t, framework.SignOptions{ - KeyPath: "test1.key", +func testTwoContainersMixedPubKeyMixedRef(fw *framework.Framework, kf framework.KeyFunc, key string) func(*testing.T) { + priv1, pub1 := framework.CreateECDSAKeyPair(fw, "test1") + priv2, pub2 := framework.CreateECDSAKeyPair(fw, "test2") + fw.SignContainer(framework.SignOptions{ + KeyPath: priv1.Path, Image: busyboxOne, }) - fw.SignContainer(t, framework.SignOptions{ - KeyPath: "test2.key", + fw.SignContainer(framework.SignOptions{ + KeyPath: priv2.Path, Image: busyboxTwo, }) @@ -255,7 +240,7 @@ func testTwoContainersMixedPubKeyMixedRef(t *testing.T) { Namespace: "test-cases", }, StringData: map[string]string{ - "cosign.pub": pub1, + "cosign.pub": pub1.Key, }, } @@ -277,7 +262,7 @@ func testTwoContainersMixedPubKeyMixedRef(t *testing.T) { TerminationGracePeriodSeconds: &terminationGracePeriodSeconds, Containers: []corev1.Container{ { - Name: "two-containers-mixed-pub-keyrefs-first", + Name: "two-containers-mixed-pub-keyrefs-from-secret", Image: busyboxOne, Command: []string{ "sh", @@ -299,7 +284,7 @@ func testTwoContainersMixedPubKeyMixedRef(t *testing.T) { }, }, { - Name: "two-containers-mixed-pub-keyrefs-second", + Name: "two-containers-mixed-pub-keyrefs-second-from-env", Image: busyboxTwo, Command: []string{ "sh", @@ -309,7 +294,7 @@ func testTwoContainersMixedPubKeyMixedRef(t *testing.T) { Env: []corev1.EnvVar{ { Name: webhook.CosignEnvVar, - Value: pub2, + Value: pub2.Key, }, }, }, @@ -319,27 +304,24 @@ func testTwoContainersMixedPubKeyMixedRef(t *testing.T) { }, } - fw.CreateSecret(t, secret) - fw.CreateDeployment(t, depl) - fw.WaitForDeployment(t, depl) - fw.Cleanup(t) + return func(*testing.T) { + fw.CreateSecret(secret) + fw.CreateDeployment(depl) + fw.WaitForDeployment(depl) + fw.Cleanup() + } } // testTwoContainersSinglePubKeyMixedRef tests that a deployment with two signed containers, // with a public key provided via a secret and an environment variable, succeeds. -func testTwoContainersSinglePubKeyMixedRef(t *testing.T) { - fw, err := framework.New() - if err != nil { - t.Fatal(err) - } - - _, pub := fw.CreateKeys(t, "test") - fw.SignContainer(t, framework.SignOptions{ - KeyPath: "test.key", +func testTwoContainersSinglePubKeyMixedRef(fw *framework.Framework, kf framework.KeyFunc, key string) func(*testing.T) { + priv, pub := kf(fw, key) + fw.SignContainer(framework.SignOptions{ + KeyPath: priv.Path, Image: busyboxOne, }) - fw.SignContainer(t, framework.SignOptions{ - KeyPath: "test.key", + fw.SignContainer(framework.SignOptions{ + KeyPath: priv.Path, Image: busyboxTwo, }) @@ -350,7 +332,7 @@ func testTwoContainersSinglePubKeyMixedRef(t *testing.T) { Namespace: "test-cases", }, StringData: map[string]string{ - "cosign.pub": pub, + "cosign.pub": pub.Key, }, } @@ -404,7 +386,7 @@ func testTwoContainersSinglePubKeyMixedRef(t *testing.T) { Env: []corev1.EnvVar{ { Name: webhook.CosignEnvVar, - Value: pub, + Value: pub.Key, }, }, }, @@ -414,27 +396,24 @@ func testTwoContainersSinglePubKeyMixedRef(t *testing.T) { }, } - fw.CreateSecret(t, secret) - fw.CreateDeployment(t, depl) - fw.WaitForDeployment(t, depl) - fw.Cleanup(t) + return func(*testing.T) { + fw.CreateSecret(secret) + fw.CreateDeployment(depl) + fw.WaitForDeployment(depl) + fw.Cleanup() + } } // testTwoContainersSinglePubKeyMixedRef tests that a deployment with two signed containers, // with a public key provided via a secret and an environment variable, succeeds. -func testTwoContainersWithInitSinglePubKeyMixedRef(t *testing.T) { - fw, err := framework.New() - if err != nil { - t.Fatal(err) - } - - _, pub := fw.CreateKeys(t, "test") - fw.SignContainer(t, framework.SignOptions{ - KeyPath: "test.key", +func testTwoContainersWithInitSinglePubKeyMixedRef(fw *framework.Framework, kf framework.KeyFunc, key string) func(*testing.T) { + priv, pub := kf(fw, key) + fw.SignContainer(framework.SignOptions{ + KeyPath: priv.Path, Image: busyboxOne, }) - fw.SignContainer(t, framework.SignOptions{ - KeyPath: "test.key", + fw.SignContainer(framework.SignOptions{ + KeyPath: priv.Path, Image: busyboxTwo, }) @@ -445,7 +424,7 @@ func testTwoContainersWithInitSinglePubKeyMixedRef(t *testing.T) { Namespace: "test-cases", }, StringData: map[string]string{ - "cosign.pub": pub, + "cosign.pub": pub.Key, }, } @@ -501,7 +480,7 @@ func testTwoContainersWithInitSinglePubKeyMixedRef(t *testing.T) { Env: []corev1.EnvVar{ { Name: webhook.CosignEnvVar, - Value: pub, + Value: pub.Key, }, }, }, @@ -511,23 +490,20 @@ func testTwoContainersWithInitSinglePubKeyMixedRef(t *testing.T) { }, } - fw.CreateSecret(t, secret) - fw.CreateDeployment(t, depl) - fw.WaitForDeployment(t, depl) - fw.Cleanup(t) + return func(*testing.T) { + fw.CreateSecret(secret) + fw.CreateDeployment(depl) + fw.WaitForDeployment(depl) + fw.Cleanup() + } } // testEventEmittedOnSignatureVerification tests // that an event is emitted when a deployment passes signature verification -func testEventEmittedOnSignatureVerification(t *testing.T) { - fw, err := framework.New() - if err != nil { - t.Fatal(err) - } - - _, pub := fw.CreateKeys(t, "test") - fw.SignContainer(t, framework.SignOptions{ - KeyPath: "test.key", +func testEventEmittedOnSignatureVerification(fw *framework.Framework, kf framework.KeyFunc, key string) func(*testing.T) { + priv, pub := kf(fw, key) + fw.SignContainer(framework.SignOptions{ + KeyPath: priv.Path, Image: busyboxOne, }) @@ -559,7 +535,7 @@ func testEventEmittedOnSignatureVerification(t *testing.T) { Env: []corev1.EnvVar{ { Name: webhook.CosignEnvVar, - Value: pub, + Value: pub.Key, }, }, }, @@ -569,19 +545,16 @@ func testEventEmittedOnSignatureVerification(t *testing.T) { }, } - fw.CreateDeployment(t, depl) - fw.WaitForDeployment(t, depl) - pod := fw.GetPods(t, depl) - fw.AssertEventForPod(t, "PodVerified", pod.Items[0]) - fw.Cleanup(t) -} - -func testEventEmittedOnNoSignatureVerification(t *testing.T) { - fw, err := framework.New() - if err != nil { - t.Fatal(err) + return func(*testing.T) { + fw.CreateDeployment(depl) + fw.WaitForDeployment(depl) + pod := fw.GetPods(depl) + fw.AssertEventForPod("PodVerified", pod.Items[0]) + fw.Cleanup() } +} +func testEventEmittedOnNoSignatureVerification(fw *framework.Framework, kf framework.KeyFunc, key string) func(*testing.T) { // create a deployment with a single unsigned container depl := appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ @@ -610,26 +583,23 @@ func testEventEmittedOnNoSignatureVerification(t *testing.T) { }, } - fw.CreateDeployment(t, depl) - fw.WaitForDeployment(t, depl) - pl := fw.GetPods(t, depl) - fw.AssertEventForPod(t, "NoVerification", pl.Items[0]) - fw.Cleanup(t) + return func(t *testing.T) { + fw.CreateDeployment(depl) + fw.WaitForDeployment(depl) + pl := fw.GetPods(depl) + fw.AssertEventForPod("NoVerification", pl.Items[0]) + fw.Cleanup() + } } // testOneContainerWithCosignRepository tests that a deployment with a single signed container, // with a public key provided via a secret succeeds. // The signature for the container is present in the repository // defined in the environment variables of the container. -func testOneContainerWithCosignRepository(t *testing.T) { - fw, err := framework.New() - if err != nil { - t.Fatal(err) - } - - _, pub := fw.CreateKeys(t, "test") - fw.SignContainer(t, framework.SignOptions{ - KeyPath: "test.key", +func testOneContainerWithCosignRepository(fw *framework.Framework, kf framework.KeyFunc, key string) func(*testing.T) { + priv, pub := kf(fw, key) + fw.SignContainer(framework.SignOptions{ + KeyPath: priv.Path, Image: busyboxOne, SignatureRepo: signatureRepo, }) @@ -641,7 +611,7 @@ func testOneContainerWithCosignRepository(t *testing.T) { Namespace: "test-cases", }, StringData: map[string]string{ - "cosign.pub": pub, + "cosign.pub": pub.Key, }, } @@ -694,153 +664,21 @@ func testOneContainerWithCosignRepository(t *testing.T) { }, } - fw.CreateSecret(t, secret) - fw.CreateDeployment(t, depl) - fw.WaitForDeployment(t, depl) - fw.Cleanup(t) -} - -// testOneContainerSinglePubKeyEnvRefRSA tests that a deployment with a single signed container, -// with a public key provided via an environment variable, succeeds. The keypair used for this test is an RSA keypair. -func testOneContainerSinglePubKeyEnvRefRSA(t *testing.T) { - fw, err := framework.New() - if err != nil { - t.Fatal(err) - } - - _, pub := fw.CreateRSAKeyPair(t, "test") - fw.SignContainer(t, framework.SignOptions{ - KeyPath: fmt.Sprintf("test-%s.key", framework.ImportKeySuffix), - Image: busyboxOne, - }) - - // create a deployment with a single signed container and a public key provided via an environment variable - depl := appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: "one-container-env-ref-rsa", - Namespace: "test-cases", - }, - Spec: appsv1.DeploymentSpec{ - Selector: &metav1.LabelSelector{ - MatchLabels: map[string]string{"app": "one-container-env-ref-rsa"}, - }, - Template: corev1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: map[string]string{"app": "one-container-env-ref-rsa"}, - }, - Spec: corev1.PodSpec{ - TerminationGracePeriodSeconds: &terminationGracePeriodSeconds, - Containers: []corev1.Container{ - { - Name: "one-container-env-ref-rsa", - Image: busyboxOne, - Command: []string{ - "sh", - "-c", - "while true; do echo 'hello world, i am tired and will sleep now'; sleep 60; done", - }, - Env: []corev1.EnvVar{ - { - Name: webhook.CosignEnvVar, - Value: pub, - }, - }, - }, - }, - }, - }, - }, - } - - fw.CreateDeployment(t, depl) - fw.WaitForDeployment(t, depl) - fw.Cleanup(t) -} - -func TestTwoContainersSinglePubKeyEnvRefRSA(t *testing.T) { - fw, err := framework.New() - if err != nil { - t.Fatal(err) - } - - // Create a deployment with two containers signed by the same RSA key - _, rsaPub := fw.CreateRSAKeyPair(t, "test") - fw.SignContainer(t, framework.SignOptions{ - KeyPath: fmt.Sprintf("test-%s.key", framework.ImportKeySuffix), - Image: busyboxOne, - }) - fw.SignContainer(t, framework.SignOptions{ - KeyPath: fmt.Sprintf("test-%s.key", framework.ImportKeySuffix), - Image: busyboxTwo, - }) - - depl := appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: "two-containers-single-pubkey-envref", - Namespace: "test-cases", - }, - Spec: appsv1.DeploymentSpec{ - Selector: &metav1.LabelSelector{ - MatchLabels: map[string]string{"app": "two-containers-single-pubkey-envref"}, - }, - Template: corev1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: map[string]string{"app": "two-containers-single-pubkey-envref"}, - }, - Spec: corev1.PodSpec{ - TerminationGracePeriodSeconds: &terminationGracePeriodSeconds, - Containers: []corev1.Container{ - { - Name: "two-containers-same-rsa-pub-key-env-ref-first", - Image: busyboxOne, - Command: []string{ - "sh", "-c", - "echo 'hello world, i am tired and will sleep now'; sleep 60", - }, - Env: []corev1.EnvVar{ - { - Name: webhook.CosignEnvVar, - Value: rsaPub, - }, - }, - }, - { - Name: "two-containers-same-rsa-pub-key-env-ref-second", - Image: busyboxTwo, - Command: []string{ - "sh", "-c", - "echo 'hello world, i am tired and will sleep now'; sleep 60", - }, - Env: []corev1.EnvVar{ - { - Name: webhook.CosignEnvVar, - Value: rsaPub, - }, - }, - }, - }, - }, - }, - }, + return func(*testing.T) { + fw.CreateSecret(secret) + fw.CreateDeployment(depl) + fw.WaitForDeployment(depl) + fw.Cleanup() } - - fw.CreateDeployment(t, depl) - fw.WaitForDeployment(t, depl) - fw.Cleanup(t) } // testOneContainerSinglePubKeyNoMatchEnvRef tests that a deployment with a single signed container, // with a public key provided via an environment variable, fails if the public key does not match the signature. -func testOneContainerSinglePubKeyNoMatchEnvRef(t *testing.T) { - fw, err := framework.New() - if err != nil { - t.Fatal(err) - } - - _, _ = fw.CreateKeys(t, "test") - _, other := fw.CreateKeys(t, "other") - fw.SignContainer(t, framework.SignOptions{ - KeyPath: "test.key", +func testOneContainerSinglePubKeyNoMatchEnvRef(fw *framework.Framework, kf framework.KeyFunc, key string) func(*testing.T) { + priv, _ := kf(fw, key) + _, otherPub := framework.CreateECDSAKeyPair(fw, "other") + fw.SignContainer(framework.SignOptions{ + KeyPath: priv.Path, Image: busyboxOne, }) @@ -872,7 +710,7 @@ func testOneContainerSinglePubKeyNoMatchEnvRef(t *testing.T) { Env: []corev1.EnvVar{ { Name: webhook.CosignEnvVar, - Value: other, + Value: otherPub.Key, }, }, }, @@ -882,22 +720,19 @@ func testOneContainerSinglePubKeyNoMatchEnvRef(t *testing.T) { }, } - fw.CreateDeployment(t, depl) - fw.AssertDeploymentFailed(t, depl) - fw.Cleanup(t) + return func(t *testing.T) { + fw.CreateDeployment(depl) + fw.AssertDeploymentFailed(depl) + fw.Cleanup() + } } // testTwoContainersSinglePubKeyNoMatchEnvRef tests that a deployment with two signed containers, -// with a public key provided via an environment variable, fails if one of the container's pub key is malformed. -func testTwoContainersSinglePubKeyMalformedEnvRef(t *testing.T) { - fw, err := framework.New() - if err != nil { - t.Fatal(err) - } - - _, pub := fw.CreateKeys(t, "test") - fw.SignContainer(t, framework.SignOptions{ - KeyPath: "test.key", +// with a public key provided via an environment variable, fails if one of the containers public key is malformed. +func testTwoContainersSinglePubKeyMalformedEnvRef(fw *framework.Framework, kf framework.KeyFunc, key string) func(*testing.T) { + priv, pub := kf(fw, key) + fw.SignContainer(framework.SignOptions{ + KeyPath: priv.Path, Image: busyboxOne, }) @@ -929,7 +764,7 @@ func testTwoContainersSinglePubKeyMalformedEnvRef(t *testing.T) { Env: []corev1.EnvVar{ { Name: webhook.CosignEnvVar, - Value: pub, + Value: pub.Key, }, }, }, @@ -954,18 +789,21 @@ func testTwoContainersSinglePubKeyMalformedEnvRef(t *testing.T) { }, } - fw.CreateDeployment(t, depl) - fw.AssertDeploymentFailed(t, depl) - fw.Cleanup(t) + return func(t *testing.T) { + fw.CreateDeployment(depl) + fw.AssertDeploymentFailed(depl) + fw.Cleanup() + } } // testOneContainerSinglePubKeyMalformedEnvRef tests that a deployment with a single signed container, -// // with a public key provided via an environment variable, fails if the public key has an incorrect format. -func testOneContainerSinglePubKeyMalformedEnvRef(t *testing.T) { - fw, err := framework.New() - if err != nil { - t.Fatal(err) - } +// with a public key provided via an environment variable, fails if the public key has an incorrect format. +func testOneContainerSinglePubKeyMalformedEnvRef(fw *framework.Framework, kf framework.KeyFunc, key string) func(*testing.T) { + priv, _ := kf(fw, key) + fw.SignContainer(framework.SignOptions{ + KeyPath: priv.Path, + Image: busyboxOne, + }) depl := appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ @@ -1004,23 +842,20 @@ func testOneContainerSinglePubKeyMalformedEnvRef(t *testing.T) { }, } - fw.CreateDeployment(t, depl) - fw.AssertDeploymentFailed(t, depl) - fw.Cleanup(t) + return func(t *testing.T) { + fw.CreateDeployment(depl) + fw.AssertDeploymentFailed(depl) + fw.Cleanup() + } } // testOneContainerSinglePubKeyNoMatchSecretRef tests that a deployment with a single signed container, // with a public key provided via a secret, fails if the public key does not match the signature, which // is uploaded in a different repository as the image itself -func testOneContainerWithCosingRepoVariableMissing(t *testing.T) { - fw, err := framework.New() - if err != nil { - t.Fatal(err) - } - - _, pub := fw.CreateKeys(t, "test") - fw.SignContainer(t, framework.SignOptions{ - KeyPath: "test.key", +func testOneContainerWithCosingRepoVariableMissing(fw *framework.Framework, kf framework.KeyFunc, key string) func(*testing.T) { + priv, pub := kf(fw, key) + fw.SignContainer(framework.SignOptions{ + KeyPath: priv.Path, Image: busyboxOne, SignatureRepo: signatureRepo, }) @@ -1051,7 +886,7 @@ func testOneContainerWithCosingRepoVariableMissing(t *testing.T) { Env: []corev1.EnvVar{ { Name: webhook.CosignEnvVar, - Value: pub, + Value: pub.Key, }, }, }, @@ -1061,7 +896,9 @@ func testOneContainerWithCosingRepoVariableMissing(t *testing.T) { }, } - fw.CreateDeployment(t, depl) - fw.AssertDeploymentFailed(t, depl) - fw.Cleanup(t) + return func(t *testing.T) { + fw.CreateDeployment(depl) + fw.AssertDeploymentFailed(depl) + fw.Cleanup() + } }