NET-2038: Add envoy assertion function of listener verification (#15969)
This commit is contained in:
parent
892ef07715
commit
66a88b65f2
|
@ -0,0 +1,96 @@
|
|||
package assert
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/consul/sdk/testutil/retry"
|
||||
libservice "github.com/hashicorp/consul/test/integration/consul-container/libs/service"
|
||||
"github.com/hashicorp/consul/test/integration/consul-container/libs/utils"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// GetEnvoyListenerTCPFilters validates that proxy was configured with tcp protocol and one rbac listener filter
|
||||
func GetEnvoyListenerTCPFilters(t *testing.T, adminPort int) {
|
||||
var (
|
||||
dump string
|
||||
err error
|
||||
)
|
||||
failer := func() *retry.Timer {
|
||||
return &retry.Timer{Timeout: 30 * time.Second, Wait: 1 * time.Second}
|
||||
}
|
||||
|
||||
retry.RunWith(failer(), t, func(r *retry.R) {
|
||||
dump, err = libservice.GetEnvoyConfigDump(adminPort, "")
|
||||
if err != nil {
|
||||
r.Fatal("could not fetch envoy configuration")
|
||||
}
|
||||
})
|
||||
|
||||
// The services configured for the tests have proxy tcp protocol configured, therefore the HTTP request is on tcp protocol
|
||||
// the steps below validate that the json result from envoy config dump returns active listener with rbac and tcp_proxy configured
|
||||
filter := `.configs[2].dynamic_listeners[].active_state.listener | "\(.name) \( .filter_chains[0].filters | map(.name) | join(","))"`
|
||||
results, err := utils.JQFilter(dump, filter)
|
||||
require.NoError(t, err, "could not parse envoy configuration")
|
||||
|
||||
if len(results) != 2 {
|
||||
require.Error(t, fmt.Errorf("s1 proxy should have been configured with one rbac listener filter. Got %d listener(s)", len(results)))
|
||||
}
|
||||
|
||||
var filteredResult []string
|
||||
for _, result := range results {
|
||||
santizedResult := sanitizeResult(result)
|
||||
filteredResult = append(filteredResult, santizedResult...)
|
||||
}
|
||||
|
||||
require.Contains(t, filteredResult, "envoy.filters.network.rbac")
|
||||
require.Contains(t, filteredResult, "envoy.filters.network.tcp_proxy")
|
||||
}
|
||||
|
||||
// GetEnvoyHTTPrbacFilters validates that proxy was configured with an http connection manager
|
||||
// this assertion is currently unused current tests use http protocol
|
||||
func GetEnvoyHTTPrbacFilters(t *testing.T, port int) {
|
||||
var (
|
||||
dump string
|
||||
err error
|
||||
)
|
||||
failer := func() *retry.Timer {
|
||||
return &retry.Timer{Timeout: 30 * time.Second, Wait: 1 * time.Second}
|
||||
}
|
||||
|
||||
retry.RunWith(failer(), t, func(r *retry.R) {
|
||||
dump, err = libservice.GetEnvoyConfigDump(port, "")
|
||||
if err != nil {
|
||||
r.Fatal("could not fetch envoy configuration")
|
||||
}
|
||||
})
|
||||
|
||||
// the steps below validate that the json result from envoy config dump configured active listeners with rbac and http filters
|
||||
filter := `.configs[2].dynamic_listeners[].active_state.listener | "\(.name) \( .filter_chains[0].filters[] | select(.name == "envoy.filters.network.http_connection_manager") | .typed_config.http_filters | map(.name) | join(","))"`
|
||||
results, err := utils.JQFilter(dump, filter)
|
||||
require.NoError(t, err, "could not parse envoy configuration")
|
||||
|
||||
if len(results) != 2 {
|
||||
require.Error(t, fmt.Errorf("s1 proxy should have been configured with one rbac listener filter. Got %d listener(s)", len(results)))
|
||||
}
|
||||
|
||||
var filteredResult []string
|
||||
for _, result := range results {
|
||||
sanitizedResult := sanitizeResult(result)
|
||||
filteredResult = append(filteredResult, sanitizedResult...)
|
||||
}
|
||||
require.Contains(t, filteredResult, "envoy.filters.http.rbac")
|
||||
assert.Contains(t, filteredResult, "envoy.filters.http.header_to_metadata")
|
||||
assert.Contains(t, filteredResult, "envoy.filters.http.router")
|
||||
}
|
||||
|
||||
// sanitizeResult takes the value returned from config_dump json and cleans it up to remove special characters
|
||||
// e.g public_listener:0.0.0.0:21001 envoy.filters.network.rbac,envoy.filters.network.tcp_proxy
|
||||
// returns [envoy.filters.network.rbac envoy.filters.network.tcp_proxy]
|
||||
func sanitizeResult(s string) []string {
|
||||
result := strings.Split(strings.ReplaceAll(s, `,`, " "), " ")
|
||||
return append(result[:0], result[1:]...)
|
||||
}
|
|
@ -117,3 +117,7 @@ func NewExampleService(ctx context.Context, name string, httpPort int, grpcPort
|
|||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (g exampleContainer) GetAdminAddr() (string, int) {
|
||||
return "localhost", 0
|
||||
}
|
||||
|
|
|
@ -119,9 +119,9 @@ func CreateAndRegisterStaticClientSidecar(
|
|||
return clientConnectProxy, nil
|
||||
}
|
||||
|
||||
func GetEnvoyConfigDump(port int) (string, error) {
|
||||
func GetEnvoyConfigDump(port int, filter string) (string, error) {
|
||||
client := cleanhttp.DefaultClient()
|
||||
url := fmt.Sprintf("http://localhost:%d/config_dump?include_eds", port)
|
||||
url := fmt.Sprintf("http://localhost:%d/config_dump?%s", port, filter)
|
||||
|
||||
res, err := client.Get(url)
|
||||
if err != nil {
|
||||
|
|
|
@ -12,4 +12,5 @@ type Service interface {
|
|||
// Export a service to the peering cluster
|
||||
Export(partition, peer string, client *api.Client) error
|
||||
GetServiceName() string
|
||||
GetAdminAddr() (string, int)
|
||||
}
|
||||
|
|
|
@ -25,8 +25,10 @@ func TestBasicConnectService(t *testing.T) {
|
|||
|
||||
clientService := createServices(t, cluster)
|
||||
_, port := clientService.GetAddr()
|
||||
_, adminPort := clientService.GetAdminAddr()
|
||||
|
||||
libassert.HTTPServiceEchoes(t, "localhost", port)
|
||||
libassert.GetEnvoyListenerTCPFilters(t, adminPort)
|
||||
}
|
||||
|
||||
func createCluster(t *testing.T) *libcluster.Cluster {
|
||||
|
|
|
@ -192,8 +192,8 @@ func verifySidecarHasTwoRootCAs(t *testing.T, sidecar libservice.Service) {
|
|||
}
|
||||
|
||||
retry.RunWith(failer(), t, func(r *retry.R) {
|
||||
dump, err := libservice.GetEnvoyConfigDump(adminPort)
|
||||
require.NoError(r, err, "could not curl envoy configuration")
|
||||
dump, err := libservice.GetEnvoyConfigDump(adminPort, "include_eds")
|
||||
require.NoError(r, err, "could not fetch envoy configuration")
|
||||
|
||||
// Make sure there are two certs in the sidecar
|
||||
filter := `.configs[] | select(.["@type"] | contains("type.googleapis.com/envoy.admin.v3.ClustersConfigDump")).dynamic_active_clusters[] | select(.cluster.name | contains("static-server.default.dialing-to-acceptor.external")).cluster.transport_socket.typed_config.common_tls_context.validation_context.trusted_ca.inline_string`
|
||||
|
|
Loading…
Reference in New Issue