github.com/redhat-appstudio/e2e-tests@v0.0.0-20240520140907-9709f6f59323/pkg/clients/common/secret.go (about) 1 package common 2 3 import ( 4 "context" 5 "encoding/base64" 6 "errors" 7 "fmt" 8 "time" 9 10 "github.com/redhat-appstudio/e2e-tests/pkg/constants" 11 . "github.com/redhat-appstudio/e2e-tests/pkg/constants" 12 "github.com/redhat-appstudio/e2e-tests/pkg/utils" 13 corev1 "k8s.io/api/core/v1" 14 k8sErrors "k8s.io/apimachinery/pkg/api/errors" 15 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 16 "k8s.io/apimachinery/pkg/util/wait" 17 ) 18 19 // Creates a new secret in a specified namespace 20 func (s *SuiteController) CreateSecret(ns string, secret *corev1.Secret) (*corev1.Secret, error) { 21 return s.KubeInterface().CoreV1().Secrets(ns).Create(context.Background(), secret, metav1.CreateOptions{}) 22 } 23 24 // Check if a secret exists, return secret and error 25 func (s *SuiteController) GetSecret(ns string, name string) (*corev1.Secret, error) { 26 return s.KubeInterface().CoreV1().Secrets(ns).Get(context.Background(), name, metav1.GetOptions{}) 27 } 28 29 // Deleted a secret in a specified namespace 30 func (s *SuiteController) DeleteSecret(ns string, name string) error { 31 return s.KubeInterface().CoreV1().Secrets(ns).Delete(context.Background(), name, metav1.DeleteOptions{}) 32 } 33 34 // Links a secret to a specified serviceaccount, if argument addImagePullSecrets is true secret will be added also to ImagePullSecrets of SA. 35 func (s *SuiteController) LinkSecretToServiceAccount(ns, secret, serviceaccount string, addImagePullSecrets bool) error { 36 timeout := 20 * time.Second 37 return wait.PollUntilContextTimeout(context.Background(), time.Second, timeout, true, func(ctx context.Context) (bool, error) { 38 serviceAccountObject, err := s.KubeInterface().CoreV1().ServiceAccounts(ns).Get(context.Background(), serviceaccount, metav1.GetOptions{}) 39 if err != nil { 40 return false, err 41 } 42 for _, credentialSecret := range serviceAccountObject.Secrets { 43 if credentialSecret.Name == secret { 44 // The secret is present in the service account, no updates needed 45 return true, nil 46 } 47 } 48 serviceAccountObject.Secrets = append(serviceAccountObject.Secrets, corev1.ObjectReference{Name: secret}) 49 if addImagePullSecrets { 50 serviceAccountObject.ImagePullSecrets = append(serviceAccountObject.ImagePullSecrets, corev1.LocalObjectReference{Name: secret}) 51 } 52 _, err = s.KubeInterface().CoreV1().ServiceAccounts(ns).Update(context.Background(), serviceAccountObject, metav1.UpdateOptions{}) 53 if err != nil { 54 return false, nil 55 } 56 return true, nil 57 }) 58 } 59 60 // UnlinkSecretFromServiceAccount unlinks secret from service account 61 func (s *SuiteController) UnlinkSecretFromServiceAccount(namespace, secretName, serviceAccount string, rmImagePullSecrets bool) error { 62 serviceAccountObject, err := s.KubeInterface().CoreV1().ServiceAccounts(namespace).Get(context.Background(), serviceAccount, metav1.GetOptions{}) 63 if err != nil { 64 return err 65 } 66 67 for index, secret := range serviceAccountObject.Secrets { 68 if secret.Name == secretName { 69 serviceAccountObject.Secrets = append(serviceAccountObject.Secrets[:index], serviceAccountObject.Secrets[index+1:]...) 70 break 71 } 72 } 73 74 if rmImagePullSecrets { 75 for index, secret := range serviceAccountObject.ImagePullSecrets { 76 if secret.Name == secretName { 77 serviceAccountObject.ImagePullSecrets = append(serviceAccountObject.ImagePullSecrets[:index], serviceAccountObject.ImagePullSecrets[index+1:]...) 78 break 79 } 80 } 81 } 82 _, err = s.KubeInterface().CoreV1().ServiceAccounts(namespace).Update(context.Background(), serviceAccountObject, metav1.UpdateOptions{}) 83 if err != nil { 84 return err 85 } 86 87 return nil 88 } 89 90 // CreateRegistryAuthSecret create a docker registry secret in a given ns 91 func (s *SuiteController) CreateRegistryAuthSecret(secretName, namespace, secretStringData string) (*corev1.Secret, error) { 92 rawDecodedTextStringData, err := base64.StdEncoding.DecodeString(secretStringData) 93 if err != nil { 94 return nil, err 95 } 96 97 secret := &corev1.Secret{ 98 ObjectMeta: metav1.ObjectMeta{ 99 Name: secretName, 100 Namespace: namespace, 101 }, 102 Type: corev1.SecretTypeDockerConfigJson, 103 StringData: map[string]string{corev1.DockerConfigJsonKey: string(rawDecodedTextStringData)}, 104 } 105 er := s.KubeRest().Create(context.Background(), secret) 106 if er != nil { 107 return nil, er 108 } 109 return secret, nil 110 } 111 112 // CreateRegistryJsonSecret creates a secret for registry repository in namespace given with key passed. 113 func (s *SuiteController) CreateRegistryJsonSecret(name, namespace, authKey, keyName string) (*corev1.Secret, error) { 114 secret := &corev1.Secret{ 115 ObjectMeta: metav1.ObjectMeta{Name: name, Namespace: namespace}, 116 Type: corev1.SecretTypeDockerConfigJson, 117 Data: map[string][]byte{".dockerconfigjson": []byte(fmt.Sprintf("{\"auths\":{\"quay.io\":{\"username\":\"%s\",\"password\":\"%s\",\"auth\":\"dGVzdDp0ZXN0\",\"email\":\"\"}}}", keyName, authKey))}, 118 } 119 err := s.KubeRest().Create(context.Background(), secret) 120 if err != nil { 121 return nil, err 122 } 123 return secret, nil 124 } 125 126 // AddRegistryAuthSecretToSA adds registry auth secret to service account 127 func (s *SuiteController) AddRegistryAuthSecretToSA(registryAuth, namespace string) error { 128 quayToken := utils.GetEnv(registryAuth, "") 129 if quayToken == "" { 130 return errors.New("failed to get registry auth secret") 131 } 132 133 _, err := s.CreateRegistryAuthSecret(RegistryAuthSecretName, namespace, quayToken) 134 if err != nil { 135 return err 136 } 137 138 err = s.LinkSecretToServiceAccount(namespace, RegistryAuthSecretName, DefaultPipelineServiceAccount, true) 139 if err != nil { 140 return err 141 } 142 143 return nil 144 } 145 146 // copy the quay secret to a user defined namespace 147 func (s *SuiteController) CreateQuayRegistrySecret(namespace string) error { 148 sharedSecret, err := s.GetSecret(constants.QuayRepositorySecretNamespace, constants.QuayRepositorySecretName) 149 if err != nil { 150 return err 151 } 152 _, err = s.GetSecret(namespace, constants.QuayRepositorySecretName) 153 if err != nil { 154 if !k8sErrors.IsNotFound(err) { 155 return err 156 } 157 } else { 158 err = s.DeleteSecret(namespace, constants.QuayRepositorySecretName) 159 if err != nil { 160 return err 161 } 162 } 163 164 repositorySecret := &corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: constants.QuayRepositorySecretName, Namespace: namespace}, 165 Type: corev1.SecretTypeDockerConfigJson, 166 Data: map[string][]byte{corev1.DockerConfigJsonKey: sharedSecret.Data[".dockerconfigjson"]}} 167 _, err = s.CreateSecret(namespace, repositorySecret) 168 if err != nil { 169 return err 170 } 171 172 err = s.LinkSecretToServiceAccount(namespace, constants.QuayRepositorySecretName, constants.DefaultPipelineServiceAccount, true) 173 if err != nil { 174 return err 175 } 176 177 return nil 178 }