envoy-tools
envoy-tools copied to clipboard
feature: adds support for go-control-plane based xDS implementations
👋 This proposal adds support for OSS implementations of the xDS control plane.
Kindly let me know whether this is something you would like integrated into envoy-tools/csds-client, and what are your thoughts on this approach.
platform go
This patch adds support for a second type of platform, named go
. It does so by providing utility function ConnToXDS
and DialOptions
to initiate gRPCs to the address specified by the flag service_uri
.
authentication options for platform go
Support is added for mTLS via the introduction of the following new flags:
-authority string
the :authority header to use when connecting to uri
-cacert string
filepath to the CAs certs used to verify the server's certificate
-cert string
filepath to the client TLS certificate
-key string
filepath to the client TLS private key
The the client certificate/private key pair are included in the ClientHello message for establishing a connection over TLS.
If a certificate authority is provided via cacert
, it is used to validate the server's certificate identity.
Additionally, the -authority
flag allows for setting the HTTP/2 :authority
header to use for SNI.
Example
$ ~/github/owayss/envoy-tools/csds-client/csds-client \
-request_file ~/github/owayss/envoy-tools/csds-client/client/v3/test_request.yaml \
-cert client.crt \
-key client.key \
-cacert ca.crt \
-service_uri localhost:18000 \
-platform go \
-api_version v3
Click to expand response output
Client ID xDS stream type Config Status
api-gateway CDS SYNCED
LDS SYNCED
Detailed Config:
{
"config": [
{
"node": {
"id": "api-gateway"
},
"xdsConfig": [
{
"status": "SYNCED",
"clusterConfig": {
"staticClusters": [
{
"cluster": {
"@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster",
"name": "service_api-gateway-stg",
"type": "STRICT_DNS",
"connectTimeout": "5s",
"loadAssignment": {
"clusterName": "service_api-gateway-stg",
"endpoints": [
{
"lbEndpoints": [
{},
{
"endpoint": {
"address": {
"socketAddress": {
"address": "envoyproxy.io",
"portValue": 443
}
}
}
}
]
}
]
},
"healthChecks": [
{
"timeout": "5s",
"interval": "5s",
"unhealthyThreshold": 3,
"healthyThreshold": 3,
"reuseConnection": true,
"httpHealthCheck": {
"host": "api-gateway-stg.mydomain.com",
"path": "/api/health",
"expectedStatuses": [
{
"start": "200",
"end": "405"
}
]
},
"noTrafficInterval": "60s",
"eventLogPath": "/dev/stdout",
"alwaysLogHealthCheckFailures": true
}
],
"dnsLookupFamily": "V4_ONLY",
"transportSocket": {
"name": "envoy.transport_sockets.tls"
}
}
}
]
}
},
{
"status": "SYNCED",
"listenerConfig": {
"staticListeners": [
{
"listener": {
"@type": "type.googleapis.com/envoy.config.listener.v3.Listener",
"name": "listener_api-gateway-stg",
"address": {
"socketAddress": {
"address": "0.0.0.0",
"portValue": 4455
}
},
"filterChains": [
{
"filters": [
{
"name": "envoy.filters.network.http_connection_manager",
"typedConfig": {
"@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager",
"statPrefix": "http",
"routeConfig": {
"name": "route_api-gateway-stg",
"virtualHosts": [
{
"name": "route_api-gateway-stg",
"domains": [
"*"
],
"routes": [
{
"match": {
"path": "/__envoy__/status"
},
"directResponse": {
"status": 200,
"body": {
"inlineString": "OK"
}
}
},
{
"match": {
"prefix": "/"
},
"route": {
"cluster": "service_api-gateway-stg",
"hostRewriteLiteral": "api-gateway-stg.mydomain.com"
}
}
]
}
]
},
"httpFilters": [
{
"name": "envoy.filters.http.router"
}
],
"accessLog": [
{
"name": "envoy.access_loggers.file",
"typedConfig": {
"@type": "type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog",
"path": "/dev/stdout",
"logFormat": {
"jsonFormat": {
"bytes_received": "%BYTES_RECEIVED%",
"bytes_sent": "%BYTES_SENT%",
"downstream_local_address": "%DOWNSTREAM_LOCAL_ADDRESS%",
"downstream_local_uri_san": "%DOWNSTREAM_LOCAL_URI_SAN%",
"downstream_peer_uri_san": "%DOWNSTREAM_PEER_URI_SAN%",
"downstream_remote_address": "%DOWNSTREAM_REMOTE_ADDRESS%",
"duration": "%DURATION%",
"envoy_upstream_service_time": "%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%",
"epoch_micro": "%START_TIME(%s.%6f)%",
"jwt_aud": "%DYNAMIC_METADATA(envoy.filters.http.jwt_authn\\:config)%",
"protocol": "%PROTOCOL%",
"req_authority": "%REQ(:AUTHORITY)%",
"req_envoy_original_path": "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%",
"req_path": "%REQ(:PATH)%",
"req_user_agent": "%REQ(USER-AGENT)%",
"req_x_request_id": "%REQ(X-REQUEST-ID)%",
"req_xff": "%REQ(X-FORWARDED-FOR)%",
"request_method": "%REQ(:METHOD)%",
"response_code": "%RESPONSE_CODE%",
"response_duration": "%RESPONSE_DURATION%",
"response_flags": "%RESPONSE_FLAGS%",
"response_tx_duration": "%RESPONSE_TX_DURATION%",
"start_time": "%START_TIME(%Y/%m/%d %H:%M:%S)%",
"upstream_cluster": "%UPSTREAM_CLUSTER%",
"upstream_host": "%UPSTREAM_HOST%",
"upstream_local_address": "%UPSTREAM_LOCAL_ADDRESS%",
"upstream_transport_failure_reason": "%UPSTREAM_TRANSPORT_FAILURE_REASON%"
}
}
}
}
]
}
}
]
}
]
}
}
]
}
}
]
}
]
}
Testing coverage
The patch does not include any additional tests. The various test functions in the client/v2
and client/v3
seem to cover the existing utility functions (for parsing and printing out detailed responses) with golden JSON data files.
The part that I think would benefit from a unit test is the DialOptions
functions that configures the HTTP/2 connection depending on the provided command-line flags for authentication.
Best, Owayss.