github.com/redhat-appstudio/e2e-tests@v0.0.0-20240520140907-9709f6f59323/tests/release/pipelines/push_to_external_registry.go (about)

     1  package pipelines
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"strings"
     7  
     8  	tektonutils "github.com/redhat-appstudio/release-service/tekton/utils"
     9  	"k8s.io/apimachinery/pkg/runtime"
    10  
    11  	ecp "github.com/enterprise-contract/enterprise-contract-controller/api/v1alpha1"
    12  	. "github.com/onsi/ginkgo/v2"
    13  	. "github.com/onsi/gomega"
    14  	appservice "github.com/redhat-appstudio/application-api/api/v1alpha1"
    15  	"github.com/redhat-appstudio/e2e-tests/pkg/clients/has"
    16  	"github.com/redhat-appstudio/e2e-tests/pkg/constants"
    17  	"github.com/redhat-appstudio/e2e-tests/pkg/framework"
    18  	"github.com/redhat-appstudio/e2e-tests/pkg/utils"
    19  	"github.com/redhat-appstudio/e2e-tests/pkg/utils/contract"
    20  	"github.com/redhat-appstudio/e2e-tests/pkg/utils/tekton"
    21  	releasecommon "github.com/redhat-appstudio/e2e-tests/tests/release"
    22  	releaseApi "github.com/redhat-appstudio/release-service/api/v1alpha1"
    23  	corev1 "k8s.io/api/core/v1"
    24  )
    25  
    26  var _ = framework.ReleasePipelinesSuiteDescribe("Push to external registry", Label("release-pipelines", "push-to-external-registry"), func() {
    27  	defer GinkgoRecover()
    28  
    29  	var fw *framework.Framework
    30  	AfterEach(framework.ReportFailure(&fw))
    31  	var err error
    32  	var devNamespace, managedNamespace string
    33  
    34  	var component *appservice.Component
    35  	var releaseCR *releaseApi.Release
    36  
    37  	BeforeAll(func() {
    38  		// Initialize the tests controllers
    39  		fw, err = framework.NewFramework(utils.GetGeneratedNamespace("ex-registry"))
    40  		Expect(err).NotTo(HaveOccurred())
    41  		devNamespace = fw.UserNamespace
    42  		managedNamespace = utils.GetGeneratedNamespace("ex-registry-managed")
    43  		_, err = fw.AsKubeAdmin.CommonController.CreateTestNamespace(managedNamespace)
    44  		Expect(err).NotTo(HaveOccurred(), "Error when creating managedNamespace: %v", err)
    45  
    46  		sourceAuthJson := utils.GetEnv("QUAY_TOKEN", "")
    47  		Expect(sourceAuthJson).ToNot(BeEmpty())
    48  
    49  		managedServiceAccount, err := fw.AsKubeAdmin.CommonController.CreateServiceAccount(releasecommon.ReleasePipelineServiceAccountDefault, managedNamespace, releasecommon.ManagednamespaceSecret, nil)
    50  		Expect(err).NotTo(HaveOccurred())
    51  
    52  		_, err = fw.AsKubeAdmin.ReleaseController.CreateReleasePipelineRoleBindingForServiceAccount(managedNamespace, managedServiceAccount)
    53  		Expect(err).NotTo(HaveOccurred())
    54  
    55  		_, err = fw.AsKubeAdmin.CommonController.CreateRegistryAuthSecret(releasecommon.RedhatAppstudioUserSecret, managedNamespace, sourceAuthJson)
    56  		Expect(err).ToNot(HaveOccurred())
    57  
    58  		err = fw.AsKubeAdmin.CommonController.LinkSecretToServiceAccount(devNamespace, releasecommon.HacbsReleaseTestsTokenSecret, constants.DefaultPipelineServiceAccount, true)
    59  		Expect(err).ToNot(HaveOccurred())
    60  
    61  		err = fw.AsKubeAdmin.CommonController.LinkSecretToServiceAccount(managedNamespace, releasecommon.RedhatAppstudioUserSecret, constants.DefaultPipelineServiceAccount, true)
    62  		Expect(err).ToNot(HaveOccurred())
    63  
    64  		publicKey, err := fw.AsKubeAdmin.TektonController.GetTektonChainsPublicKey()
    65  		Expect(err).ToNot(HaveOccurred())
    66  		Expect(fw.AsKubeAdmin.TektonController.CreateOrUpdateSigningSecret(
    67  			publicKey, releasecommon.PublicSecretNameAuth, managedNamespace)).To(Succeed())
    68  
    69  		defaultECP, err := fw.AsKubeAdmin.TektonController.GetEnterpriseContractPolicy("default", "enterprise-contract-service")
    70  		Expect(err).NotTo(HaveOccurred())
    71  		policy := contract.PolicySpecWithSourceConfig(defaultECP.Spec, ecp.SourceConfig{Include: []string{"@minimal"}, Exclude: []string{"cve"}})
    72  
    73  		_, err = fw.AsKubeAdmin.HasController.CreateApplication(releasecommon.ApplicationNameDefault, devNamespace)
    74  		Expect(err).NotTo(HaveOccurred())
    75  
    76  		component = releasecommon.CreateComponentByCDQ(*fw, devNamespace, managedNamespace, releasecommon.ApplicationNameDefault, releasecommon.ComponentName, releasecommon.GitSourceComponentUrl)
    77  
    78  		_, err = fw.AsKubeAdmin.ReleaseController.CreateReleasePlan(releasecommon.SourceReleasePlanName, devNamespace, releasecommon.ApplicationNameDefault, managedNamespace, "", nil)
    79  		Expect(err).NotTo(HaveOccurred())
    80  
    81  		data, err := json.Marshal(map[string]interface{}{
    82  			"mapping": map[string]interface{}{
    83  				"components": []map[string]interface{}{
    84  					{
    85  						"name":       component.GetName(),
    86  						"repository": releasecommon.ReleasedImagePushRepo,
    87  					},
    88  				},
    89  			},
    90  		})
    91  		Expect(err).NotTo(HaveOccurred())
    92  
    93  		_, err = fw.AsKubeAdmin.ReleaseController.CreateReleasePlanAdmission(releasecommon.TargetReleasePlanAdmissionName, managedNamespace, "", devNamespace, releasecommon.ReleaseStrategyPolicyDefault, releasecommon.ReleasePipelineServiceAccountDefault, []string{releasecommon.ApplicationNameDefault}, true, &tektonutils.PipelineRef{
    94  			Resolver: "git",
    95  			Params: []tektonutils.Param{
    96  				{Name: "url", Value: releasecommon.RelSvcCatalogURL},
    97  				{Name: "revision", Value: releasecommon.RelSvcCatalogRevision},
    98  				{Name: "pathInRepo", Value: "pipelines/push-to-external-registry/push-to-external-registry.yaml"},
    99  			},
   100  		}, &runtime.RawExtension{
   101  			Raw: data,
   102  		})
   103  		Expect(err).NotTo(HaveOccurred())
   104  
   105  		_, err = fw.AsKubeAdmin.TektonController.CreateEnterpriseContractPolicy(releasecommon.ReleaseStrategyPolicyDefault, managedNamespace, policy)
   106  		Expect(err).NotTo(HaveOccurred())
   107  
   108  		_, err = fw.AsKubeAdmin.TektonController.CreatePVCInAccessMode(releasecommon.ReleasePvcName, managedNamespace, corev1.ReadWriteOnce)
   109  		Expect(err).NotTo(HaveOccurred())
   110  
   111  		_, err = fw.AsKubeAdmin.CommonController.CreateRole("role-release-service-account", managedNamespace, map[string][]string{
   112  			"apiGroupsList": {""},
   113  			"roleResources": {"secrets"},
   114  			"roleVerbs":     {"get", "list", "watch"},
   115  		})
   116  		Expect(err).NotTo(HaveOccurred())
   117  
   118  		_, err = fw.AsKubeAdmin.CommonController.CreateRoleBinding("role-release-service-account-binding", managedNamespace, "ServiceAccount", releasecommon.ReleasePipelineServiceAccountDefault, managedNamespace, "Role", "role-release-service-account", "rbac.authorization.k8s.io")
   119  		Expect(err).NotTo(HaveOccurred())
   120  	})
   121  
   122  	AfterAll(func() {
   123  		if !CurrentSpecReport().Failed() {
   124  			Expect(fw.AsKubeAdmin.CommonController.DeleteNamespace(managedNamespace)).NotTo(HaveOccurred())
   125  			Expect(fw.SandboxController.DeleteUserSignup(fw.UserName)).To(BeTrue())
   126  		}
   127  	})
   128  
   129  	var _ = Describe("Post-release verification", func() {
   130  		It("verifies that a build PipelineRun is created in dev namespace and succeeds", func() {
   131  			Expect(fw.AsKubeAdmin.HasController.WaitForComponentPipelineToBeFinished(component, "",
   132  				fw.AsKubeAdmin.TektonController, &has.RetryOptions{Retries: 2, Always: true}, nil)).To(Succeed())
   133  		})
   134  
   135  		It("verifies that a Release CR should have been created in the dev namespace", func() {
   136  			Eventually(func() error {
   137  				releaseCR, err = fw.AsKubeAdmin.ReleaseController.GetFirstReleaseInNamespace(devNamespace)
   138  				return err
   139  			}, releasecommon.ReleaseCreationTimeout, releasecommon.DefaultInterval).Should(Succeed())
   140  		})
   141  
   142  		It("verifies that Release PipelineRun is triggered", func() {
   143  			Eventually(func() error {
   144  				pr, err := fw.AsKubeAdmin.ReleaseController.GetPipelineRunInNamespace(managedNamespace, releaseCR.GetName(), releaseCR.GetNamespace())
   145  				if err != nil {
   146  					GinkgoWriter.Printf("release pipelineRun for release '%s' in namespace '%s' not created yet: %+v\n", releaseCR.GetName(), releaseCR.GetNamespace(), err)
   147  					return err
   148  				}
   149  				if !pr.HasStarted() {
   150  					return fmt.Errorf("pipelinerun %s/%s hasn't started yet", pr.GetNamespace(), pr.GetName())
   151  				}
   152  				return nil
   153  			}, releasecommon.ReleasePipelineRunCreationTimeout, releasecommon.DefaultInterval).Should(Succeed(), fmt.Sprintf("timed out waiting for a pipelinerun to start for a release %s/%s", releaseCR.GetName(), releaseCR.GetNamespace()))
   154  		})
   155  
   156  		It("verifies that Release PipelineRun should eventually succeed", func() {
   157  			Eventually(func() error {
   158  				pr, err := fw.AsKubeAdmin.ReleaseController.GetPipelineRunInNamespace(managedNamespace, releaseCR.GetName(), releaseCR.GetNamespace())
   159  				Expect(err).ShouldNot(HaveOccurred())
   160  				if !pr.IsDone() {
   161  					return fmt.Errorf("release pipelinerun %s/%s did not finish yet", pr.GetNamespace(), pr.GetName())
   162  				}
   163  				Expect(tekton.HasPipelineRunSucceeded(pr)).To(BeTrue(), fmt.Sprintf("release pipelinerun %s/%s did not succeed", pr.GetNamespace(), pr.GetName()))
   164  				return nil
   165  			}, releasecommon.ReleasePipelineRunCompletionTimeout, releasecommon.DefaultInterval).Should(Succeed())
   166  		})
   167  
   168  		It("tests if the image was pushed to quay", func() {
   169  			// retrieve the component to get the latest data
   170  			component, err := fw.AsKubeAdmin.HasController.GetComponent(component.GetName(), devNamespace)
   171  			Expect(err).ShouldNot(HaveOccurred(), fmt.Sprintf("could not get component %s in the %s namespace", component.GetName(), devNamespace))
   172  			containerImageDigest := strings.Split(component.Spec.ContainerImage, "@")[1]
   173  			digestExist, err := releasecommon.DoesDigestExistInQuay(releasecommon.ReleasedImagePushRepo, containerImageDigest)
   174  			Expect(err).ShouldNot(HaveOccurred(), fmt.Sprintf("failed while getting Digest for quay image %s with error: %+v", releasecommon.ReleasedImagePushRepo+"@"+containerImageDigest, err))
   175  			Expect(digestExist).To(BeTrue())
   176  		})
   177  
   178  		It("verifies that a Release is marked as succeeded.", func() {
   179  			Eventually(func() error {
   180  				releaseCR, err = fw.AsKubeAdmin.ReleaseController.GetFirstReleaseInNamespace(devNamespace)
   181  				if err != nil {
   182  					return err
   183  				}
   184  				if !releaseCR.IsReleased() {
   185  					return fmt.Errorf("release %s/%s is not marked as finished yet", releaseCR.GetNamespace(), releaseCR.GetName())
   186  				}
   187  				return nil
   188  			}, releasecommon.ReleaseCreationTimeout, releasecommon.DefaultInterval).Should(Succeed())
   189  		})
   190  	})
   191  })