github.com/kubeshop/testkube@v1.17.23/pkg/mapper/testsuites/kube_openapi.go (about) 1 package testsuites 2 3 import ( 4 corev1 "k8s.io/api/core/v1" 5 6 commonv1 "github.com/kubeshop/testkube-operator/api/common/v1" 7 testsuitesv3 "github.com/kubeshop/testkube-operator/api/testsuite/v3" 8 "github.com/kubeshop/testkube/pkg/api/v1/testkube" 9 ) 10 11 // MapTestSuiteListKubeToAPI maps TestSuiteList CRD to list of OpenAPI spec TestSuite 12 func MapTestSuiteListKubeToAPI(cr testsuitesv3.TestSuiteList) (tests []testkube.TestSuite) { 13 tests = make([]testkube.TestSuite, len(cr.Items)) 14 for i, item := range cr.Items { 15 tests[i] = MapCRToAPI(item) 16 } 17 18 return 19 } 20 21 // MapCRToAPI maps TestSuite CRD to OpenAPI spec TestSuite 22 func MapCRToAPI(cr testsuitesv3.TestSuite) (test testkube.TestSuite) { 23 test.Name = cr.Name 24 test.Namespace = cr.Namespace 25 var batches = []struct { 26 source *[]testsuitesv3.TestSuiteBatchStep 27 dest *[]testkube.TestSuiteBatchStep 28 }{ 29 { 30 source: &cr.Spec.Before, 31 dest: &test.Before, 32 }, 33 { 34 source: &cr.Spec.Steps, 35 dest: &test.Steps, 36 }, 37 { 38 source: &cr.Spec.After, 39 dest: &test.After, 40 }, 41 } 42 43 for i := range batches { 44 for _, b := range *batches[i].source { 45 steps := make([]testkube.TestSuiteStep, len(b.Execute)) 46 for j := range b.Execute { 47 steps[j] = mapCRStepToAPI(b.Execute[j]) 48 } 49 50 var downloadArtifacts *testkube.DownloadArtifactOptions 51 if b.DownloadArtifacts != nil { 52 downloadArtifacts = &testkube.DownloadArtifactOptions{ 53 AllPreviousSteps: b.DownloadArtifacts.AllPreviousSteps, 54 PreviousStepNumbers: b.DownloadArtifacts.PreviousStepNumbers, 55 PreviousTestNames: b.DownloadArtifacts.PreviousTestNames, 56 } 57 } 58 59 *batches[i].dest = append(*batches[i].dest, testkube.TestSuiteBatchStep{ 60 StopOnFailure: b.StopOnFailure, 61 Execute: steps, 62 DownloadArtifacts: downloadArtifacts, 63 }) 64 } 65 } 66 67 test.Description = cr.Spec.Description 68 test.Repeats = int32(cr.Spec.Repeats) 69 test.Labels = cr.Labels 70 test.Schedule = cr.Spec.Schedule 71 test.Created = cr.CreationTimestamp.Time 72 test.ExecutionRequest = MapExecutionRequestFromSpec(cr.Spec.ExecutionRequest) 73 test.Status = MapStatusFromSpec(cr.Status) 74 return 75 } 76 77 // mapCRStepToAPI maps CRD TestSuiteStepSpec to OpenAPI spec TestSuiteStep 78 func mapCRStepToAPI(crstep testsuitesv3.TestSuiteStepSpec) (teststep testkube.TestSuiteStep) { 79 80 switch true { 81 case crstep.Test != "": 82 teststep = testkube.TestSuiteStep{ 83 Test: crstep.Test, 84 ExecutionRequest: MapTestStepExecutionRequestCRDToAPI(crstep.ExecutionRequest), 85 } 86 87 case crstep.Delay.Duration != 0: 88 teststep = testkube.TestSuiteStep{ 89 Delay: crstep.Delay.Duration.String(), 90 } 91 } 92 93 return 94 } 95 96 // @Depracated 97 // MapDepratcatedParams maps old params to new variables data structure 98 func MapDepratcatedParams(in map[string]testkube.Variable) map[string]string { 99 out := map[string]string{} 100 for k, v := range in { 101 out[k] = v.Value 102 } 103 return out 104 } 105 106 // MapCRDVariables maps variables between API and operator CRDs 107 // TODO if we could merge operator into testkube repository we would get rid of those mappings 108 func MapCRDVariables(in map[string]testkube.Variable) map[string]testsuitesv3.Variable { 109 out := map[string]testsuitesv3.Variable{} 110 for k, v := range in { 111 variable := testsuitesv3.Variable{ 112 Name: v.Name, 113 Type_: string(*v.Type_), 114 Value: v.Value, 115 } 116 117 if v.SecretRef != nil { 118 variable.ValueFrom = corev1.EnvVarSource{ 119 SecretKeyRef: &corev1.SecretKeySelector{ 120 LocalObjectReference: corev1.LocalObjectReference{ 121 Name: v.SecretRef.Name, 122 }, 123 Key: v.SecretRef.Key, 124 }, 125 } 126 } 127 128 if v.ConfigMapRef != nil { 129 variable.ValueFrom = corev1.EnvVarSource{ 130 ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ 131 LocalObjectReference: corev1.LocalObjectReference{ 132 Name: v.ConfigMapRef.Name, 133 }, 134 Key: v.ConfigMapRef.Key, 135 }, 136 } 137 } 138 139 out[k] = variable 140 } 141 return out 142 } 143 144 func MergeVariablesAndParams(variables map[string]testsuitesv3.Variable, params map[string]string) map[string]testkube.Variable { 145 out := map[string]testkube.Variable{} 146 for k, v := range params { 147 out[k] = testkube.NewBasicVariable(k, v) 148 } 149 150 for k, v := range variables { 151 if v.Type_ == commonv1.VariableTypeSecret { 152 if v.ValueFrom.SecretKeyRef == nil { 153 out[k] = testkube.NewSecretVariable(v.Name, v.Value) 154 } else { 155 out[k] = testkube.NewSecretVariableReference(v.Name, v.ValueFrom.SecretKeyRef.Name, v.ValueFrom.SecretKeyRef.Key) 156 } 157 } 158 if v.Type_ == commonv1.VariableTypeBasic { 159 if v.ValueFrom.ConfigMapKeyRef == nil { 160 out[k] = testkube.NewBasicVariable(v.Name, v.Value) 161 } else { 162 out[k] = testkube.NewConfigMapVariableReference(v.Name, v.ValueFrom.ConfigMapKeyRef.Name, v.ValueFrom.ConfigMapKeyRef.Key) 163 } 164 } 165 } 166 167 return out 168 } 169 170 // MapExecutionRequestFromSpec maps CRD to OpenAPI spec ExecutionRequest 171 func MapExecutionRequestFromSpec(specExecutionRequest *testsuitesv3.TestSuiteExecutionRequest) *testkube.TestSuiteExecutionRequest { 172 if specExecutionRequest == nil { 173 return nil 174 } 175 176 return &testkube.TestSuiteExecutionRequest{ 177 Name: specExecutionRequest.Name, 178 Labels: specExecutionRequest.Labels, 179 ExecutionLabels: specExecutionRequest.ExecutionLabels, 180 Namespace: specExecutionRequest.Namespace, 181 Variables: MergeVariablesAndParams(specExecutionRequest.Variables, nil), 182 SecretUUID: specExecutionRequest.SecretUUID, 183 Sync: specExecutionRequest.Sync, 184 HttpProxy: specExecutionRequest.HttpProxy, 185 HttpsProxy: specExecutionRequest.HttpsProxy, 186 Timeout: specExecutionRequest.Timeout, 187 JobTemplate: specExecutionRequest.JobTemplate, 188 JobTemplateReference: specExecutionRequest.JobTemplateReference, 189 CronJobTemplate: specExecutionRequest.CronJobTemplate, 190 CronJobTemplateReference: specExecutionRequest.CronJobTemplateReference, 191 PvcTemplate: specExecutionRequest.PvcTemplate, 192 PvcTemplateReference: specExecutionRequest.PvcTemplateReference, 193 ScraperTemplate: specExecutionRequest.ScraperTemplate, 194 ScraperTemplateReference: specExecutionRequest.ScraperTemplateReference, 195 } 196 } 197 198 // MapStatusFromSpec maps CRD to OpenAPI spec TestSuiteStatus 199 func MapStatusFromSpec(specStatus testsuitesv3.TestSuiteStatus) *testkube.TestSuiteStatus { 200 if specStatus.LatestExecution == nil { 201 return nil 202 } 203 204 return &testkube.TestSuiteStatus{ 205 LatestExecution: &testkube.TestSuiteExecutionCore{ 206 Id: specStatus.LatestExecution.Id, 207 Status: (*testkube.TestSuiteExecutionStatus)(specStatus.LatestExecution.Status), 208 StartTime: specStatus.LatestExecution.StartTime.Time, 209 EndTime: specStatus.LatestExecution.EndTime.Time, 210 }, 211 } 212 } 213 214 // MapTestSuiteTestCRDToUpdateRequest maps TestSuite CRD spec to TestSuiteUpdateRequest OpenAPI spec 215 func MapTestSuiteTestCRDToUpdateRequest(testSuite *testsuitesv3.TestSuite) (request testkube.TestSuiteUpdateRequest) { 216 var fields = []struct { 217 source *string 218 destination **string 219 }{ 220 { 221 &testSuite.Name, 222 &request.Name, 223 }, 224 { 225 &testSuite.Namespace, 226 &request.Namespace, 227 }, 228 { 229 &testSuite.Spec.Description, 230 &request.Description, 231 }, 232 { 233 &testSuite.Spec.Schedule, 234 &request.Schedule, 235 }, 236 } 237 238 for _, field := range fields { 239 *field.destination = field.source 240 } 241 242 before := mapCRDToTestBatchSteps(testSuite.Spec.Before) 243 request.Before = &before 244 245 steps := mapCRDToTestBatchSteps(testSuite.Spec.Steps) 246 request.Steps = &steps 247 248 after := mapCRDToTestBatchSteps(testSuite.Spec.After) 249 request.After = &after 250 251 request.Labels = &testSuite.Labels 252 253 repeats := int32(testSuite.Spec.Repeats) 254 request.Repeats = &repeats 255 256 if testSuite.Spec.ExecutionRequest != nil { 257 value := MapSpecExecutionRequestToExecutionUpdateRequest(testSuite.Spec.ExecutionRequest) 258 request.ExecutionRequest = &value 259 } 260 261 return request 262 } 263 264 func mapCRDToTestBatchSteps(in []testsuitesv3.TestSuiteBatchStep) (batches []testkube.TestSuiteBatchStep) { 265 for _, batch := range in { 266 steps := make([]testkube.TestSuiteStep, len(batch.Execute)) 267 for i := range batch.Execute { 268 steps[i] = mapCRStepToAPI(batch.Execute[i]) 269 } 270 271 batches = append(batches, testkube.TestSuiteBatchStep{ 272 StopOnFailure: batch.StopOnFailure, 273 Execute: steps, 274 }) 275 } 276 277 return batches 278 } 279 280 // MapSpecExecutionRequestToExecutionUpdateRequest maps ExecutionRequest CRD spec to ExecutionUpdateRequest OpenAPI spec 281 func MapSpecExecutionRequestToExecutionUpdateRequest(request *testsuitesv3.TestSuiteExecutionRequest) (executionRequest *testkube.TestSuiteExecutionUpdateRequest) { 282 executionRequest = &testkube.TestSuiteExecutionUpdateRequest{} 283 284 var fields = []struct { 285 source *string 286 destination **string 287 }{ 288 { 289 &request.Name, 290 &executionRequest.Name, 291 }, 292 { 293 &request.Namespace, 294 &executionRequest.Namespace, 295 }, 296 { 297 &request.SecretUUID, 298 &executionRequest.SecretUUID, 299 }, 300 { 301 &request.HttpProxy, 302 &executionRequest.HttpProxy, 303 }, 304 { 305 &request.HttpsProxy, 306 &executionRequest.HttpsProxy, 307 }, 308 { 309 &request.JobTemplate, 310 &executionRequest.JobTemplate, 311 }, 312 { 313 &request.JobTemplateReference, 314 &executionRequest.JobTemplateReference, 315 }, 316 { 317 &request.CronJobTemplate, 318 &executionRequest.CronJobTemplate, 319 }, 320 { 321 &request.CronJobTemplateReference, 322 &executionRequest.CronJobTemplateReference, 323 }, 324 { 325 &request.PvcTemplate, 326 &executionRequest.PvcTemplate, 327 }, 328 { 329 &request.PvcTemplateReference, 330 &executionRequest.PvcTemplateReference, 331 }, 332 { 333 &request.ScraperTemplate, 334 &executionRequest.ScraperTemplate, 335 }, 336 { 337 &request.ScraperTemplateReference, 338 &executionRequest.ScraperTemplateReference, 339 }, 340 } 341 342 for _, field := range fields { 343 *field.destination = field.source 344 } 345 346 executionRequest.Labels = &request.Labels 347 348 executionRequest.ExecutionLabels = &request.ExecutionLabels 349 350 executionRequest.Sync = &request.Sync 351 352 executionRequest.Timeout = &request.Timeout 353 354 vars := MergeVariablesAndParams(request.Variables, nil) 355 executionRequest.Variables = &vars 356 357 return executionRequest 358 } 359 360 func MapTestStepExecutionRequestCRDToAPI(request *testsuitesv3.TestSuiteStepExecutionRequest) *testkube.TestSuiteStepExecutionRequest { 361 if request == nil { 362 return nil 363 } 364 variables := map[string]testkube.Variable{} 365 for k, v := range request.Variables { 366 varType := testkube.VariableType(v.Type_) 367 variables[k] = testkube.Variable{ 368 Name: v.Name, 369 Value: v.Value, 370 Type_: &varType, 371 } 372 } 373 374 var runningContext *testkube.RunningContext 375 376 if request.RunningContext != nil { 377 runningContext = &testkube.RunningContext{ 378 Type_: string(request.RunningContext.Type_), 379 Context: request.RunningContext.Context, 380 } 381 } 382 383 argsMode := "" 384 if request.ArgsMode != "" { 385 argsMode = string(request.ArgsMode) 386 } 387 388 return &testkube.TestSuiteStepExecutionRequest{ 389 ExecutionLabels: request.ExecutionLabels, 390 Variables: variables, 391 Command: request.Command, 392 Args: request.Args, 393 ArgsMode: argsMode, 394 Sync: request.Sync, 395 HttpProxy: request.HttpProxy, 396 HttpsProxy: request.HttpsProxy, 397 NegativeTest: request.NegativeTest, 398 JobTemplate: request.JobTemplate, 399 JobTemplateReference: request.JobTemplateReference, 400 CronJobTemplate: request.CronJobTemplate, 401 CronJobTemplateReference: request.CronJobTemplateReference, 402 ScraperTemplate: request.ScraperTemplate, 403 ScraperTemplateReference: request.ScraperTemplateReference, 404 PvcTemplate: request.PvcTemplate, 405 PvcTemplateReference: request.PvcTemplateReference, 406 RunningContext: runningContext, 407 } 408 }