Skip to content

Commit

Permalink
Manual backports of Prop Override doc updates (#17830)
Browse files Browse the repository at this point in the history
backport of commit 910a115 (#17813)
backport of commit 21263c8 (#17811)
  • Loading branch information
zalimeni committed Jun 21, 2023
1 parent 5bf4381 commit b7524f7
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 67 deletions.
20 changes: 19 additions & 1 deletion test/integration/connect/envoy/case-property-override/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,30 @@ EnvoyExtensions = [
Path = "/upstream_connection_options/tcp_keepalive/keepalive_probes"
Value = 1234
},
{
ResourceFilter = {
ResourceType = "cluster"
TrafficDirection = "outbound"
}
Op = "add"
Path = "/outlier_detection/max_ejection_time/seconds"
Value = 120
},
{
ResourceFilter = {
ResourceType = "cluster"
TrafficDirection = "outbound"
}
Op = "add"
Path = "/outlier_detection/max_ejection_time_jitter/seconds"
Value = 1
},
{
ResourceFilter = {
ResourceType = "cluster"
TrafficDirection = "outbound"
Services = [{
Name = "s2"
Name = "s3"
}]
}
Op = "remove"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@ load helpers
[ "$status" == 0 ]

[ "$(echo "$output" | jq -r '.upstream_connection_options.tcp_keepalive.keepalive_probes')" == "1234" ]
[ "$(echo "$output" | jq -r '.outlier_detection')" == "null" ]
[ "$(echo "$output" | jq -r '.outlier_detection.max_ejection_time')" == "120s" ]
[ "$(echo "$output" | jq -r '.outlier_detection.max_ejection_time_jitter')" == "1s" ]

run get_envoy_cluster_config localhost:19000 s3
[ "$status" == 0 ]

[ "$(echo "$output" | jq -r '.upstream_connection_options.tcp_keepalive.keepalive_probes')" == "1234" ]
[ "$(echo "$output" | jq -r '.outlier_detection')" == "{}" ]
[ "$(echo "$output" | jq -r '.outlier_detection')" == "null" ]
}

@test "s2 proxy is configured with the expected envoy patches" {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,14 @@ Patches = [
TrafficDirection = "<inbound or outbound>"
Services = [
{
Name = "<name of service to filter for>",
Name = "<name of service to filter for>"
Namespace = "<Consul namespace containing the service>"
Partition = "<Consul partition containing the service>"
}
]
Op = "<add or remove>",
Path = "<path/to/field>",
}
Op = "<add or remove>"
Path = "</path/to/field>"
Value = "<values or map of field-values>"
}
]
Expand Down Expand Up @@ -117,7 +118,7 @@ The following table describes how to configure a `ResourceFilter`:

Specifies the JSON Patch operation to perform when the `ResourceFilter` matches a local Envoy proxy configuration. You can specify one of the following values for each patch:

- `add`: Replaces a property or message specified by [`Path`](#patches-path) with the given value. The JSON patch format does not merge objects. To emulate merges, you must configure discrete `add` operations for each changed field. Consul returns an error if the target field does not exist in the corresponding schema.
- `add`: Replaces a property or message specified by [`Path`](#patches-path) with the given value. The JSON Patch `add` operation does not merge objects. To emulate merges, you must configure discrete `add` operations for each changed field. Consul returns an error if the target field does not exist in the corresponding schema.
- `remove`: Unsets the value of the field specified by [`Path`](#patches-path). If the field is not set, no changes are made. Consul returns an error if the target field does not exist in the corresponding schema.

#### Values
Expand All @@ -134,7 +135,7 @@ Specifies where the extension performs the associated operation on the specified

The `Path` field does not support addressing array elements or protobuf map field entries. Refer to [Constructing paths](/consul/docs/connect/proxies/envoy-extensions/usage/property-override#constructing-paths) for information about how to construct paths.

When setting fields, the extension sets any unset intermediate fields to their default values. A a single operation on a nested field can set multiple intermediate fields. Because Consul sets the intermediate fields to their default values, you may need to configure subsequent patches to satisfy Envoy or Consul validation.
When setting fields, the extension sets any unset intermediate fields to their default values. A single operation on a nested field can set multiple intermediate fields. Because Consul sets the intermediate fields to their default values, you may need to configure subsequent patches to satisfy Envoy or Consul validation.

#### Values

Expand All @@ -144,9 +145,10 @@ When setting fields, the extension sets any unset intermediate fields to their d

### `Patches[].Value{}`

Defines a value to set at the specified [path](#patches-path) if the [operation](#patches-op) is set to `add`. You can specify either a scalar or enum value or define a map that contains string keys and values corresponding to scalar or enum child fields. Refer to the [example configurations](#examples) for additional guidance and to the [Envoy API documentation](https://www.envoyproxy.io/docs/envoy/latest/api-v3/api) for additional information about Envoy proxy interfaces.
Defines a value to set at the specified [path](#patches-path) if the [operation](#patches-op) is set to `add`. You can specify either a scalar or enum value, an array of scalar or enum values (for repeated fields), or define a map that contains string keys and values corresponding to scalar or enum child fields. Single and repeated scalar and enum values are supported. Refer to the [example configurations](#examples) for additional guidance and to the [Envoy API documentation](https://www.envoyproxy.io/docs/envoy/latest/api-v3/api) for additional information about Envoy proxy interfaces.

If Envoy specifies a wrapper as the target field type, the extension automatically coerces simple values to the wrapped type when patching. For example, the value `32768` is allowed when targeting a cluster's `per_connection_buffer_limit_bytes`, which is a `UInt32Value` field. Refer to the [protobuf documentation](https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/wrappers.proto) for additional information about wrappers.

#### Values

- Default: None
Expand All @@ -160,9 +162,9 @@ If Envoy specifies a wrapper as the target field type, the extension automatical

The following examples demonstrate patterns that you may be able to model your configurations on.

### Enable `enforcing_consecutive_5xx` outlier detection
### Enable `respect_dns_ttl` in a cluster

In the following example, the `add` operation patches an outlier detection property into outbound cluster traffic. The `Path` specifies the `enforcing_consecutive_5xx` interface and sets a value of `1234`:
In the following example, the `add` operation patches the outbound cluster corresponding to the `other-svc` upstream service to enable `respect_dns_ttl`. The `Path` specifies the [Cluster `/respect_dns_ttl`](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#envoy-v3-api-field-config-cluster-v3-cluster-respect-dns-ttl) top-level field and `Value` specifies a value of `true`:

```hcl
Kind = "service-defaults"
Expand All @@ -183,18 +185,18 @@ EnvoyExtensions = [
},
},
"Op" = "add",
"Path" = "/outlier_detection/enforcing_consecutive_5xx",
"Value" = 1234,
"Path" = "/respect_dns_ttl",
"Value" = true,
}
]
}
}
]
```

### Update multiple values in the default map
### Update multiple values in a message field

In the following example, two `ResourceFilter` blocks target outbound traffic to the `db` service and add `/outlier_detection/enforcing_consecutive_5xx` and `/outlier_detection/failure_percentage_request_volume` properties:
In the following example, both `ResourceFilter` blocks target the cluster corresponding to the `other-svc` upstream service and modify [Cluster `/outlier_detection`](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/outlier_detection.proto) properties:

```hcl
Kind = "service-defaults"
Expand All @@ -208,65 +210,71 @@ EnvoyExtensions = [
Patches = [
{
ResourceFilter = {
ResourceType = "cluster",
TrafficDirection = "outbound",
ResourceType = "cluster"
TrafficDirection = "outbound"
Services = [{
Name = "other-svc"
}],
},
Op = "add",
Path = "/outlier_detection/enforcing_consecutive_5xx",
Value = 1234,
}]
}
Op = "add"
Path = "/outlier_detection/max_ejection_time/seconds"
Value = 120
},
{
ResourceFilter = {
ResourceType = "cluster",
TrafficDirection = "outbound",
ResourceType = "cluster"
TrafficDirection = "outbound"
Services = [{
Name = "other-svc"
}],
},
Op = "add",
Path = "/outlier_detection/failure_percentage_request_volume",
Value = 2345,
}]
}
Op = "add"
Path = "/outlier_detection/max_ejection_time_jitter/seconds"
Value = 1
}
]
}
}
]
```

### Set multiple values that replace the map
The use of `/seconds` in these examples corresponds to the same field in the [google.protobuf.Duration](https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/duration.proto) proto definition, since the extension does not support JSON serialized string forms of common protobuf types (e.g. `120s`).

-> **Note:** Using separate patches per field preserves any existing configuration of other fields in `outlier_detection` that may be directly set by Consul, such as [`enforcing_consecutive_5xx`](https://developer.hashicorp.com/consul/docs/connect/proxies/envoy#enforcing_consecutive_5xx).

### Replace a message field

In the following example, a `ResourceFilter` targets outbound traffic to the `db` service and replaces the map of properties located at `/outlier_detection` with `enforcing_consecutive_5xx` and `failure_percentage_request_volume` and properties:
In the following example, a `ResourceFilter` targets the cluster corresponding to the `other-svc` upstream service and _replaces_ the entire map of properties located at `/outlier_detection`, including explicitly set `enforcing_success_rate` and `success_rate_minimum_hosts` properties:

```hcl
Kind = "service-defaults"
Name = "my-svc"
Protocol = "http"
EnvoyExtensions = [
{
Name = "builtin/property-override",
Name = "builtin/property-override"
Arguments = {
ProxyType = "connect-proxy",
ProxyType = "connect-proxy"
Patches = [
{
ResourceFilter = {
ResourceType = "cluster",
TrafficDirection = "outbound",
ResourceType = "cluster"
TrafficDirection = "outbound"
Services = [{
Name = "other-svc"
}],
},
Op = "add",
Path = "/outlier_detection",
}]
}
Op = "add"
Path = "/outlier_detection"
Value = {
"enforcing_consecutive_5xx" = 1234,
"failure_percentage_request_volume" = 2345,
},
"enforcing_success_rate" = 80
"success_rate_minimum_hosts" = 2
}
}
]
}
}
]
```

Unlike the previous example, other `/outlier_detection` values set by Consul will _not_ be retained unless they match Envoy's defaults, because the entire value of `/outlier_detection` will be replaced.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ description: Learn how to use the property-override extension for Envoy proxies

This topic describes how to use the `property-override` extension to set and remove individual properties for the Envoy resources Consul generates. The extension uses the [protoreflect](https://pkg.go.dev/google.golang.org/protobuf/reflect/protoreflect), which enables Consul to dynamically manipulate messages.

The extension currently supports setting scalar and enum fields, removing individual fields addressable by `Path`, and initializing unset intermediate message fields indicated in `Path`.

It currently does _not_ support the following use cases:
- Adding, updating, or removing repeated field members
- Adding or updating [protobuf `map`](https://protobuf.dev/programming-guides/proto3/#maps) fields
- Adding or updating [protobuf `Any`](https://protobuf.dev/programming-guides/proto3/#any) fields

## Workflow

- Complete the following steps to use the `property-override` extension:
Expand All @@ -23,17 +30,17 @@ Add Envoy extension configurations to a proxy defaults or service defaults confi
- When you configure Envoy extensions on proxy defaults, they apply to every service.
- When you configure Envoy extensions on service defaults, they apply to a specific service.

Consul applies Envoy extensions configured in proxy defaults before it applies extensions in service defaults. As a result, the Envoy extension configuration in service defaults may override configurations in proxy defaults.
Consul applies Envoy extensions configured in proxy defaults before it applies extensions in service defaults. As a result, the Envoy extension configuration in service defaults may override configurations in proxy defaults.

In the following service defaults configuration entry example, Consul adds a new `/upstream_connection_options/tcp_keepalive/keepalive_probes-5` field to each of the proxy's cluster configuration for the outbound `db`service upstream. The configuration applies to all `connect-proxy` proxies with services configured to communicate over HTTP:
In the following proxy defaults configuration entry example, Consul sets the `/respect_dns_ttl` field on the `api` service proxy's cluster configuration for the `other-svc` upstream service:

<Tabs>
<Tab heading="HCL" group="hcl">
<CodeBlockConfig filename="property-override-extension-service-defaults.hcl">

```hcl
Kind = "service-defaults"
Name = "global"
Name = "api"
Protocol = "http"
EnvoyExtensions = [
{
Expand All @@ -50,8 +57,8 @@ EnvoyExtensions = [
}]
}
Op = "add"
Path = "/upstream_connection_options/tcp_keepalive/keepalive_probes"
Value = 5
Path = "/respect_dns_ttl"
Value = true
}
]
}
Expand All @@ -66,35 +73,35 @@ EnvoyExtensions = [

```json
"kind": "service-defaults",
"name": "global",
"name": "api",
"protocol": "http",
"envoy_extensions": [{
"envoyExtensions": [{
"name": "builtin/property-override",
"arguments": {
"proxyType": "connect-proxy",
"patches": [{
"resourceFilter": {
"resourceType": "cluster",
"trafficDirection": "outbound",
"services": [{ "name": "other-svc" }],
"op": "add",
"path": "/upstream_connection_options/tcp_keepalive/keepalive_probes",
"value": 5
}
"services": [{ "name": "other-svc" }]
},
"op": "add",
"path": "/respect_dns_ttl",
"value": true
}]
}
}]
```
</CodeBlockConfig>
</Tab>
<Tab heading="Kubernetes" group="kubernetes">
<CodeBlockConfig filename="property-override-extension-proxy-defaults.yaml">
<CodeBlockConfig filename="property-override-extension-service-defaults.yaml">

```yaml
apiversion: consul.hashicorp.com/v1alpha1
kind: ServiceDefaults
metadata:
name: global
name: api
spec:
protocol: http
envoyExtensions:
Expand All @@ -108,8 +115,8 @@ spec:
services:
- name: "other-svc"
op: "add"
path: "/upstream_connection_options/tcp_keepalive/keepalive_probes",
value: 5
path: "/respect_dns_ttl",
value: true
```

</CodeBlockConfig>
Expand All @@ -136,6 +143,7 @@ EnvoyExtensions = [
{
Name = "builtin/property-override"
Arguments = {
Debug = true
ProxyType = "connect-proxy"
Patches = [
{
Expand All @@ -146,7 +154,7 @@ EnvoyExtensions = [
Op = "add"
Path = ""
Value = 5
}
}
]
}
}
Expand All @@ -157,19 +165,23 @@ After applying the configuration entry, Consul prints a message that includes th

```shell-session
$ consul config write api.hcl
non-empty, non-root Path is required. available cluster fields:
/outlier_detection
/outlier_detection/enforcing_consecutive_5xx
/outlier_detection/failure_percentage_request_volume
/round_robin_lb_config
/round_robin_lb_config/slow_start_config
non-empty, non-root Path is required;
available envoy.config.cluster.v3.Cluster fields:
transport_socket_matches
name
alt_stat_name
type
cluster_type
eds_cluster_config
connect_timeout
...
```

You can use the output to help you construct the appropriate value for the `Path` field. For example:

```shell-session
$ consul config write api.hcl | grep round_robin
/round_robin_lb_config
$ consul config write api.hcl 2>&1 | grep round_robin
round_robin_lb_config
```


Expand Down

0 comments on commit b7524f7

Please sign in to comment.