diff --git a/api/testexecution/v1/testexecution_types.go b/api/testexecution/v1/testexecution_types.go index 3a6ec716..47aba6c5 100644 --- a/api/testexecution/v1/testexecution_types.go +++ b/api/testexecution/v1/testexecution_types.go @@ -59,7 +59,7 @@ type RunningContext struct { } // RunningContextType defines running context type -// +kubebuilder:validation:Enum=user-cli;user-ui;testsuite;testtrigger;scheduler;testexecution;testsuiteexecution +// +kubebuilder:validation:Enum=user-cli;user-ui;testsuite;testtrigger;scheduler;testexecution;testsuiteexecution;testworkflow type RunningContextType string const ( @@ -70,6 +70,7 @@ const ( RunningContextTypeScheduler RunningContextType = "scheduler" RunningContextTypeTestExecution RunningContextType = "testexecution" RunningContextTypeTestSuiteExecution RunningContextType = "testsuiteexecution" + RunningContextTypeTestWorkflow RunningContextType = "testworkflow" RunningContextTypeEmpty RunningContextType = "" ) diff --git a/api/testworkflows/v1/status_types.go b/api/testworkflows/v1/status_types.go index 2ef887ec..0822efd7 100644 --- a/api/testworkflows/v1/status_types.go +++ b/api/testworkflows/v1/status_types.go @@ -20,6 +20,8 @@ type TestWorkflowExecutionSummary struct { Workflow *TestWorkflowSummary `json:"workflow"` // test workflow execution tags Tags map[string]string `json:"tags,omitempty"` + // running context for the test workflow execution (Pro edition only) + RunningContext *TestWorkflowRunningContext `json:"runningContext,omitempty"` } // TestWorkflowResultSummary defines TestWorkflow result summary diff --git a/api/testworkflows/v1/testworkflowexecution_types.go b/api/testworkflows/v1/testworkflowexecution_types.go index c07947f3..dc08702e 100644 --- a/api/testworkflows/v1/testworkflowexecution_types.go +++ b/api/testworkflows/v1/testworkflowexecution_types.go @@ -39,6 +39,8 @@ type TestWorkflowExecutionRequest struct { DisableWebhooks bool `json:"disableWebhooks,omitempty"` // test workflow execution tags Tags map[string]string `json:"tags,omitempty" expr:"template"` + // running context for the test workflow execution (Pro edition only) + RunningContext *TestWorkflowRunningContext `json:"runningContext,omitempty"` } // TestWorkflowExecutionStatus defines the observed state of TestWorkflowExecution @@ -83,6 +85,61 @@ type TestWorkflowExecutionDetails struct { DisableWebhooks bool `json:"disableWebhooks,omitempty"` // test workflow execution tags Tags map[string]string `json:"tags,omitempty"` + // running context for the test workflow execution (Pro edition only) + RunningContext *TestWorkflowRunningContext `json:"runningContext,omitempty"` +} + +// running context for test workflow execution +type TestWorkflowRunningContext struct { + Interface_ *TestWorkflowRunningContextInterface `json:"interface"` + Actor *TestWorkflowRunningContextActor `json:"actor"` +} + +// supported actors for test workflow running context +// +kubebuilder:validation:Enum=cron;testtrigger;user;testworkflow;testworkflowexecution;program +type TestWorkflowRunningContextActorType string + +// List of TestWorkflowRunningContextActorType +const ( + CRON_TestWorkflowRunningContextActorType TestWorkflowRunningContextActorType = "cron" + TESTRIGGER_TestWorkflowRunningContextActorType TestWorkflowRunningContextActorType = "testtrigger" + USER_TestWorkflowRunningContextActorType TestWorkflowRunningContextActorType = "user" + TESTWORKFLOW_TestWorkflowRunningContextActorType TestWorkflowRunningContextActorType = "testworkflow" + TESTWORKFLOWEXECUTION_TestWorkflowRunningContextActorType TestWorkflowRunningContextActorType = "testworkflowexecution" + PROGRAM_TestWorkflowRunningContextActorType TestWorkflowRunningContextActorType = "program" +) + +// running context actor for test workflow execution +type TestWorkflowRunningContextActor struct { + // actor name + Name string `json:"name,omitempty"` + // actor email + Email string `json:"email,omitempty"` + // test workflow execution id + ExecutionId string `json:"executionId,omitempty"` + // all test workflow execution ids starting from the root + ExecutionPath string `json:"executionPath,omitempty"` + Type_ *TestWorkflowRunningContextActorType `json:"type"` +} + +// supported interfaces for test workflow running context +// +kubebuilder:validation:Enum=cli;ui;api;ci/cd;internal +type TestWorkflowRunningContextInterfaceType string + +// List of TestWorkflowRunningContextInterfaceType +const ( + CLI_TestWorkflowRunningContextInterfaceType TestWorkflowRunningContextInterfaceType = "cli" + UI_TestWorkflowRunningContextInterfaceType TestWorkflowRunningContextInterfaceType = "ui" + API_TestWorkflowRunningContextInterfaceType TestWorkflowRunningContextInterfaceType = "api" + CICD_TestWorkflowRunningContextInterfaceType TestWorkflowRunningContextInterfaceType = "ci/cd" + INTERNAL_TestWorkflowRunningContextInterfaceType TestWorkflowRunningContextInterfaceType = "internal" +) + +// running context interface for test workflow execution +type TestWorkflowRunningContextInterface struct { + // interface name + Name string `json:"name,omitempty"` + Type_ *TestWorkflowRunningContextInterfaceType `json:"type"` } // TestWorkflowSignature has signature of TestWorkflow diff --git a/api/testworkflows/v1/zz_generated.deepcopy.go b/api/testworkflows/v1/zz_generated.deepcopy.go index cb445387..8d6cdc35 100644 --- a/api/testworkflows/v1/zz_generated.deepcopy.go +++ b/api/testworkflows/v1/zz_generated.deepcopy.go @@ -321,7 +321,7 @@ func (in *IndependentServiceSpec) DeepCopy() *IndependentServiceSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *IndependentStep) DeepCopyInto(out *IndependentStep) { *out = *in - out.StepMeta = in.StepMeta + in.StepMeta.DeepCopyInto(&out.StepMeta) in.StepControl.DeepCopyInto(&out.StepControl) in.StepSource.DeepCopyInto(&out.StepSource) if in.Services != nil { @@ -729,7 +729,7 @@ func (in *ServiceSpec) DeepCopy() *ServiceSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Step) DeepCopyInto(out *Step) { *out = *in - out.StepMeta = in.StepMeta + in.StepMeta.DeepCopyInto(&out.StepMeta) in.StepControl.DeepCopyInto(&out.StepControl) if in.Use != nil { in, out := &in.Use, &out.Use @@ -988,6 +988,11 @@ func (in *StepExecuteWorkflow) DeepCopy() *StepExecuteWorkflow { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *StepMeta) DeepCopyInto(out *StepMeta) { *out = *in + if in.Pure != nil { + in, out := &in.Pure, &out.Pure + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StepMeta. @@ -1359,6 +1364,11 @@ func (in *TestWorkflowExecutionDetails) DeepCopyInto(out *TestWorkflowExecutionD (*out)[key] = val } } + if in.RunningContext != nil { + in, out := &in.RunningContext, &out.RunningContext + *out = new(TestWorkflowRunningContext) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TestWorkflowExecutionDetails. @@ -1420,6 +1430,11 @@ func (in *TestWorkflowExecutionRequest) DeepCopyInto(out *TestWorkflowExecutionR (*out)[key] = val } } + if in.RunningContext != nil { + in, out := &in.RunningContext, &out.RunningContext + *out = new(TestWorkflowRunningContext) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TestWorkflowExecutionRequest. @@ -1499,6 +1514,11 @@ func (in *TestWorkflowExecutionSummary) DeepCopyInto(out *TestWorkflowExecutionS (*out)[key] = val } } + if in.RunningContext != nil { + in, out := &in.RunningContext, &out.RunningContext + *out = new(TestWorkflowRunningContext) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TestWorkflowExecutionSummary. @@ -1692,6 +1712,71 @@ func (in *TestWorkflowResultSummary) DeepCopy() *TestWorkflowResultSummary { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TestWorkflowRunningContext) DeepCopyInto(out *TestWorkflowRunningContext) { + *out = *in + if in.Interface_ != nil { + in, out := &in.Interface_, &out.Interface_ + *out = new(TestWorkflowRunningContextInterface) + (*in).DeepCopyInto(*out) + } + if in.Actor != nil { + in, out := &in.Actor, &out.Actor + *out = new(TestWorkflowRunningContextActor) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TestWorkflowRunningContext. +func (in *TestWorkflowRunningContext) DeepCopy() *TestWorkflowRunningContext { + if in == nil { + return nil + } + out := new(TestWorkflowRunningContext) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TestWorkflowRunningContextActor) DeepCopyInto(out *TestWorkflowRunningContextActor) { + *out = *in + if in.Type_ != nil { + in, out := &in.Type_, &out.Type_ + *out = new(TestWorkflowRunningContextActorType) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TestWorkflowRunningContextActor. +func (in *TestWorkflowRunningContextActor) DeepCopy() *TestWorkflowRunningContextActor { + if in == nil { + return nil + } + out := new(TestWorkflowRunningContextActor) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TestWorkflowRunningContextInterface) DeepCopyInto(out *TestWorkflowRunningContextInterface) { + *out = *in + if in.Type_ != nil { + in, out := &in.Type_, &out.Type_ + *out = new(TestWorkflowRunningContextInterfaceType) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TestWorkflowRunningContextInterface. +func (in *TestWorkflowRunningContextInterface) DeepCopy() *TestWorkflowRunningContextInterface { + if in == nil { + return nil + } + out := new(TestWorkflowRunningContextInterface) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TestWorkflowSignature) DeepCopyInto(out *TestWorkflowSignature) { *out = *in @@ -1775,6 +1860,11 @@ func (in *TestWorkflowSpecBase) DeepCopyInto(out *TestWorkflowSpecBase) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.System != nil { + in, out := &in.System, &out.System + *out = new(TestWorkflowSystem) + (*in).DeepCopyInto(*out) + } if in.Config != nil { in, out := &in.Config, &out.Config *out = make(map[string]ParameterSchema, len(*in)) @@ -1896,6 +1986,31 @@ func (in *TestWorkflowSummary) DeepCopy() *TestWorkflowSummary { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TestWorkflowSystem) DeepCopyInto(out *TestWorkflowSystem) { + *out = *in + if in.PureByDefault != nil { + in, out := &in.PureByDefault, &out.PureByDefault + *out = new(bool) + **out = **in + } + if in.IsolatedContainers != nil { + in, out := &in.IsolatedContainers, &out.IsolatedContainers + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TestWorkflowSystem. +func (in *TestWorkflowSystem) DeepCopy() *TestWorkflowSystem { + if in == nil { + return nil + } + out := new(TestWorkflowSystem) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TestWorkflowTagSchema) DeepCopyInto(out *TestWorkflowTagSchema) { *out = *in diff --git a/config/crd/bases/tests.testkube.io_testexecutions.yaml b/config/crd/bases/tests.testkube.io_testexecutions.yaml index 756682c1..b8b09cb7 100644 --- a/config/crd/bases/tests.testkube.io_testexecutions.yaml +++ b/config/crd/bases/tests.testkube.io_testexecutions.yaml @@ -256,6 +256,7 @@ spec: - scheduler - testexecution - testsuiteexecution + - testworkflow type: string required: - type @@ -722,6 +723,7 @@ spec: - scheduler - testexecution - testsuiteexecution + - testworkflow type: string required: - type diff --git a/config/crd/bases/testworkflows.testkube.io_testworkflowexecutions.yaml b/config/crd/bases/testworkflows.testkube.io_testworkflowexecutions.yaml index 1430fb95..5f3ca96b 100644 --- a/config/crd/bases/testworkflows.testkube.io_testworkflowexecutions.yaml +++ b/config/crd/bases/testworkflows.testkube.io_testworkflowexecutions.yaml @@ -55,6 +55,60 @@ spec: name: description: custom execution name type: string + runningContext: + description: running context for the test workflow execution (Pro edition only) + properties: + actor: + description: running context actor for test workflow execution + properties: + email: + description: actor email + type: string + executionId: + description: test workflow execution id + type: string + executionPath: + description: all test workflow execution ids starting + from the root + type: string + name: + description: actor name + type: string + type: + description: supported actors for test workflow running context + enum: + - cron + - testtrigger + - user + - testworkflow + - testworkflowexecution + - program + type: string + required: + - type + type: object + interface: + description: running context interface for test workflow execution + properties: + name: + description: interface name + type: string + type: + description: supported interfaces for test workflow running context + enum: + - cli + - ui + - api + - ci/cd + - internal + type: string + required: + - type + type: object + required: + - actor + - interface + type: object tags: additionalProperties: type: string @@ -298,6 +352,60 @@ spec: - predictedStatus - status type: object + runningContext: + description: running context for the test workflow execution (Pro edition only) + properties: + actor: + description: running context actor for test workflow execution + properties: + email: + description: actor email + type: string + executionId: + description: test workflow execution id + type: string + executionPath: + description: all test workflow execution ids starting + from the root + type: string + name: + description: actor name + type: string + type: + description: supported actors for test workflow running context' + enum: + - cron + - testtrigger + - user + - testworkflow + - testworkflowexecution + - program + type: string + required: + - type + type: object + interface: + description: running context interface for test workflow execution + properties: + name: + description: interface name + type: string + type: + description: supported interfaces for test workflow running context + enum: + - cli + - ui + - api + - ci/cd + - internal + type: string + required: + - type + type: object + required: + - actor + - interface + type: object scheduledAt: description: when the execution has been scheduled to run format: date-time diff --git a/config/crd/bases/testworkflows.testkube.io_testworkflows.yaml b/config/crd/bases/testworkflows.testkube.io_testworkflows.yaml index 57513e5b..2646beeb 100644 --- a/config/crd/bases/testworkflows.testkube.io_testworkflows.yaml +++ b/config/crd/bases/testworkflows.testkube.io_testworkflows.yaml @@ -10740,6 +10740,59 @@ spec: - status - totalDurationMs type: object + runningContext: + description: running context for the test workflow execution (Pro edition only) + properties: + actor: + description: running context actor for test workflow execution + properties: + email: + description: actor email + type: string + executionId: + description: test workflow execution id + type: string + executionPath: + description: all test workflow execution ids starting from the root + type: string + name: + description: actor name + type: string + type: + description: supported actors for test workflow running context + enum: + - cron + - testtrigger + - user + - testworkflow + - testworkflowexecution + - program + type: string + required: + - type + type: object + interface: + description: running context interface for test workflow execution + properties: + name: + description: interface name + type: string + type: + description: supported interfaces for test workflow running context + enum: + - cli + - ui + - api + - ci/cd + - internal + type: string + required: + - type + type: object + required: + - actor + - interface + type: object scheduledAt: description: when the execution has been scheduled to run format: date-time diff --git a/internal/controller/testexecution/testexecution_controller.go b/internal/controller/testexecution/testexecution_controller.go index a93fe890..4a6ceab3 100644 --- a/internal/controller/testexecution/testexecution_controller.go +++ b/internal/controller/testexecution/testexecution_controller.go @@ -72,11 +72,13 @@ func (r *TestExecutionReconciler) Reconcile(ctx context.Context, req ctrl.Reques return ctrl.Result{}, nil } - if testExecution.Spec.ExecutionRequest != nil { - testExecution.Spec.ExecutionRequest.RunningContext = &testexecutionv1.RunningContext{ - Type_: testexecutionv1.RunningContextTypeTestExecution, - Context: testExecution.Name, - } + if testExecution.Spec.ExecutionRequest == nil { + testExecution.Spec.ExecutionRequest = &testexecutionv1.ExecutionRequest{} + } + + testExecution.Spec.ExecutionRequest.RunningContext = &testexecutionv1.RunningContext{ + Type_: testexecutionv1.RunningContextTypeTestExecution, + Context: testExecution.Name, } jsonData, err := json.Marshal(testExecution.Spec.ExecutionRequest) diff --git a/internal/controller/testsuiteexecution/testsuiteexecution_controllller.go b/internal/controller/testsuiteexecution/testsuiteexecution_controllller.go index fcc00a75..cc2ec8bc 100644 --- a/internal/controller/testsuiteexecution/testsuiteexecution_controllller.go +++ b/internal/controller/testsuiteexecution/testsuiteexecution_controllller.go @@ -72,11 +72,13 @@ func (r *TestSuiteExecutionReconciler) Reconcile(ctx context.Context, req ctrl.R return ctrl.Result{}, nil } - if testSuiteExecution.Spec.ExecutionRequest != nil { - testSuiteExecution.Spec.ExecutionRequest.RunningContext = &testsuiteexecutionv1.RunningContext{ - Type_: testsuiteexecutionv1.RunningContextTypeTestSuiteExecution, - Context: testSuiteExecution.Name, - } + if testSuiteExecution.Spec.ExecutionRequest == nil { + testSuiteExecution.Spec.ExecutionRequest = &testsuiteexecutionv1.TestSuiteExecutionRequest{} + } + + testSuiteExecution.Spec.ExecutionRequest.RunningContext = &testsuiteexecutionv1.RunningContext{ + Type_: testsuiteexecutionv1.RunningContextTypeTestSuiteExecution, + Context: testSuiteExecution.Name, } jsonData, err := json.Marshal(testSuiteExecution.Spec.ExecutionRequest) diff --git a/internal/controller/testworkflowexecution/testworkflowexecution_controller.go b/internal/controller/testworkflowexecution/testworkflowexecution_controller.go index 86be61cd..33508aac 100644 --- a/internal/controller/testworkflowexecution/testworkflowexecution_controller.go +++ b/internal/controller/testworkflowexecution/testworkflowexecution_controller.go @@ -72,6 +72,22 @@ func (r *TestWorkflowExecutionReconciler) Reconcile(ctx context.Context, req ctr return ctrl.Result{}, nil } + if testWorkflowExecution.Spec.ExecutionRequest == nil { + testWorkflowExecution.Spec.ExecutionRequest = &testworkflowsv1.TestWorkflowExecutionRequest{} + } + + interface_ := testworkflowsv1.API_TestWorkflowRunningContextInterfaceType + actor := testworkflowsv1.TESTWORKFLOWEXECUTION_TestWorkflowRunningContextActorType + testWorkflowExecution.Spec.ExecutionRequest.RunningContext = &testworkflowsv1.TestWorkflowRunningContext{ + Interface_: &testworkflowsv1.TestWorkflowRunningContextInterface{ + Type_: &interface_, + }, + Actor: &testworkflowsv1.TestWorkflowRunningContextActor{ + Name: testWorkflowExecution.Name, + Type_: &actor, + }, + } + jsonData, err := json.Marshal(testWorkflowExecution.Spec.ExecutionRequest) if err != nil { return ctrl.Result{}, err diff --git a/internal/controller/testworkflows/testworkflow_controller.go b/internal/controller/testworkflows/testworkflow_controller.go index fac25cee..f3ad3fed 100644 --- a/internal/controller/testworkflows/testworkflow_controller.go +++ b/internal/controller/testworkflows/testworkflow_controller.go @@ -18,6 +18,7 @@ package testworkflows import ( "context" + "encoding/json" "fmt" "maps" "net/http" @@ -135,6 +136,22 @@ func (r *TestWorkflowReconciler) Reconcile(ctx context.Context, req ctrl.Request } } + interface_ := testworkflowsv1.API_TestWorkflowRunningContextInterfaceType + actor := testworkflowsv1.CRON_TestWorkflowRunningContextActorType + data, err := json.Marshal(testworkflowsv1.TestWorkflowExecutionRequest{ + RunningContext: &testworkflowsv1.TestWorkflowRunningContext{ + Interface_: &testworkflowsv1.TestWorkflowRunningContextInterface{ + Type_: &interface_, + }, + Actor: &testworkflowsv1.TestWorkflowRunningContextActor{ + Type_: &actor, + }, + }, + }) + if err != nil { + return ctrl.Result{}, err + } + for schedule, oldCronJob := range oldCronJobs { if newCronJobConfig, ok := newCronJobConfigs[schedule]; !ok { // Delete removed Cron Jobs @@ -157,7 +174,7 @@ func (r *TestWorkflowReconciler) Reconcile(ctx context.Context, req ctrl.Request ResourceURI: cronjob.TestWorkflowResourceURI, Labels: newCronJobConfig.Labels, Annotations: newCronJobConfig.Annotations, - Data: "{}", + Data: string(data), } if err = r.CronJobClient.Update(ctx, oldCronJob, testWorkflow.Name, @@ -184,7 +201,7 @@ func (r *TestWorkflowReconciler) Reconcile(ctx context.Context, req ctrl.Request ResourceURI: cronjob.TestWorkflowResourceURI, Labels: newCronJobConfig.Labels, Annotations: newCronJobConfig.Annotations, - Data: "{}", + Data: string(data), } if err = r.CronJobClient.Create(ctx, testWorkflow.Name,