github.com/kubeshop/testkube@v1.17.23/pkg/mapper/tests/openapi_kube.go (about)

     1  package tests
     2  
     3  import (
     4  	corev1 "k8s.io/api/core/v1"
     5  	v1 "k8s.io/api/core/v1"
     6  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
     7  
     8  	testsv3 "github.com/kubeshop/testkube-operator/api/tests/v3"
     9  	"github.com/kubeshop/testkube/pkg/api/v1/testkube"
    10  	mappertcl "github.com/kubeshop/testkube/pkg/tcl/mappertcl/tests"
    11  )
    12  
    13  // MapUpsertToSpec maps TestUpsertRequest to Test CRD spec
    14  func MapUpsertToSpec(request testkube.TestUpsertRequest) *testsv3.Test {
    15  
    16  	test := &testsv3.Test{
    17  		ObjectMeta: metav1.ObjectMeta{
    18  			Name:      request.Name,
    19  			Namespace: request.Namespace,
    20  			Labels:    request.Labels,
    21  		},
    22  		Spec: testsv3.TestSpec{
    23  			Description:      request.Description,
    24  			Type_:            request.Type_,
    25  			Content:          MapContentToSpecContent(request.Content),
    26  			Source:           request.Source,
    27  			Schedule:         request.Schedule,
    28  			ExecutionRequest: MapExecutionRequestToSpecExecutionRequest(request.ExecutionRequest),
    29  			Uploads:          request.Uploads,
    30  		},
    31  	}
    32  
    33  	return test
    34  
    35  }
    36  
    37  // @Depracated
    38  // MapDepratcatedParams maps old params to new variables data structure
    39  func MapDepratcatedParams(in map[string]testkube.Variable) map[string]string {
    40  	out := map[string]string{}
    41  	for k, v := range in {
    42  		out[k] = v.Value
    43  	}
    44  	return out
    45  }
    46  
    47  // MapCRDVariables maps variables between API and operator CRDs
    48  func MapCRDVariables(in map[string]testkube.Variable) map[string]testsv3.Variable {
    49  	out := map[string]testsv3.Variable{}
    50  	for k, v := range in {
    51  		variable := testsv3.Variable{
    52  			Name:  v.Name,
    53  			Type_: string(*v.Type_),
    54  			Value: v.Value,
    55  		}
    56  
    57  		if v.SecretRef != nil {
    58  			variable.ValueFrom = corev1.EnvVarSource{
    59  				SecretKeyRef: &corev1.SecretKeySelector{
    60  					LocalObjectReference: corev1.LocalObjectReference{
    61  						Name: v.SecretRef.Name,
    62  					},
    63  					Key: v.SecretRef.Key,
    64  				},
    65  			}
    66  		}
    67  
    68  		if v.ConfigMapRef != nil {
    69  			variable.ValueFrom = corev1.EnvVarSource{
    70  				ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
    71  					LocalObjectReference: corev1.LocalObjectReference{
    72  						Name: v.ConfigMapRef.Name,
    73  					},
    74  					Key: v.ConfigMapRef.Key,
    75  				},
    76  			}
    77  		}
    78  
    79  		out[k] = variable
    80  	}
    81  	return out
    82  }
    83  
    84  // MapContentToSpecContent maps TestContent OpenAPI spec to TestContent CRD spec
    85  func MapContentToSpecContent(content *testkube.TestContent) (specContent *testsv3.TestContent) {
    86  	if content == nil {
    87  		return
    88  	}
    89  
    90  	var repository *testsv3.Repository
    91  	if content.Repository != nil && !content.Repository.IsEmpty() {
    92  		repository = &testsv3.Repository{
    93  			Type_:             content.Repository.Type_,
    94  			Uri:               content.Repository.Uri,
    95  			Branch:            content.Repository.Branch,
    96  			Commit:            content.Repository.Commit,
    97  			Path:              content.Repository.Path,
    98  			WorkingDir:        content.Repository.WorkingDir,
    99  			CertificateSecret: content.Repository.CertificateSecret,
   100  			AuthType:          testsv3.GitAuthType(content.Repository.AuthType),
   101  		}
   102  
   103  		if content.Repository.UsernameSecret != nil && !content.Repository.UsernameSecret.IsEmpty() {
   104  			repository.UsernameSecret = &testsv3.SecretRef{
   105  				Name: content.Repository.UsernameSecret.Name,
   106  				Key:  content.Repository.UsernameSecret.Key,
   107  			}
   108  		}
   109  
   110  		if content.Repository.TokenSecret != nil && !content.Repository.TokenSecret.IsEmpty() {
   111  			repository.TokenSecret = &testsv3.SecretRef{
   112  				Name: content.Repository.TokenSecret.Name,
   113  				Key:  content.Repository.TokenSecret.Key,
   114  			}
   115  		}
   116  	}
   117  
   118  	return &testsv3.TestContent{
   119  		Repository: repository,
   120  		Data:       content.Data,
   121  		Uri:        content.Uri,
   122  		Type_:      testsv3.TestContentType(content.Type_),
   123  	}
   124  }
   125  
   126  // MapExecutionRequestToSpecExecutionRequest maps ExecutionRequest OpenAPI spec to ExecutionRequest CRD spec
   127  func MapExecutionRequestToSpecExecutionRequest(executionRequest *testkube.ExecutionRequest) *testsv3.ExecutionRequest {
   128  	if executionRequest == nil {
   129  		return nil
   130  	}
   131  
   132  	var artifactRequest *testsv3.ArtifactRequest
   133  	if executionRequest.ArtifactRequest != nil {
   134  		artifactRequest = &testsv3.ArtifactRequest{
   135  			StorageClassName:           executionRequest.ArtifactRequest.StorageClassName,
   136  			VolumeMountPath:            executionRequest.ArtifactRequest.VolumeMountPath,
   137  			Dirs:                       executionRequest.ArtifactRequest.Dirs,
   138  			Masks:                      executionRequest.ArtifactRequest.Masks,
   139  			StorageBucket:              executionRequest.ArtifactRequest.StorageBucket,
   140  			OmitFolderPerExecution:     executionRequest.ArtifactRequest.OmitFolderPerExecution,
   141  			SharedBetweenPods:          executionRequest.ArtifactRequest.SharedBetweenPods,
   142  			UseDefaultStorageClassName: executionRequest.ArtifactRequest.UseDefaultStorageClassName,
   143  		}
   144  	}
   145  
   146  	var podRequest *testsv3.PodRequest
   147  	if executionRequest.SlavePodRequest != nil {
   148  		podRequest = &testsv3.PodRequest{}
   149  		if executionRequest.SlavePodRequest.Resources != nil {
   150  			podRequest.Resources = &testsv3.PodResourcesRequest{}
   151  			if executionRequest.SlavePodRequest.Resources.Requests != nil {
   152  				podRequest.Resources.Requests = &testsv3.ResourceRequest{
   153  					Cpu:    executionRequest.SlavePodRequest.Resources.Requests.Cpu,
   154  					Memory: executionRequest.SlavePodRequest.Resources.Requests.Memory,
   155  				}
   156  			}
   157  
   158  			if executionRequest.SlavePodRequest.Resources.Limits != nil {
   159  				podRequest.Resources.Limits = &testsv3.ResourceRequest{
   160  					Cpu:    executionRequest.SlavePodRequest.Resources.Limits.Cpu,
   161  					Memory: executionRequest.SlavePodRequest.Resources.Limits.Memory,
   162  				}
   163  			}
   164  		}
   165  
   166  		podRequest.PodTemplate = executionRequest.SlavePodRequest.PodTemplate
   167  		podRequest.PodTemplateReference = executionRequest.SlavePodRequest.PodTemplateReference
   168  	}
   169  
   170  	result := &testsv3.ExecutionRequest{
   171  		Name:                               executionRequest.Name,
   172  		TestSuiteName:                      executionRequest.TestSuiteName,
   173  		Number:                             executionRequest.Number,
   174  		ExecutionLabels:                    executionRequest.ExecutionLabels,
   175  		Namespace:                          executionRequest.Namespace,
   176  		IsVariablesFileUploaded:            executionRequest.IsVariablesFileUploaded,
   177  		VariablesFile:                      executionRequest.VariablesFile,
   178  		Variables:                          MapCRDVariables(executionRequest.Variables),
   179  		TestSecretUUID:                     executionRequest.TestSecretUUID,
   180  		TestSuiteSecretUUID:                executionRequest.TestSuiteSecretUUID,
   181  		Args:                               executionRequest.Args,
   182  		ArgsMode:                           testsv3.ArgsModeType(executionRequest.ArgsMode),
   183  		Envs:                               executionRequest.Envs,
   184  		SecretEnvs:                         executionRequest.SecretEnvs,
   185  		Sync:                               executionRequest.Sync,
   186  		HttpProxy:                          executionRequest.HttpProxy,
   187  		HttpsProxy:                         executionRequest.HttpsProxy,
   188  		Image:                              executionRequest.Image,
   189  		ImagePullSecrets:                   mapImagePullSecrets(executionRequest.ImagePullSecrets),
   190  		ActiveDeadlineSeconds:              executionRequest.ActiveDeadlineSeconds,
   191  		Command:                            executionRequest.Command,
   192  		ArtifactRequest:                    artifactRequest,
   193  		JobTemplate:                        executionRequest.JobTemplate,
   194  		JobTemplateReference:               executionRequest.JobTemplateReference,
   195  		CronJobTemplate:                    executionRequest.CronJobTemplate,
   196  		CronJobTemplateReference:           executionRequest.CronJobTemplateReference,
   197  		PreRunScript:                       executionRequest.PreRunScript,
   198  		PostRunScript:                      executionRequest.PostRunScript,
   199  		ExecutePostRunScriptBeforeScraping: executionRequest.ExecutePostRunScriptBeforeScraping,
   200  		SourceScripts:                      executionRequest.SourceScripts,
   201  		PvcTemplate:                        executionRequest.PvcTemplate,
   202  		PvcTemplateReference:               executionRequest.PvcTemplateReference,
   203  		ScraperTemplate:                    executionRequest.ScraperTemplate,
   204  		ScraperTemplateReference:           executionRequest.ScraperTemplateReference,
   205  		NegativeTest:                       executionRequest.NegativeTest,
   206  		EnvConfigMaps:                      mapEnvReferences(executionRequest.EnvConfigMaps),
   207  		EnvSecrets:                         mapEnvReferences(executionRequest.EnvSecrets),
   208  		SlavePodRequest:                    podRequest,
   209  	}
   210  
   211  	// Pro edition only (tcl protected code)
   212  	return mappertcl.MapExecutionRequestToSpecExecutionRequest(executionRequest, result)
   213  }
   214  
   215  func mapImagePullSecrets(secrets []testkube.LocalObjectReference) (res []v1.LocalObjectReference) {
   216  	for _, secret := range secrets {
   217  		res = append(res, v1.LocalObjectReference{Name: secret.Name})
   218  	}
   219  	return res
   220  }
   221  
   222  func mapEnvReferences(envs []testkube.EnvReference) []testsv3.EnvReference {
   223  	if envs == nil {
   224  		return nil
   225  	}
   226  	var res []testsv3.EnvReference
   227  	for _, env := range envs {
   228  		if env.Reference == nil {
   229  			continue
   230  		}
   231  
   232  		res = append(res, testsv3.EnvReference{
   233  			LocalObjectReference: v1.LocalObjectReference{
   234  				Name: env.Reference.Name,
   235  			},
   236  			Mount:          env.Mount,
   237  			MountPath:      env.MountPath,
   238  			MapToVariables: env.MapToVariables,
   239  		})
   240  	}
   241  
   242  	return res
   243  }
   244  
   245  // MapUpdateToSpec maps TestUpdateRequest to Test CRD spec
   246  func MapUpdateToSpec(request testkube.TestUpdateRequest, test *testsv3.Test) *testsv3.Test {
   247  	var fields = []struct {
   248  		source      *string
   249  		destination *string
   250  	}{
   251  		{
   252  			request.Name,
   253  			&test.Name,
   254  		},
   255  		{
   256  			request.Namespace,
   257  			&test.Namespace,
   258  		},
   259  		{
   260  			request.Description,
   261  			&test.Spec.Description,
   262  		},
   263  		{
   264  			request.Type_,
   265  			&test.Spec.Type_,
   266  		},
   267  		{
   268  			request.Source,
   269  			&test.Spec.Source,
   270  		},
   271  		{
   272  			request.Schedule,
   273  			&test.Spec.Schedule,
   274  		},
   275  	}
   276  
   277  	for _, field := range fields {
   278  		if field.source != nil {
   279  			*field.destination = *field.source
   280  		}
   281  	}
   282  
   283  	if request.Content != nil {
   284  		test.Spec.Content = MapUpdateContentToSpecContent(*request.Content, test.Spec.Content)
   285  	}
   286  
   287  	if request.ExecutionRequest != nil {
   288  		test.Spec.ExecutionRequest = MapExecutionUpdateRequestToSpecExecutionRequest(*request.ExecutionRequest, test.Spec.ExecutionRequest)
   289  	}
   290  
   291  	if request.Labels != nil {
   292  		test.Labels = *request.Labels
   293  	}
   294  
   295  	if request.Uploads != nil {
   296  		test.Spec.Uploads = *request.Uploads
   297  	}
   298  
   299  	return test
   300  }
   301  
   302  // MapUpdateContentToSpecContent maps TestUpdateContent OpenAPI spec to TestContent CRD spec
   303  func MapUpdateContentToSpecContent(content *testkube.TestContentUpdate, testContent *testsv3.TestContent) *testsv3.TestContent {
   304  	if content == nil {
   305  		return nil
   306  	}
   307  
   308  	if testContent == nil {
   309  		testContent = &testsv3.TestContent{}
   310  	}
   311  
   312  	emptyContent := true
   313  	var fields = []struct {
   314  		source      *string
   315  		destination *string
   316  	}{
   317  		{
   318  			content.Data,
   319  			&testContent.Data,
   320  		},
   321  		{
   322  			content.Uri,
   323  			&testContent.Uri,
   324  		},
   325  	}
   326  
   327  	for _, field := range fields {
   328  		if field.source != nil {
   329  			*field.destination = *field.source
   330  			emptyContent = false
   331  		}
   332  	}
   333  
   334  	if content.Type_ != nil {
   335  		testContent.Type_ = testsv3.TestContentType(*content.Type_)
   336  		emptyContent = false
   337  	}
   338  
   339  	if content.Repository != nil {
   340  		if *content.Repository == nil {
   341  			testContent.Repository = nil
   342  			return testContent
   343  		}
   344  
   345  		if (*content.Repository).IsEmpty() {
   346  			testContent.Repository = nil
   347  			return testContent
   348  		}
   349  
   350  		if testContent.Repository == nil {
   351  			testContent.Repository = &testsv3.Repository{}
   352  		}
   353  
   354  		emptyRepository := true
   355  		fake := ""
   356  		var fields = []struct {
   357  			source      *string
   358  			destination *string
   359  		}{
   360  			{
   361  				(*content.Repository).Type_,
   362  				&testContent.Repository.Type_,
   363  			},
   364  			{
   365  				(*content.Repository).Uri,
   366  				&testContent.Repository.Uri,
   367  			},
   368  			{
   369  				(*content.Repository).Branch,
   370  				&testContent.Repository.Branch,
   371  			},
   372  			{
   373  				(*content.Repository).Commit,
   374  				&testContent.Repository.Commit,
   375  			},
   376  			{
   377  				(*content.Repository).Path,
   378  				&testContent.Repository.Path,
   379  			},
   380  			{
   381  				(*content.Repository).WorkingDir,
   382  				&testContent.Repository.WorkingDir,
   383  			},
   384  			{
   385  				(*content.Repository).CertificateSecret,
   386  				&testContent.Repository.CertificateSecret,
   387  			},
   388  			{
   389  				(*content.Repository).Username,
   390  				&fake,
   391  			},
   392  			{
   393  				(*content.Repository).Token,
   394  				&fake,
   395  			},
   396  		}
   397  
   398  		for _, field := range fields {
   399  			if field.source != nil {
   400  				*field.destination = *field.source
   401  				emptyRepository = false
   402  			}
   403  		}
   404  
   405  		if (*content.Repository).AuthType != nil {
   406  			testContent.Repository.AuthType = testsv3.GitAuthType(*(*content.Repository).AuthType)
   407  			emptyRepository = false
   408  		}
   409  
   410  		if (*content.Repository).UsernameSecret != nil {
   411  			if (*(*content.Repository).UsernameSecret).IsEmpty() {
   412  				testContent.Repository.UsernameSecret = nil
   413  			} else {
   414  				testContent.Repository.UsernameSecret = &testsv3.SecretRef{
   415  					Name: (*(*content.Repository).UsernameSecret).Name,
   416  					Key:  (*(*content.Repository).UsernameSecret).Key,
   417  				}
   418  			}
   419  
   420  			emptyRepository = false
   421  		}
   422  
   423  		if (*content.Repository).TokenSecret != nil {
   424  			if (*(*content.Repository).TokenSecret).IsEmpty() {
   425  				testContent.Repository.TokenSecret = nil
   426  			} else {
   427  				testContent.Repository.TokenSecret = &testsv3.SecretRef{
   428  					Name: (*(*content.Repository).TokenSecret).Name,
   429  					Key:  (*(*content.Repository).TokenSecret).Key,
   430  				}
   431  			}
   432  
   433  			emptyRepository = false
   434  		}
   435  
   436  		if emptyRepository {
   437  			testContent.Repository = nil
   438  		} else {
   439  			emptyContent = false
   440  		}
   441  	}
   442  
   443  	if emptyContent {
   444  		return nil
   445  	}
   446  
   447  	return testContent
   448  }
   449  
   450  // MapExecutionUpdateRequestToSpecExecutionRequest maps ExecutionUpdateRequest OpenAPI spec to ExecutionRequest CRD spec
   451  func MapExecutionUpdateRequestToSpecExecutionRequest(executionRequest *testkube.ExecutionUpdateRequest,
   452  	request *testsv3.ExecutionRequest) *testsv3.ExecutionRequest {
   453  	if executionRequest == nil {
   454  		return nil
   455  	}
   456  
   457  	if request == nil {
   458  		request = &testsv3.ExecutionRequest{}
   459  	}
   460  
   461  	emptyExecution := true
   462  	var fields = []struct {
   463  		source      *string
   464  		destination *string
   465  	}{
   466  		{
   467  			executionRequest.Name,
   468  			&request.Name,
   469  		},
   470  		{
   471  			executionRequest.TestSuiteName,
   472  			&request.TestSuiteName,
   473  		},
   474  		{
   475  			executionRequest.Namespace,
   476  			&request.Namespace,
   477  		},
   478  		{
   479  			executionRequest.VariablesFile,
   480  			&request.VariablesFile,
   481  		},
   482  		{
   483  			executionRequest.TestSecretUUID,
   484  			&request.TestSecretUUID,
   485  		},
   486  		{
   487  			executionRequest.TestSuiteSecretUUID,
   488  			&request.TestSuiteSecretUUID,
   489  		},
   490  		{
   491  			executionRequest.HttpProxy,
   492  			&request.HttpProxy,
   493  		},
   494  		{
   495  			executionRequest.HttpsProxy,
   496  			&request.HttpsProxy,
   497  		},
   498  		{
   499  			executionRequest.Image,
   500  			&request.Image,
   501  		},
   502  		{
   503  			executionRequest.JobTemplate,
   504  			&request.JobTemplate,
   505  		},
   506  		{
   507  			executionRequest.JobTemplateReference,
   508  			&request.JobTemplateReference,
   509  		},
   510  		{
   511  			executionRequest.PreRunScript,
   512  			&request.PreRunScript,
   513  		},
   514  		{
   515  			executionRequest.PostRunScript,
   516  			&request.PostRunScript,
   517  		},
   518  		{
   519  			executionRequest.CronJobTemplate,
   520  			&request.CronJobTemplate,
   521  		},
   522  		{
   523  			executionRequest.CronJobTemplateReference,
   524  			&request.CronJobTemplateReference,
   525  		},
   526  		{
   527  			executionRequest.PvcTemplate,
   528  			&request.PvcTemplate,
   529  		},
   530  		{
   531  			executionRequest.PvcTemplateReference,
   532  			&request.PvcTemplateReference,
   533  		},
   534  		{
   535  			executionRequest.ScraperTemplate,
   536  			&request.ScraperTemplate,
   537  		},
   538  		{
   539  			executionRequest.ScraperTemplateReference,
   540  			&request.ScraperTemplateReference,
   541  		},
   542  	}
   543  
   544  	for _, field := range fields {
   545  		if field.source != nil {
   546  			*field.destination = *field.source
   547  			emptyExecution = false
   548  		}
   549  	}
   550  
   551  	if executionRequest.ArgsMode != nil {
   552  		request.ArgsMode = testsv3.ArgsModeType(*executionRequest.ArgsMode)
   553  		emptyExecution = false
   554  	}
   555  
   556  	var slices = []struct {
   557  		source      *map[string]string
   558  		destination *map[string]string
   559  	}{
   560  		{
   561  			executionRequest.ExecutionLabels,
   562  			&request.ExecutionLabels,
   563  		},
   564  		{
   565  			executionRequest.Envs,
   566  			&request.Envs,
   567  		},
   568  		{
   569  			executionRequest.SecretEnvs,
   570  			&request.SecretEnvs,
   571  		},
   572  	}
   573  
   574  	for _, slice := range slices {
   575  		if slice.source != nil {
   576  			*slice.destination = *slice.source
   577  			emptyExecution = false
   578  		}
   579  	}
   580  
   581  	if executionRequest.Number != nil {
   582  		request.Number = *executionRequest.Number
   583  		emptyExecution = false
   584  	}
   585  
   586  	if executionRequest.Sync != nil {
   587  		request.Sync = *executionRequest.Sync
   588  		emptyExecution = false
   589  	}
   590  
   591  	if executionRequest.NegativeTest != nil {
   592  		request.NegativeTest = *executionRequest.NegativeTest
   593  		emptyExecution = false
   594  	}
   595  
   596  	if executionRequest.ActiveDeadlineSeconds != nil {
   597  		request.ActiveDeadlineSeconds = *executionRequest.ActiveDeadlineSeconds
   598  		emptyExecution = false
   599  	}
   600  
   601  	if executionRequest.Args != nil {
   602  		request.Args = *executionRequest.Args
   603  		emptyExecution = false
   604  	}
   605  
   606  	if executionRequest.Command != nil {
   607  		request.Command = *executionRequest.Command
   608  		emptyExecution = false
   609  	}
   610  
   611  	if executionRequest.Variables != nil {
   612  		request.Variables = MapCRDVariables(*executionRequest.Variables)
   613  		emptyExecution = false
   614  	}
   615  
   616  	if executionRequest.ImagePullSecrets != nil {
   617  		request.ImagePullSecrets = mapImagePullSecrets(*executionRequest.ImagePullSecrets)
   618  		emptyExecution = false
   619  	}
   620  
   621  	if executionRequest.EnvConfigMaps != nil {
   622  		request.EnvConfigMaps = mapEnvReferences(*executionRequest.EnvConfigMaps)
   623  		emptyExecution = false
   624  	}
   625  
   626  	if executionRequest.EnvSecrets != nil {
   627  		request.EnvSecrets = mapEnvReferences(*executionRequest.EnvSecrets)
   628  		emptyExecution = false
   629  	}
   630  
   631  	if executionRequest.ExecutePostRunScriptBeforeScraping != nil {
   632  		request.ExecutePostRunScriptBeforeScraping = *executionRequest.ExecutePostRunScriptBeforeScraping
   633  		emptyExecution = false
   634  	}
   635  
   636  	// Pro edition only (tcl protected code)
   637  	if !mappertcl.MapExecutionUpdateRequestToSpecExecutionRequest(executionRequest, request) {
   638  		emptyExecution = false
   639  	}
   640  
   641  	if executionRequest.SourceScripts != nil {
   642  		request.SourceScripts = *executionRequest.SourceScripts
   643  	}
   644  
   645  	if executionRequest.ArtifactRequest != nil {
   646  		emptyArtifact := true
   647  		if !(*executionRequest.ArtifactRequest == nil || (*executionRequest.ArtifactRequest).IsEmpty()) {
   648  			if request.ArtifactRequest == nil {
   649  				request.ArtifactRequest = &testsv3.ArtifactRequest{}
   650  			}
   651  
   652  			if (*executionRequest.ArtifactRequest).StorageClassName != nil {
   653  				request.ArtifactRequest.StorageClassName = *(*executionRequest.ArtifactRequest).StorageClassName
   654  				emptyArtifact = false
   655  			}
   656  
   657  			if (*executionRequest.ArtifactRequest).VolumeMountPath != nil {
   658  				request.ArtifactRequest.VolumeMountPath = *(*executionRequest.ArtifactRequest).VolumeMountPath
   659  				emptyArtifact = false
   660  			}
   661  
   662  			if (*executionRequest.ArtifactRequest).Dirs != nil {
   663  				request.ArtifactRequest.Dirs = *(*executionRequest.ArtifactRequest).Dirs
   664  				emptyArtifact = false
   665  			}
   666  
   667  			if (*executionRequest.ArtifactRequest).Masks != nil {
   668  				request.ArtifactRequest.Masks = *(*executionRequest.ArtifactRequest).Masks
   669  				emptyArtifact = false
   670  			}
   671  
   672  			if (*executionRequest.ArtifactRequest).StorageBucket != nil {
   673  				request.ArtifactRequest.StorageBucket = *(*executionRequest.ArtifactRequest).StorageBucket
   674  				emptyArtifact = false
   675  			}
   676  
   677  			if (*executionRequest.ArtifactRequest).OmitFolderPerExecution != nil {
   678  				request.ArtifactRequest.OmitFolderPerExecution = *(*executionRequest.ArtifactRequest).OmitFolderPerExecution
   679  				emptyArtifact = false
   680  			}
   681  
   682  			if (*executionRequest.ArtifactRequest).SharedBetweenPods != nil {
   683  				request.ArtifactRequest.SharedBetweenPods = *(*executionRequest.ArtifactRequest).SharedBetweenPods
   684  				emptyArtifact = false
   685  			}
   686  
   687  			if (*executionRequest.ArtifactRequest).UseDefaultStorageClassName != nil {
   688  				request.ArtifactRequest.UseDefaultStorageClassName = *(*executionRequest.ArtifactRequest).UseDefaultStorageClassName
   689  				emptyArtifact = false
   690  			}
   691  		}
   692  
   693  		if emptyArtifact {
   694  			request.ArtifactRequest = nil
   695  		} else {
   696  			emptyExecution = false
   697  		}
   698  	}
   699  
   700  	if executionRequest.SlavePodRequest != nil {
   701  		emptyPodRequest := true
   702  		if !(*executionRequest.SlavePodRequest == nil || (*executionRequest.SlavePodRequest).IsEmpty()) {
   703  			if request.SlavePodRequest == nil {
   704  				request.SlavePodRequest = &testsv3.PodRequest{}
   705  			}
   706  
   707  			if (*executionRequest.SlavePodRequest).Resources != nil {
   708  				if request.SlavePodRequest.Resources == nil {
   709  					request.SlavePodRequest.Resources = &testsv3.PodResourcesRequest{}
   710  				}
   711  
   712  				if (*(*executionRequest.SlavePodRequest).Resources).Requests != nil {
   713  					if request.SlavePodRequest.Resources.Requests == nil {
   714  						request.SlavePodRequest.Resources.Requests = &testsv3.ResourceRequest{}
   715  					}
   716  
   717  					if (*(*executionRequest.SlavePodRequest).Resources).Requests.Cpu != nil {
   718  						request.SlavePodRequest.Resources.Requests.Cpu = *(*(*executionRequest.SlavePodRequest).Resources).Requests.Cpu
   719  						emptyPodRequest = false
   720  					}
   721  
   722  					if (*(*executionRequest.SlavePodRequest).Resources).Requests.Memory != nil {
   723  						request.SlavePodRequest.Resources.Requests.Memory = *(*(*executionRequest.SlavePodRequest).Resources).Requests.Memory
   724  						emptyPodRequest = false
   725  					}
   726  				}
   727  
   728  				if (*(*executionRequest.SlavePodRequest).Resources).Limits != nil {
   729  					if request.SlavePodRequest.Resources.Limits == nil {
   730  						request.SlavePodRequest.Resources.Limits = &testsv3.ResourceRequest{}
   731  					}
   732  
   733  					if (*(*executionRequest.SlavePodRequest).Resources).Limits.Cpu != nil {
   734  						request.SlavePodRequest.Resources.Limits.Cpu = *(*(*executionRequest.SlavePodRequest).Resources).Limits.Cpu
   735  						emptyPodRequest = false
   736  					}
   737  
   738  					if (*(*executionRequest.SlavePodRequest).Resources).Limits.Memory != nil {
   739  						request.SlavePodRequest.Resources.Limits.Memory = *(*(*executionRequest.SlavePodRequest).Resources).Limits.Memory
   740  						emptyPodRequest = false
   741  					}
   742  				}
   743  			}
   744  
   745  			if (*executionRequest.SlavePodRequest).PodTemplate != nil {
   746  				request.SlavePodRequest.PodTemplate = *(*executionRequest.SlavePodRequest).PodTemplate
   747  				emptyPodRequest = false
   748  			}
   749  
   750  			if (*executionRequest.SlavePodRequest).PodTemplateReference != nil {
   751  				request.SlavePodRequest.PodTemplateReference = *(*executionRequest.SlavePodRequest).PodTemplateReference
   752  				emptyPodRequest = false
   753  			}
   754  		}
   755  
   756  		if emptyPodRequest {
   757  			request.SlavePodRequest = nil
   758  		} else {
   759  			emptyExecution = false
   760  		}
   761  	}
   762  
   763  	if emptyExecution {
   764  		return nil
   765  	}
   766  
   767  	return request
   768  }
   769  
   770  // MapStatusToSpec maps OpenAPI spec TestStatus to CRD
   771  func MapStatusToSpec(testStatus *testkube.TestStatus) (specStatus testsv3.TestStatus) {
   772  	if testStatus == nil || testStatus.LatestExecution == nil {
   773  		return specStatus
   774  	}
   775  
   776  	specStatus.LatestExecution = &testsv3.ExecutionCore{
   777  		Id:     testStatus.LatestExecution.Id,
   778  		Number: testStatus.LatestExecution.Number,
   779  		Status: (*testsv3.ExecutionStatus)(testStatus.LatestExecution.Status),
   780  	}
   781  
   782  	specStatus.LatestExecution.StartTime.Time = testStatus.LatestExecution.StartTime
   783  	specStatus.LatestExecution.EndTime.Time = testStatus.LatestExecution.EndTime
   784  
   785  	return specStatus
   786  }
   787  
   788  // MapExecutionToTestStatus maps OpenAPI Execution to TestStatus CRD
   789  func MapExecutionToTestStatus(execution *testkube.Execution) (specStatus testsv3.TestStatus) {
   790  	specStatus.LatestExecution = &testsv3.ExecutionCore{
   791  		Id:     execution.Id,
   792  		Number: execution.Number,
   793  	}
   794  
   795  	if execution.ExecutionResult != nil {
   796  		specStatus.LatestExecution.Status = (*testsv3.ExecutionStatus)(execution.ExecutionResult.Status)
   797  	}
   798  
   799  	specStatus.LatestExecution.StartTime.Time = execution.StartTime
   800  	specStatus.LatestExecution.EndTime.Time = execution.EndTime
   801  
   802  	return specStatus
   803  }
   804  
   805  // MapTestSuiteExecutionStatusToExecutionStatus maps test suite execution status to execution status
   806  func MapTestSuiteExecutionStatusToExecutionStatus(testSuiteStatus *testkube.TestSuiteExecutionStatus) (
   807  	testStatus *testkube.ExecutionStatus) {
   808  	switch testSuiteStatus {
   809  	case testkube.TestSuiteExecutionStatusAborted:
   810  		testStatus = testkube.ExecutionStatusAborted
   811  	case testkube.TestSuiteExecutionStatusTimeout:
   812  		testStatus = testkube.ExecutionStatusTimeout
   813  	case testkube.TestSuiteExecutionStatusRunning:
   814  		testStatus = testkube.ExecutionStatusRunning
   815  	case testkube.TestSuiteExecutionStatusQueued:
   816  		testStatus = testkube.ExecutionStatusQueued
   817  	case testkube.TestSuiteExecutionStatusFailed:
   818  		testStatus = testkube.ExecutionStatusFailed
   819  	case testkube.TestSuiteExecutionStatusPassed:
   820  		testStatus = testkube.ExecutionStatusPassed
   821  
   822  	}
   823  
   824  	return testStatus
   825  }