Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: [TKC-3146] [TKC-3147] trigger parameters and regex #6130

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions api/v1/testkube.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7923,6 +7923,8 @@ components:
$ref: "#/components/schemas/TestTriggerProbeSpec"
action:
$ref: "#/components/schemas/TestTriggerActions"
actionParameters:
$ref: "#/components/schemas/TestTriggerActionParameters"
execution:
$ref: "#/components/schemas/TestTriggerExecutions"
testSelector:
Expand Down Expand Up @@ -7979,6 +7981,10 @@ components:
type: string
description: resource namespace
example: testkube
namespaceRegex:
type: string
description: kubernetes resource namespace regex
example: test*
labelSelector:
$ref: "https://raw.githubusercontent.com/garethr/kubernetes-json-schema/master/v1.7.8/_definitions.json#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector"
description: label selector for Kubernetes resources
Expand Down Expand Up @@ -8010,6 +8016,15 @@ components:
enum:
- run

TestTriggerActionParameters:
description: supported action parameters for test triggers
type: object
properties:
config:
$ref: "#/components/schemas/TestWorkflowConfigValue"
tags:
$ref: "#/components/schemas/TestWorkflowTagValue"

TestTriggerConditionSpec:
type: object
properties:
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,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.20250122143845-e35b2034b520
github.com/kubeshop/testkube-operator v1.17.55-0.20250123143852-c71bd24e539a
github.com/minio/minio-go/v7 v7.0.66
github.com/montanaflynn/stats v0.7.1
github.com/moogar0880/problems v0.1.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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.20250122143845-e35b2034b520 h1:OE0GtE9qeyxBUu6ctfpZbftaUngMt9EjaEcDzDUFOns=
github.com/kubeshop/testkube-operator v1.17.55-0.20250122143845-e35b2034b520/go.mod h1:P47tw1nKQFufdsZndyq2HG2MSa0zK/lU0XpRfZtEmIk=
github.com/kubeshop/testkube-operator v1.17.55-0.20250123143852-c71bd24e539a h1:hvRkE6ORdTo9tct0B3ddhAvrQAl3TlKYx83k9DP1d/I=
github.com/kubeshop/testkube-operator v1.17.55-0.20250123143852-c71bd24e539a/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=
Expand Down
1 change: 1 addition & 0 deletions pkg/api/v1/testkube/model_test_trigger.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type TestTrigger struct {
ConditionSpec *TestTriggerConditionSpec `json:"conditionSpec,omitempty"`
ProbeSpec *TestTriggerProbeSpec `json:"probeSpec,omitempty"`
Action *TestTriggerActions `json:"action"`
ActionParameters *TestTriggerActionParameters `json:"actionParameters,omitempty"`
Execution *TestTriggerExecutions `json:"execution"`
TestSelector *TestTriggerSelector `json:"testSelector"`
ConcurrencyPolicy *TestTriggerConcurrencyPolicies `json:"concurrencyPolicy,omitempty"`
Expand Down
16 changes: 16 additions & 0 deletions pkg/api/v1/testkube/model_test_trigger_action_parameters.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* Testkube API
*
* Testkube provides a Kubernetes-native framework for test definition, execution and results
*
* API version: 1.0.0
* Contact: [email protected]
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package testkube

// supported action parameters for test triggers
type TestTriggerActionParameters struct {
Config map[string]string `json:"config,omitempty"`
Tags map[string]string `json:"tags,omitempty"`
}
6 changes: 4 additions & 2 deletions pkg/api/v1/testkube/model_test_trigger_selector.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ type TestTriggerSelector struct {
// kubernetes resource name regex
NameRegex string `json:"nameRegex,omitempty"`
// resource namespace
Namespace string `json:"namespace,omitempty"`
LabelSelector *IoK8sApimachineryPkgApisMetaV1LabelSelector `json:"labelSelector,omitempty"`
Namespace string `json:"namespace,omitempty"`
// kubernetes resource namespace regex
NamespaceRegex string `json:"namespaceRegex,omitempty"`
LabelSelector *IoK8sApimachineryPkgApisMetaV1LabelSelector `json:"labelSelector,omitempty"`
}
1 change: 1 addition & 0 deletions pkg/api/v1/testkube/model_test_trigger_upsert_request.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type TestTriggerUpsertRequest struct {
ConditionSpec *TestTriggerConditionSpec `json:"conditionSpec,omitempty"`
ProbeSpec *TestTriggerProbeSpec `json:"probeSpec,omitempty"`
Action *TestTriggerActions `json:"action"`
ActionParameters *TestTriggerActionParameters `json:"actionParameters,omitempty"`
Execution *TestTriggerExecutions `json:"execution"`
TestSelector *TestTriggerSelector `json:"testSelector"`
ConcurrencyPolicy *TestTriggerConcurrencyPolicies `json:"concurrencyPolicy,omitempty"`
Expand Down
22 changes: 18 additions & 4 deletions pkg/mapper/testtriggers/kube_openapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ func MapCRDToAPI(crd *testsv1.TestTrigger) testkube.TestTrigger {
ConditionSpec: mapConditionSpecFromCRD(crd.Spec.ConditionSpec),
ProbeSpec: mapProbeSpecFromCRD(crd.Spec.ProbeSpec),
Action: action,
ActionParameters: mapActionParametersFromCRD(crd.Spec.ActionParameters),
Execution: execution,
TestSelector: mapSelectorFromCRD(crd.Spec.TestSelector),
ConcurrencyPolicy: concurrencyPolicy,
Expand All @@ -62,10 +63,11 @@ func mapSelectorFromCRD(selector testsv1.TestTriggerSelector) *testkube.TestTrig
labelSelector = mapLabelSelectorFromCRD(selector.LabelSelector)
}
return &testkube.TestTriggerSelector{
Name: selector.Name,
NameRegex: selector.NameRegex,
Namespace: selector.Namespace,
LabelSelector: labelSelector,
Name: selector.Name,
NameRegex: selector.NameRegex,
Namespace: selector.Namespace,
NamespaceRegex: selector.NamespaceRegex,
LabelSelector: labelSelector,
}
}

Expand Down Expand Up @@ -108,6 +110,17 @@ func mapConditionSpecFromCRD(conditionSpec *testsv1.TestTriggerConditionSpec) *t
}
}

func mapActionParametersFromCRD(actionParameters *testsv1.TestTriggerActionParameters) *testkube.TestTriggerActionParameters {
if actionParameters == nil {
return nil
}

return &testkube.TestTriggerActionParameters{
Config: actionParameters.Config,
Tags: actionParameters.Tags,
}
}

func MapTestTriggerCRDToTestTriggerUpsertRequest(request testsv1.TestTrigger) testkube.TestTriggerUpsertRequest {
var resource *testkube.TestTriggerResources
if request.Spec.Resource != "" {
Expand Down Expand Up @@ -139,6 +152,7 @@ func MapTestTriggerCRDToTestTriggerUpsertRequest(request testsv1.TestTrigger) te
ConditionSpec: mapConditionSpecFromCRD(request.Spec.ConditionSpec),
ProbeSpec: mapProbeSpecFromCRD(request.Spec.ProbeSpec),
Action: action,
ActionParameters: mapActionParametersFromCRD(request.Spec.ActionParameters),
Execution: execution,
TestSelector: mapSelectorFromCRD(request.Spec.TestSelector),
ConcurrencyPolicy: concurrencyPolicy,
Expand Down
21 changes: 17 additions & 4 deletions pkg/mapper/testtriggers/openapi_kube.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ func MapTestTriggerUpsertRequestToTestTriggerCRD(request testkube.TestTriggerUps
ConditionSpec: mapConditionSpecCRD(request.ConditionSpec),
ProbeSpec: mapProbeSpecCRD(request.ProbeSpec),
Action: action,
ActionParameters: mapActionParametersCRD(request.ActionParameters),
Execution: execution,
TestSelector: mapSelectorToCRD(request.TestSelector),
ConcurrencyPolicy: concurrencyPolicy,
Expand All @@ -55,10 +56,11 @@ func mapSelectorToCRD(selector *testkube.TestTriggerSelector) testsv1.TestTrigge
labelSelector = mapLabelSelectorToCRD(selector.LabelSelector)
}
return testsv1.TestTriggerSelector{
Name: selector.Name,
NameRegex: selector.NameRegex,
Namespace: selector.Namespace,
LabelSelector: labelSelector,
Name: selector.Name,
NameRegex: selector.NameRegex,
Namespace: selector.Namespace,
NamespaceRegex: selector.NamespaceRegex,
LabelSelector: labelSelector,
}
}

Expand Down Expand Up @@ -131,3 +133,14 @@ func mapProbeSpecCRD(probeSpec *testkube.TestTriggerProbeSpec) *testsv1.TestTrig
Probes: probes,
}
}

func mapActionParametersCRD(actionParameters *testkube.TestTriggerActionParameters) *testsv1.TestTriggerActionParameters {
if actionParameters == nil {
return nil
}

return &testsv1.TestTriggerActionParameters{
Config: actionParameters.Config,
Tags: actionParameters.Tags,
}
}
19 changes: 11 additions & 8 deletions pkg/triggers/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ type watcherEvent struct {
name string
namespace string
labels map[string]string
object metav1.Object
objectMeta metav1.Object
object any
eventType testtrigger.EventType
causes []testtrigger.Cause
conditionsGetter conditionsGetterFn
Expand Down Expand Up @@ -68,17 +69,19 @@ func withNotEmptyName(name string) watcherOpts {

func newWatcherEvent(
eventType testtrigger.EventType,
object metav1.Object,
objectMeta metav1.Object,
object any,
resource testtrigger.ResourceType,
opts ...watcherOpts,
) *watcherEvent {
w := &watcherEvent{
resource: resource,
name: object.GetName(),
namespace: object.GetNamespace(),
labels: object.GetLabels(),
object: object,
eventType: eventType,
resource: resource,
name: objectMeta.GetName(),
namespace: objectMeta.GetNamespace(),
labels: objectMeta.GetLabels(),
objectMeta: objectMeta,
object: object,
eventType: eventType,
}

for _, opt := range opts {
Expand Down
68 changes: 65 additions & 3 deletions pkg/triggers/executor.go
Original file line number Diff line number Diff line change
@@ -1,28 +1,30 @@
package triggers

import (
"bytes"
"context"
"fmt"
"regexp"
"strings"
"time"

"github.com/pkg/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/util/jsonpath"

testsv3 "github.com/kubeshop/testkube-operator/api/tests/v3"
testsuitesv3 "github.com/kubeshop/testkube-operator/api/testsuite/v3"
testtriggersv1 "github.com/kubeshop/testkube-operator/api/testtriggers/v1"
testworkflowsv1 "github.com/kubeshop/testkube-operator/api/testworkflows/v1"
"github.com/kubeshop/testkube/internal/common"
"github.com/kubeshop/testkube/pkg/api/v1/testkube"
"github.com/kubeshop/testkube/pkg/cloud"
"github.com/kubeshop/testkube/pkg/log"
"github.com/kubeshop/testkube/pkg/mapper/testworkflows"
"github.com/kubeshop/testkube/pkg/newclients/testworkflowclient"
"github.com/kubeshop/testkube/pkg/testworkflows/testworkflowexecutor"

"github.com/kubeshop/testkube/pkg/api/v1/testkube"
"github.com/kubeshop/testkube/pkg/scheduler"
triggerstcl "github.com/kubeshop/testkube/pkg/tcl/testworkflowstcl/triggers"
"github.com/kubeshop/testkube/pkg/testworkflows/testworkflowexecutor"
"github.com/kubeshop/testkube/pkg/workerpool"
)

Expand All @@ -32,6 +34,7 @@ const (
ExecutionTest = "test"
ExecutionTestSuite = "testsuite"
ExecutionTestWorkflow = "testworkflow"
JsonPathPrefix = "jsonpath="
)

type ExecutorF func(context.Context, *watcherEvent, *testtriggersv1.TestTrigger) error
Expand Down Expand Up @@ -150,6 +153,49 @@ func (s *Service) execute(ctx context.Context, e *watcherEvent, t *testtriggersv
for _, variable := range variables {
execution.Config[variable.Name] = variable.Value
}

if t.Spec.ActionParameters != nil {
if len(t.Spec.ActionParameters.Tags) > 0 && execution.Tags == nil {
execution.Tags = make(map[string]string)
}

var parameters = []struct {
name string
s *map[string]string
d *map[string]string
}{
{
"config",
&t.Spec.ActionParameters.Config,
&execution.Config,
},
{
"tag",
&t.Spec.ActionParameters.Tags,
&execution.Tags,
},
}

for _, parameter := range parameters {
for key, value := range *parameter.s {
if strings.HasPrefix(value, JsonPathPrefix) {
s.logger.Debugf("trigger service: executor component: trigger %s/%s parsing jsonpath %s for %s %s",
t.Namespace, t.Name, key, parameter.name, value)
data, err := s.getJsonPathData(e, strings.TrimPrefix(value, JsonPathPrefix))
if err != nil {
s.logger.Errorf("trigger service: executor component: trigger %s/%s parsing jsonpath %s for %s %s error %v",
t.Namespace, t.Name, key, value, parameter.name, err)
continue
}

(*parameter.d)[key] = data
} else {
(*parameter.d)[key] = value
}
}
}
}

return execution
}),
}
Expand Down Expand Up @@ -191,6 +237,22 @@ func (s *Service) execute(ctx context.Context, e *watcherEvent, t *testtriggersv
return nil
}

func (s *Service) getJsonPathData(e *watcherEvent, value string) (string, error) {
jp := jsonpath.New("field")
err := jp.Parse(value)
if err != nil {
return "", err
}

buf := new(bytes.Buffer)
err = jp.Execute(buf, e.object)
if err != nil {
return "", err
}

return buf.String(), nil
}

func (s *Service) getTests(t *testtriggersv1.TestTrigger) ([]testsv3.Test, error) {
var tests []testsv3.Test
if t.Spec.TestSelector.Name != "" {
Expand Down
Loading
Loading