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  }