Skip to content

Commit

Permalink
fix: [TKC-2209] add webhooks events (#5666)
Browse files Browse the repository at this point in the history
* fix: sync docs

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

* fix: remove on state changed

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

* fix: unit tests

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

* fix: add new webhook events

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

* fix: remove link

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

* fix: remove slack events

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

* fix: support new evenys in webhooks

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

* docs: new event types

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

* fix: unit test for event types

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

* fix: unit tests for events

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

* fix: unit tests for exetended event type

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

* fix: add parallel unit tests

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

* fix: unit tests for emitter

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

* fix: add break

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

* fix: add nil check

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

* fix: test suite event end time

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

* fix: dep update

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

* fix: doc typo

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

---------

Signed-off-by: Vladislav Sukhin <[email protected]>
  • Loading branch information
vsukhin committed Jul 19, 2024
1 parent b614f25 commit af6ac02
Show file tree
Hide file tree
Showing 26 changed files with 744 additions and 120 deletions.
21 changes: 14 additions & 7 deletions api/v1/testkube.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7096,13 +7096,6 @@ components:
example:
- true
- false
onStateChange:
type: boolean
description: whether webhook is triggered on state change only
default: false
example:
- true
- false

Event:
description: Event data
Expand Down Expand Up @@ -7165,16 +7158,30 @@ components:
- end-test-failed
- end-test-aborted
- end-test-timeout
- become-test-up
- become-test-down
- become-test-failed
- become-test-aborted
- become-test-timeout
- start-testsuite
- end-testsuite-success
- end-testsuite-failed
- end-testsuite-aborted
- end-testsuite-timeout
- become-testsuite-up
- become-testsuite-down
- become-testsuite-failed
- become-testsuite-aborted
- become-testsuite-timeout
- queue-testworkflow
- start-testworkflow
- end-testworkflow-success
- end-testworkflow-failed
- end-testworkflow-aborted
- become-testworkflow-up
- become-testworkflow-down
- become-testworkflow-failed
- become-testworkflow-aborted
- created
- updated
- deleted
Expand Down
14 changes: 0 additions & 14 deletions cmd/kubectl-testkube/commands/webhooks/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,6 @@ func NewCreateWebhookOptionsFromFlags(cmd *cobra.Command) (options apiv1.CreateW
return options, err
}

onStateChange, err := cmd.Flags().GetBool("on-state-change")
if err != nil {
return options, err
}

disabled, err := cmd.Flags().GetBool("disable")
if err != nil {
return options, err
Expand All @@ -64,7 +59,6 @@ func NewCreateWebhookOptionsFromFlags(cmd *cobra.Command) (options apiv1.CreateW
PayloadTemplate: payloadTemplateContent,
Headers: headers,
PayloadTemplateReference: payloadTemplateReference,
OnStateChange: onStateChange,
Disabled: disabled,
}

Expand Down Expand Up @@ -157,13 +151,5 @@ func NewUpdateWebhookOptionsFromFlags(cmd *cobra.Command) (options apiv1.UpdateW
options.Disabled = &disabled
}

if cmd.Flag("on-state-change").Changed {
onStateChange, err := cmd.Flags().GetBool("on-state-change")
if err != nil {
return options, err
}
options.OnStateChange = &onStateChange
}

return options, nil
}
2 changes: 0 additions & 2 deletions cmd/kubectl-testkube/commands/webhooks/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ func NewCreateWebhookCmd() *cobra.Command {
payloadTemplateReference string
update bool
disable bool
onStateChange bool
)

cmd := &cobra.Command{
Expand Down Expand Up @@ -103,7 +102,6 @@ func NewCreateWebhookCmd() *cobra.Command {
cmd.Flags().BoolVar(&update, "update", false, "update, if webhook already exists")
cmd.Flags().BoolVar(&disable, "disable", false, "disable webhook")
cmd.Flags().MarkDeprecated("enable", "enable webhook is deprecated")
cmd.Flags().BoolVar(&onStateChange, "on-state-change", false, "specify whether webhook should be triggered only on a state change")

return cmd
}
2 changes: 0 additions & 2 deletions cmd/kubectl-testkube/commands/webhooks/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ func UpdateWebhookCmd() *cobra.Command {
headers map[string]string
payloadTemplateReference string
disable bool
onStateChange bool
)

cmd := &cobra.Command{
Expand Down Expand Up @@ -60,7 +59,6 @@ func UpdateWebhookCmd() *cobra.Command {
cmd.Flags().StringVar(&payloadTemplateReference, "payload-template-reference", "", "reference to payload template to use for the webhook")
cmd.Flags().BoolVar(&disable, "disable", false, "disable webhook")
cmd.Flags().MarkDeprecated("enable", "enable webhook is depecated")
cmd.Flags().BoolVar(&onStateChange, "on-state-change", false, "specify whether webhook should be triggered only on a state change")

return cmd
}
54 changes: 47 additions & 7 deletions docs/docs/articles/webhooks.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ spec:
selector: ""
```
Where <YOUR_ENDPOINT_URL> should be replaced with the HTTPS endpoint URL where you want to receive the webhook events.
Where `<YOUR_ENDPOINT_URL>` should be replaced with the HTTPS endpoint URL where you want to receive the webhook events.

And then apply with:

Expand Down Expand Up @@ -170,7 +170,7 @@ And set it with `--payload-template template.json`.
testkube create webhook --name example-webhook --events start-test --events end-test-passed --events end-test-failed --payload-template template.json --uri <YOUR_ENDPOINT_URL>
```

Where <YOUR_ENDPOINT_URL> should be replaced with the HTTPS endpoint URL where you want to receive the webhook events.
Where `<YOUR_ENDPOINT_URL>` should be replaced with the HTTPS endpoint URL where you want to receive the webhook events.

```sh title="Expected output:"
Webhook created example-webhook 🥇
Expand Down Expand Up @@ -310,16 +310,30 @@ Webhooks can be triggered on any of the following events:
- end-test-failed
- end-test-aborted
- end-test-timeout
- become-test-up
- become-test-down
- become-test-failed
- become-test-aborted
- become-test-timeout
- start-testsuite
- end-testsuite-success
- end-testsuite-failed
- end-testsuite-aborted
- end-testsuite-timeout
- start-testworkflow
- become-testsuite-up
- become-testsuite-down
- become-testsuite-failed
- become-testsuite-aborted
- become-testsuite-timeout
- queue-testworkflow
- start-testworkflow
- end-testworkflow-success
- end-testworkflow-failed
- end-testworkflow-aborted
- become-testworkflow-up
- become-testworkflow-down
- become-testworkflow-failed
- become-testworkflow-aborted
- created
- updated
- deleted
Expand Down Expand Up @@ -353,6 +367,10 @@ The full Event Data Model can be found [here](https://github.com/kubeshop/testku

### TestExecution (Execution):

:::warning
Test and Test Suite webhooks are being deprecated from Testkube.
:::

- `Id` - Execution ID (for example, `64f8cf3c712890925aea51ce`)
- `TestName` - Test Name (for example, `postman-executor-smoke`)
- `TestSuiteName` - Test Suite name (if run as a part of a Test Suite)
Expand All @@ -377,6 +395,10 @@ The full Execution data model can be found [here](https://github.com/kubeshop/te

### TestSuiteExecution:

:::warning
Test and Test Suite webhooks are being deprecated from Testkube.
:::

- `Id` - TestSuiteExecution ID (for example, `64f8d5b2712890925aea51dc`)
- `Name` - TestSuite execution name (for example, `ts-executor-postman-smoke-tests-472`)
- `Status` - TestSuite execution status (for example, `running` or `passed`)
Expand Down Expand Up @@ -646,14 +668,34 @@ The examples show only the `create` operations, however, these instructions work

## Enable Webhooks on State Changes

It is possible to get notified by webhooks only when the latest execution's outcome differs from the previous one. This way you can see instantly when one of your scheduled tests was healed or when they got broken. It could also help prevent alert fatigue by deduplicating the alerts and therefore decreasing the load on your monitoring systems. Enable this by setting `onStateChange` to true directly on the webhook.
It is possible to get notified by webhooks only when the latest execution's outcome differs from the previous one. This way you can see instantly when one of your scheduled tests was healed or when they got broken. It could also help prevent alert fatigue by deduplicating the alerts and therefore decreasing the load on your monitoring systems.
Testkube suppots special webhook event types to track changes between current and previous execution states.
For Tests:
- become-test-up (from any error state to succeed one)
- become-test-down (from succeed state to any error one)
- become-test-failed (from any state to failed one)
- become-test-aborted (from any state to aborted one)
- become-test-timeout (from any state to timeout one)

For Test Suites:
- become-testsuite-up (from any error state to succeed one)
- become-testsuite-down (from succeed state to any error one)
- become-testsuite-failed (from any state to failed one)
- become-testsuite-aborted (from any state to aborted one)
- become-testsuite-timeout (from any state to timeout one)

For Test Workflows:
- become-testworkflow-up (from any error state to succeed one)
- become-testworkflow-down (from succeed state to any error one)
- become-testworkflow-failed (from any state to failed one)
- become-testworkflow-aborted (from any state to aborted one)

<Tabs>

<TabItem value="cli" label="CLI">

```bash
testkube update webhook --name example-webhook --on-state-change
testkube update webhook --name example-webhook
```

</TabItem>
Expand All @@ -671,7 +713,6 @@ testkube update webhook --name example-webhook --on-state-change
"end-test-failed"
],
"disabled": false,
"onStateChange": true,
}
```

Expand All @@ -690,7 +731,6 @@ spec:
- start-test
- end-test-success
- end-test-failed
onStateChange: true
uri: https://webhook.url/
```

Expand Down
1 change: 0 additions & 1 deletion docs/docs/cli/testkube_create_webhook.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ testkube create webhook [flags]
-h, --help help for webhook
-l, --label stringToString label key value pair: --label key1=value1 (default [])
-n, --name string unique webhook name - mandatory
--on-state-change specify whether webhook should be triggered only on a state change
--payload-field string field to use for notification object payload
--payload-template string if webhook needs to send a custom notification, then a path to template file should be provided
--payload-template-reference string reference to payload template to use for the webhook
Expand Down
1 change: 0 additions & 1 deletion docs/docs/cli/testkube_update_webhook.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ testkube update webhook [flags]
-h, --help help for webhook
-l, --label stringToString label key value pair: --label key1=value1 (default [])
-n, --name string unique webhook name - mandatory
--on-state-change specify whether webhook should be triggered only on a state change
--payload-field string field to use for notification object payload
--payload-template string if webhook needs to send a custom notification, then a path to template file should be provided
--payload-template-reference string reference to payload template to use for the webhook
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,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.20240716095745-a1fa1f1a8d25
github.com/kubeshop/testkube-operator v1.15.2-beta1.0.20240719112653-d677ef7c3437
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 @@ -358,8 +358,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.20240716095745-a1fa1f1a8d25 h1:U0IaIRvYnx3THAvKc2Y2P9Xp4aKUj5E3cpTmA6VGLU8=
github.com/kubeshop/testkube-operator v1.15.2-beta1.0.20240716095745-a1fa1f1a8d25/go.mod h1:P47tw1nKQFufdsZndyq2HG2MSa0zK/lU0XpRfZtEmIk=
github.com/kubeshop/testkube-operator v1.15.2-beta1.0.20240719112653-d677ef7c3437 h1:Ov4w/ozhVUwdOekhD3YzFQ3IYwKkmILGRAy3LdRFGck=
github.com/kubeshop/testkube-operator v1.15.2-beta1.0.20240719112653-d677ef7c3437/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
20 changes: 14 additions & 6 deletions pkg/api/v1/testkube/model_event_extended.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ func (e Event) Log() []any {
}
}

func (e Event) Valid(selector string, types []EventType) (valid bool) {
func (e Event) Valid(selector string, types []EventType) (matchedTypes []EventType, valid bool) {
var executionLabels map[string]string

// load labels from event test execution or test-suite execution or test workflow execution
Expand All @@ -231,21 +231,29 @@ func (e Event) Valid(selector string, types []EventType) (valid bool) {

typesMatch := false
for _, t := range types {
if t == e.Type() {
typesMatch = true
break
ts := []EventType{t}
if t.IsBecome() {
ts = t.MapBecomeToRegular()
}

for _, et := range ts {
if et == e.Type() {
typesMatch = true
matchedTypes = append(matchedTypes, t)
break
}
}
}

if !typesMatch {
return false
return nil, false
}

valid = selector == ""
if !valid {
selector, err := labels.Parse(selector)
if err != nil {
return false
return nil, false
}

valid = selector.Matches(labels.Set(executionLabels))
Expand Down
Loading

0 comments on commit af6ac02

Please sign in to comment.