github.com/redhat-appstudio/e2e-tests@v0.0.0-20240520140907-9709f6f59323/tests/remote-secret/image-repository-cr-image-pull-remote-secret.go (about)

     1  package remotesecret
     2  
     3  import (
     4  	"fmt"
     5  	"time"
     6  
     7  	image "github.com/konflux-ci/image-controller/api/v1alpha1"
     8  	. "github.com/onsi/ginkgo/v2"
     9  	. "github.com/onsi/gomega"
    10  	appservice "github.com/redhat-appstudio/application-api/api/v1alpha1"
    11  	"github.com/redhat-appstudio/e2e-tests/pkg/clients/has"
    12  	"github.com/redhat-appstudio/e2e-tests/pkg/framework"
    13  	"github.com/redhat-appstudio/e2e-tests/pkg/utils"
    14  	rs "github.com/redhat-appstudio/remote-secret/api/v1beta1"
    15  	"k8s.io/apimachinery/pkg/api/meta"
    16  )
    17  
    18  /*
    19   * Component: remote secret
    20   * Description: SVPI-574 - Ensure existence of image pull remote secret and image pull secret when ImageRepository is created
    21   *              SVPI-652 - Ensure existence of image push remote secret and image push secret when ImageRepository is created
    22   * Note: This test covers the preferred approach (ImageRepository CR) that it is already in prod
    23   * More info: https://github.com/konflux-ci/image-controller#general-purpose-image-repository
    24   */
    25  
    26  var _ = framework.RemoteSecretSuiteDescribe(Label("remote-secret", "image-repository-cr-image-pull-remote-secret"), func() {
    27  
    28  	defer GinkgoRecover()
    29  
    30  	var fw *framework.Framework
    31  	var err error
    32  	var namespace string
    33  	var timeout, interval time.Duration
    34  
    35  	application := &appservice.Application{}
    36  	cdq := &appservice.ComponentDetectionQuery{}
    37  	componentList := []*appservice.Component{}
    38  	component := &appservice.Component{}
    39  	imagePullRemoteSecret := &rs.RemoteSecret{}
    40  	imagePushRemoteSecret := &rs.RemoteSecret{}
    41  	pullTargets := []rs.TargetStatus{}
    42  	pushTargets := []rs.TargetStatus{}
    43  	imageRepository := &image.ImageRepository{}
    44  	snapshot := &appservice.Snapshot{}
    45  
    46  	applicationName := "image-repository-cr-dotnet-component"
    47  	gitSourceUrl := "https://github.com/devfile-samples/devfile-sample-dotnet60-basic"
    48  	secret := ""
    49  
    50  	AfterEach(framework.ReportFailure(&fw))
    51  
    52  	Describe("SVPI-574 and SVPI-652 - Ensure existence of image pull remote secret, image push remote secret, image pull secret and image push secret when ImageRepository is created", Ordered, func() {
    53  		BeforeAll(func() {
    54  			// Initialize the tests controllers
    55  			fw, err = framework.NewFramework(utils.GetGeneratedNamespace("rs-demos"))
    56  			Expect(err).NotTo(HaveOccurred())
    57  			namespace = fw.UserNamespace
    58  			Expect(namespace).NotTo(BeEmpty())
    59  		})
    60  
    61  		AfterAll(func() {
    62  			if !CurrentSpecReport().Failed() {
    63  				Expect(fw.SandboxController.DeleteUserSignup(fw.UserName)).To(BeTrue())
    64  			}
    65  		})
    66  
    67  		It("creates an application", func() {
    68  			createdApplication, err := fw.AsKubeDeveloper.HasController.CreateApplication(applicationName, namespace)
    69  			Expect(err).NotTo(HaveOccurred())
    70  			Expect(createdApplication.Spec.DisplayName).To(Equal(applicationName))
    71  			Expect(createdApplication.Namespace).To(Equal(namespace))
    72  		})
    73  
    74  		It("checks if application is healthy", func() {
    75  			Eventually(func() string {
    76  				appstudioApp, err := fw.AsKubeDeveloper.HasController.GetApplication(applicationName, namespace)
    77  				Expect(err).NotTo(HaveOccurred())
    78  				application = appstudioApp
    79  
    80  				return application.Status.Devfile
    81  			}, 3*time.Minute, 100*time.Millisecond).Should(Not(BeEmpty()), fmt.Sprintf("timed out waiting for the %s application in %s namespace to be ready", applicationName, fw.UserNamespace))
    82  		})
    83  
    84  		It("creates component detection query", func() {
    85  			cdq, err = fw.AsKubeDeveloper.HasController.CreateComponentDetectionQuery(applicationName, namespace, gitSourceUrl, "", "", secret, false)
    86  			Expect(err).NotTo(HaveOccurred())
    87  		})
    88  
    89  		It("creates component", func() {
    90  			for _, compDetected := range cdq.Status.ComponentDetected {
    91  				c, err := fw.AsKubeDeveloper.HasController.CreateComponentWithoutGenerateAnnotation(compDetected.ComponentStub, namespace, secret, applicationName, true)
    92  				Expect(err).NotTo(HaveOccurred())
    93  				Expect(c.Name).To(Equal(compDetected.ComponentStub.ComponentName))
    94  
    95  				componentList = append(componentList, c)
    96  			}
    97  
    98  			Expect(componentList).To(HaveLen(1))
    99  			component = componentList[0]
   100  
   101  			Expect(component.Annotations["image.redhat.com/generate"]).To(Equal(""))
   102  		})
   103  
   104  		It("creates an image repository", func() {
   105  			imageRepository, err = fw.AsKubeAdmin.ImageController.CreateImageRepositoryCR("image-repository", namespace, application.Name, component.Name)
   106  			Expect(err).NotTo(HaveOccurred())
   107  		})
   108  
   109  		It("checks if image repository is ready", func() {
   110  			Eventually(func() image.ImageRepositoryState {
   111  				imageRepository, err = fw.AsKubeAdmin.ImageController.GetImageRepositoryCR(imageRepository.Name, imageRepository.Namespace)
   112  				Expect(err).NotTo(HaveOccurred())
   113  
   114  				return imageRepository.Status.State
   115  			}, 2*time.Minute, 5*time.Second).Should(Equal(image.ImageRepositoryStateReady), fmt.Sprintf("ImageRepository '%s/%s' is not ready", imageRepository.Name, imageRepository.Namespace))
   116  		})
   117  
   118  		It("updates component with generated image from ImageRepository CR", func() {
   119  			Eventually(func() string {
   120  				imageRepository, err = fw.AsKubeAdmin.ImageController.GetImageRepositoryCR(imageRepository.Name, imageRepository.Namespace)
   121  				Expect(err).NotTo(HaveOccurred())
   122  
   123  				return imageRepository.Status.Image.URL
   124  			}, 2*time.Minute, 5*time.Second).ShouldNot(BeEmpty(), fmt.Sprintf("ImageRepository '%s/%s' did not generate any image", imageRepository.Name, imageRepository.Namespace))
   125  
   126  			component, err = fw.AsKubeDeveloper.HasController.GetComponent(component.GetName(), component.GetNamespace())
   127  			Expect(err).NotTo(HaveOccurred())
   128  
   129  			component.Spec.ContainerImage = imageRepository.Status.Image.URL
   130  			err := fw.AsKubeDeveloper.HasController.UpdateComponent(component)
   131  			Expect(err).NotTo(HaveOccurred())
   132  		})
   133  
   134  		It("waits for component pipeline to be finished", func() {
   135  			component, err = fw.AsKubeAdmin.HasController.GetComponent(component.Name, namespace)
   136  			Expect(err).ShouldNot(HaveOccurred(), "failed to get component: %v", err)
   137  
   138  			Expect(fw.AsKubeAdmin.HasController.WaitForComponentPipelineToBeFinished(component, "",
   139  				fw.AsKubeAdmin.TektonController, &has.RetryOptions{Retries: 2, Always: true}, nil)).To(Succeed())
   140  		})
   141  
   142  		It("finds the snapshot and checks if it is marked as successful", func() {
   143  			timeout = time.Second * 600
   144  			interval = time.Second * 10
   145  
   146  			Eventually(func() error {
   147  				snapshot, err = fw.AsKubeAdmin.IntegrationController.GetSnapshot("", "", component.Name, namespace)
   148  				if err != nil {
   149  					GinkgoWriter.Println("snapshot has not been found yet")
   150  					return err
   151  				}
   152  				if !fw.AsKubeAdmin.CommonController.HaveTestsSucceeded(snapshot) {
   153  					return fmt.Errorf("tests haven't succeeded for snapshot %s/%s. snapshot status: %+v", snapshot.GetNamespace(), snapshot.GetName(), snapshot.Status)
   154  				}
   155  				return nil
   156  			}, timeout, interval).Should(Succeed(), fmt.Sprintf("timed out waiting for the snapshot for the component %s/%s to be marked as successful", component.GetNamespace(), component.GetName()))
   157  
   158  		})
   159  
   160  		It("checks if image pull remote secret was created", func() {
   161  			Eventually(func() error {
   162  				imagePullRemoteSecret, err = fw.AsKubeAdmin.RemoteSecretController.GetImageRepositoryRemoteSecret("image-repository-image-pull", applicationName, component.Spec.ComponentName, namespace)
   163  
   164  				return err
   165  			}, 5*time.Minute, 5*time.Second).Should(Succeed(), fmt.Sprintf("Image Pull Remote Secret in '%s' was not created", namespace))
   166  		})
   167  
   168  		It("checks if image push remote secret was created", func() {
   169  			Eventually(func() error {
   170  				imagePushRemoteSecret, err = fw.AsKubeAdmin.RemoteSecretController.GetImageRepositoryRemoteSecret("image-repository-image-push", applicationName, component.Spec.ComponentName, namespace)
   171  
   172  				return err
   173  			}, 5*time.Minute, 5*time.Second).Should(Succeed(), fmt.Sprintf("Image Push Remote Secret in '%s' was not created", namespace))
   174  		})
   175  
   176  		It("checks if image pull remote secret was deployed", func() {
   177  			Eventually(func() bool {
   178  				imagePullRemoteSecret, err = fw.AsKubeAdmin.RemoteSecretController.GetRemoteSecret(imagePullRemoteSecret.Name, imagePullRemoteSecret.Namespace)
   179  				Expect(err).NotTo(HaveOccurred())
   180  
   181  				return meta.IsStatusConditionTrue(imagePullRemoteSecret.Status.Conditions, "Deployed")
   182  			}, 5*time.Minute, 5*time.Second).Should(BeTrue(), fmt.Sprintf("Pull RemoteSecret %s/%s is not in deployed phase", namespace, imagePullRemoteSecret.GetName()))
   183  		})
   184  
   185  		It("checks if image push remote secret was deployed", func() {
   186  			Eventually(func() bool {
   187  				imagePushRemoteSecret, err = fw.AsKubeAdmin.RemoteSecretController.GetRemoteSecret(imagePushRemoteSecret.Name, imagePushRemoteSecret.Namespace)
   188  				Expect(err).NotTo(HaveOccurred())
   189  
   190  				return meta.IsStatusConditionTrue(imagePushRemoteSecret.Status.Conditions, "Deployed")
   191  			}, 5*time.Minute, 5*time.Second).Should(BeTrue(), fmt.Sprintf("Push RemoteSecret %s/%s is not in deployed phase", namespace, imagePushRemoteSecret.GetName()))
   192  		})
   193  
   194  		It("checks if image pull secret is set and linked to the default service account", func() {
   195  			pullTargets = imagePullRemoteSecret.Status.Targets
   196  			Expect(pullTargets).To(HaveLen(1))
   197  
   198  			IsTargetSecretLinkedToRightSA(namespace, imagePullRemoteSecret.Name, "default", pullTargets[0])
   199  		})
   200  
   201  		It("checks if image push secret is set and linked to the appstudio-pipeline service account", func() {
   202  			pushTargets = imagePushRemoteSecret.Status.Targets
   203  			Expect(pushTargets).To(HaveLen(1))
   204  
   205  			IsTargetSecretLinkedToRightSA(namespace, imagePushRemoteSecret.Name, "appstudio-pipeline", pushTargets[0])
   206  		})
   207  
   208  		It("checks if image pull secret is correct", func() {
   209  			IsRobotAccountTokenCorrect(pullTargets[0].DeployedSecret.Name, namespace, "pull", imageRepository, fw)
   210  		})
   211  
   212  		It("checks if image push secret is correct", func() {
   213  			IsRobotAccountTokenCorrect(pushTargets[0].DeployedSecret.Name, namespace, "push", imageRepository, fw)
   214  		})
   215  
   216  	})
   217  })