github.com/redhat-appstudio/e2e-tests@v0.0.0-20240520140907-9709f6f59323/pkg/clients/spi/access_tokens.go (about) 1 package spi 2 3 import ( 4 "bytes" 5 "context" 6 "crypto/tls" 7 "fmt" 8 "net/http" 9 "time" 10 11 . "github.com/onsi/gomega" 12 "github.com/redhat-appstudio/e2e-tests/pkg/utils" 13 spi "github.com/redhat-appstudio/service-provider-integration-operator/api/v1beta1" 14 v1 "k8s.io/api/core/v1" 15 k8sErrors "k8s.io/apimachinery/pkg/api/errors" 16 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 17 "k8s.io/apimachinery/pkg/types" 18 "k8s.io/klog" 19 "sigs.k8s.io/controller-runtime/pkg/client" 20 ) 21 22 const ( 23 SPIAccessTokenBindingPrefixName = "e2e-access-token-binding" 24 ) 25 26 // GetSPIAccessTokenBinding returns the requested SPIAccessTokenBinding object 27 func (s *SPIController) GetSPIAccessToken(name, namespace string) (*spi.SPIAccessToken, error) { 28 namespacedName := types.NamespacedName{ 29 Name: name, 30 Namespace: namespace, 31 } 32 33 spiAccessToken := spi.SPIAccessToken{ 34 Spec: spi.SPIAccessTokenSpec{}, 35 } 36 err := s.KubeRest().Get(context.Background(), namespacedName, &spiAccessToken) 37 if err != nil { 38 return nil, err 39 } 40 return &spiAccessToken, nil 41 } 42 43 // Inject manually access tokens using spi API 44 func (s *SPIController) InjectManualSPIToken(namespace string, repoUrl string, oauthCredentials string, secretType v1.SecretType, secretName string) string { 45 var spiAccessTokenBinding *spi.SPIAccessTokenBinding 46 47 // Get the token for the current openshift user 48 bearerToken, err := utils.GetOpenshiftToken() 49 Expect(err).NotTo(HaveOccurred()) 50 51 // https://issues.redhat.com/browse/STONE-444. Is not possible to create more than 1 secret per user namespace 52 secret, err := s.KubeInterface().CoreV1().Secrets(namespace).Get(context.Background(), secretName, metav1.GetOptions{}) 53 if k8sErrors.IsAlreadyExists(err) { 54 klog.Infof("secret %s already exists", secret.Name) 55 56 return secret.Name 57 } 58 59 spiAccessTokenBinding, err = s.CreateSPIAccessTokenBinding(SPIAccessTokenBindingPrefixName, namespace, repoUrl, secretName, secretType) 60 Expect(err).NotTo(HaveOccurred()) 61 spiAccessTokenBindingName := spiAccessTokenBinding.Name 62 63 Eventually(func() spi.SPIAccessTokenBindingPhase { 64 // application info should be stored even after deleting the application in application variable 65 spiAccessTokenBinding, err = s.GetSPIAccessTokenBinding(spiAccessTokenBindingName, namespace) 66 Expect(err).NotTo(HaveOccurred()) 67 68 return spiAccessTokenBinding.Status.Phase 69 }, 2*time.Minute, 5*time.Second).Should(Or(Equal(spi.SPIAccessTokenBindingPhaseInjected), Equal(spi.SPIAccessTokenBindingPhaseAwaitingTokenData)), fmt.Sprintf("SPIAccessTokenBinding %s/%s is not in %s or %s phase", spiAccessTokenBinding.GetNamespace(), spiAccessTokenBinding.GetName(), spi.SPIAccessTokenBindingPhaseInjected, spi.SPIAccessTokenBindingPhaseAwaitingTokenData)) 70 71 Eventually(func() string { 72 // application info should be stored even after deleting the application in application variable 73 spiAccessTokenBinding, err = s.GetSPIAccessTokenBinding(spiAccessTokenBindingName, namespace) 74 Expect(err).NotTo(HaveOccurred()) 75 76 return spiAccessTokenBinding.Status.UploadUrl 77 }, 5*time.Minute, 100*time.Millisecond).ShouldNot(BeEmpty(), fmt.Sprintf(".Status.UploadUrl for SPIAccessTokenBinding %s/%s is not set. Please check if spi oauth-config configmap contain all necessary providers for tests.", spiAccessTokenBinding.GetNamespace(), spiAccessTokenBinding.GetName())) 78 79 if spiAccessTokenBinding.Status.Phase == spi.SPIAccessTokenBindingPhaseAwaitingTokenData { 80 // If the phase is AwaitingTokenData then manually inject the git token 81 // Get the oauth url and linkedAccessTokenName from the spiaccesstokenbinding resource 82 Expect(err).NotTo(HaveOccurred()) 83 linkedAccessTokenName := spiAccessTokenBinding.Status.LinkedAccessTokenName 84 85 // Before injecting the token, validate that the linkedaccesstoken resource exists, otherwise injecting will return a 404 error code 86 Eventually(func() bool { 87 // application info should be stored even after deleting the application in application variable 88 _, err := s.GetSPIAccessToken(linkedAccessTokenName, namespace) 89 return err == nil 90 }, 1*time.Minute, 100*time.Millisecond).Should(BeTrue(), "SPI controller didn't create the SPIAccessToken") 91 92 // Format for quay.io token injection: `{"access_token":"tokenToInject","username":"redhat-appstudio-qe+redhat_appstudio_qe_bot"}` 93 // Now that the spiaccesstokenbinding is in the AwaitingTokenData phase, inject the GitHub token 94 http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true} 95 req, err := http.NewRequest("POST", spiAccessTokenBinding.Status.UploadUrl, bytes.NewBuffer([]byte(oauthCredentials))) 96 Expect(err).NotTo(HaveOccurred()) 97 req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", string(bearerToken))) 98 req.Header.Set("Content-Type", "application/json") 99 100 client := &http.Client{} 101 resp, err := client.Do(req) 102 Expect(err).NotTo(HaveOccurred()) 103 Expect(resp.StatusCode).Should(Equal(204)) 104 defer resp.Body.Close() 105 106 // Check to see if the token was successfully injected 107 Eventually(func() spi.SPIAccessTokenBindingPhase { 108 // application info should be stored even after deleting the application in application variable 109 spiAccessTokenBinding, err = s.GetSPIAccessTokenBinding(spiAccessTokenBindingName, namespace) 110 Expect(err).NotTo(HaveOccurred()) 111 112 return spiAccessTokenBinding.Status.Phase 113 }, 1*time.Minute, 100*time.Millisecond).Should(Equal(spi.SPIAccessTokenBindingPhaseInjected), fmt.Sprintf("SPIAccessTokenBinding %s/%s is not in %s phase", spiAccessTokenBinding.GetNamespace(), spiAccessTokenBinding.GetName(), spi.SPIAccessTokenBindingPhaseInjected)) 114 } 115 return secretName 116 } 117 118 // Remove all SPIAccessToken from a given namespace. Useful when creating a lot of resources and wanting to remove all of them 119 func (s *SPIController) DeleteAllAccessTokensInASpecificNamespace(namespace string) error { 120 return s.KubeRest().DeleteAllOf(context.Background(), &spi.SPIAccessToken{}, client.InNamespace(namespace)) 121 } 122 123 // Remove all SPIAccessTokenDataUpdate from a given namespace. Useful when creating a lot of resources and wanting to remove all of them 124 func (s *SPIController) DeleteAllAccessTokenDataInASpecificNamespace(namespace string) error { 125 return s.KubeRest().DeleteAllOf(context.Background(), &spi.SPIAccessTokenDataUpdate{}, client.InNamespace(namespace)) 126 }