From 7530e0523e3c3093e4fe2120b93395bae5ef5571 Mon Sep 17 00:00:00 2001 From: Vladislav Sukhin Date: Wed, 11 Dec 2024 16:26:03 +0300 Subject: [PATCH 01/20] feat: pvc config Signed-off-by: Vladislav Sukhin --- api/v1/testkube.yaml | 33 +++++++++++++++++++ ...test_workflow_independent_step_parallel.go | 1 + .../model_test_workflow_pvc_config.go | 23 +++++++++++++ .../v1/testkube/model_test_workflow_spec.go | 1 + .../model_test_workflow_step_parallel.go | 1 + .../model_test_workflow_template_spec.go | 1 + 6 files changed, 60 insertions(+) create mode 100644 pkg/api/v1/testkube/model_test_workflow_pvc_config.go diff --git a/api/v1/testkube.yaml b/api/v1/testkube.yaml index 50079b8db75..d6852fd61a1 100644 --- a/api/v1/testkube.yaml +++ b/api/v1/testkube.yaml @@ -8797,6 +8797,10 @@ components: $ref: "#/components/schemas/TestWorkflowEvent" execution: $ref: "#/components/schemas/TestWorkflowTagSchema" + pvcs: + type: object + additionalProperties: + $ref: "#/components/schemas/TestWorkflowPVCConfig" TestWorkflowTemplateSpec: type: object @@ -8835,6 +8839,10 @@ components: $ref: "#/components/schemas/TestWorkflowEvent" execution: $ref: "#/components/schemas/TestWorkflowTagSchema" + pvcs: + type: object + additionalProperties: + $ref: "#/components/schemas/TestWorkflowPVCConfig" TestWorkflowStepControl: type: object @@ -10588,6 +10596,31 @@ components: must be defined type: boolean + TestWorkflowPVCConfig: + type: object + properties: + shared: + description: Specify whether the PVC should be shared between test workflow pods + type: boolean + accessModes: + description: 'Access mode for claim storage. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes' + type: array + items: + type: string + volumeMode: + description: 'Volume mode indicates the consumption of the volume as either a filesystem or block device. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#volume-mode' + type: string + resources: + description: 'Resources required for PVC' + $ref: "#/components/schemas/TestWorkflowResources" + storageClassName: + description: 'Storage class name specifies the name of a StorageClass. More info: https://kubernetes.io/docs/concepts/storage/storage-classes/' + type: string + selector: + description: Only the volumes whose labels match the selector can be bound to the claim + $ref: "#/components/schemas/LabelSelector" + # # Errors # diff --git a/pkg/api/v1/testkube/model_test_workflow_independent_step_parallel.go b/pkg/api/v1/testkube/model_test_workflow_independent_step_parallel.go index ddb97dc54ce..a68339239ef 100644 --- a/pkg/api/v1/testkube/model_test_workflow_independent_step_parallel.go +++ b/pkg/api/v1/testkube/model_test_workflow_independent_step_parallel.go @@ -53,4 +53,5 @@ type TestWorkflowIndependentStepParallel struct { After []TestWorkflowIndependentStep `json:"after,omitempty"` Events []TestWorkflowEvent `json:"events,omitempty"` Execution *TestWorkflowTagSchema `json:"execution,omitempty"` + Pvcs map[string]TestWorkflowPvcConfig `json:"pvcs,omitempty"` } diff --git a/pkg/api/v1/testkube/model_test_workflow_pvc_config.go b/pkg/api/v1/testkube/model_test_workflow_pvc_config.go new file mode 100644 index 00000000000..d4ac765a78a --- /dev/null +++ b/pkg/api/v1/testkube/model_test_workflow_pvc_config.go @@ -0,0 +1,23 @@ +/* + * Testkube API + * + * Testkube provides a Kubernetes-native framework for test definition, execution and results + * + * API version: 1.0.0 + * Contact: testkube@kubeshop.io + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package testkube + +type TestWorkflowPvcConfig struct { + // Specify whether the PVC should be shared between test workflow pods + Shared bool `json:"shared,omitempty"` + // Access mode for claim storage. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes + AccessModes []string `json:"accessModes,omitempty"` + // Volume mode indicates the consumption of the volume as either a filesystem or block device. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#volume-mode + VolumeMode string `json:"volumeMode,omitempty"` + Resources *TestWorkflowResources `json:"resources,omitempty"` + // Storage class name specifies the name of a StorageClass. More info: https://kubernetes.io/docs/concepts/storage/storage-classes/ + StorageClassName string `json:"storageClassName,omitempty"` + Selector *LabelSelector `json:"selector,omitempty"` +} diff --git a/pkg/api/v1/testkube/model_test_workflow_spec.go b/pkg/api/v1/testkube/model_test_workflow_spec.go index 87a6c0e7ee8..f8a69366d4a 100644 --- a/pkg/api/v1/testkube/model_test_workflow_spec.go +++ b/pkg/api/v1/testkube/model_test_workflow_spec.go @@ -23,4 +23,5 @@ type TestWorkflowSpec struct { After []TestWorkflowStep `json:"after,omitempty"` Events []TestWorkflowEvent `json:"events,omitempty"` Execution *TestWorkflowTagSchema `json:"execution,omitempty"` + Pvcs map[string]TestWorkflowPvcConfig `json:"pvcs,omitempty"` } diff --git a/pkg/api/v1/testkube/model_test_workflow_step_parallel.go b/pkg/api/v1/testkube/model_test_workflow_step_parallel.go index 7c8a9ffcca7..d11b2e1d85a 100644 --- a/pkg/api/v1/testkube/model_test_workflow_step_parallel.go +++ b/pkg/api/v1/testkube/model_test_workflow_step_parallel.go @@ -55,4 +55,5 @@ type TestWorkflowStepParallel struct { After []TestWorkflowStep `json:"after,omitempty"` Events []TestWorkflowEvent `json:"events,omitempty"` Execution *TestWorkflowTagSchema `json:"execution,omitempty"` + Pvcs map[string]TestWorkflowPvcConfig `json:"pvcs,omitempty"` } diff --git a/pkg/api/v1/testkube/model_test_workflow_template_spec.go b/pkg/api/v1/testkube/model_test_workflow_template_spec.go index 17d16455a72..c1b9c34c401 100644 --- a/pkg/api/v1/testkube/model_test_workflow_template_spec.go +++ b/pkg/api/v1/testkube/model_test_workflow_template_spec.go @@ -22,4 +22,5 @@ type TestWorkflowTemplateSpec struct { After []TestWorkflowIndependentStep `json:"after,omitempty"` Events []TestWorkflowEvent `json:"events,omitempty"` Execution *TestWorkflowTagSchema `json:"execution,omitempty"` + Pvcs map[string]TestWorkflowPvcConfig `json:"pvcs,omitempty"` } From 6d67658ea0bf118a6c4a6d5023f43724860f93ef Mon Sep 17 00:00:00 2001 From: Vladislav Sukhin Date: Wed, 11 Dec 2024 17:17:37 +0300 Subject: [PATCH 02/20] fix: rename var Signed-off-by: Vladislav Sukhin --- api/v1/testkube.yaml | 10 +++++----- pkg/api/v1/testkube/model_test_workflow_pvc_config.go | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/api/v1/testkube.yaml b/api/v1/testkube.yaml index d6852fd61a1..0d98bd8a8df 100644 --- a/api/v1/testkube.yaml +++ b/api/v1/testkube.yaml @@ -8800,7 +8800,7 @@ components: pvcs: type: object additionalProperties: - $ref: "#/components/schemas/TestWorkflowPVCConfig" + $ref: "#/components/schemas/TestWorkflowPvcConfig" TestWorkflowTemplateSpec: type: object @@ -8842,7 +8842,7 @@ components: pvcs: type: object additionalProperties: - $ref: "#/components/schemas/TestWorkflowPVCConfig" + $ref: "#/components/schemas/TestWorkflowPvcConfig" TestWorkflowStepControl: type: object @@ -10596,11 +10596,11 @@ components: must be defined type: boolean - TestWorkflowPVCConfig: + TestWorkflowPvcConfig: type: object properties: shared: - description: Specify whether the PVC should be shared between test workflow pods + description: Specify whether the pvc should be shared between test workflow pods type: boolean accessModes: description: 'Access mode for claim storage. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes' @@ -10612,7 +10612,7 @@ components: More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#volume-mode' type: string resources: - description: 'Resources required for PVC' + description: 'Resources required for pvc' $ref: "#/components/schemas/TestWorkflowResources" storageClassName: description: 'Storage class name specifies the name of a StorageClass. More info: https://kubernetes.io/docs/concepts/storage/storage-classes/' diff --git a/pkg/api/v1/testkube/model_test_workflow_pvc_config.go b/pkg/api/v1/testkube/model_test_workflow_pvc_config.go index d4ac765a78a..8e7de8dfbf9 100644 --- a/pkg/api/v1/testkube/model_test_workflow_pvc_config.go +++ b/pkg/api/v1/testkube/model_test_workflow_pvc_config.go @@ -10,7 +10,7 @@ package testkube type TestWorkflowPvcConfig struct { - // Specify whether the PVC should be shared between test workflow pods + // Specify whether the pvc should be shared between test workflow pods Shared bool `json:"shared,omitempty"` // Access mode for claim storage. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes AccessModes []string `json:"accessModes,omitempty"` From 76ea394881b26b007ed9a99874b839bf1dde5eab Mon Sep 17 00:00:00 2001 From: Vladislav Sukhin Date: Wed, 11 Dec 2024 18:08:55 +0300 Subject: [PATCH 03/20] fix: dep update Signed-off-by: Vladislav Sukhin --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index f2e215d06b9..bdd0facf6c8 100644 --- a/go.mod +++ b/go.mod @@ -42,7 +42,7 @@ require ( github.com/keygen-sh/jsonapi-go v1.2.1 github.com/keygen-sh/keygen-go/v3 v3.2.0 github.com/kubepug/kubepug v1.7.1 - github.com/kubeshop/testkube-operator v1.17.55-0.20241118133003-70462ac10f4a + github.com/kubeshop/testkube-operator v1.17.55-0.20241211150637-26f07cccd389 github.com/minio/minio-go/v7 v7.0.66 github.com/montanaflynn/stats v0.7.1 github.com/moogar0880/problems v0.1.1 diff --git a/go.sum b/go.sum index 56f08fbd156..c4081dfec7b 100644 --- a/go.sum +++ b/go.sum @@ -336,8 +336,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kubepug/kubepug v1.7.1 h1:LKhfSxS8Y5mXs50v+3Lpyec+cogErDLcV7CMUuiaisw= github.com/kubepug/kubepug v1.7.1/go.mod h1:lv+HxD0oTFL7ZWjj0u6HKhMbbTIId3eG7aWIW0gyF8g= -github.com/kubeshop/testkube-operator v1.17.55-0.20241118133003-70462ac10f4a h1:xget2cwwqOL+K2Op9FPbMgfzj9lSVJAzZ9p48yxuFrE= -github.com/kubeshop/testkube-operator v1.17.55-0.20241118133003-70462ac10f4a/go.mod h1:P47tw1nKQFufdsZndyq2HG2MSa0zK/lU0XpRfZtEmIk= +github.com/kubeshop/testkube-operator v1.17.55-0.20241211150637-26f07cccd389 h1:dP8c/kJmIFzy6F07qG+Wmo3jq8dfEvjYcAItJHDyjJQ= +github.com/kubeshop/testkube-operator v1.17.55-0.20241211150637-26f07cccd389/go.mod h1:P47tw1nKQFufdsZndyq2HG2MSa0zK/lU0XpRfZtEmIk= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8LFgLN4= From 6b99bc4cac74bef6c56dc9182fc7cfbfa9f4e6a0 Mon Sep 17 00:00:00 2001 From: Vladislav Sukhin Date: Wed, 11 Dec 2024 18:38:40 +0300 Subject: [PATCH 04/20] fix: map pvc to api Signed-off-by: Vladislav Sukhin --- pkg/mapper/testworkflows/kube_openapi.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/pkg/mapper/testworkflows/kube_openapi.go b/pkg/mapper/testworkflows/kube_openapi.go index 9076451da8f..ac221087d21 100644 --- a/pkg/mapper/testworkflows/kube_openapi.go +++ b/pkg/mapper/testworkflows/kube_openapi.go @@ -915,6 +915,7 @@ func MapStepParallelKubeToAPI(v testworkflowsv1.StepParallel) testkube.TestWorkf Run: common.MapPtr(v.Run, MapStepRunKubeToAPI), Execute: common.MapPtr(v.Execute, MapStepExecuteKubeToAPI), Artifacts: common.MapPtr(v.Artifacts, MapStepArtifactsKubeToAPI), + Pvcs: common.MapMap(v.Pvcs, MapPvcConfigKubeToAPI), } } @@ -948,6 +949,7 @@ func MapIndependentStepParallelKubeToAPI(v testworkflowsv1.IndependentStepParall Run: common.MapPtr(v.Run, MapStepRunKubeToAPI), Execute: common.MapPtr(v.Execute, MapStepExecuteKubeToAPI), Artifacts: common.MapPtr(v.Artifacts, MapStepArtifactsKubeToAPI), + Pvcs: common.MapMap(v.Pvcs, MapPvcConfigKubeToAPI), } } @@ -1134,6 +1136,7 @@ func MapSpecKubeToAPI(v testworkflowsv1.TestWorkflowSpec) testkube.TestWorkflowS After: common.MapSlice(v.After, MapStepKubeToAPI), Events: common.MapSlice(v.Events, MapEventKubeToAPI), Execution: common.MapPtr(v.Execution, MapTestWorkflowTagSchemaKubeToAPI), + Pvcs: common.MapMap(v.Pvcs, MapPvcConfigKubeToAPI), } } @@ -1150,6 +1153,7 @@ func MapTemplateSpecKubeToAPI(v testworkflowsv1.TestWorkflowTemplateSpec) testku After: common.MapSlice(v.After, MapIndependentStepKubeToAPI), Events: common.MapSlice(v.Events, MapEventKubeToAPI), Execution: common.MapPtr(v.Execution, MapTestWorkflowTagSchemaKubeToAPI), + Pvcs: common.MapMap(v.Pvcs, MapPvcConfigKubeToAPI), } } @@ -1206,3 +1210,14 @@ func MapTestWorkflowTagSchemaKubeToAPI(v testworkflowsv1.TestWorkflowTagSchema) Tags: v.Tags, } } + +func MapPvcConfigKubeToAPI(v testworkflowsv1.TestWorkflowPvcConfig) testkube.TestWorkflowPvcConfig { + return testkube.TestWorkflowPvcConfig{ + Shared: v.Shared, + AccessModes: v.AccessModes, + VolumeMode: v.VolumeMode, + Resources: common.MapPtr(v.Resources, MapResourcesKubeToAPI), + StorageClassName: v.StorageClassName, + Selector: common.MapPtr(v.Selector, MapSelectorToAPI), + } +} From a7c36c054180be8c6e89b9523f9c053bb12abb80 Mon Sep 17 00:00:00 2001 From: Vladislav Sukhin Date: Wed, 11 Dec 2024 18:57:04 +0300 Subject: [PATCH 05/20] fix: map to kube Signed-off-by: Vladislav Sukhin --- pkg/mapper/testworkflows/openapi_kube.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/pkg/mapper/testworkflows/openapi_kube.go b/pkg/mapper/testworkflows/openapi_kube.go index 86b9bf7edee..ca78b436e5f 100644 --- a/pkg/mapper/testworkflows/openapi_kube.go +++ b/pkg/mapper/testworkflows/openapi_kube.go @@ -951,6 +951,7 @@ func MapStepParallelAPIToKube(v testkube.TestWorkflowStepParallel) testworkflows Setup: common.MapSlice(v.Setup, MapStepAPIToKube), Steps: common.MapSlice(v.Steps, MapStepAPIToKube), After: common.MapSlice(v.After, MapStepAPIToKube), + Pvcs: common.MapMap(v.Pvcs, MapPvcConfigAPIToKube), }, StepControl: testworkflowsv1.StepControl{ Paused: v.Paused, @@ -995,6 +996,7 @@ func MapIndependentStepParallelAPIToKube(v testkube.TestWorkflowIndependentStepP Setup: common.MapSlice(v.Setup, MapIndependentStepAPIToKube), Steps: common.MapSlice(v.Steps, MapIndependentStepAPIToKube), After: common.MapSlice(v.After, MapIndependentStepAPIToKube), + Pvcs: common.MapMap(v.Pvcs, MapPvcConfigAPIToKube), }, StepControl: testworkflowsv1.StepControl{ Paused: v.Paused, @@ -1234,6 +1236,7 @@ func MapSpecAPIToKube(v testkube.TestWorkflowSpec) testworkflowsv1.TestWorkflowS Setup: common.MapSlice(v.Setup, MapStepAPIToKube), Steps: common.MapSlice(v.Steps, MapStepAPIToKube), After: common.MapSlice(v.After, MapStepAPIToKube), + Pvcs: common.MapMap(v.Pvcs, MapPvcConfigAPIToKube), } } @@ -1253,6 +1256,7 @@ func MapTemplateSpecAPIToKube(v testkube.TestWorkflowTemplateSpec) testworkflows Setup: common.MapSlice(v.Setup, MapIndependentStepAPIToKube), Steps: common.MapSlice(v.Steps, MapIndependentStepAPIToKube), After: common.MapSlice(v.After, MapIndependentStepAPIToKube), + Pvcs: common.MapMap(v.Pvcs, MapPvcConfigAPIToKube), } } @@ -1485,3 +1489,14 @@ func MapTestWorkflowTagSchemaAPIToKube(v testkube.TestWorkflowTagSchema) testwor Tags: v.Tags, } } + +func MapPvcConfigAPIToKube(v testkube.TestWorkflowPvcConfig) testworkflowsv1.TestWorkflowPvcConfig { + return testworkflowsv1.TestWorkflowPvcConfig{ + Shared: v.Shared, + AccessModes: v.AccessModes, + VolumeMode: v.VolumeMode, + Resources: common.MapPtr(v.Resources, MapResourcesAPIToKube), + StorageClassName: v.StorageClassName, + Selector: common.MapPtr(v.Selector, MapLabelSelectorAPIToKube), + } +} From 8e8d073b1f646b9c21248260e6625b26cf9631ba Mon Sep 17 00:00:00 2001 From: Vladislav Sukhin Date: Wed, 11 Dec 2024 21:38:41 +0300 Subject: [PATCH 06/20] fix: add pvc to control plane Signed-off-by: Vladislav Sukhin --- .../testworkflowprocessor/bundle.go | 11 +++++++ .../testworkflowprocessor/intermediate.go | 16 +++++++-- .../testworkflowprocessor/processor.go | 11 +++++++ .../testworkflowresolver/apply.go | 1 + .../testworkflowresolver/merge.go | 33 +++++++++++++++++++ 5 files changed, 70 insertions(+), 2 deletions(-) diff --git a/pkg/testworkflows/testworkflowprocessor/bundle.go b/pkg/testworkflows/testworkflowprocessor/bundle.go index 84bfe8a6947..fb49754391e 100644 --- a/pkg/testworkflows/testworkflowprocessor/bundle.go +++ b/pkg/testworkflows/testworkflowprocessor/bundle.go @@ -27,6 +27,7 @@ type BundleOptions struct { type Bundle struct { Secrets []corev1.Secret ConfigMaps []corev1.ConfigMap + Pvcs []corev1.PersistentVolumeClaim Job batchv1.Job Signature []stage.Signature FullSignature []stage.Signature @@ -50,6 +51,9 @@ func (b *Bundle) SetGroupId(groupId string) { for i := range b.Secrets { AnnotateGroupId(&b.Secrets[i], groupId) } + for i := range b.Pvcs { + AnnotateGroupId(&b.Pvcs[i], groupId) + } } func (b *Bundle) Deploy(ctx context.Context, clientSet kubernetes.Interface, namespace string) (err error) { @@ -68,6 +72,13 @@ func (b *Bundle) Deploy(ctx context.Context, clientSet kubernetes.Interface, nam return errors.Wrap(err, "failed to deploy config maps") } } + for _, item := range b.Pvcs { + _, err = clientSet.CoreV1().PersistentVolumeClaims(namespace).Create(ctx, &item, metav1.CreateOptions{}) + if err != nil { + return errors.Wrap(err, "failed to deploy pvcs") + } + } + _, err = clientSet.BatchV1().Jobs(namespace).Create(ctx, &b.Job, metav1.CreateOptions{}) return errors.Wrap(err, "failed to deploy job") } diff --git a/pkg/testworkflows/testworkflowprocessor/intermediate.go b/pkg/testworkflows/testworkflowprocessor/intermediate.go index b92b268338a..7b43adeb040 100644 --- a/pkg/testworkflows/testworkflowprocessor/intermediate.go +++ b/pkg/testworkflows/testworkflowprocessor/intermediate.go @@ -21,6 +21,7 @@ type Intermediate interface { ConfigMaps() []corev1.ConfigMap Secrets() []corev1.Secret Volumes() []corev1.Volume + Pvcs() []corev1.PersistentVolumeClaim AppendJobConfig(cfg *testworkflowsv1.JobConfig) Intermediate AppendPodConfig(cfg *testworkflowsv1.PodConfig) Intermediate @@ -28,6 +29,7 @@ type Intermediate interface { AddConfigMap(configMap corev1.ConfigMap) Intermediate AddSecret(secret corev1.Secret) Intermediate AddVolume(volume corev1.Volume) Intermediate + AddPvc(pvc corev1.PersistentVolumeClaim) Intermediate AddEmptyDirVolume(source *corev1.EmptyDirVolumeSource, mountPath string) corev1.VolumeMount @@ -47,8 +49,9 @@ type intermediate struct { Job testworkflowsv1.JobConfig `expr:"include"` // Actual Kubernetes resources to use - Secs []corev1.Secret `expr:"force"` - Cfgs []corev1.ConfigMap `expr:"force"` + Secs []corev1.Secret `expr:"force"` + Cfgs []corev1.ConfigMap `expr:"force"` + Ps []corev1.PersistentVolumeClaim `expr:"force"` // Storing files Files ConfigMapFiles `expr:"include"` @@ -87,6 +90,10 @@ func (s *intermediate) Volumes() []corev1.Volume { return append(s.Pod.Volumes, s.Files.Volumes()...) } +func (s *intermediate) Pvcs() []corev1.PersistentVolumeClaim { + return s.Ps +} + func (s *intermediate) AppendJobConfig(cfg *testworkflowsv1.JobConfig) Intermediate { s.Job = *testworkflowresolver.MergeJobConfig(&s.Job, cfg) return s @@ -102,6 +109,11 @@ func (s *intermediate) AddVolume(volume corev1.Volume) Intermediate { return s } +func (s *intermediate) AddPvc(pvc corev1.PersistentVolumeClaim) Intermediate { + s.Ps = append(s.Ps, pvc) + return s +} + func (s *intermediate) AddConfigMap(configMap corev1.ConfigMap) Intermediate { s.Cfgs = append(s.Cfgs, configMap) return s diff --git a/pkg/testworkflows/testworkflowprocessor/processor.go b/pkg/testworkflows/testworkflowprocessor/processor.go index 1a0d460a69c..af5d881f9bb 100644 --- a/pkg/testworkflows/testworkflowprocessor/processor.go +++ b/pkg/testworkflows/testworkflowprocessor/processor.go @@ -162,6 +162,16 @@ func (p *processor) Bundle(ctx context.Context, workflow *testworkflowsv1.TestWo } } + // Finalize Pvcs + pvcs := layer.Pvcs() + for i := range pvcs { + AnnotateControlledBy(&pvcs[i], options.Config.Resource.RootId, options.Config.Resource.Id) + err = expressions.FinalizeForce(&pvcs[i], machines...) + if err != nil { + return nil, errors.Wrap(err, "finalizing Pvc") + } + } + // Finalize Secrets secrets := append(layer.Secrets(), options.Secrets...) for i := range secrets { @@ -420,6 +430,7 @@ func (p *processor) Bundle(ctx context.Context, workflow *testworkflowsv1.TestWo bundle = &Bundle{ ConfigMaps: configMaps, Secrets: secrets, + Pvcs: pvcs, Job: jobSpec, Signature: sig, FullSignature: fullSig, diff --git a/pkg/testworkflows/testworkflowresolver/apply.go b/pkg/testworkflows/testworkflowresolver/apply.go index a3afdc9ea84..03c8b67da43 100644 --- a/pkg/testworkflows/testworkflowresolver/apply.go +++ b/pkg/testworkflows/testworkflowresolver/apply.go @@ -69,6 +69,7 @@ func injectTemplateToSpec(spec *testworkflowsv1.TestWorkflowSpec, template testw spec.Services = MergeMap(common.MapMap(template.Spec.Services, ConvertIndependentServiceToService), spec.Services) spec.Container = MergeContainerConfig(template.Spec.Container, spec.Container) spec.System = MergeSystem(template.Spec.System, spec.System) + spec.Pvcs = MergeMap(template.Spec.Pvcs, spec.Pvcs) // Include the steps from the template setup := common.MapSlice(template.Spec.Setup, ConvertIndependentStepToStep) diff --git a/pkg/testworkflows/testworkflowresolver/merge.go b/pkg/testworkflows/testworkflowresolver/merge.go index 1d503f1b84c..51cdd08d0dd 100644 --- a/pkg/testworkflows/testworkflowresolver/merge.go +++ b/pkg/testworkflows/testworkflowresolver/merge.go @@ -12,6 +12,7 @@ import ( "maps" corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" testworkflowsv1 "github.com/kubeshop/testkube-operator/api/testworkflows/v1" "github.com/kubeshop/testkube/internal/common" @@ -414,3 +415,35 @@ func MergeTags(dst, src map[string]string) map[string]string { return dst } + +func MergePvcConfig(dst, include *testworkflowsv1.TestWorkflowPvcConfig) *testworkflowsv1.TestWorkflowPvcConfig { + if dst == nil { + return include + } else if include == nil { + return dst + } + if include.Shared { + dst.Shared = include.Shared + } + dst.AccessModes = append(dst.AccessModes, include.AccessModes...) + if include.VolumeMode != "" { + dst.VolumeMode = include.VolumeMode + } + dst.Resources = MergeResources(dst.Resources, include.Resources) + if include.StorageClassName != "" { + dst.StorageClassName = include.StorageClassName + } + dst.Selector = MergeLabelSelector(dst.Selector, include.Selector) + return dst +} + +func MergeLabelSelector(dst, include *metav1.LabelSelector) *metav1.LabelSelector { + if dst == nil { + return include + } else if include == nil { + return dst + } + dst.MatchLabels = common.MergeMaps(dst.MatchLabels, include.MatchLabels) + dst.MatchExpressions = append(dst.MatchExpressions, include.MatchExpressions...) + return dst +} From 3bbba2548e6386ad541bc56cb8bfe03cedd255f4 Mon Sep 17 00:00:00 2001 From: Vladislav Sukhin Date: Thu, 12 Dec 2024 13:22:03 +0300 Subject: [PATCH 07/20] cleanup pvcs Signed-off-by: Vladislav Sukhin --- .../executionworker/controller/cleanup.go | 14 ++++++++++ .../mock_intermediate.go | 28 +++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/pkg/testworkflows/executionworker/controller/cleanup.go b/pkg/testworkflows/executionworker/controller/cleanup.go index 1a6faa7d8b6..a70d7194ee9 100644 --- a/pkg/testworkflows/executionworker/controller/cleanup.go +++ b/pkg/testworkflows/executionworker/controller/cleanup.go @@ -57,6 +57,17 @@ func cleanupJobs(labelName string) func(ctx context.Context, clientSet kubernete } } +func cleanupPvcs(labelName string) func(ctx context.Context, clientSet kubernetes.Interface, namespace, id string) error { + return func(ctx context.Context, clientSet kubernetes.Interface, namespace, id string) error { + return clientSet.CoreV1().PersistentVolumeClaims(namespace).DeleteCollection(ctx, metav1.DeleteOptions{ + GracePeriodSeconds: common.Ptr(int64(0)), + PropagationPolicy: common.Ptr(metav1.DeletePropagationBackground), + }, metav1.ListOptions{ + LabelSelector: fmt.Sprintf("%s=%s", labelName, id), + }) + } +} + func Cleanup(ctx context.Context, clientSet kubernetes.Interface, namespace, id string) error { var errs []error var errsMu sync.Mutex @@ -70,6 +81,8 @@ func Cleanup(ctx context.Context, clientSet kubernetes.Interface, namespace, id cleanupConfigMaps(constants.ResourceIdLabelName), cleanupSecrets(constants.RootResourceIdLabelName), cleanupSecrets(constants.ResourceIdLabelName), + cleanupPvcs(constants.RootResourceIdLabelName), + cleanupPvcs(constants.ResourceIdLabelName), } wg.Add(len(ops)) for _, op := range ops { @@ -96,6 +109,7 @@ func CleanupGroup(ctx context.Context, clientSet kubernetes.Interface, namespace cleanupPods(constants.GroupIdLabelName), cleanupConfigMaps(constants.GroupIdLabelName), cleanupSecrets(constants.GroupIdLabelName), + cleanupPvcs(constants.GroupIdLabelName), } wg.Add(len(ops)) for _, op := range ops { diff --git a/pkg/testworkflows/testworkflowprocessor/mock_intermediate.go b/pkg/testworkflows/testworkflowprocessor/mock_intermediate.go index 119db5cbdbf..5d42526cf59 100644 --- a/pkg/testworkflows/testworkflowprocessor/mock_intermediate.go +++ b/pkg/testworkflows/testworkflowprocessor/mock_intermediate.go @@ -79,6 +79,20 @@ func (mr *MockIntermediateMockRecorder) AddEmptyDirVolume(arg0, arg1 interface{} return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddEmptyDirVolume", reflect.TypeOf((*MockIntermediate)(nil).AddEmptyDirVolume), arg0, arg1) } +// AddPvc mocks base method. +func (m *MockIntermediate) AddPvc(arg0 v10.PersistentVolumeClaim) Intermediate { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AddPvc", arg0) + ret0, _ := ret[0].(Intermediate) + return ret0 +} + +// AddPvc indicates an expected call of AddPvc. +func (mr *MockIntermediateMockRecorder) AddPvc(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddPvc", reflect.TypeOf((*MockIntermediate)(nil).AddPvc), arg0) +} + // AddSecret mocks base method. func (m *MockIntermediate) AddSecret(arg0 v10.Secret) Intermediate { m.ctrl.T.Helper() @@ -220,6 +234,20 @@ func (mr *MockIntermediateMockRecorder) PodConfig() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PodConfig", reflect.TypeOf((*MockIntermediate)(nil).PodConfig)) } +// Pvcs mocks base method. +func (m *MockIntermediate) Pvcs() []v10.PersistentVolumeClaim { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Pvcs") + ret0, _ := ret[0].([]v10.PersistentVolumeClaim) + return ret0 +} + +// Pvcs indicates an expected call of Pvcs. +func (mr *MockIntermediateMockRecorder) Pvcs() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Pvcs", reflect.TypeOf((*MockIntermediate)(nil).Pvcs)) +} + // Secrets mocks base method. func (m *MockIntermediate) Secrets() []v10.Secret { m.ctrl.T.Helper() From d9fcff8408e5eef7cc541d66543d1d2fb0b904da Mon Sep 17 00:00:00 2001 From: Vladislav Sukhin Date: Thu, 12 Dec 2024 14:49:44 +0300 Subject: [PATCH 08/20] fix: merge pvcs map Signed-off-by: Vladislav Sukhin --- .../testworkflowresolver/apply.go | 1 + .../testworkflowresolver/merge.go | 33 ------------------- 2 files changed, 1 insertion(+), 33 deletions(-) diff --git a/pkg/testworkflows/testworkflowresolver/apply.go b/pkg/testworkflows/testworkflowresolver/apply.go index 03c8b67da43..0808a09fda6 100644 --- a/pkg/testworkflows/testworkflowresolver/apply.go +++ b/pkg/testworkflows/testworkflowresolver/apply.go @@ -63,6 +63,7 @@ func injectTemplateToSpec(spec *testworkflowsv1.TestWorkflowSpec, template testw spec.Job = MergeJobConfig(template.Spec.Job, spec.Job) spec.Events = append(template.Spec.Events, spec.Events...) spec.Execution = MergeExecution(template.Spec.Execution, spec.Execution) + spec.Pvcs = MergeMap(template.Spec.Pvcs, spec.Pvcs) // Apply basic configuration spec.Content = MergeContent(template.Spec.Content, spec.Content) diff --git a/pkg/testworkflows/testworkflowresolver/merge.go b/pkg/testworkflows/testworkflowresolver/merge.go index 51cdd08d0dd..1d503f1b84c 100644 --- a/pkg/testworkflows/testworkflowresolver/merge.go +++ b/pkg/testworkflows/testworkflowresolver/merge.go @@ -12,7 +12,6 @@ import ( "maps" corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" testworkflowsv1 "github.com/kubeshop/testkube-operator/api/testworkflows/v1" "github.com/kubeshop/testkube/internal/common" @@ -415,35 +414,3 @@ func MergeTags(dst, src map[string]string) map[string]string { return dst } - -func MergePvcConfig(dst, include *testworkflowsv1.TestWorkflowPvcConfig) *testworkflowsv1.TestWorkflowPvcConfig { - if dst == nil { - return include - } else if include == nil { - return dst - } - if include.Shared { - dst.Shared = include.Shared - } - dst.AccessModes = append(dst.AccessModes, include.AccessModes...) - if include.VolumeMode != "" { - dst.VolumeMode = include.VolumeMode - } - dst.Resources = MergeResources(dst.Resources, include.Resources) - if include.StorageClassName != "" { - dst.StorageClassName = include.StorageClassName - } - dst.Selector = MergeLabelSelector(dst.Selector, include.Selector) - return dst -} - -func MergeLabelSelector(dst, include *metav1.LabelSelector) *metav1.LabelSelector { - if dst == nil { - return include - } else if include == nil { - return dst - } - dst.MatchLabels = common.MergeMaps(dst.MatchLabels, include.MatchLabels) - dst.MatchExpressions = append(dst.MatchExpressions, include.MatchExpressions...) - return dst -} From bd2cf57b1718bf18950bb48973d2d20b65416897 Mon Sep 17 00:00:00 2001 From: Vladislav Sukhin Date: Thu, 12 Dec 2024 15:13:16 +0300 Subject: [PATCH 09/20] fix: add pvcs to service spec Signed-off-by: Vladislav Sukhin --- api/v1/testkube.yaml | 7 ++++--- .../model_test_workflow_independent_service_spec.go | 3 ++- pkg/api/v1/testkube/model_test_workflow_pvc_config.go | 2 -- pkg/api/v1/testkube/model_test_workflow_service_spec.go | 3 ++- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/api/v1/testkube.yaml b/api/v1/testkube.yaml index 0d98bd8a8df..3855d42115f 100644 --- a/api/v1/testkube.yaml +++ b/api/v1/testkube.yaml @@ -8678,6 +8678,10 @@ components: type: string readinessProbe: $ref: "#/components/schemas/Probe" + pvcs: + type: object + additionalProperties: + $ref: "#/components/schemas/TestWorkflowPvcConfig" TestWorkflowServiceSpec: type: object @@ -10599,9 +10603,6 @@ components: TestWorkflowPvcConfig: type: object properties: - shared: - description: Specify whether the pvc should be shared between test workflow pods - type: boolean accessModes: description: 'Access mode for claim storage. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes' type: array diff --git a/pkg/api/v1/testkube/model_test_workflow_independent_service_spec.go b/pkg/api/v1/testkube/model_test_workflow_independent_service_spec.go index 192eeadb608..57ea947f73d 100644 --- a/pkg/api/v1/testkube/model_test_workflow_independent_service_spec.go +++ b/pkg/api/v1/testkube/model_test_workflow_independent_service_spec.go @@ -41,5 +41,6 @@ type TestWorkflowIndependentServiceSpec struct { // matrix of parameters to spawn instances Matrix map[string]interface{} `json:"matrix,omitempty"` // parameters that should be distributed across sharded instances - Shards map[string]interface{} `json:"shards,omitempty"` + Shards map[string]interface{} `json:"shards,omitempty"` + Pvcs map[string]TestWorkflowPvcConfig `json:"pvcs,omitempty"` } diff --git a/pkg/api/v1/testkube/model_test_workflow_pvc_config.go b/pkg/api/v1/testkube/model_test_workflow_pvc_config.go index 8e7de8dfbf9..289c61df362 100644 --- a/pkg/api/v1/testkube/model_test_workflow_pvc_config.go +++ b/pkg/api/v1/testkube/model_test_workflow_pvc_config.go @@ -10,8 +10,6 @@ package testkube type TestWorkflowPvcConfig struct { - // Specify whether the pvc should be shared between test workflow pods - Shared bool `json:"shared,omitempty"` // Access mode for claim storage. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes AccessModes []string `json:"accessModes,omitempty"` // Volume mode indicates the consumption of the volume as either a filesystem or block device. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#volume-mode diff --git a/pkg/api/v1/testkube/model_test_workflow_service_spec.go b/pkg/api/v1/testkube/model_test_workflow_service_spec.go index ad915dd162e..4df57b081e1 100644 --- a/pkg/api/v1/testkube/model_test_workflow_service_spec.go +++ b/pkg/api/v1/testkube/model_test_workflow_service_spec.go @@ -42,5 +42,6 @@ type TestWorkflowServiceSpec struct { // matrix of parameters to spawn instances Matrix map[string]interface{} `json:"matrix,omitempty"` // parameters that should be distributed across sharded instances - Shards map[string]interface{} `json:"shards,omitempty"` + Shards map[string]interface{} `json:"shards,omitempty"` + Pvcs map[string]TestWorkflowPvcConfig `json:"pvcs,omitempty"` } From 0d02d16f04eb248905ad3029908cb61d7fb0133c Mon Sep 17 00:00:00 2001 From: Vladislav Sukhin Date: Thu, 12 Dec 2024 15:16:48 +0300 Subject: [PATCH 10/20] fix: remove duplication Signed-off-by: Vladislav Sukhin --- pkg/testworkflows/testworkflowresolver/apply.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/testworkflows/testworkflowresolver/apply.go b/pkg/testworkflows/testworkflowresolver/apply.go index 0808a09fda6..23b2845305e 100644 --- a/pkg/testworkflows/testworkflowresolver/apply.go +++ b/pkg/testworkflows/testworkflowresolver/apply.go @@ -70,7 +70,6 @@ func injectTemplateToSpec(spec *testworkflowsv1.TestWorkflowSpec, template testw spec.Services = MergeMap(common.MapMap(template.Spec.Services, ConvertIndependentServiceToService), spec.Services) spec.Container = MergeContainerConfig(template.Spec.Container, spec.Container) spec.System = MergeSystem(template.Spec.System, spec.System) - spec.Pvcs = MergeMap(template.Spec.Pvcs, spec.Pvcs) // Include the steps from the template setup := common.MapSlice(template.Spec.Setup, ConvertIndependentStepToStep) From b85e2743e76c47baa6b2a42629cbc900d58912bf Mon Sep 17 00:00:00 2001 From: Vladislav Sukhin Date: Thu, 12 Dec 2024 16:13:27 +0300 Subject: [PATCH 11/20] fix: dep update Signed-off-by: Vladislav Sukhin --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index bdd0facf6c8..c97ba8eab84 100644 --- a/go.mod +++ b/go.mod @@ -42,7 +42,7 @@ require ( github.com/keygen-sh/jsonapi-go v1.2.1 github.com/keygen-sh/keygen-go/v3 v3.2.0 github.com/kubepug/kubepug v1.7.1 - github.com/kubeshop/testkube-operator v1.17.55-0.20241211150637-26f07cccd389 + github.com/kubeshop/testkube-operator v1.17.55-0.20241212130344-02ce60b6d6b1 github.com/minio/minio-go/v7 v7.0.66 github.com/montanaflynn/stats v0.7.1 github.com/moogar0880/problems v0.1.1 diff --git a/go.sum b/go.sum index c4081dfec7b..8161814abbc 100644 --- a/go.sum +++ b/go.sum @@ -336,8 +336,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kubepug/kubepug v1.7.1 h1:LKhfSxS8Y5mXs50v+3Lpyec+cogErDLcV7CMUuiaisw= github.com/kubepug/kubepug v1.7.1/go.mod h1:lv+HxD0oTFL7ZWjj0u6HKhMbbTIId3eG7aWIW0gyF8g= -github.com/kubeshop/testkube-operator v1.17.55-0.20241211150637-26f07cccd389 h1:dP8c/kJmIFzy6F07qG+Wmo3jq8dfEvjYcAItJHDyjJQ= -github.com/kubeshop/testkube-operator v1.17.55-0.20241211150637-26f07cccd389/go.mod h1:P47tw1nKQFufdsZndyq2HG2MSa0zK/lU0XpRfZtEmIk= +github.com/kubeshop/testkube-operator v1.17.55-0.20241212130344-02ce60b6d6b1 h1:IV87xKZ8ezTbyOp0Qu6hDrzR/9Zo9iEvzsdB9uG8mOg= +github.com/kubeshop/testkube-operator v1.17.55-0.20241212130344-02ce60b6d6b1/go.mod h1:P47tw1nKQFufdsZndyq2HG2MSa0zK/lU0XpRfZtEmIk= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8LFgLN4= From fd2dd602230b0f52785ae849ef798886fd8bf9e3 Mon Sep 17 00:00:00 2001 From: Vladislav Sukhin Date: Thu, 12 Dec 2024 16:30:40 +0300 Subject: [PATCH 12/20] fix: setvice pvcs Signed-off-by: Vladislav Sukhin --- pkg/mapper/testworkflows/kube_openapi.go | 3 ++- pkg/mapper/testworkflows/openapi_kube.go | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pkg/mapper/testworkflows/kube_openapi.go b/pkg/mapper/testworkflows/kube_openapi.go index ac221087d21..79c69d3f8c6 100644 --- a/pkg/mapper/testworkflows/kube_openapi.go +++ b/pkg/mapper/testworkflows/kube_openapi.go @@ -1030,6 +1030,7 @@ func MapIndependentServiceSpecKubeToAPI(v testworkflowsv1.IndependentServiceSpec Logs: MapStringToBoxedString(v.Logs), RestartPolicy: string(v.RestartPolicy), ReadinessProbe: common.MapPtr(v.ReadinessProbe, MapProbeKubeToAPI), + Pvcs: common.MapMap(v.Pvcs, MapPvcConfigKubeToAPI), } } @@ -1059,6 +1060,7 @@ func MapServiceSpecKubeToAPI(v testworkflowsv1.ServiceSpec) testkube.TestWorkflo Logs: MapStringToBoxedString(v.Logs), RestartPolicy: string(v.RestartPolicy), ReadinessProbe: common.MapPtr(v.ReadinessProbe, MapProbeKubeToAPI), + Pvcs: common.MapMap(v.Pvcs, MapPvcConfigKubeToAPI), } } @@ -1213,7 +1215,6 @@ func MapTestWorkflowTagSchemaKubeToAPI(v testworkflowsv1.TestWorkflowTagSchema) func MapPvcConfigKubeToAPI(v testworkflowsv1.TestWorkflowPvcConfig) testkube.TestWorkflowPvcConfig { return testkube.TestWorkflowPvcConfig{ - Shared: v.Shared, AccessModes: v.AccessModes, VolumeMode: v.VolumeMode, Resources: common.MapPtr(v.Resources, MapResourcesKubeToAPI), diff --git a/pkg/mapper/testworkflows/openapi_kube.go b/pkg/mapper/testworkflows/openapi_kube.go index ca78b436e5f..0865309fbfc 100644 --- a/pkg/mapper/testworkflows/openapi_kube.go +++ b/pkg/mapper/testworkflows/openapi_kube.go @@ -1100,6 +1100,7 @@ func MapIndependentServiceSpecAPIToKube(v testkube.TestWorkflowIndependentServic Logs: MapBoxedStringToString(v.Logs), RestartPolicy: testworkflowsv1.ServiceRestartPolicy(v.RestartPolicy), ReadinessProbe: common.MapPtr(v.ReadinessProbe, MapProbeAPIToKube), + Pvcs: common.MapMap(v.Pvcs, MapPvcConfigAPIToKube), } } @@ -1136,6 +1137,7 @@ func MapServiceSpecAPIToKube(v testkube.TestWorkflowServiceSpec) testworkflowsv1 Logs: MapBoxedStringToString(v.Logs), RestartPolicy: testworkflowsv1.ServiceRestartPolicy(v.RestartPolicy), ReadinessProbe: common.MapPtr(v.ReadinessProbe, MapProbeAPIToKube), + Pvcs: common.MapMap(v.Pvcs, MapPvcConfigAPIToKube), }, } } @@ -1492,7 +1494,6 @@ func MapTestWorkflowTagSchemaAPIToKube(v testkube.TestWorkflowTagSchema) testwor func MapPvcConfigAPIToKube(v testkube.TestWorkflowPvcConfig) testworkflowsv1.TestWorkflowPvcConfig { return testworkflowsv1.TestWorkflowPvcConfig{ - Shared: v.Shared, AccessModes: v.AccessModes, VolumeMode: v.VolumeMode, Resources: common.MapPtr(v.Resources, MapResourcesAPIToKube), From 551f1b2b46d03fab3a8219b77142bac738cef280 Mon Sep 17 00:00:00 2001 From: Vladislav Sukhin Date: Thu, 12 Dec 2024 18:44:08 +0300 Subject: [PATCH 13/20] fi: dep update Signed-off-by: Vladislav Sukhin --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index c97ba8eab84..a37d552c929 100644 --- a/go.mod +++ b/go.mod @@ -42,7 +42,7 @@ require ( github.com/keygen-sh/jsonapi-go v1.2.1 github.com/keygen-sh/keygen-go/v3 v3.2.0 github.com/kubepug/kubepug v1.7.1 - github.com/kubeshop/testkube-operator v1.17.55-0.20241212130344-02ce60b6d6b1 + github.com/kubeshop/testkube-operator v1.17.55-0.20241212153943-9d18068064f1 github.com/minio/minio-go/v7 v7.0.66 github.com/montanaflynn/stats v0.7.1 github.com/moogar0880/problems v0.1.1 diff --git a/go.sum b/go.sum index 8161814abbc..a468a77b2cf 100644 --- a/go.sum +++ b/go.sum @@ -336,8 +336,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kubepug/kubepug v1.7.1 h1:LKhfSxS8Y5mXs50v+3Lpyec+cogErDLcV7CMUuiaisw= github.com/kubepug/kubepug v1.7.1/go.mod h1:lv+HxD0oTFL7ZWjj0u6HKhMbbTIId3eG7aWIW0gyF8g= -github.com/kubeshop/testkube-operator v1.17.55-0.20241212130344-02ce60b6d6b1 h1:IV87xKZ8ezTbyOp0Qu6hDrzR/9Zo9iEvzsdB9uG8mOg= -github.com/kubeshop/testkube-operator v1.17.55-0.20241212130344-02ce60b6d6b1/go.mod h1:P47tw1nKQFufdsZndyq2HG2MSa0zK/lU0XpRfZtEmIk= +github.com/kubeshop/testkube-operator v1.17.55-0.20241212153943-9d18068064f1 h1:TmmGhFII/sIdEy6lMRHkRovG7Xr1pW4NkF9sPiPgtNc= +github.com/kubeshop/testkube-operator v1.17.55-0.20241212153943-9d18068064f1/go.mod h1:P47tw1nKQFufdsZndyq2HG2MSa0zK/lU0XpRfZtEmIk= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8LFgLN4= From 6faffdb5244b56a1124514e6e0595a62d7af49eb Mon Sep 17 00:00:00 2001 From: Vladislav Sukhin Date: Thu, 12 Dec 2024 19:05:21 +0300 Subject: [PATCH 14/20] fix: append pvcs Signed-off-by: Vladislav Sukhin --- .../testworkflowprocessor/intermediate.go | 13 +++++---- .../mock_intermediate.go | 28 +++++++++---------- .../testworkflowprocessor/processor.go | 4 ++- .../testworkflowresolver/apply.go | 1 + .../testworkflowresolver/merge.go | 13 +++++++++ 5 files changed, 39 insertions(+), 20 deletions(-) diff --git a/pkg/testworkflows/testworkflowprocessor/intermediate.go b/pkg/testworkflows/testworkflowprocessor/intermediate.go index 7b43adeb040..cd908f26839 100644 --- a/pkg/testworkflows/testworkflowprocessor/intermediate.go +++ b/pkg/testworkflows/testworkflowprocessor/intermediate.go @@ -4,6 +4,7 @@ import ( "fmt" corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" testworkflowsv1 "github.com/kubeshop/testkube-operator/api/testworkflows/v1" "github.com/kubeshop/testkube/pkg/testworkflows/testworkflowprocessor/stage" @@ -25,11 +26,11 @@ type Intermediate interface { AppendJobConfig(cfg *testworkflowsv1.JobConfig) Intermediate AppendPodConfig(cfg *testworkflowsv1.PodConfig) Intermediate + AppendPvc(cfg map[string]corev1.PersistentVolumeClaimSpec) Intermediate AddConfigMap(configMap corev1.ConfigMap) Intermediate AddSecret(secret corev1.Secret) Intermediate AddVolume(volume corev1.Volume) Intermediate - AddPvc(pvc corev1.PersistentVolumeClaim) Intermediate AddEmptyDirVolume(source *corev1.EmptyDirVolumeSource, mountPath string) corev1.VolumeMount @@ -104,13 +105,15 @@ func (s *intermediate) AppendPodConfig(cfg *testworkflowsv1.PodConfig) Intermedi return s } -func (s *intermediate) AddVolume(volume corev1.Volume) Intermediate { - s.Pod.Volumes = append(s.Pod.Volumes, volume) +func (s *intermediate) AppendPvc(cfg map[string]corev1.PersistentVolumeClaimSpec) Intermediate { + for name, spec := range cfg { + s.Ps = append(s.Ps, corev1.PersistentVolumeClaim{ObjectMeta: metav1.ObjectMeta{Name: name}, Spec: spec}) + } return s } -func (s *intermediate) AddPvc(pvc corev1.PersistentVolumeClaim) Intermediate { - s.Ps = append(s.Ps, pvc) +func (s *intermediate) AddVolume(volume corev1.Volume) Intermediate { + s.Pod.Volumes = append(s.Pod.Volumes, volume) return s } diff --git a/pkg/testworkflows/testworkflowprocessor/mock_intermediate.go b/pkg/testworkflows/testworkflowprocessor/mock_intermediate.go index 5d42526cf59..a5627ed0d50 100644 --- a/pkg/testworkflows/testworkflowprocessor/mock_intermediate.go +++ b/pkg/testworkflows/testworkflowprocessor/mock_intermediate.go @@ -79,20 +79,6 @@ func (mr *MockIntermediateMockRecorder) AddEmptyDirVolume(arg0, arg1 interface{} return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddEmptyDirVolume", reflect.TypeOf((*MockIntermediate)(nil).AddEmptyDirVolume), arg0, arg1) } -// AddPvc mocks base method. -func (m *MockIntermediate) AddPvc(arg0 v10.PersistentVolumeClaim) Intermediate { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AddPvc", arg0) - ret0, _ := ret[0].(Intermediate) - return ret0 -} - -// AddPvc indicates an expected call of AddPvc. -func (mr *MockIntermediateMockRecorder) AddPvc(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddPvc", reflect.TypeOf((*MockIntermediate)(nil).AddPvc), arg0) -} - // AddSecret mocks base method. func (m *MockIntermediate) AddSecret(arg0 v10.Secret) Intermediate { m.ctrl.T.Helper() @@ -164,6 +150,20 @@ func (mr *MockIntermediateMockRecorder) AppendPodConfig(arg0 interface{}) *gomoc return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendPodConfig", reflect.TypeOf((*MockIntermediate)(nil).AppendPodConfig), arg0) } +// AppendPvc mocks base method. +func (m *MockIntermediate) AppendPvc(arg0 map[string]v10.PersistentVolumeClaimSpec) Intermediate { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AppendPvc", arg0) + ret0, _ := ret[0].(Intermediate) + return ret0 +} + +// AppendPvc indicates an expected call of AppendPvc. +func (mr *MockIntermediateMockRecorder) AppendPvc(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendPvc", reflect.TypeOf((*MockIntermediate)(nil).AppendPvc), arg0) +} + // ConfigMaps mocks base method. func (m *MockIntermediate) ConfigMaps() []v10.ConfigMap { m.ctrl.T.Helper() diff --git a/pkg/testworkflows/testworkflowprocessor/processor.go b/pkg/testworkflows/testworkflowprocessor/processor.go index af5d881f9bb..bc5674addfd 100644 --- a/pkg/testworkflows/testworkflowprocessor/processor.go +++ b/pkg/testworkflows/testworkflowprocessor/processor.go @@ -23,6 +23,7 @@ import ( "github.com/kubeshop/testkube/pkg/testworkflows/testworkflowprocessor/action/actiontypes/lite" "github.com/kubeshop/testkube/pkg/testworkflows/testworkflowprocessor/constants" "github.com/kubeshop/testkube/pkg/testworkflows/testworkflowprocessor/stage" + "github.com/kubeshop/testkube/pkg/testworkflows/testworkflowresolver" ) //go:generate mockgen -destination=./mock_processor.go -package=testworkflowprocessor "github.com/kubeshop/testkube/pkg/testworkflows/testworkflowprocessor" Processor @@ -106,7 +107,8 @@ func (p *processor) Bundle(ctx context.Context, workflow *testworkflowsv1.TestWo // Initialize intermediate layer layer := NewIntermediate(). AppendPodConfig(workflow.Spec.Pod). - AppendJobConfig(workflow.Spec.Job) + AppendJobConfig(workflow.Spec.Job). + AppendPvc(common.MapMap(workflow.Spec.Pvcs, testworkflowresolver.ConvertTestWorkflowPvcConfigToPersistentVolumeClaimSpec)) layer.ContainerDefaults(). ApplyCR(constants.DefaultContainerConfig.DeepCopy()). AppendVolumeMounts(layer.AddEmptyDirVolume(nil, constants.DefaultInternalPath)). diff --git a/pkg/testworkflows/testworkflowresolver/apply.go b/pkg/testworkflows/testworkflowresolver/apply.go index 23b2845305e..07ee151165e 100644 --- a/pkg/testworkflows/testworkflowresolver/apply.go +++ b/pkg/testworkflows/testworkflowresolver/apply.go @@ -126,6 +126,7 @@ func InjectServiceTemplate(svc *testworkflowsv1.ServiceSpec, template testworkfl svc.Pod = MergePodConfig(template.Spec.Pod, svc.Pod) svc.Content = MergeContent(template.Spec.Content, svc.Content) svc.ContainerConfig = *MergeContainerConfig(template.Spec.Container, &svc.ContainerConfig) + svc.Pvcs = MergeMap(template.Spec.Pvcs, svc.Pvcs) return nil } diff --git a/pkg/testworkflows/testworkflowresolver/merge.go b/pkg/testworkflows/testworkflowresolver/merge.go index 1d503f1b84c..9d932cee8d6 100644 --- a/pkg/testworkflows/testworkflowresolver/merge.go +++ b/pkg/testworkflows/testworkflowresolver/merge.go @@ -373,6 +373,7 @@ func ConvertIndependentStepParallelToStepParallel(step testworkflowsv1.Independe Setup: common.MapSlice(step.TestWorkflowTemplateSpec.Setup, ConvertIndependentStepToStep), Steps: common.MapSlice(step.TestWorkflowTemplateSpec.Steps, ConvertIndependentStepToStep), After: common.MapSlice(step.TestWorkflowTemplateSpec.After, ConvertIndependentStepToStep), + Pvcs: step.TestWorkflowTemplateSpec.Pvcs, }, StepControl: step.StepControl, StepOperations: step.StepOperations, @@ -414,3 +415,15 @@ func MergeTags(dst, src map[string]string) map[string]string { return dst } + +func ConvertTestWorkflowPvcConfigToPersistentVolumeClaimSpec(pvc testworkflowsv1.TestWorkflowPvcConfig) corev1.PersistentVolumeClaimSpec { + return corev1.PersistentVolumeClaimSpec{ + AccessModes: common.MapSlice(pvc.AccessModes, func(s string) corev1.PersistentVolumeAccessMode { + return corev1.PersistentVolumeAccessMode(s) + }), + Selector: pvc.Selector, + // Resources: pvc.Resources.Limits, + StorageClassName: &pvc.StorageClassName, + VolumeMode: (*corev1.PersistentVolumeMode)(&pvc.VolumeMode), + } +} From da9e7f13417821955c1f1502bb4ddfbdccb3789b Mon Sep 17 00:00:00 2001 From: Vladislav Sukhin Date: Thu, 12 Dec 2024 19:35:07 +0300 Subject: [PATCH 15/20] fix: copy service pvcs Signed-off-by: Vladislav Sukhin --- cmd/tcl/testworkflow-toolkit/commands/services.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/tcl/testworkflow-toolkit/commands/services.go b/cmd/tcl/testworkflow-toolkit/commands/services.go index b32f3231fb9..ce692cc849b 100644 --- a/cmd/tcl/testworkflow-toolkit/commands/services.go +++ b/cmd/tcl/testworkflow-toolkit/commands/services.go @@ -156,6 +156,7 @@ func NewServicesCmd() *cobra.Command { Steps: []testworkflowsv1.Step{ {StepOperations: testworkflowsv1.StepOperations{Run: common.Ptr(svcSpec.StepRun)}}, }, + Pvcs: svcSpec.Pvcs, } spec.Steps[0].Run.ContainerConfig = testworkflowsv1.ContainerConfig{} From 541721126fa860b2177bc39dec0685868f3fe145 Mon Sep 17 00:00:00 2001 From: Vladislav Sukhin Date: Thu, 12 Dec 2024 19:43:24 +0300 Subject: [PATCH 16/20] fix: pvc name for execution Signed-off-by: Vladislav Sukhin --- pkg/testworkflows/testworkflowprocessor/intermediate.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pkg/testworkflows/testworkflowprocessor/intermediate.go b/pkg/testworkflows/testworkflowprocessor/intermediate.go index cd908f26839..9be9b86fe09 100644 --- a/pkg/testworkflows/testworkflowprocessor/intermediate.go +++ b/pkg/testworkflows/testworkflowprocessor/intermediate.go @@ -106,8 +106,14 @@ func (s *intermediate) AppendPodConfig(cfg *testworkflowsv1.PodConfig) Intermedi } func (s *intermediate) AppendPvc(cfg map[string]corev1.PersistentVolumeClaimSpec) Intermediate { + ref := s.NextRef() for name, spec := range cfg { - s.Ps = append(s.Ps, corev1.PersistentVolumeClaim{ObjectMeta: metav1.ObjectMeta{Name: name}, Spec: spec}) + s.Ps = append(s.Ps, corev1.PersistentVolumeClaim{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("%s-%s", name, ref), + }, + Spec: spec, + }) } return s } From 597a69a4c4a1662935fcf6820454626d31d9e184 Mon Sep 17 00:00:00 2001 From: Vladislav Sukhin Date: Thu, 12 Dec 2024 21:44:02 +0300 Subject: [PATCH 17/20] fix: register pvc names Signed-off-by: Vladislav Sukhin --- .../testworkflowconfig/expressions.go | 22 ++++++++++++++++++- .../testworkflowprocessor/processor.go | 3 ++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/pkg/testworkflows/testworkflowconfig/expressions.go b/pkg/testworkflows/testworkflowconfig/expressions.go index 3cd5cd330b8..b951bddb63a 100644 --- a/pkg/testworkflows/testworkflowconfig/expressions.go +++ b/pkg/testworkflows/testworkflowconfig/expressions.go @@ -1,6 +1,12 @@ package testworkflowconfig -import "github.com/kubeshop/testkube/pkg/expressions" +import ( + "strings" + + corev1 "k8s.io/api/core/v1" + + "github.com/kubeshop/testkube/pkg/expressions" +) func CreateExecutionMachine(cfg *ExecutionConfig) expressions.Machine { return expressions.NewMachine(). @@ -77,3 +83,17 @@ func CreateWorkerMachine(cfg *WorkerConfig) expressions.Machine { }) return expressions.CombinedMachines(machine) } + +func CreatePvcMachine(pvcs []corev1.PersistentVolumeClaim) expressions.Machine { + pvcMap := make(map[string]string) + for _, pvc := range pvcs { + name := pvc.Name + if index := strings.LastIndex(name, "-"); index != -1 { + name = name[:index] + } + + pvcMap[name+".name"] = pvc.Name + } + + return expressions.NewMachine().RegisterStringMap("pvcs", pvcMap) +} diff --git a/pkg/testworkflows/testworkflowprocessor/processor.go b/pkg/testworkflows/testworkflowprocessor/processor.go index bc5674addfd..43e8b054a4d 100644 --- a/pkg/testworkflows/testworkflowprocessor/processor.go +++ b/pkg/testworkflows/testworkflowprocessor/processor.go @@ -119,7 +119,8 @@ func (p *processor) Bundle(ctx context.Context, workflow *testworkflowsv1.TestWo machines = append(machines, createSecretMachine(mapEnv), testworkflowconfig.CreateWorkerMachine(&options.Config.Worker), - testworkflowconfig.CreateResourceMachine(&options.Config.Resource)) + testworkflowconfig.CreateResourceMachine(&options.Config.Resource), + testworkflowconfig.CreatePvcMachine(layer.Pvcs())) // Fetch resource root and resource ID if options.Config.Resource.Id == "" { From bd3aad2819967cadc472e829615c793be948c371 Mon Sep 17 00:00:00 2001 From: Vladislav Sukhin Date: Fri, 13 Dec 2024 16:08:28 +0300 Subject: [PATCH 18/20] fix: convert pvc Signed-off-by: Vladislav Sukhin --- api/v1/testkube.yaml | 3 ++ go.mod | 2 +- go.sum | 2 + .../model_test_workflow_pvc_config.go | 6 ++- pkg/mapper/testworkflows/kube_openapi.go | 1 + pkg/mapper/testworkflows/openapi_kube.go | 1 + .../testworkflowresolver/merge.go | 51 ++++++++++++++++++- 7 files changed, 61 insertions(+), 5 deletions(-) diff --git a/api/v1/testkube.yaml b/api/v1/testkube.yaml index 3855d42115f..60336c86c10 100644 --- a/api/v1/testkube.yaml +++ b/api/v1/testkube.yaml @@ -10618,6 +10618,9 @@ components: storageClassName: description: 'Storage class name specifies the name of a StorageClass. More info: https://kubernetes.io/docs/concepts/storage/storage-classes/' type: string + volumeName: + description: 'Volume name is used to identify the volume' + type: string selector: description: Only the volumes whose labels match the selector can be bound to the claim $ref: "#/components/schemas/LabelSelector" diff --git a/go.mod b/go.mod index a37d552c929..f3e1bd55f07 100644 --- a/go.mod +++ b/go.mod @@ -42,7 +42,7 @@ require ( github.com/keygen-sh/jsonapi-go v1.2.1 github.com/keygen-sh/keygen-go/v3 v3.2.0 github.com/kubepug/kubepug v1.7.1 - github.com/kubeshop/testkube-operator v1.17.55-0.20241212153943-9d18068064f1 + github.com/kubeshop/testkube-operator v1.17.55-0.20241213114930-df3327436207 github.com/minio/minio-go/v7 v7.0.66 github.com/montanaflynn/stats v0.7.1 github.com/moogar0880/problems v0.1.1 diff --git a/go.sum b/go.sum index a468a77b2cf..d55ba5f3ef2 100644 --- a/go.sum +++ b/go.sum @@ -338,6 +338,8 @@ github.com/kubepug/kubepug v1.7.1 h1:LKhfSxS8Y5mXs50v+3Lpyec+cogErDLcV7CMUuiaisw github.com/kubepug/kubepug v1.7.1/go.mod h1:lv+HxD0oTFL7ZWjj0u6HKhMbbTIId3eG7aWIW0gyF8g= github.com/kubeshop/testkube-operator v1.17.55-0.20241212153943-9d18068064f1 h1:TmmGhFII/sIdEy6lMRHkRovG7Xr1pW4NkF9sPiPgtNc= github.com/kubeshop/testkube-operator v1.17.55-0.20241212153943-9d18068064f1/go.mod h1:P47tw1nKQFufdsZndyq2HG2MSa0zK/lU0XpRfZtEmIk= +github.com/kubeshop/testkube-operator v1.17.55-0.20241213114930-df3327436207 h1:IQvoge5CpG0Z1uEjb/rcA4SN+ZiAmPrO0XSTLLlPDeg= +github.com/kubeshop/testkube-operator v1.17.55-0.20241213114930-df3327436207/go.mod h1:P47tw1nKQFufdsZndyq2HG2MSa0zK/lU0XpRfZtEmIk= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8LFgLN4= diff --git a/pkg/api/v1/testkube/model_test_workflow_pvc_config.go b/pkg/api/v1/testkube/model_test_workflow_pvc_config.go index 289c61df362..77cacf8f69e 100644 --- a/pkg/api/v1/testkube/model_test_workflow_pvc_config.go +++ b/pkg/api/v1/testkube/model_test_workflow_pvc_config.go @@ -16,6 +16,8 @@ type TestWorkflowPvcConfig struct { VolumeMode string `json:"volumeMode,omitempty"` Resources *TestWorkflowResources `json:"resources,omitempty"` // Storage class name specifies the name of a StorageClass. More info: https://kubernetes.io/docs/concepts/storage/storage-classes/ - StorageClassName string `json:"storageClassName,omitempty"` - Selector *LabelSelector `json:"selector,omitempty"` + StorageClassName string `json:"storageClassName,omitempty"` + // Volume name is used to identify the volume + VolumeName string `json:"volumeName,omitempty"` + Selector *LabelSelector `json:"selector,omitempty"` } diff --git a/pkg/mapper/testworkflows/kube_openapi.go b/pkg/mapper/testworkflows/kube_openapi.go index 79c69d3f8c6..5509cc6736d 100644 --- a/pkg/mapper/testworkflows/kube_openapi.go +++ b/pkg/mapper/testworkflows/kube_openapi.go @@ -1219,6 +1219,7 @@ func MapPvcConfigKubeToAPI(v testworkflowsv1.TestWorkflowPvcConfig) testkube.Tes VolumeMode: v.VolumeMode, Resources: common.MapPtr(v.Resources, MapResourcesKubeToAPI), StorageClassName: v.StorageClassName, + VolumeName: v.VolumeName, Selector: common.MapPtr(v.Selector, MapSelectorToAPI), } } diff --git a/pkg/mapper/testworkflows/openapi_kube.go b/pkg/mapper/testworkflows/openapi_kube.go index 0865309fbfc..caf0f3860ec 100644 --- a/pkg/mapper/testworkflows/openapi_kube.go +++ b/pkg/mapper/testworkflows/openapi_kube.go @@ -1498,6 +1498,7 @@ func MapPvcConfigAPIToKube(v testkube.TestWorkflowPvcConfig) testworkflowsv1.Tes VolumeMode: v.VolumeMode, Resources: common.MapPtr(v.Resources, MapResourcesAPIToKube), StorageClassName: v.StorageClassName, + VolumeName: v.VolumeName, Selector: common.MapPtr(v.Selector, MapLabelSelectorAPIToKube), } } diff --git a/pkg/testworkflows/testworkflowresolver/merge.go b/pkg/testworkflows/testworkflowresolver/merge.go index 9d932cee8d6..9da13ade7a2 100644 --- a/pkg/testworkflows/testworkflowresolver/merge.go +++ b/pkg/testworkflows/testworkflowresolver/merge.go @@ -12,6 +12,8 @@ import ( "maps" corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + "k8s.io/apimachinery/pkg/util/intstr" testworkflowsv1 "github.com/kubeshop/testkube-operator/api/testworkflows/v1" "github.com/kubeshop/testkube/internal/common" @@ -421,9 +423,54 @@ func ConvertTestWorkflowPvcConfigToPersistentVolumeClaimSpec(pvc testworkflowsv1 AccessModes: common.MapSlice(pvc.AccessModes, func(s string) corev1.PersistentVolumeAccessMode { return corev1.PersistentVolumeAccessMode(s) }), - Selector: pvc.Selector, - // Resources: pvc.Resources.Limits, + Selector: pvc.Selector, + Resources: ConvertResourcesToVolumeResourceRequirements(pvc.Resources), + VolumeName: pvc.VolumeName, StorageClassName: &pvc.StorageClassName, VolumeMode: (*corev1.PersistentVolumeMode)(&pvc.VolumeMode), } } + +func ConvertResourcesToVolumeResourceRequirements(r *testworkflowsv1.Resources) corev1.VolumeResourceRequirements { + var limits, requests corev1.ResourceList + if r != nil { + if len(r.Limits) != 0 { + limits = make(corev1.ResourceList) + } + + if len(r.Requests) != 0 { + requests = make(corev1.ResourceList) + } + + for key, value := range r.Limits { + var quantity resource.Quantity + if value.Type == intstr.Int { + quantity = *resource.NewQuantity(int64(value.IntVal), resource.BinarySI) + } + + if value.Type == intstr.String { + quantity, _ = resource.ParseQuantity(value.String()) + } + + limits[key] = quantity + } + + for key, value := range r.Requests { + var quantity resource.Quantity + if value.Type == intstr.Int { + quantity = *resource.NewQuantity(int64(value.IntVal), resource.BinarySI) + } + + if value.Type == intstr.String { + quantity, _ = resource.ParseQuantity(value.String()) + } + + requests[key] = quantity + } + } + + return corev1.VolumeResourceRequirements{ + Limits: limits, + Requests: requests, + } +} From 95c8992e9905b54935098673814ba1d88556a086 Mon Sep 17 00:00:00 2001 From: Vladislav Sukhin Date: Fri, 13 Dec 2024 17:14:07 +0300 Subject: [PATCH 19/20] fix: move fields to boxed strings Signed-off-by: Vladislav Sukhin --- api/v1/testkube.yaml | 4 ++-- pkg/api/v1/testkube/model_test_workflow_pvc_config.go | 10 ++++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/api/v1/testkube.yaml b/api/v1/testkube.yaml index 60336c86c10..065638042c4 100644 --- a/api/v1/testkube.yaml +++ b/api/v1/testkube.yaml @@ -10611,13 +10611,13 @@ components: volumeMode: description: 'Volume mode indicates the consumption of the volume as either a filesystem or block device. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#volume-mode' - type: string + $ref: "#/components/schemas/BoxedString" resources: description: 'Resources required for pvc' $ref: "#/components/schemas/TestWorkflowResources" storageClassName: description: 'Storage class name specifies the name of a StorageClass. More info: https://kubernetes.io/docs/concepts/storage/storage-classes/' - type: string + $ref: "#/components/schemas/BoxedString" volumeName: description: 'Volume name is used to identify the volume' type: string diff --git a/pkg/api/v1/testkube/model_test_workflow_pvc_config.go b/pkg/api/v1/testkube/model_test_workflow_pvc_config.go index 77cacf8f69e..02b3f00cdb5 100644 --- a/pkg/api/v1/testkube/model_test_workflow_pvc_config.go +++ b/pkg/api/v1/testkube/model_test_workflow_pvc_config.go @@ -11,12 +11,10 @@ package testkube type TestWorkflowPvcConfig struct { // Access mode for claim storage. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes - AccessModes []string `json:"accessModes,omitempty"` - // Volume mode indicates the consumption of the volume as either a filesystem or block device. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#volume-mode - VolumeMode string `json:"volumeMode,omitempty"` - Resources *TestWorkflowResources `json:"resources,omitempty"` - // Storage class name specifies the name of a StorageClass. More info: https://kubernetes.io/docs/concepts/storage/storage-classes/ - StorageClassName string `json:"storageClassName,omitempty"` + AccessModes []string `json:"accessModes,omitempty"` + VolumeMode *BoxedString `json:"volumeMode,omitempty"` + Resources *TestWorkflowResources `json:"resources,omitempty"` + StorageClassName *BoxedString `json:"storageClassName,omitempty"` // Volume name is used to identify the volume VolumeName string `json:"volumeName,omitempty"` Selector *LabelSelector `json:"selector,omitempty"` From 54b352d5ceaaf8c723455bb60bc5386fde1a082b Mon Sep 17 00:00:00 2001 From: Vladislav Sukhin Date: Fri, 13 Dec 2024 17:59:35 +0300 Subject: [PATCH 20/20] fix: dep update Signed-off-by: Vladislav Sukhin --- go.mod | 2 +- go.sum | 6 ++---- pkg/mapper/testworkflows/kube_openapi.go | 4 ++-- pkg/mapper/testworkflows/openapi_kube.go | 4 ++-- pkg/testworkflows/testworkflowresolver/merge.go | 4 ++-- 5 files changed, 9 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index f3e1bd55f07..d83e255cfb4 100644 --- a/go.mod +++ b/go.mod @@ -42,7 +42,7 @@ require ( github.com/keygen-sh/jsonapi-go v1.2.1 github.com/keygen-sh/keygen-go/v3 v3.2.0 github.com/kubepug/kubepug v1.7.1 - github.com/kubeshop/testkube-operator v1.17.55-0.20241213114930-df3327436207 + github.com/kubeshop/testkube-operator v1.17.55-0.20241213144851-e0d37fb5899a github.com/minio/minio-go/v7 v7.0.66 github.com/montanaflynn/stats v0.7.1 github.com/moogar0880/problems v0.1.1 diff --git a/go.sum b/go.sum index d55ba5f3ef2..35bbe8851a3 100644 --- a/go.sum +++ b/go.sum @@ -336,10 +336,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kubepug/kubepug v1.7.1 h1:LKhfSxS8Y5mXs50v+3Lpyec+cogErDLcV7CMUuiaisw= github.com/kubepug/kubepug v1.7.1/go.mod h1:lv+HxD0oTFL7ZWjj0u6HKhMbbTIId3eG7aWIW0gyF8g= -github.com/kubeshop/testkube-operator v1.17.55-0.20241212153943-9d18068064f1 h1:TmmGhFII/sIdEy6lMRHkRovG7Xr1pW4NkF9sPiPgtNc= -github.com/kubeshop/testkube-operator v1.17.55-0.20241212153943-9d18068064f1/go.mod h1:P47tw1nKQFufdsZndyq2HG2MSa0zK/lU0XpRfZtEmIk= -github.com/kubeshop/testkube-operator v1.17.55-0.20241213114930-df3327436207 h1:IQvoge5CpG0Z1uEjb/rcA4SN+ZiAmPrO0XSTLLlPDeg= -github.com/kubeshop/testkube-operator v1.17.55-0.20241213114930-df3327436207/go.mod h1:P47tw1nKQFufdsZndyq2HG2MSa0zK/lU0XpRfZtEmIk= +github.com/kubeshop/testkube-operator v1.17.55-0.20241213144851-e0d37fb5899a h1:nQDxKFu67lz9BH8isLnP7ttp7cgBWYnRDMV9VxMaYH0= +github.com/kubeshop/testkube-operator v1.17.55-0.20241213144851-e0d37fb5899a/go.mod h1:P47tw1nKQFufdsZndyq2HG2MSa0zK/lU0XpRfZtEmIk= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8LFgLN4= diff --git a/pkg/mapper/testworkflows/kube_openapi.go b/pkg/mapper/testworkflows/kube_openapi.go index 5509cc6736d..333a2c4d121 100644 --- a/pkg/mapper/testworkflows/kube_openapi.go +++ b/pkg/mapper/testworkflows/kube_openapi.go @@ -1216,9 +1216,9 @@ func MapTestWorkflowTagSchemaKubeToAPI(v testworkflowsv1.TestWorkflowTagSchema) func MapPvcConfigKubeToAPI(v testworkflowsv1.TestWorkflowPvcConfig) testkube.TestWorkflowPvcConfig { return testkube.TestWorkflowPvcConfig{ AccessModes: v.AccessModes, - VolumeMode: v.VolumeMode, + VolumeMode: MapStringToBoxedString(v.VolumeMode), Resources: common.MapPtr(v.Resources, MapResourcesKubeToAPI), - StorageClassName: v.StorageClassName, + StorageClassName: MapStringToBoxedString(v.StorageClassName), VolumeName: v.VolumeName, Selector: common.MapPtr(v.Selector, MapSelectorToAPI), } diff --git a/pkg/mapper/testworkflows/openapi_kube.go b/pkg/mapper/testworkflows/openapi_kube.go index caf0f3860ec..fa5a76abc01 100644 --- a/pkg/mapper/testworkflows/openapi_kube.go +++ b/pkg/mapper/testworkflows/openapi_kube.go @@ -1495,9 +1495,9 @@ func MapTestWorkflowTagSchemaAPIToKube(v testkube.TestWorkflowTagSchema) testwor func MapPvcConfigAPIToKube(v testkube.TestWorkflowPvcConfig) testworkflowsv1.TestWorkflowPvcConfig { return testworkflowsv1.TestWorkflowPvcConfig{ AccessModes: v.AccessModes, - VolumeMode: v.VolumeMode, + VolumeMode: MapBoxedStringToString(v.VolumeMode), Resources: common.MapPtr(v.Resources, MapResourcesAPIToKube), - StorageClassName: v.StorageClassName, + StorageClassName: MapBoxedStringToString(v.StorageClassName), VolumeName: v.VolumeName, Selector: common.MapPtr(v.Selector, MapLabelSelectorAPIToKube), } diff --git a/pkg/testworkflows/testworkflowresolver/merge.go b/pkg/testworkflows/testworkflowresolver/merge.go index 9da13ade7a2..3ebf623ab09 100644 --- a/pkg/testworkflows/testworkflowresolver/merge.go +++ b/pkg/testworkflows/testworkflowresolver/merge.go @@ -426,8 +426,8 @@ func ConvertTestWorkflowPvcConfigToPersistentVolumeClaimSpec(pvc testworkflowsv1 Selector: pvc.Selector, Resources: ConvertResourcesToVolumeResourceRequirements(pvc.Resources), VolumeName: pvc.VolumeName, - StorageClassName: &pvc.StorageClassName, - VolumeMode: (*corev1.PersistentVolumeMode)(&pvc.VolumeMode), + StorageClassName: pvc.StorageClassName, + VolumeMode: (*corev1.PersistentVolumeMode)(pvc.VolumeMode), } }