github.com/kubeshop/testkube@v1.17.23/pkg/executor/env/manager.go (about) 1 package env 2 3 import ( 4 "bytes" 5 "fmt" 6 "os" 7 "strings" 8 9 corev1 "k8s.io/api/core/v1" 10 11 "github.com/kubeshop/testkube/pkg/api/v1/testkube" 12 ) 13 14 const ( 15 // SecretEnvVarPrefix is a prefix for secret env vars 16 SecretEnvVarPrefix = "RUNNER_SECRET_ENV" 17 // SecretVarPrefix is a prefix for secret vars 18 SecretVarPrefix = "RUNNER_SECRET_VAR_" 19 // ConfigMapVarPrefix is a prefix for config map vars 20 ConfigMapVarPrefix = "RUNNER_CONFIGMAP_VAR_" 21 // GitUsernameEnvVarName is git username environment var name 22 GitUsernameEnvVarName = "RUNNER_GITUSERNAME" 23 // GitTokenEnvVarName is git token environment var name 24 GitTokenEnvVarName = "RUNNER_GITTOKEN" 25 ) 26 27 // Interface is responsible for exchanging envs and vars with executor pod 28 type Interface interface { 29 // PrepareSecrets prepares secret env vars based on secret envs and variables 30 PrepareSecrets(secretEnvs map[string]string, variables map[string]testkube.Variable) (secretEnvVars []corev1.EnvVar) 31 // PrepareEnvs prepares env vars based on envs and variables 32 PrepareEnvs(envs map[string]string, variables map[string]testkube.Variable) []corev1.EnvVar 33 // PrepareGitCredentials prepares git credentials 34 PrepareGitCredentials(usernameSecret, tokenSecret *testkube.SecretRef) (envVars []corev1.EnvVar) 35 // GetSecretEnvs get secret envs 36 GetSecretEnvs() (secretEnvs map[string]string) 37 // GetReferenceVars gets reference vars 38 GetReferenceVars(variables map[string]testkube.Variable) 39 // ObfuscateSecrets obfuscates secret values 40 ObfuscateSecrets(p []byte) []byte 41 // ObfuscateStringSlice obfuscates string slice values 42 ObfuscateStringSlice(values []string) []string 43 } 44 45 // NewManager returns an implementation of the Manager 46 func NewManager() *Manager { 47 return &Manager{} 48 } 49 50 // NewManagerWithVars returns an implementation of the Manager with variables 51 func NewManagerWithVars(variables map[string]testkube.Variable) *Manager { 52 return &Manager{ 53 Variables: variables, 54 } 55 } 56 57 // Manager manages secret and config map exchange from job pods using env 58 type Manager struct { 59 Variables map[string]testkube.Variable 60 } 61 62 // PrepareSecrets prepares secret env vars based on secret envs and variables 63 func (m Manager) PrepareSecrets(secretEnvs map[string]string, variables map[string]testkube.Variable) (secretEnvVars []corev1.EnvVar) { 64 // preparet secret envs 65 i := 1 66 // Deprecated: use Secret Variables instead 67 for secretVar, secretName := range secretEnvs { 68 // TODO: these are duplicated because Postman executor is expecting it as json string 69 // and gets unmarshalled and the name and the value are taken from there, for other executors it will be like a normal env var. 70 secretEnvVars = append(secretEnvVars, corev1.EnvVar{ 71 Name: secretVar, 72 ValueFrom: &corev1.EnvVarSource{ 73 SecretKeyRef: &corev1.SecretKeySelector{ 74 LocalObjectReference: corev1.LocalObjectReference{ 75 Name: secretName, 76 }, 77 Key: secretVar, 78 }, 79 }, 80 }) 81 82 secretEnvVars = append(secretEnvVars, corev1.EnvVar{ 83 Name: fmt.Sprintf("%s%d", SecretEnvVarPrefix, i), 84 ValueFrom: &corev1.EnvVarSource{ 85 SecretKeyRef: &corev1.SecretKeySelector{ 86 LocalObjectReference: corev1.LocalObjectReference{ 87 Name: secretName, 88 }, 89 Key: secretVar, 90 }, 91 }, 92 }) 93 i++ 94 } 95 96 i = 1 97 // prepare secret vars 98 for name, variable := range variables { 99 if !variable.IsSecret() || variable.SecretRef == nil { 100 continue 101 } 102 103 // TODO: these are duplicated because Postman executor is expecting it as json string 104 // and gets unmarshalled and the name and the value are taken from there, for other executors it will be like a normal env var. 105 secretEnvVars = append(secretEnvVars, corev1.EnvVar{ 106 Name: name, 107 ValueFrom: &corev1.EnvVarSource{ 108 SecretKeyRef: &corev1.SecretKeySelector{ 109 LocalObjectReference: corev1.LocalObjectReference{ 110 Name: variable.SecretRef.Name, 111 }, 112 Key: variable.SecretRef.Key, 113 }, 114 }, 115 }) 116 117 secretEnvVars = append(secretEnvVars, corev1.EnvVar{ 118 Name: fmt.Sprintf("%s%d", SecretEnvVarPrefix, i), 119 ValueFrom: &corev1.EnvVarSource{ 120 SecretKeyRef: &corev1.SecretKeySelector{ 121 LocalObjectReference: corev1.LocalObjectReference{ 122 Name: variable.SecretRef.Name, 123 }, 124 Key: variable.SecretRef.Key, 125 }, 126 }, 127 }) 128 i++ 129 130 secretEnvVars = append(secretEnvVars, corev1.EnvVar{ 131 Name: fmt.Sprintf("%s%s", SecretVarPrefix, name), 132 ValueFrom: &corev1.EnvVarSource{ 133 SecretKeyRef: &corev1.SecretKeySelector{ 134 LocalObjectReference: corev1.LocalObjectReference{ 135 Name: variable.SecretRef.Name, 136 }, 137 Key: variable.SecretRef.Key, 138 }, 139 }, 140 }) 141 } 142 143 return secretEnvVars 144 } 145 146 // PrepareEnvs prepares env vars based on envs and variables 147 func (m Manager) PrepareEnvs(envs map[string]string, variables map[string]testkube.Variable) []corev1.EnvVar { 148 var env []corev1.EnvVar 149 for k, v := range envs { 150 env = append(env, corev1.EnvVar{ 151 Name: k, 152 Value: v, 153 }) 154 } 155 // prepare vars 156 for name, variable := range variables { 157 if variable.IsSecret() { 158 continue 159 } 160 161 if variable.ConfigMapRef == nil { 162 env = append(env, corev1.EnvVar{ 163 Name: name, 164 Value: variable.Value, 165 }) 166 } else { 167 env = append(env, corev1.EnvVar{ 168 Name: name, 169 ValueFrom: &corev1.EnvVarSource{ 170 ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ 171 LocalObjectReference: corev1.LocalObjectReference{ 172 Name: variable.ConfigMapRef.Name, 173 }, 174 Key: variable.ConfigMapRef.Key, 175 }, 176 }, 177 }) 178 179 env = append(env, corev1.EnvVar{ 180 Name: fmt.Sprintf("%s%s", ConfigMapVarPrefix, name), 181 ValueFrom: &corev1.EnvVarSource{ 182 ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ 183 LocalObjectReference: corev1.LocalObjectReference{ 184 Name: variable.ConfigMapRef.Name, 185 }, 186 Key: variable.ConfigMapRef.Key, 187 }, 188 }, 189 }) 190 } 191 } 192 193 return env 194 } 195 196 // PrepareGitCredentials prepares git credentials 197 func (m Manager) PrepareGitCredentials(usernameSecret, tokenSecret *testkube.SecretRef) (envVars []corev1.EnvVar) { 198 var data = []struct { 199 envVar string 200 secretRef *testkube.SecretRef 201 }{ 202 { 203 GitUsernameEnvVarName, 204 usernameSecret, 205 }, 206 { 207 GitTokenEnvVarName, 208 tokenSecret, 209 }, 210 } 211 212 for _, value := range data { 213 if value.secretRef != nil { 214 envVars = append(envVars, corev1.EnvVar{ 215 Name: value.envVar, 216 ValueFrom: &corev1.EnvVarSource{ 217 SecretKeyRef: &corev1.SecretKeySelector{ 218 LocalObjectReference: corev1.LocalObjectReference{ 219 Name: value.secretRef.Name, 220 }, 221 Key: value.secretRef.Key, 222 }, 223 }, 224 }) 225 } 226 } 227 228 return envVars 229 } 230 231 // GetSecretEnvs gets secret envs 232 func (m Manager) GetSecretEnvs() (secretEnvs map[string]string) { 233 secretEnvs = make(map[string]string, 0) 234 i := 1 235 for { 236 envName := fmt.Sprintf("%s%d", SecretEnvVarPrefix, i) 237 secretEnv, ok := os.LookupEnv(envName) 238 if !ok { 239 break 240 } 241 242 secretEnvs[envName] = secretEnv 243 i++ 244 } 245 246 return secretEnvs 247 } 248 249 // GetReferenceVars gets reference vars 250 func (m Manager) GetReferenceVars(variables map[string]testkube.Variable) { 251 for name, variable := range variables { 252 if variable.IsSecret() { 253 value, ok := os.LookupEnv(fmt.Sprintf("%s%s", SecretVarPrefix, name)) 254 if !ok { 255 continue 256 } 257 258 variable.Value = value 259 variables[name] = variable 260 } else { 261 value, ok := os.LookupEnv(fmt.Sprintf("%s%s", ConfigMapVarPrefix, name)) 262 if !ok { 263 continue 264 } 265 266 variable.Value = value 267 variables[name] = variable 268 } 269 } 270 271 return 272 } 273 274 // ObfuscateSecrets obfuscates secret values 275 func (m Manager) ObfuscateSecrets(p []byte) []byte { 276 if m.Variables == nil { 277 return p 278 } 279 280 for _, variable := range m.Variables { 281 if !variable.IsSecret() { 282 continue 283 } 284 285 p = bytes.ReplaceAll(p, []byte(variable.Value), []byte(strings.Repeat("*", len(variable.Value)))) 286 } 287 288 return p 289 } 290 291 // ObfuscateStringSlice obfuscates string slice values 292 func (m Manager) ObfuscateStringSlice(values []string) []string { 293 if m.Variables == nil { 294 return values 295 } 296 297 var results []string 298 for _, value := range values { 299 for _, variable := range m.Variables { 300 if !variable.IsSecret() { 301 continue 302 } 303 304 value = strings.ReplaceAll(value, variable.Value, strings.Repeat("*", len(variable.Value))) 305 } 306 307 results = append(results, value) 308 } 309 310 return results 311 }