github.com/redhat-appstudio/e2e-tests@v0.0.0-20230619105049-9a422b2094d7/pkg/utils/gitops/controller.go (about)

     1  package gitops
     2  
     3  import (
     4  	"context"
     5  	"crypto/tls"
     6  	"fmt"
     7  	"net/http"
     8  	"time"
     9  
    10  	"github.com/redhat-appstudio/e2e-tests/pkg/utils"
    11  
    12  	routev1 "github.com/openshift/api/route/v1"
    13  	appservice "github.com/redhat-appstudio/application-api/api/v1alpha1"
    14  	kubeCl "github.com/redhat-appstudio/e2e-tests/pkg/apis/kubernetes"
    15  	managedgitopsv1alpha1 "github.com/redhat-appstudio/managed-gitops/backend/apis/managed-gitops/v1alpha1"
    16  	appsv1 "k8s.io/api/apps/v1"
    17  	k8sErrors "k8s.io/apimachinery/pkg/api/errors"
    18  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    19  	"k8s.io/apimachinery/pkg/types"
    20  	"sigs.k8s.io/controller-runtime/pkg/client"
    21  )
    22  
    23  type SuiteController struct {
    24  	*kubeCl.CustomClient
    25  }
    26  
    27  func NewSuiteController(kube *kubeCl.CustomClient) (*SuiteController, error) {
    28  	return &SuiteController{
    29  		kube,
    30  	}, nil
    31  }
    32  
    33  func (h *SuiteController) CreateGitOpsCR(name string, namespace string, repoUrl string, repoPath string, repoRevision string) (*managedgitopsv1alpha1.GitOpsDeployment, error) {
    34  	gitOpsDeployment := &managedgitopsv1alpha1.GitOpsDeployment{
    35  		ObjectMeta: metav1.ObjectMeta{
    36  			GenerateName: name,
    37  			Namespace:    namespace,
    38  		},
    39  		Spec: managedgitopsv1alpha1.GitOpsDeploymentSpec{
    40  			Source: managedgitopsv1alpha1.ApplicationSource{
    41  				RepoURL:        repoUrl,
    42  				Path:           repoPath,
    43  				TargetRevision: repoRevision,
    44  			},
    45  			Type: managedgitopsv1alpha1.GitOpsDeploymentSpecType_Automated,
    46  		},
    47  	}
    48  
    49  	err := h.KubeRest().Create(context.TODO(), gitOpsDeployment)
    50  	if err != nil {
    51  		return nil, err
    52  	}
    53  	return gitOpsDeployment, nil
    54  }
    55  
    56  // DeleteGitOpsDeployment deletes an gitops deployment from a given name and namespace
    57  func (h *SuiteController) DeleteGitOpsCR(name string, namespace string) error {
    58  	gitOpsDeployment := &managedgitopsv1alpha1.GitOpsDeployment{
    59  		ObjectMeta: metav1.ObjectMeta{
    60  			Name:      name,
    61  			Namespace: namespace,
    62  		},
    63  	}
    64  	return h.KubeRest().Delete(context.TODO(), gitOpsDeployment)
    65  }
    66  
    67  // GetGitOpsDeployedImage return the image used by the given component deployment
    68  func (h *SuiteController) GetGitOpsDeployedImage(deployment *appsv1.Deployment) (string, error) {
    69  	if len(deployment.Spec.Template.Spec.Containers) > 0 {
    70  		return deployment.Spec.Template.Spec.Containers[0].Image, nil
    71  	} else {
    72  		return "", fmt.Errorf("error when getting the deployed image")
    73  	}
    74  }
    75  
    76  // Checks that the deployed backend component is actually reachable and returns 200
    77  func (h *SuiteController) CheckGitOpsEndpoint(route *routev1.Route, endpoint string) error {
    78  	if len(route.Spec.Host) > 0 {
    79  		routeUrl := "https://" + route.Spec.Host + endpoint
    80  
    81  		http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
    82  		resp, err := http.Get(routeUrl)
    83  		if err != nil {
    84  			return err
    85  		}
    86  		if resp.StatusCode != 200 {
    87  			return fmt.Errorf("route responded with '%d' status code", resp.StatusCode)
    88  		}
    89  	} else {
    90  		return fmt.Errorf("route is invalid: '%s'", route.Spec.Host)
    91  	}
    92  
    93  	return nil
    94  }
    95  
    96  // Remove all gitopsdeployments from a given namespace. Useful when creating a lot of resources and want to remove all of them
    97  func (h *SuiteController) DeleteAllGitOpsDeploymentInASpecificNamespace(namespace string, timeout time.Duration) error {
    98  	if err := h.KubeRest().DeleteAllOf(context.TODO(), &managedgitopsv1alpha1.GitOpsDeployment{}, client.InNamespace(namespace)); err != nil {
    99  		return fmt.Errorf("error when deleting gitopsdeployments in %s namespace: %+v", namespace, err)
   100  	}
   101  
   102  	gdList := &managedgitopsv1alpha1.GitOpsDeploymentList{}
   103  	return utils.WaitUntil(func() (done bool, err error) {
   104  		if err = h.KubeRest().List(context.Background(), gdList, client.InNamespace(namespace)); err != nil {
   105  			return false, nil
   106  		}
   107  		return len(gdList.Items) == 0, nil
   108  	}, timeout)
   109  }
   110  
   111  /*
   112  * CreateEphemeralEnvironment: create an RHTAP environment pointing to a valid Kubernetes/Openshift cluster
   113  * Args:
   114  *	- name: Environment name
   115  *	- namespace: Namespace where to create the environment. Note: Should be in the same namespace where cluster credential secret it is
   116  *	- targetNamespace: Cluster namespace where to create Gitops resources
   117  *	- serverApi: A valid API kubernetes server for a specific Kubernetes/Openshift cluster
   118  *   - clusterCredentialsSecret: Secret with a valid kubeconfig credentials
   119  *   - clusterType: Openshift/Kubernetes
   120  *   - kubeIngressDomain: If clusterType == "Kubernetes", ingressDomain is mandatory and is enforced by the webhook validation
   121   */
   122  func (h *SuiteController) CreateEphemeralEnvironment(name string, namespace string, targetNamespace string, serverApi string, clusterCredentialsSecret string, clusterType appservice.ConfigurationClusterType, kubeIngressDomain string) (*appservice.Environment, error) {
   123  	ephemeralEnvironmentObj := &appservice.Environment{
   124  		ObjectMeta: metav1.ObjectMeta{
   125  			Name:      name,
   126  			Namespace: namespace,
   127  		},
   128  		Spec: appservice.EnvironmentSpec{
   129  			DeploymentStrategy: appservice.DeploymentStrategy_AppStudioAutomated,
   130  			Configuration: appservice.EnvironmentConfiguration{
   131  				Env: []appservice.EnvVarPair{
   132  					{
   133  						Name:  "POC",
   134  						Value: "POC",
   135  					},
   136  				},
   137  			},
   138  			UnstableConfigurationFields: &appservice.UnstableEnvironmentConfiguration{
   139  				ClusterType: clusterType,
   140  				KubernetesClusterCredentials: appservice.KubernetesClusterCredentials{
   141  					TargetNamespace:            targetNamespace,
   142  					APIURL:                     serverApi,
   143  					ClusterCredentialsSecret:   clusterCredentialsSecret,
   144  					AllowInsecureSkipTLSVerify: true,
   145  				},
   146  			},
   147  		},
   148  	}
   149  
   150  	if clusterType == appservice.ConfigurationClusterType_Kubernetes {
   151  		ephemeralEnvironmentObj.Spec.UnstableConfigurationFields.IngressDomain = kubeIngressDomain
   152  	}
   153  
   154  	if err := h.KubeRest().Create(context.TODO(), ephemeralEnvironmentObj); err != nil {
   155  		if err != nil {
   156  			if k8sErrors.IsAlreadyExists(err) {
   157  				environment := &appservice.Environment{}
   158  
   159  				err := h.KubeRest().Get(context.TODO(), types.NamespacedName{
   160  					Name:      name,
   161  					Namespace: namespace,
   162  				}, environment)
   163  
   164  				return environment, err
   165  			} else {
   166  				return nil, err
   167  			}
   168  		}
   169  	}
   170  
   171  	return ephemeralEnvironmentObj, nil
   172  }
   173  
   174  // CreateEnvironment creates a new environment
   175  func (h *SuiteController) CreateEnvironment(name, namespace string) (*appservice.Environment, error) {
   176  	environment := &appservice.Environment{
   177  		ObjectMeta: metav1.ObjectMeta{
   178  			Name:      name,
   179  			Namespace: namespace,
   180  		},
   181  		Spec: appservice.EnvironmentSpec{
   182  			Configuration: appservice.EnvironmentConfiguration{
   183  				Env: []appservice.EnvVarPair{},
   184  			},
   185  			DeploymentStrategy: appservice.DeploymentStrategy_Manual,
   186  			DisplayName:        name,
   187  			Type:               appservice.EnvironmentType_POC,
   188  			ParentEnvironment:  "non-existent-environment-to-fool-integration-service",
   189  		},
   190  	}
   191  
   192  	err := h.KubeRest().Create(context.TODO(), environment)
   193  	if err != nil {
   194  		return nil, err
   195  	}
   196  	return environment, nil
   197  }
   198  
   199  // DeleteAllEnvironmentsInASpecificNamespace removes all environments from a specific namespace. Useful when creating a lot of resources and want to remove all of them
   200  func (h *SuiteController) DeleteAllEnvironmentsInASpecificNamespace(namespace string, timeout time.Duration) error {
   201  	if err := h.KubeRest().DeleteAllOf(context.TODO(), &appservice.Environment{}, client.InNamespace(namespace)); err != nil {
   202  		return fmt.Errorf("error deleting environments from the namespace %s: %+v", namespace, err)
   203  	}
   204  
   205  	environmentList := &appservice.EnvironmentList{}
   206  	return utils.WaitUntil(func() (done bool, err error) {
   207  		if err := h.KubeRest().List(context.Background(), environmentList, &client.ListOptions{Namespace: namespace}); err != nil {
   208  			return false, nil
   209  		}
   210  		return len(environmentList.Items) == 0, nil
   211  	}, timeout)
   212  }