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

test(meshtimeout): e2e test that checks golden envoy configs #12650

Merged
merged 5 commits into from
Jan 27, 2025

Conversation

lobkovilya
Copy link
Contributor

@lobkovilya lobkovilya commented Jan 23, 2025

Motivation

When we test BuildRules we pass MeshTimeout policies as input and check outbound.ResourceRules Go struct.

When we test MeshTimeout plugin we pass outbound.ResourceRules Go struct as input and check envoy configs.

We need an easy way to pass MeshTimeout policies and check envoy configs. It's sort of an integration test that involves 2 packages. The easiest way to do that is to add another universal e2e test with golden files. This way we have running Kuma CP and we basically test it as a black box.

I managed to find 2 bugs using these tests:

Implementation information

We check DPP config (marshalled Snapshot in Kuma CP) instead of the actual Envoy config dump for a few reasons:

  • no need to add logic that waits while config is propagated on DPP
  • less setup-specific values we have to reduct to have stable golden file (only IP addresses)
  • we can use kuma.io/effect: shadow and quickly review the diff policies introduces

@lobkovilya lobkovilya requested a review from a team as a code owner January 23, 2025 09:37
Copy link
Contributor

Reviewer Checklist

🔍 Each of these sections need to be checked by the reviewer of the PR 🔍:
If something doesn't apply please check the box and add a justification if the reason is non obvious.

  • Is the PR title satisfactory? Is this part of a larger feature and should be grouped using > Changelog?
  • PR description is clear and complete. It Links to relevant issue as well as docs and UI issues
  • This will not break child repos: it doesn't hardcode values (.e.g "kumahq" as an image registry)
  • IPv6 is taken into account (.e.g: no string concatenation of host port)
  • Tests (Unit test, E2E tests, manual test on universal and k8s)
    • Don't forget ci/ labels to run additional/fewer tests
  • Does this contain a change that needs to be notified to users? In this case, UPGRADE.md should be updated.
  • Does it need to be backported according to the backporting policy? (this GH action will add "backport" label based on these file globs, if you want to prevent it from adding the "backport" label use no-backport-autolabel label)

@lobkovilya lobkovilya merged commit 645d0de into kumahq:master Jan 27, 2025
13 checks passed
@lobkovilya lobkovilya deleted the test/mesh-timeout-envoy-config branch January 27, 2025 13:33
bartsmykla added a commit that referenced this pull request Jan 28, 2025
)

## Motivation & Implementation information

Updated tests to replace both IPv4 and IPv6 addresses with "IP_REDACTED"
in generated golden files. This fixes issues with e2e tests checking
golden envoy configs (introduced in
#12650)

## Supporting documentation

<details>
<summary>How I've tested regexps</summary>

```go
package main

import (
	"fmt"
	"regexp"
)

var txt = `
"path":    "Listener/outbound:[fd00:fd01::5]:3000/filterChains/0/filters/0/typedConfig/idleTimeout",
"path":    "Listener/outbound:[fd00:fd01::6]:80/filterChains/0/filters/0/typedConfig/requestHeadersTimeout",
"address": "::6",
"address": "fd00:fd12:3456::5",
"address": "fd00:fd12:3456::c",
"foo":     inbound:[fd00:fd12:3456::5]:3000": {
"bar":     outbound:[fd00:fd01::5]:3000": {
"name":    "outbound:[fd00:fd01::5]:3000",
"address": "fd00:fd01::5",
"baz":     outbound:[fd00:fd01::6]:80": {
"name":    "outbound:[fd00:fd01::6]:80",
"address": "fd00:fd01::6",
"address": "127.0.0.1:3000",
"address": "aaaa 1.1.1.1:234",
"::"
`

func main() {
	redactIPs := func(jsonStr string) string {
		ipv6Regex := `\[?` + // Optional opening square bracket for IPv6 in URLs (e.g., [2001:db8::1])
			`(` +
			// Full IPv6 address with 8 segments (e.g., 2001:0db8:85a3:0000:0000:8a2e:0370:7334)
			`([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|` +
			// IPv6 with leading compression (e.g., ::1, ::8a2e:0370:7334)
			`([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|` +
			// IPv6 with trailing compression (e.g., 2001:db8::, 2001:db8::1:2)
			`([0-9a-fA-F]{1,4}:){1,7}:|` +
			// IPv6 with mixed compression (e.g., 2001:db8:0:0::1:2)
			`([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|` +
			`([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|` +
			`([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|` +
			`([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|` +
			// IPv6 with only one segment and compression (e.g., 2001::1:2:3:4:5:6)
			`[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|` +
			// Fully compressed IPv6 (::) or with trailing segments (::1, ::8a2e:0370:7334)
			`:((:[0-9a-fA-F]{1,4}){1,7}|:)|` +
			// Link-local IPv6 with zone identifiers (e.g., fe80::1%eth0)
			`fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]+|` +
			// IPv6 with embedded IPv4 (e.g., ::ffff:192.168.1.1)
			`::(ffff(:0{1,4})?:)?((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\.){3}` +
			`(25[0-5]|(2[0-4]|1?[0-9])?[0-9])|` +
			// Mixed IPv6 and IPv4 (e.g., 2001:db8::192.168.1.1)
			`([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\.){3}` +
			`(25[0-5]|(2[0-4]|1?[0-9])?[0-9])` +
			`)` +
			`]?` // Optional closing square bracket for IPv6 in URLs (e.g., [2001:db8::1])

		ipv4Regex := `\b` + // Word boundary to ensure we match standalone IPv4 addresses
			`\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}` + // Matches IPv4 format (e.g., 192.168.0.1)
			`\b`

		return regexp.
			MustCompile(ipv4Regex+"|"+ipv6Regex).
			ReplaceAllString(jsonStr, "IP_REDACTED")
	}

	fmt.Println(redactIPs(txt))
}
```

**Results**
```
"path":    "Listener/outbound:IP_REDACTED:3000/filterChains/0/filters/0/typedConfig/idleTimeout",
"path":    "Listener/outbound:IP_REDACTED:80/filterChains/0/filters/0/typedConfig/requestHeadersTimeout",
"address": "IP_REDACTED",
"address": "IP_REDACTED",
"address": "IP_REDACTED",
"foo":     inbound:IP_REDACTED:3000": {
"bar":     outbound:IP_REDACTED:3000": {
"name":    "outbound:IP_REDACTED:3000",
"address": "IP_REDACTED",
"baz":     outbound:IP_REDACTED:80": {
"name":    "outbound:IP_REDACTED:80",
"address": "IP_REDACTED",
"address": "IP_REDACTED:3000",
"address": "aaaa IP_REDACTED:234",
"IP_REDACTED"
```

</details>

Signed-off-by: Bart Smykla <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants