Skip to content

Commit

Permalink
feat: [TKC-2299] add tags to testworkflow models (#5744)
Browse files Browse the repository at this point in the history
* feat: add tags to testworkflow models

Signed-off-by: Vladislav Sukhin <[email protected]>

* fix: missed model

Signed-off-by: Vladislav Sukhin <[email protected]>

* fix: dep update

Signed-off-by: Vladislav Sukhin <[email protected]>

* feat: filter by tags

Signed-off-by: Vladislav Sukhin <[email protected]>

* fix: convert dots for parallel step

Signed-off-by: Vladislav Sukhin <[email protected]>

* fix: convert dots for execute

Signed-off-by: Vladislav Sukhin <[email protected]>

* fix: remove filed

Signed-off-by: Vladislav Sukhin <[email protected]>

* fix: remove tags

Signed-off-by: Vladislav Sukhin <[email protected]>

* fix: remove unsued tags

Signed-off-by: Vladislav Sukhin <[email protected]>

* fix: unit tests

Signed-off-by: Vladislav Sukhin <[email protected]>

* feat: pass execution tags

Signed-off-by: Vladislav Sukhin <[email protected]>

* fix: format result

Signed-off-by: Vladislav Sukhin <[email protected]>

* fix: remove from parallel step

Signed-off-by: Vladislav Sukhin <[email protected]>

* fix: cli docs

Signed-off-by: Vladislav Sukhin <[email protected]>

* fix: extract methods

Signed-off-by: Vladislav Sukhin <[email protected]>

* fix: go mod tidy

Signed-off-by: Vladislav Sukhin <[email protected]>

* fix: typo

Signed-off-by: Vladislav Sukhin <[email protected]>

---------

Signed-off-by: Vladislav Sukhin <[email protected]>
Co-authored-by: Jacek Wysocki <[email protected]>
  • Loading branch information
vsukhin and exu authored Aug 19, 2024
1 parent 4a09d78 commit 437ce41
Show file tree
Hide file tree
Showing 34 changed files with 230 additions and 23 deletions.
31 changes: 31 additions & 0 deletions api/v1/testkube.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3735,6 +3735,7 @@ paths:
- pro
parameters:
- $ref: "#/components/parameters/ID"
- $ref: "#/components/parameters/TagSelector"
summary: List test workflow executions
description: List test workflow executions
operationId: listTestWorkflowExecutionsByTestWorkflow
Expand Down Expand Up @@ -3963,6 +3964,7 @@ paths:
- pro
parameters:
- $ref: "#/components/parameters/ID"
- $ref: "#/components/parameters/TagSelector"
summary: List test workflow executions
description: List test workflow executions
operationId: listTestWorkflowExecutions
Expand Down Expand Up @@ -7889,6 +7891,8 @@ components:
type: boolean
description: whether webhooks on the execution of this test workflow are disabled
default: false
tags:
$ref: "#/components/schemas/TestWorkflowTagValue"

TestWorkflowWithExecution:
type: object
Expand Down Expand Up @@ -7980,6 +7984,8 @@ components:
example:
- true
- false
tags:
$ref: "#/components/schemas/TestWorkflowTagValue"
required:
- id
- name
Expand Down Expand Up @@ -8012,6 +8018,8 @@ components:
$ref: "#/components/schemas/TestWorkflowResultSummary"
workflow:
$ref: "#/components/schemas/TestWorkflowSummary"
tags:
$ref: "#/components/schemas/TestWorkflowTagValue"
required:
- id
- name
Expand Down Expand Up @@ -8525,6 +8533,8 @@ components:
type: array
items:
$ref: "#/components/schemas/TestWorkflowEvent"
execution:
$ref: "#/components/schemas/TestWorkflowTagSchema"

TestWorkflowTemplateSpec:
type: object
Expand Down Expand Up @@ -8561,6 +8571,8 @@ components:
type: array
items:
$ref: "#/components/schemas/TestWorkflowEvent"
execution:
$ref: "#/components/schemas/TestWorkflowTagSchema"

TestWorkflowStepControl:
type: object
Expand Down Expand Up @@ -9382,6 +9394,19 @@ components:
format: int64
description: test workflow execution generation

TestWorkflowTagValue:
type: object
description: tag values to pass to the test workflow execution
additionalProperties:
type: string

TestWorkflowTagSchema:
type: object
description: test workflow execution tag definition
properties:
tags:
$ref: "#/components/schemas/TestWorkflowTagValue"

ContentGitAuthType:
type: string
description: auth type for git requests
Expand Down Expand Up @@ -10505,6 +10530,12 @@ components:
default: false
description: dont delete CRD
required: false
TagSelector:
in: query
name: tagSelector
schema:
type: string
description: Test workflow execution tags
requestBodies:
UploadsBody:
description: "Upload files request body data"
Expand Down
5 changes: 4 additions & 1 deletion cmd/kubectl-testkube/commands/testworkflows/executions.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ func NewGetTestWorkflowExecutionsCmd() *cobra.Command {
selectors []string
testWorkflowName string
logsOnly bool
tags []string
)

cmd := &cobra.Command{
Expand All @@ -44,7 +45,8 @@ func NewGetTestWorkflowExecutionsCmd() *cobra.Command {
client, _, err := common.GetClient(cmd)
ui.ExitOnError("getting client", err)

executions, err := client.ListTestWorkflowExecutions(testWorkflowName, limit, strings.Join(selectors, ","))
executions, err := client.ListTestWorkflowExecutions(testWorkflowName, limit,
strings.Join(selectors, ","), strings.Join(tags, ","))
ui.ExitOnError("getting test workflow executions list", err)
err = render.List(cmd, testkube.TestWorkflowExecutionSummaries(executions.Results), os.Stdout)
ui.ExitOnError("rendering list", err)
Expand Down Expand Up @@ -84,6 +86,7 @@ func NewGetTestWorkflowExecutionsCmd() *cobra.Command {
cmd.Flags().IntVar(&limit, "limit", 1000, "max number of records to return")
cmd.Flags().StringSliceVarP(&selectors, "label", "l", nil, "label key value pair: --label key1=value1")
cmd.Flags().BoolVar(&logsOnly, "logs-only", false, "show only execution logs")
cmd.Flags().StringSliceVarP(&tags, "tag", "", nil, "tag key value pair: --tag key1=value1")

return cmd
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,14 @@ func printPrettyOutput(ui *ui.UI, execution testkube.TestWorkflowExecution) {
}
ui.Warn("Requested at: ", execution.ScheduledAt.String())
ui.Warn("Disabled webhooks: ", fmt.Sprint(execution.DisableWebhooks))
if len(execution.Tags) > 0 {
ui.NL()
ui.Warn("Tags: ", testkube.MapToString(execution.Tags))
}
if execution.Result != nil && execution.Result.Status != nil {
ui.Warn("Status: ", string(*execution.Result.Status))
if !execution.Result.QueuedAt.IsZero() {
ui.Warn("Queued at: ", execution.Result.QueuedAt.String())
ui.Warn("Queued at: ", execution.Result.QueuedAt.String())
}
if !execution.Result.StartedAt.IsZero() {
ui.Warn("Started at: ", execution.Result.StartedAt.String())
Expand Down
3 changes: 3 additions & 0 deletions cmd/kubectl-testkube/commands/testworkflows/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ func NewRunTestWorkflowCmd() *cobra.Command {
downloadDir string
format string
masks []string
tags map[string]string
)

cmd := &cobra.Command{
Expand All @@ -65,6 +66,7 @@ func NewRunTestWorkflowCmd() *cobra.Command {
Name: executionName,
Config: config,
DisableWebhooks: disableWebhooks,
Tags: tags,
})
if err != nil {
// User friendly Open Source operation error
Expand Down Expand Up @@ -121,6 +123,7 @@ func NewRunTestWorkflowCmd() *cobra.Command {
cmd.Flags().BoolVarP(&downloadArtifactsEnabled, "download-artifacts", "d", false, "download artifacts automatically")
cmd.Flags().StringVar(&format, "format", "folder", "data format for storing files, one of folder|archive")
cmd.Flags().StringArrayVarP(&masks, "mask", "", []string{}, "regexp to filter downloaded files, single or comma separated, like report/.* or .*\\.json,.*\\.js$")
cmd.Flags().StringToStringVarP(&tags, "tag", "", map[string]string{}, "execution tags in a form of name1=val1 passed to executor")

return cmd
}
Expand Down
7 changes: 7 additions & 0 deletions cmd/tcl/testworkflow-toolkit/commands/execute.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"github.com/kubeshop/testkube/pkg/mapper/testworkflows"
"github.com/kubeshop/testkube/pkg/testworkflows/testworkflowprocessor/constants"
"github.com/kubeshop/testkube/pkg/ui"
"github.com/kubeshop/testkube/pkg/utils"
)

type testExecutionDetails struct {
Expand Down Expand Up @@ -151,10 +152,16 @@ func buildWorkflowExecution(workflow testworkflowsv1.StepExecuteWorkflow, async
return func() (err error) {
c := env.Testkube()

tags, err := utils.DecodeEnvVarToStringMap(env.ExecutionTags())
if err != nil {
ui.Errf("failed to decode tags: %s: %s", workflow.Name, err.Error())
}

exec, err := c.ExecuteTestWorkflow(workflow.Name, testkube.TestWorkflowExecutionRequest{
Name: workflow.ExecutionName,
Config: testworkflows.MapConfigValueKubeToAPI(workflow.Config),
DisableWebhooks: env.ExecutionDisableWebhooks(),
Tags: tags,
})
execName := exec.Name
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions cmd/tcl/testworkflow-toolkit/spawn/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ func CreateExecutionMachine(prefix string, index int64) (string, expressions.Mac
"number": env.ExecutionNumber(),
"scheduledAt": env.ExecutionScheduledAt().UTC().Format(constants.RFC3339Millis),
"disableWebhooks": env.ExecutionDisableWebhooks(),
"tags": env.ExecutionTags(),
})
}

Expand Down
5 changes: 5 additions & 0 deletions cmd/testworkflow-toolkit/env/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ type envExecutionConfig struct {
RootResourceId string `envconfig:"TK_EXR"`
FSPrefix string `envconfig:"TK_FS"`
DisableWebhooks bool `envconfig:"TK_DWH"`
Tags string `envconfig:"TK_TAG"`
}

type envSystemConfig struct {
Expand Down Expand Up @@ -157,3 +158,7 @@ func ExecutionDisableWebhooks() bool {
func JUnitParserEnabled() bool {
return Config().Features.EnableJUnitParser
}

func ExecutionTags() string {
return Config().Execution.Tags
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ require (
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
github.com/kelseyhightower/envconfig v1.4.0
github.com/kubepug/kubepug v1.7.1
github.com/kubeshop/testkube-operator v1.15.2-beta1.0.20240808123612-1bfae781ec4c
github.com/kubeshop/testkube-operator v1.15.2-beta1.0.20240812092626-c23e9abedcd0
github.com/minio/minio-go/v7 v7.0.47
github.com/montanaflynn/stats v0.6.6
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 @@ -371,8 +371,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.15.2-beta1.0.20240808123612-1bfae781ec4c h1:lMNmYvazHkx+yDxxbNUg0Vfk+5tvexLwhUGZAZ9mM6Y=
github.com/kubeshop/testkube-operator v1.15.2-beta1.0.20240808123612-1bfae781ec4c/go.mod h1:P47tw1nKQFufdsZndyq2HG2MSa0zK/lU0XpRfZtEmIk=
github.com/kubeshop/testkube-operator v1.15.2-beta1.0.20240812092626-c23e9abedcd0 h1:5+V5zL1CyCGQkoi9rYrf1ttOus6j2A5xGfuPjXA2+Ns=
github.com/kubeshop/testkube-operator v1.15.2-beta1.0.20240812092626-c23e9abedcd0/go.mod h1:P47tw1nKQFufdsZndyq2HG2MSa0zK/lU0XpRfZtEmIk=
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
github.com/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8LFgLN4=
Expand Down
5 changes: 5 additions & 0 deletions internal/app/api/v1/testworkflowexecutions.go
Original file line number Diff line number Diff line change
Expand Up @@ -510,5 +510,10 @@ func getWorkflowExecutionsFilterFromRequest(c *fiber.Ctx) testworkflow2.Filter {
filter = filter.WithSelector(selector)
}

tagSelector := c.Query("tagSelector")
if tagSelector != "" {
filter = filter.WithTagSelector(tagSelector)
}

return filter
}
2 changes: 1 addition & 1 deletion pkg/api/v1/client/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ type TestWorkflowAPI interface {
// TestWorkflowExecutionAPI describes test workflow api methods
type TestWorkflowExecutionAPI interface {
GetTestWorkflowExecution(executionID string) (execution testkube.TestWorkflowExecution, err error)
ListTestWorkflowExecutions(id string, limit int, selector string) (executions testkube.TestWorkflowExecutionsResult, err error)
ListTestWorkflowExecutions(id string, limit int, selector, tagSelector string) (executions testkube.TestWorkflowExecutionsResult, err error)
AbortTestWorkflowExecution(workflow string, id string) error
AbortTestWorkflowExecutions(workflow string) error
GetTestWorkflowExecutionArtifacts(executionID string) (artifacts testkube.Artifacts, err error)
Expand Down
7 changes: 4 additions & 3 deletions pkg/api/v1/client/testworkflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,14 +136,15 @@ func (c TestWorkflowClient) GetTestWorkflowExecution(id string) (testkube.TestWo
}

// ListTestWorkflowExecutions list test workflow executions for selected workflow
func (c TestWorkflowClient) ListTestWorkflowExecutions(id string, limit int, selector string) (testkube.TestWorkflowExecutionsResult, error) {
func (c TestWorkflowClient) ListTestWorkflowExecutions(id string, limit int, selector, tagSelector string) (testkube.TestWorkflowExecutionsResult, error) {
uri := c.testWorkflowExecutionsResultTransport.GetURI("/test-workflow-executions/")
if id != "" {
uri = c.testWorkflowExecutionsResultTransport.GetURI(fmt.Sprintf("/test-workflows/%s/executions", id))
}
params := map[string]string{
"selector": selector,
"pageSize": fmt.Sprintf("%d", limit),
"selector": selector,
"pageSize": fmt.Sprintf("%d", limit),
"tagSelector": tagSelector,
}
return c.testWorkflowExecutionsResultTransport.Execute(http.MethodGet, uri, nil, params)
}
Expand Down
3 changes: 2 additions & 1 deletion pkg/api/v1/testkube/model_test_workflow_execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,6 @@ type TestWorkflowExecution struct {
// test workflow execution name started the test workflow execution
TestWorkflowExecutionName string `json:"testWorkflowExecutionName,omitempty"`
// whether webhooks on the execution of this test workflow are disabled
DisableWebhooks bool `json:"disableWebhooks,omitempty"`
DisableWebhooks bool `json:"disableWebhooks,omitempty"`
Tags map[string]string `json:"tags,omitempty"`
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import "github.com/kubeshop/testkube/pkg/utils"
type TestWorkflowExecutions []TestWorkflowExecution

func (executions TestWorkflowExecutions) Table() (header []string, output [][]string) {
header = []string{"Id", "Name", "Test Workflow Name", "Status", "Labels"}
header = []string{"Id", "Name", "Test Workflow Name", "Status", "Labels", "Tags"}

for _, e := range executions {
status := "unknown"
Expand All @@ -19,6 +19,7 @@ func (executions TestWorkflowExecutions) Table() (header []string, output [][]st
e.Workflow.Name,
status,
MapToString(e.Workflow.Labels),
MapToString(e.Tags),
})
}

Expand All @@ -28,6 +29,9 @@ func (executions TestWorkflowExecutions) Table() (header []string, output [][]st
func (e *TestWorkflowExecution) ConvertDots(fn func(string) string) *TestWorkflowExecution {
e.Workflow.ConvertDots(fn)
e.ResolvedWorkflow.ConvertDots(fn)
if e.Tags != nil {
e.Tags = convertDotsInMap(e.Tags, fn)
}
return e
}

Expand Down
3 changes: 2 additions & 1 deletion pkg/api/v1/testkube/model_test_workflow_execution_request.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@ type TestWorkflowExecutionRequest struct {
// test workflow execution name started the test workflow execution
TestWorkflowExecutionName string `json:"testWorkflowExecutionName,omitempty"`
// whether webhooks on the execution of this test workflow are disabled
DisableWebhooks bool `json:"disableWebhooks,omitempty"`
DisableWebhooks bool `json:"disableWebhooks,omitempty"`
Tags map[string]string `json:"tags,omitempty"`
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ type TestWorkflowExecutionSummary struct {
StatusAt time.Time `json:"statusAt,omitempty"`
Result *TestWorkflowResultSummary `json:"result,omitempty"`
Workflow *TestWorkflowSummary `json:"workflow"`
Tags map[string]string `json:"tags,omitempty"`
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
type TestWorkflowExecutionSummaries []TestWorkflowExecutionSummary

func (executions TestWorkflowExecutionSummaries) Table() (header []string, output [][]string) {
header = []string{"Id", "Name", "Test Workflow Name", "Status", "Labels"}
header = []string{"Id", "Name", "Test Workflow Name", "Status", "Labels", "Tags"}

for _, e := range executions {
status := "unknown"
Expand All @@ -21,6 +21,7 @@ func (executions TestWorkflowExecutionSummaries) Table() (header []string, outpu
e.Workflow.Name,
status,
MapToString(e.Workflow.Labels),
MapToString(e.Tags),
})
}

Expand All @@ -29,6 +30,9 @@ func (executions TestWorkflowExecutionSummaries) Table() (header []string, outpu

func (e *TestWorkflowExecutionSummary) ConvertDots(fn func(string) string) *TestWorkflowExecutionSummary {
e.Workflow.ConvertDots(fn)
if e.Tags != nil {
e.Tags = convertDotsInMap(e.Tags, fn)
}
return e
}

Expand Down
6 changes: 5 additions & 1 deletion pkg/api/v1/testkube/model_test_workflow_extended.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func (w *TestWorkflow) ConvertDots(fn func(string) string) *TestWorkflow {
if w == nil {
return w
}
if w.Labels == nil {
if w.Labels != nil {
w.Labels = convertDotsInMap(w.Labels, fn)
}
if w.Spec.Pod != nil {
Expand All @@ -56,6 +56,10 @@ func (w *TestWorkflow) ConvertDots(fn func(string) string) *TestWorkflow {
for i := range w.Spec.After {
w.Spec.After[i].ConvertDots(fn)
}
if w.Spec.Execution != nil {
w.Spec.Execution.Tags = convertDotsInMap(w.Spec.Execution.Tags, fn)
}

return w
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,5 @@ type TestWorkflowIndependentStepParallel struct {
Steps []TestWorkflowIndependentStep `json:"steps,omitempty"`
After []TestWorkflowIndependentStep `json:"after,omitempty"`
Events []TestWorkflowEvent `json:"events,omitempty"`
Execution *TestWorkflowTagSchema `json:"execution,omitempty"`
}
1 change: 1 addition & 0 deletions pkg/api/v1/testkube/model_test_workflow_spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ type TestWorkflowSpec struct {
Steps []TestWorkflowStep `json:"steps,omitempty"`
After []TestWorkflowStep `json:"after,omitempty"`
Events []TestWorkflowEvent `json:"events,omitempty"`
Execution *TestWorkflowTagSchema `json:"execution,omitempty"`
}
1 change: 1 addition & 0 deletions pkg/api/v1/testkube/model_test_workflow_step_parallel.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,5 @@ type TestWorkflowStepParallel struct {
Steps []TestWorkflowStep `json:"steps,omitempty"`
After []TestWorkflowStep `json:"after,omitempty"`
Events []TestWorkflowEvent `json:"events,omitempty"`
Execution *TestWorkflowTagSchema `json:"execution,omitempty"`
}
15 changes: 15 additions & 0 deletions pkg/api/v1/testkube/model_test_workflow_tag_schema.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* 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

// test workflow execution tag definition
type TestWorkflowTagSchema struct {
Tags map[string]string `json:"tags,omitempty"`
}
Loading

0 comments on commit 437ce41

Please sign in to comment.