Skip to content

Commit

Permalink
Merge refs/heads/main into stevenctl/allow-custom-translator
Browse files Browse the repository at this point in the history
  • Loading branch information
soloio-bulldozer[bot] authored Jun 17, 2024
2 parents 2f50630 + 414938b commit d8b9356
Show file tree
Hide file tree
Showing 42 changed files with 468 additions and 167 deletions.
8 changes: 8 additions & 0 deletions changelog/v1.18.0-beta1/e2e-tests-cleanup.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
changelog:
- type: NON_USER_FACING
issueLink: https://github.com/solo-io/gloo/issues/9353
resolvesIssue: false
description: >-
Make Kubernetes E2E tests easily importable and runnable from enterprise suites
skipCI-docs-build:true
6 changes: 6 additions & 0 deletions changelog/v1.18.0-beta1/stateful_session_docs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
changelog:
- type: NON_USER_FACING
issueLink: https://github.com/solo-io/gloo/issues/9104
resolvesIssue: false
description: >-
Update "session affinity" Documentation to cover new stateful session filter
112 changes: 111 additions & 1 deletion docs/content/installation/advanced_configuration/session_affinity.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ description: Configure Gloo Edge session affinity (sticky sessions)
For certain applications deployed across multiple replicas, it may be desirable to route all traffic from a single client session to the same instance of the application. This can help reduce latency through better use of caches. This load balancer behavior is referred to as Session Affinity or Sticky Sessions. Gloo Edge exposes Envoy's full session affinity capabilities, as described below.

---

## Configuration overview

There are two steps to configuring session affinity:
Expand Down Expand Up @@ -341,3 +340,114 @@ Return to the app in your browser and refresh the page a few times. You should s
```

Now that you have configured cookie-based sticky sessions, web requests from your browser will be served by the same instance of the counter app (unless you delete the cookie).


## Stateful Session Filter (Enterprise Only)

Envoy provides another method of implementing sticky sessions using the [Stateful Session](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/stateful_session_filter) filter, which implements "strong" stickiness.

This example uses the session affinity app resources that are created in the [Apply the DaemonSet](#apply-the-daemonset) section. No additional modifications to the upstream or virtual service are required.

### Requirements

- A Kubernetes cluster with at least two nodes with Gloo Edge Enterprise installed.
- Permission to deploy a DaemonSet and edit Gloo Edge resources.

### Cookie-based stateful session filter

When enabling the cookie-based stateful session filter, a hash of the upstream that serves the request is stored in a `statefulsessioncookie` cookie. In subsequent requests, the same upstream resource is used to fulfill the request.

1. [Apply the session affinity DaemonSet](#apply-the-daemonset).

2. Edit the gateway proxy.
```sh
kubectl edit gateways.gateway.solo.io -n gloo-system gateway-proxy
```

3. Add the following configuration to the `spec` section of your gateway to enable the cookie-based stateful session filter.
{{< highlight yaml "hl_lines=4-11" >}}
spec:
bindAddress: '::'
bindPort: 8080
httpGateway:
options:
statefulSession:
cookieBased:
cookie:
name: statefulsessioncookie
path: /route1
ttl: 60s
proxyNames:
- gateway-proxy
ssl: false
useProxyProto: false
{{< /highlight >}}

4. Get the URL of the gateway proxy.
```sh
glooctl proxy url
```

5. Open a web browser and navigate to the `/route1` path. For example, if your gateway proxy is `http://34.111.222.111:80`, type `http://34.111.222.111:80/route1` in to your web browser.
6. Refresh the page a couple of times. Verify that you see an increasing count as the requests are now all directed to the same upstream.

Example output:
```
5,6,7,8,...
```

### Header-based stateful session filter

When enabling the header-based stateful session filter for a route, a `statefulsessionheader` header is returned with the hash of the upstream that served the request. You must use this header in subsequent requests to enable session stickiness.

1. [Apply the session affinity DaemonSet](#apply-the-daemonset).

2. Edit the gateway proxy.
```sh
kubectl edit gateways.gateway.solo.io -n gloo-system gateway-proxy
```

3. Add the following configuration to the `spec` section of your gateway to enable the header-based stateful session filter.
{{< highlight yaml "hl_lines=4-8" >}}
spec:
bindAddress: '::'
bindPort: 8080
httpGateway:
options:
statefulSession:
headerBased:
headerName: statefulsessionheader
proxyNames:
- gateway-proxy
ssl: false
useProxyProto: false
{{< /highlight >}}

4. Get the URL of the gateway proxy.
```sh
glooctl proxy url
```

5. Send a request to the `/route1` path. Requests to the `/route1` path return a `statefulsessionheader` header that you can send in subsequent requests to enable the session stickiness. Because headers are not automatically applied by the browser, it is easier to test this behavior by using a curl request.
```sh
curl -v $(glooctl proxy url)/route1
```

Example output:
```
< HTTP/1.1 200 OK
< date: Tue, 11 Jun 2024 15:11:23 GMT
< content-length: 1
< content-type: text/plain; charset=utf-8
< x-envoy-upstream-service-time: 10
< statefulsessionheader: MTAuMjQ0LjAuNDU6ODA4MA==
< server: envoy
<
* Connection #0 to host 127.0.0.1 left intact
3%
```

6. Send another request to the `/route1` path and include the `statefulsessionheader` that was returned in the previous step. Verify that you see an increased count in your response as the requests are now all directed to the same upstream.
```sh
curl -v -H "statefulsessionheader: MTAuMjQ0LjAuNDU6ODA4MA==" $(glooctl proxy url)/route1
```
12 changes: 11 additions & 1 deletion test/kubernetes/e2e/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,21 @@ We define all tests in the [features](./features) package. This is done for a va
1. We group the tests by feature, so it's easy to identify which behaviors we assert for a given feature.
2. We can invoke that same test against different `TestInstallation`s. This means we can test a feature against a variety of installation values, or even against OSS and Enterprise installations.

## Test Suites
A Test Suite is a subset of the Feature concept. A single Feature has at minimum one Test Suite, and can have many. Each Test Suite within the feature must have a function which satisfies the signature `NewSuiteFunc` found in [suite.go](./suite.go).

These test suites are registered by a name and this func in [Tests](#tests) to be run against various `TestInstallation`s.

## Tests
This package holds the entry point for each of our `TestInstallation`.

See [Load balancing tests](./load_balancing_tests.md) for more information about how these tests are run in CI.

Each `*_test.go` file contains a specific test installation and exists within the `tests_test` package. In order for tests to be imported and run from other repos, each `*_test.go` file has a corresponding `*_test.go` file which exists in the `tests` package. This is done because `_test` packages cannot be imported.

In order to add a feature suite to be run in a given test installation, it must be added to the exported function in the corresponding `*_tests.go` file.
e.g. In order to add a feature suite to be run with the test installation defined in `istio_test.go`, we have to register it by adding it to `IstioTests()` in `istio_tests.go` following the existing paradigm.

## Environment Variables

Some tests may require environment variables to be set. Some required env vars are:
Expand Down Expand Up @@ -50,4 +60,4 @@ Below are a set of known areas of improvement. The goal is to provide a starting
- **Improved install action(s)**: We rely on the [SoloTestHelper](/test/kube2e/helper/install.go) currently, and it would be nice if we relied directly on Helm or Glooctl.
- **Cluster provisioning**: We rely on the [setup-kind](/ci/kind/setup-kind.sh) script to provision a cluster. We should make this more flexible by providing a configurable, declarative way to do this.
- **Istio action**: We need a way to perform Istio actions against a cluster.
- **Argo action**: We need an easy utility to perform ArgoCD commands against a cluster.
- **Argo action**: We need an easy utility to perform ArgoCD commands against a cluster.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
"github.com/solo-io/gloo/test/kubernetes/e2e"
)

var _ e2e.NewSuiteFunc = NewIstioIntegrationTestingSuite

// istioIntegrationDeployerSuite is the entire Suite of tests for the "deployer" feature that relies on an Istio installation
// The "deployer" code can be found here: /projects/gateway2/deployer
type istioIntegrationDeployerSuite struct {
Expand Down
2 changes: 2 additions & 0 deletions test/kubernetes/e2e/features/deployer/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import (
"github.com/solo-io/gloo/test/kubernetes/testutils/runtime"
)

var _ e2e.NewSuiteFunc = NewTestingSuite

// testingSuite is the entire Suite of tests for the "deployer" feature
// The "deployer" code can be found here: /projects/gateway2/deployer
type testingSuite struct {
Expand Down
2 changes: 2 additions & 0 deletions test/kubernetes/e2e/features/example/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"github.com/solo-io/gloo/test/kubernetes/e2e"
)

var _ e2e.NewSuiteFunc = NewTestingSuite

// testingSuite is the entire Suite of tests for the "example" feature
// Typically, we would include a link to the feature code here
type testingSuite struct {
Expand Down
2 changes: 2 additions & 0 deletions test/kubernetes/e2e/features/glooctl/check_suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"github.com/stretchr/testify/suite"
)

var _ e2e.NewSuiteFunc = NewCheckSuite

// checkSuite contains the set of tests to validate the behavior of `glooctl check`
// These tests attempt to mirror: https://github.com/solo-io/gloo/blob/v1.16.x/test/kube2e/glooctl/check_test.go
type checkSuite struct {
Expand Down
2 changes: 2 additions & 0 deletions test/kubernetes/e2e/features/glooctl/debug_suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"github.com/stretchr/testify/suite"
)

var _ e2e.NewSuiteFunc = NewDebugSuite

// debugSuite contains the set of tests to validate the behavior of `glooctl debug`
// These tests attempt to mirror: https://github.com/solo-io/gloo/blob/v1.16.x/test/kube2e/glooctl/debug_test.go
type debugSuite struct {
Expand Down
2 changes: 2 additions & 0 deletions test/kubernetes/e2e/features/glooctl/get_proxy_suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import (
"github.com/stretchr/testify/suite"
)

var _ e2e.NewSuiteFunc = NewGetProxySuite

var (
yamlSeparator = regexp.MustCompile("\n---\n")
)
Expand Down
2 changes: 2 additions & 0 deletions test/kubernetes/e2e/features/glooctl/istio_inject_suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

var _ e2e.NewSuiteFunc = NewIstioInjectTestingSuite

// istioInjectTestingSuite is the entire Suite of tests for the "glooctl istio inject" integration cases
// NOTE: This suite is not intended to be run as a standalone test suite. It applies the "glooctl istio inject" command
// to an existing installation of Gloo Gateway and verifies that the necessary resources are created, but does not clean
Expand Down
2 changes: 2 additions & 0 deletions test/kubernetes/e2e/features/glooctl/istio_uninject_suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

var _ e2e.NewSuiteFunc = NewIstioUninjectTestingSuite

// istioUninjectTestingSuite is the entire Suite of tests for the "glooctl istio uninject" integration cases
// NOTE: This suite is not intended to be run as a standalone test suite. It applies the "glooctl unistio inject" command
// to an existing installation of Gloo Gateway where the istio-proxy and sds containers have already been injected
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

var _ e2e.NewSuiteFunc = NewEdgeGatewayHeadlessSvcSuite

type edgeGatewaySuite struct {
suite.Suite

Expand Down
2 changes: 2 additions & 0 deletions test/kubernetes/e2e/features/headless_svc/k8s_gw_suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
"github.com/solo-io/gloo/test/kubernetes/testutils/resources"
)

var _ e2e.NewSuiteFunc = NewK8sGatewayHeadlessSvcSuite

type k8sGatewaySuite struct {
suite.Suite

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

var _ e2e.NewSuiteFunc = NewTestingSuite

// testingSuite is the entire Suite of tests for the "HttpListenerOptions" feature
type testingSuite struct {
suite.Suite
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

var _ e2e.NewSuiteFunc = NewGlooIstioAutoMtlsSuite

// glooIstioAutoMtlsTestingSuite is the entire Suite of tests for the "Istio" integration cases where auto mTLS is enabled
type glooIstioAutoMtlsTestingSuite struct {
suite.Suite
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

var _ e2e.NewSuiteFunc = NewGlooTestingSuite

// glooIstioTestingSuite is the entire Suite of tests for the "Istio" integration cases where auto mtls is disabled
// and Upstreams do not have sslConfig values set
type glooIstioTestingSuite struct {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import (
"github.com/solo-io/gloo/test/kubernetes/e2e"
)

var _ e2e.NewSuiteFunc = NewIstioAutoMtlsSuite

// istioMtlsTestingSuite is the entire Suite of tests for the "Istio" integration cases where auto mTLS is enabled
type istioAutoMtlsTestingSuite struct {
suite.Suite
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

var _ e2e.NewSuiteFunc = NewTestingSuite

// istioTestingSuite is the entire Suite of tests for the "Istio" integration cases where auto mtls is disabled
// and Upstreams do not have sslConfig values set
type istioTestingSuite struct {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

var _ e2e.NewSuiteFunc = NewTestingSuite

// testingSuite is the entire Suite of tests for the "ListenerOptions" feature
type testingSuite struct {
suite.Suite
Expand Down
2 changes: 2 additions & 0 deletions test/kubernetes/e2e/features/port_routing/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

var _ e2e.NewSuiteFunc = NewTestingSuite

// portRoutingTestingSuite is the entire Suite of tests for the "PortRouting" cases
type portRoutingTestingSuite struct {
suite.Suite
Expand Down
4 changes: 3 additions & 1 deletion test/kubernetes/e2e/features/route_delegation/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import (
"github.com/solo-io/gloo/test/kubernetes/testutils/gloogateway"
)

var _ e2e.NewSuiteFunc = NewTestingSuite

type tsuite struct {
suite.Suite

Expand All @@ -33,7 +35,7 @@ type tsuite struct {
manifestObjects map[string][]client.Object
}

func NewTestingSuite(ctx context.Context, testInst *e2e.TestInstallation) *tsuite {
func NewTestingSuite(ctx context.Context, testInst *e2e.TestInstallation) suite.TestingSuite {
return &tsuite{
ctx: ctx,
ti: testInst,
Expand Down
2 changes: 2 additions & 0 deletions test/kubernetes/e2e/features/route_options/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import (
testdefaults "github.com/solo-io/gloo/test/kubernetes/e2e/defaults"
)

var _ e2e.NewSuiteFunc = NewTestingSuite

// testingSuite is the entire Suite of tests for the "Route Options" feature
type testingSuite struct {
suite.Suite
Expand Down
2 changes: 2 additions & 0 deletions test/kubernetes/e2e/features/upstreams/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import (
"github.com/solo-io/gloo/test/kubernetes/e2e"
)

var _ e2e.NewSuiteFunc = NewTestingSuite

// testingSuite is the entire Suite of tests for the "Upstream" feature
type testingSuite struct {
suite.Suite
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

var _ e2e.NewSuiteFunc = NewTestingSuite

// testingSuite is the entire Suite of tests for the "VirtualHostOptions" feature
type testingSuite struct {
suite.Suite
Expand Down
Loading

0 comments on commit d8b9356

Please sign in to comment.