github.com/redhat-appstudio/e2e-tests@v0.0.0-20230619105049-9a422b2094d7/tests/enterprise-contract/contract.go (about) 1 package enterprisecontract 2 3 import ( 4 "fmt" 5 "time" 6 7 "github.com/devfile/library/pkg/util" 8 ecp "github.com/enterprise-contract/enterprise-contract-controller/api/v1alpha1" 9 . "github.com/onsi/ginkgo/v2" 10 . "github.com/onsi/gomega" 11 "github.com/redhat-appstudio/e2e-tests/pkg/constants" 12 "github.com/redhat-appstudio/e2e-tests/pkg/framework" 13 "github.com/redhat-appstudio/e2e-tests/pkg/utils" 14 "github.com/redhat-appstudio/e2e-tests/pkg/utils/tekton" 15 ) 16 17 var _ = framework.EnterpriseContractSuiteDescribe("Enterprise Contract E2E tests", Label("enterprise-contract", "HACBS"), func() { 18 19 defer GinkgoRecover() 20 var fwk *framework.Framework 21 var err error 22 var namespace string 23 var kubeController tekton.KubeController 24 var policySource []ecp.Source 25 var policyConfig *ecp.EnterpriseContractPolicyConfiguration 26 var imageWithDigest string 27 var pipelineRunTimeout int 28 var generator tekton.VerifyEnterpriseContract 29 var verifyECTaskBundle string 30 publicSecretName := "cosign-public-key" 31 32 BeforeAll(func() { 33 fwk, err = framework.NewFramework(utils.GetGeneratedNamespace(constants.TEKTON_CHAINS_E2E_USER)) 34 Expect(err).NotTo(HaveOccurred()) 35 Expect(fwk.UserNamespace).NotTo(BeNil(), "failed to create sandbox user") 36 namespace = fwk.UserNamespace 37 kubeController = tekton.KubeController{ 38 Commonctrl: *fwk.AsKubeAdmin.CommonController, 39 Tektonctrl: *fwk.AsKubeAdmin.TektonController, 40 Namespace: namespace, 41 } 42 publicKey, err := kubeController.GetTektonChainsPublicKey() 43 Expect(err).ToNot(HaveOccurred()) 44 GinkgoWriter.Printf("Copy public key from %s/signing-secrets to a new secret\n", constants.TEKTON_CHAINS_NS) 45 Expect(kubeController.CreateOrUpdateSigningSecret( 46 publicKey, publicSecretName, namespace)).To(Succeed()) 47 48 defaultEcp, err := kubeController.GetEnterpriseContractPolicy("default", "enterprise-contract-service") 49 Expect(err).NotTo(HaveOccurred()) 50 policyConfig = defaultEcp.Spec.Configuration 51 policySource = defaultEcp.Spec.Sources 52 53 cm, err := kubeController.Commonctrl.GetConfigMap("ec-defaults", "enterprise-contract-service") 54 Expect(err).ToNot(HaveOccurred()) 55 verifyECTaskBundle = cm.Data["verify_ec_task_bundle"] 56 Expect(verifyECTaskBundle).ToNot(BeEmpty()) 57 GinkgoWriter.Printf("Using verify EC task bundle: %s\n", verifyECTaskBundle) 58 imageWithDigest = "quay.io/redhat-appstudio/ec-golden-image:latest" 59 }) 60 Context("ec-cli command verification", func() { 61 BeforeAll(func() { 62 generator = tekton.VerifyEnterpriseContract{ 63 Bundle: verifyECTaskBundle, 64 Image: imageWithDigest, 65 Name: "verify-enterprise-contract", 66 Namespace: namespace, 67 PolicyConfiguration: "ec-policy", 68 PublicKey: fmt.Sprintf("k8s://%s/%s", namespace, publicSecretName), 69 SSLCertDir: "/var/run/secrets/kubernetes.io/serviceaccount", 70 Strict: false, 71 EffectiveTime: "now", 72 } 73 pipelineRunTimeout = int(time.Duration(5) * time.Minute) 74 baselinePolicies := ecp.EnterpriseContractPolicySpec{ 75 Configuration: policyConfig, 76 Sources: policySource, 77 } 78 Expect(kubeController.CreateOrUpdatePolicyConfiguration(namespace, baselinePolicies)).To(Succeed()) 79 }) 80 It("verifies ec cli has error handling", func() { 81 generator.Image = "quay.io/redhat-appstudio/ec-golden-image:latest" 82 pr, err := kubeController.RunPipeline(generator, pipelineRunTimeout) 83 Expect(err).NotTo(HaveOccurred()) 84 Expect(kubeController.WatchPipelineRun(pr.Name, pipelineRunTimeout)).To(Succeed()) 85 86 pr, err = kubeController.Tektonctrl.GetPipelineRun(pr.Name, pr.Namespace) 87 Expect(err).NotTo(HaveOccurred()) 88 89 tr, err := kubeController.GetTaskRunStatus(fwk.AsKubeAdmin.CommonController.KubeRest(), pr, "verify-enterprise-contract") 90 Expect(err).NotTo(HaveOccurred()) 91 92 Expect(tr.Status.TaskRunResults).Should(Or( 93 // TODO: delete the first option after https://issues.redhat.com/browse/RHTAP-810 is completed 94 ContainElements(tekton.MatchTaskRunResultWithJSONPathValue(constants.OldTektonTaskTestOutputName, "{$.result}", `["FAILURE"]`)), 95 ContainElements(tekton.MatchTaskRunResultWithJSONPathValue(constants.TektonTaskTestOutputName, "{$.result}", `["FAILURE"]`)), 96 )) 97 //Get container step-report log details from pod 98 reportLog, err := utils.GetContainerLogs(fwk.AsKubeAdmin.CommonController.KubeInterface(), tr.Status.PodName, "step-report", namespace) 99 GinkgoWriter.Printf("*** Logs from pod '%s', container '%s':\n----- START -----%s----- END -----\n", tr.Status.PodName, "step-report", reportLog) 100 Expect(err).NotTo(HaveOccurred()) 101 Expect(reportLog).Should(ContainSubstring("msg: No image attestations found matching the given public key")) 102 }) 103 }) 104 105 Context("Release Policy", func() { 106 BeforeAll(func() { 107 secretName := fmt.Sprintf("golden-image-public-key%s", util.GenerateRandomString(10)) 108 //The staging public key for verificaiton image 109 publicKey := []byte("-----BEGIN PUBLIC KEY-----\n" + 110 "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZP/0htjhVt2y0ohjgtIIgICOtQtA\n" + 111 "naYJRuLprwIv6FDhZ5yFjYUEtsmoNcW7rx2KM6FOXGsCX3BNc7qhHELT+g==\n" + 112 "-----END PUBLIC KEY-----") 113 GinkgoWriter.Println("Create golden image public signing key") 114 Expect(kubeController.CreateOrUpdateSigningSecret(publicKey, secretName, namespace)).To(Succeed()) 115 generator = tekton.VerifyEnterpriseContract{ 116 Bundle: verifyECTaskBundle, 117 Image: imageWithDigest, 118 Name: "verify-enterprise-contract", 119 Namespace: namespace, 120 PolicyConfiguration: "ec-policy", 121 PublicKey: fmt.Sprintf("k8s://%s/%s", namespace, secretName), 122 SSLCertDir: "/var/run/secrets/kubernetes.io/serviceaccount", 123 Strict: false, 124 EffectiveTime: "now", 125 } 126 pipelineRunTimeout = int(time.Duration(5) * time.Minute) 127 }) 128 129 It("verifies ec validate accepts a list of image references", func() { 130 policy := ecp.EnterpriseContractPolicySpec{ 131 Sources: policySource, 132 Configuration: &ecp.EnterpriseContractPolicyConfiguration{ 133 Include: []string{"minimal"}, 134 }, 135 } 136 Expect(kubeController.CreateOrUpdatePolicyConfiguration(namespace, policy)).To(Succeed()) 137 138 generator.Image = snapshotComponent 139 pr, err := kubeController.RunPipeline(generator, pipelineRunTimeout) 140 Expect(err).NotTo(HaveOccurred()) 141 Expect(kubeController.WatchPipelineRun(pr.Name, pipelineRunTimeout)).To(Succeed()) 142 143 pr, err = kubeController.Tektonctrl.GetPipelineRun(pr.Name, pr.Namespace) 144 Expect(err).NotTo(HaveOccurred()) 145 146 tr, err := kubeController.GetTaskRunStatus(fwk.AsKubeAdmin.CommonController.KubeRest(), pr, "verify-enterprise-contract") 147 Expect(err).NotTo(HaveOccurred()) 148 149 Expect(tr.Status.TaskRunResults).Should(Or( 150 // TODO: delete the first option after https://issues.redhat.com/browse/RHTAP-810 is completed 151 ContainElements(tekton.MatchTaskRunResultWithJSONPathValue(constants.OldTektonTaskTestOutputName, "{$.result}", `["SUCCESS"]`)), 152 ContainElements(tekton.MatchTaskRunResultWithJSONPathValue(constants.TektonTaskTestOutputName, "{$.result}", `["SUCCESS"]`)), 153 )) 154 //Get container step-report log details from pod 155 reportLog, err := utils.GetContainerLogs(fwk.AsKubeAdmin.CommonController.KubeInterface(), tr.Status.PodName, "step-report", namespace) 156 GinkgoWriter.Printf("*** Logs from pod '%s', container '%s':\n----- START -----%s----- END -----\n", tr.Status.PodName, "step-report", reportLog) 157 Expect(err).NotTo(HaveOccurred()) 158 159 }) 160 161 It("verifies the release policy: Task bundle is not acceptable", func() { 162 policy := ecp.EnterpriseContractPolicySpec{ 163 Sources: policySource, 164 Configuration: &ecp.EnterpriseContractPolicyConfiguration{ 165 Include: []string{"attestation_task_bundle.task_ref_bundles_acceptable"}, 166 }, 167 } 168 Expect(kubeController.CreateOrUpdatePolicyConfiguration(namespace, policy)).To(Succeed()) 169 170 generator.Image = "quay.io/redhat-appstudio/ec-golden-image:e2e-test-unacceptable-task" 171 pr, err := kubeController.RunPipeline(generator, pipelineRunTimeout) 172 Expect(err).NotTo(HaveOccurred()) 173 Expect(kubeController.WatchPipelineRun(pr.Name, pipelineRunTimeout)).To(Succeed()) 174 175 pr, err = kubeController.Tektonctrl.GetPipelineRun(pr.Name, pr.Namespace) 176 Expect(err).NotTo(HaveOccurred()) 177 178 tr, err := kubeController.GetTaskRunStatus(fwk.AsKubeAdmin.CommonController.KubeRest(), pr, "verify-enterprise-contract") 179 Expect(err).NotTo(HaveOccurred()) 180 181 Expect(tr.Status.TaskRunResults).Should(Or( 182 // TODO: delete the first option after https://issues.redhat.com/browse/RHTAP-810 is completed 183 ContainElements(tekton.MatchTaskRunResultWithJSONPathValue(constants.OldTektonTaskTestOutputName, "{$.result}", `["FAILURE"]`)), 184 ContainElements(tekton.MatchTaskRunResultWithJSONPathValue(constants.TektonTaskTestOutputName, "{$.result}", `["FAILURE"]`)), 185 )) 186 187 //Get container step-report log details from pod 188 reportLog, err := utils.GetContainerLogs(fwk.AsKubeAdmin.CommonController.KubeInterface(), tr.Status.PodName, "step-report", namespace) 189 GinkgoWriter.Printf("*** Logs from pod '%s', container '%s':\n----- START -----%s----- END -----\n", tr.Status.PodName, "step-report", reportLog) 190 Expect(err).NotTo(HaveOccurred()) 191 Expect(reportLog).Should(ContainSubstring("msg: Pipeline task 'build-container' uses an unacceptable task bundle")) 192 }) 193 194 It("verifies the release policy: Task bundle is out of date", func() { 195 policy := ecp.EnterpriseContractPolicySpec{ 196 Sources: []ecp.Source{ 197 { 198 Policy: []string{ 199 "oci::quay.io/hacbs-contract/ec-release-policy:git-086f871@sha256:373a5c4c1d34123836cbfc11826f6bbf6fdf8f0dfae333a2686bbe941c4f79ef", 200 }, 201 Data: []string{ 202 "oci::quay.io/hacbs-contract/ec-policy-data:git-8629680@sha256:ee5708dda57216647f63032dd3e63375e70e2353cb1ad10c9ab5493b9236c23e", 203 }, 204 }, 205 }, 206 Configuration: &ecp.EnterpriseContractPolicyConfiguration{ 207 Include: []string{"attestation_task_bundle.task_ref_bundles_current"}, 208 }, 209 } 210 Expect(kubeController.CreateOrUpdatePolicyConfiguration(namespace, policy)).To(Succeed()) 211 212 generator.Image = "quay.io/redhat-appstudio/ec-golden-image:e2e-test-out-of-date-task" 213 generator.EffectiveTime = "2023-03-31T00:00:00Z" 214 pr, err := kubeController.RunPipeline(generator, pipelineRunTimeout) 215 Expect(err).NotTo(HaveOccurred()) 216 Expect(kubeController.WatchPipelineRun(pr.Name, pipelineRunTimeout)).To(Succeed()) 217 218 pr, err = kubeController.Tektonctrl.GetPipelineRun(pr.Name, pr.Namespace) 219 Expect(err).NotTo(HaveOccurred()) 220 221 tr, err := kubeController.GetTaskRunStatus(fwk.AsKubeAdmin.CommonController.KubeRest(), pr, "verify-enterprise-contract") 222 Expect(err).NotTo(HaveOccurred()) 223 224 Expect(tr.Status.TaskRunResults).Should(Or( 225 // TODO: delete the first option after https://issues.redhat.com/browse/RHTAP-810 is completed 226 ContainElements(tekton.MatchTaskRunResultWithJSONPathValue(constants.OldTektonTaskTestOutputName, "{$.result}", `["WARNING"]`)), 227 ContainElements(tekton.MatchTaskRunResultWithJSONPathValue(constants.TektonTaskTestOutputName, "{$.result}", `["WARNING"]`)), 228 )) 229 230 //Get container step-report log details from pod 231 reportLog, err := utils.GetContainerLogs(fwk.AsKubeAdmin.CommonController.KubeInterface(), tr.Status.PodName, "step-report", namespace) 232 GinkgoWriter.Printf("*** Logs from pod '%s', container '%s':\n----- START -----%s----- END -----\n", tr.Status.PodName, "step-report", reportLog) 233 Expect(err).NotTo(HaveOccurred()) 234 Expect(reportLog).Should(ContainSubstring("Pipeline task 'build-container' uses an out of date task bundle")) 235 }) 236 }) 237 })