github.com/redhat-appstudio/e2e-tests@v0.0.0-20240520140907-9709f6f59323/pkg/clients/has/applications.go (about) 1 package has 2 3 import ( 4 "context" 5 "fmt" 6 "time" 7 8 appservice "github.com/redhat-appstudio/application-api/api/v1alpha1" 9 "github.com/redhat-appstudio/e2e-tests/pkg/logs" 10 "github.com/redhat-appstudio/e2e-tests/pkg/utils" 11 k8sErrors "k8s.io/apimachinery/pkg/api/errors" 12 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 13 "k8s.io/apimachinery/pkg/types" 14 "k8s.io/apimachinery/pkg/util/wait" 15 rclient "sigs.k8s.io/controller-runtime/pkg/client" 16 ) 17 18 // GetApplication returns an application given a name and namespace from kubernetes cluster. 19 func (h *HasController) GetApplication(name string, namespace string) (*appservice.Application, error) { 20 application := appservice.Application{ 21 Spec: appservice.ApplicationSpec{}, 22 } 23 if err := h.KubeRest().Get(context.Background(), types.NamespacedName{Name: name, Namespace: namespace}, &application); err != nil { 24 return nil, err 25 } 26 27 return &application, nil 28 } 29 30 // ApplicationDevfilePresent check if devfile exists in the application status. 31 func (h *HasController) ApplicationDevfilePresent(application *appservice.Application) wait.ConditionFunc { 32 return func() (bool, error) { 33 app, err := h.GetApplication(application.Name, application.Namespace) 34 if err != nil { 35 return false, nil 36 } 37 application.Status = app.Status 38 return application.Status.Devfile != "", nil 39 } 40 } 41 42 // CreateApplication creates an application in the kubernetes cluster with 10 minutes default time for creation. 43 func (h *HasController) CreateApplication(name string, namespace string) (*appservice.Application, error) { 44 return h.CreateApplicationWithTimeout(name, namespace, time.Minute*10) 45 } 46 47 // CreateHasApplicationWithTimeout creates an application in the kubernetes cluster with a custom default time for creation. 48 func (h *HasController) CreateApplicationWithTimeout(name string, namespace string, timeout time.Duration) (*appservice.Application, error) { 49 application := &appservice.Application{ 50 ObjectMeta: metav1.ObjectMeta{ 51 Name: name, 52 Namespace: namespace, 53 }, 54 Spec: appservice.ApplicationSpec{ 55 DisplayName: name, 56 }, 57 } 58 59 ctx, cancel := context.WithTimeout(context.Background(), time.Minute*1) 60 defer cancel() 61 if err := h.KubeRest().Create(ctx, application); err != nil { 62 return nil, err 63 } 64 65 if err := utils.WaitUntil(h.ApplicationDevfilePresent(application), timeout); err != nil { 66 application = h.refreshApplicationForErrorDebug(application) 67 return nil, fmt.Errorf("timed out when waiting for devfile content creation for application %s in %s namespace: %+v. applicattion: %s", name, namespace, err, utils.ToPrettyJSONString(application)) 68 } 69 70 return application, nil 71 } 72 73 // DeleteApplication delete a HAS Application resource from the namespace. 74 // Optionally, it can avoid returning an error if the resource did not exist: 75 // - specify 'false', if it's likely the Application has already been deleted (for example, because the Namespace was deleted) 76 func (h *HasController) DeleteApplication(name string, namespace string, reportErrorOnNotFound bool) error { 77 application := appservice.Application{ 78 ObjectMeta: metav1.ObjectMeta{ 79 Name: name, 80 Namespace: namespace, 81 }, 82 } 83 if err := h.KubeRest().Delete(context.Background(), &application); err != nil { 84 if !k8sErrors.IsNotFound(err) || (k8sErrors.IsNotFound(err) && reportErrorOnNotFound) { 85 return fmt.Errorf("error deleting an application: %+v", err) 86 } 87 } 88 return utils.WaitUntil(h.ApplicationDeleted(&application), 1*time.Minute) 89 } 90 91 // ApplicationDeleted check if a given application object was deleted successfully from the kubernetes cluster. 92 func (h *HasController) ApplicationDeleted(application *appservice.Application) wait.ConditionFunc { 93 return func() (bool, error) { 94 _, err := h.GetApplication(application.Name, application.Namespace) 95 return err != nil && k8sErrors.IsNotFound(err), nil 96 } 97 } 98 99 // DeleteAllApplicationsInASpecificNamespace removes all application CRs from a specific namespace. Useful when creating a lot of resources and want to remove all of them 100 func (h *HasController) DeleteAllApplicationsInASpecificNamespace(namespace string, timeout time.Duration) error { 101 if err := h.KubeRest().DeleteAllOf(context.Background(), &appservice.Application{}, rclient.InNamespace(namespace)); err != nil { 102 return fmt.Errorf("error deleting applications from the namespace %s: %+v", namespace, err) 103 } 104 105 return utils.WaitUntil(func() (done bool, err error) { 106 applicationList, err := h.ListAllApplications(namespace) 107 if err != nil { 108 return false, nil 109 } 110 return len(applicationList.Items) == 0, nil 111 }, timeout) 112 } 113 114 // refreshApplicationForErrorDebug return the latest application object from the kubernetes cluster. 115 func (h *HasController) refreshApplicationForErrorDebug(application *appservice.Application) *appservice.Application { 116 retApp := &appservice.Application{} 117 118 if err := h.KubeRest().Get(context.Background(), rclient.ObjectKeyFromObject(application), retApp); err != nil { 119 return application 120 } 121 122 return retApp 123 } 124 125 // ListAllApplications returns a list of all Applications in a given namespace. 126 func (h *HasController) ListAllApplications(namespace string) (*appservice.ApplicationList, error) { 127 applicationList := &appservice.ApplicationList{} 128 err := h.KubeRest().List(context.Background(), applicationList, &rclient.ListOptions{Namespace: namespace}) 129 130 return applicationList, err 131 } 132 133 // StoreApplication stores a given Application as an artifact. 134 func (h *HasController) StoreApplication(application *appservice.Application) error { 135 return logs.StoreResourceYaml(application, "application-"+application.Name) 136 } 137 138 // StoreAllApplications stores all Applications in a given namespace. 139 func (h *HasController) StoreAllApplications(namespace string) error { 140 applicationList, err := h.ListAllApplications(namespace) 141 if err != nil { 142 return err 143 } 144 145 for _, application := range applicationList.Items { 146 if err := h.StoreApplication(&application); err != nil { 147 return err 148 } 149 } 150 return nil 151 }