This commit is contained in:
Anurag Agarwal 2025-07-22 12:10:42 +05:30 committed by GitHub
commit 8dcb16be66
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
40 changed files with 1222 additions and 438 deletions

View File

@ -141,10 +141,10 @@ def grpc_java_repositories(bzlmod = False):
if not native.existing_rule("envoy_api"): if not native.existing_rule("envoy_api"):
http_archive( http_archive(
name = "envoy_api", name = "envoy_api",
sha256 = "ecf71817233eba19cc8b4ee14e126ffd5838065d5b5a92b2506258a42ac55199", sha256 = "e1c59ea08b84ad2994ccfc8d0cb6fc02358f24f659ea42dd8fc7755ff6887d01",
strip_prefix = "data-plane-api-0bc95493c5e88b7b07e62758d23b39341813a827", strip_prefix = "envoy-464320b866ca5d2fddaa609a62d77d7d12f0f078/api",
urls = [ urls = [
"https://github.com/envoyproxy/data-plane-api/archive/0bc95493c5e88b7b07e62758d23b39341813a827.tar.gz", "https://github.com/envoyproxy/envoy/archive/464320b866ca5d2fddaa609a62d77d7d12f0f078.tar.gz",
], ],
) )

View File

@ -30,6 +30,7 @@ import io.envoyproxy.envoy.config.cluster.v3.Cluster.RingHashLbConfig;
import io.envoyproxy.envoy.config.cluster.v3.LoadBalancingPolicy; import io.envoyproxy.envoy.config.cluster.v3.LoadBalancingPolicy;
import io.envoyproxy.envoy.config.cluster.v3.LoadBalancingPolicy.Policy; import io.envoyproxy.envoy.config.cluster.v3.LoadBalancingPolicy.Policy;
import io.envoyproxy.envoy.extensions.load_balancing_policies.client_side_weighted_round_robin.v3.ClientSideWeightedRoundRobin; import io.envoyproxy.envoy.extensions.load_balancing_policies.client_side_weighted_round_robin.v3.ClientSideWeightedRoundRobin;
import io.envoyproxy.envoy.extensions.load_balancing_policies.common.v3.SlowStartConfig;
import io.envoyproxy.envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest; import io.envoyproxy.envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest;
import io.envoyproxy.envoy.extensions.load_balancing_policies.pick_first.v3.PickFirst; import io.envoyproxy.envoy.extensions.load_balancing_policies.pick_first.v3.PickFirst;
import io.envoyproxy.envoy.extensions.load_balancing_policies.ring_hash.v3.RingHash; import io.envoyproxy.envoy.extensions.load_balancing_policies.ring_hash.v3.RingHash;
@ -92,6 +93,14 @@ class LoadBalancerConfigFactory {
static final String ERROR_UTILIZATION_PENALTY = "errorUtilizationPenalty"; static final String ERROR_UTILIZATION_PENALTY = "errorUtilizationPenalty";
static final String AGGRESSION = "aggression";
static final String SLOW_START_WINDOW = "slowStartWindow";
static final String MIN_WEIGHT_PERCENT = "minWeightPercent";
static final String SLOW_START_CONFIG = "slowStartConfig";
/** /**
* Factory method for creating a new {link LoadBalancerConfigConverter} for a given xDS {@link * Factory method for creating a new {link LoadBalancerConfigConverter} for a given xDS {@link
* Cluster}. * Cluster}.
@ -138,7 +147,8 @@ class LoadBalancerConfigFactory {
String oobReportingPeriod, String oobReportingPeriod,
Boolean enableOobLoadReport, Boolean enableOobLoadReport,
String weightUpdatePeriod, String weightUpdatePeriod,
Float errorUtilizationPenalty) { Float errorUtilizationPenalty,
ImmutableMap<String, ?> slowStartConfig) {
ImmutableMap.Builder<String, Object> configBuilder = ImmutableMap.builder(); ImmutableMap.Builder<String, Object> configBuilder = ImmutableMap.builder();
if (blackoutPeriod != null) { if (blackoutPeriod != null) {
configBuilder.put(BLACK_OUT_PERIOD, blackoutPeriod); configBuilder.put(BLACK_OUT_PERIOD, blackoutPeriod);
@ -158,10 +168,29 @@ class LoadBalancerConfigFactory {
if (errorUtilizationPenalty != null) { if (errorUtilizationPenalty != null) {
configBuilder.put(ERROR_UTILIZATION_PENALTY, errorUtilizationPenalty); configBuilder.put(ERROR_UTILIZATION_PENALTY, errorUtilizationPenalty);
} }
if (slowStartConfig != null) {
configBuilder.put(SLOW_START_CONFIG, slowStartConfig);
}
return ImmutableMap.of(WeightedRoundRobinLoadBalancerProvider.SCHEME, return ImmutableMap.of(WeightedRoundRobinLoadBalancerProvider.SCHEME,
configBuilder.buildOrThrow()); configBuilder.buildOrThrow());
} }
private static ImmutableMap<String, ?> buildSlowStartConfig(Double minWeightPercent,
Double aggression,
String slowStartWindow) {
ImmutableMap.Builder<String, Object> configBuilder = ImmutableMap.builder();
if (minWeightPercent != null) {
configBuilder.put(MIN_WEIGHT_PERCENT, minWeightPercent);
}
if (aggression != null) {
configBuilder.put(AGGRESSION, aggression);
}
if (slowStartWindow != null) {
configBuilder.put(SLOW_START_WINDOW, slowStartWindow);
}
return configBuilder.buildOrThrow();
}
/** /**
* Builds a service config JSON object for the least_request load balancer config based on the * Builds a service config JSON object for the least_request load balancer config based on the
* given config values. * given config values.
@ -293,13 +322,28 @@ class LoadBalancerConfigFactory {
wrr.hasOobReportingPeriod() ? Durations.toString(wrr.getOobReportingPeriod()) : null, wrr.hasOobReportingPeriod() ? Durations.toString(wrr.getOobReportingPeriod()) : null,
wrr.hasEnableOobLoadReport() ? wrr.getEnableOobLoadReport().getValue() : null, wrr.hasEnableOobLoadReport() ? wrr.getEnableOobLoadReport().getValue() : null,
wrr.hasWeightUpdatePeriod() ? Durations.toString(wrr.getWeightUpdatePeriod()) : null, wrr.hasWeightUpdatePeriod() ? Durations.toString(wrr.getWeightUpdatePeriod()) : null,
wrr.hasErrorUtilizationPenalty() ? wrr.getErrorUtilizationPenalty().getValue() : null); wrr.hasErrorUtilizationPenalty() ? wrr.getErrorUtilizationPenalty().getValue() : null,
wrr.hasSlowStartConfig() ? convertSlotStartConfig(wrr.getSlowStartConfig()) : null);
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
throw new ResourceInvalidException("Invalid duration in weighted round robin config: " throw new ResourceInvalidException("Invalid duration in weighted round robin config: "
+ ex.getMessage()); + ex.getMessage());
} }
} }
private static ImmutableMap<String, ?> convertSlotStartConfig(
SlowStartConfig config) throws ResourceInvalidException {
try {
return buildSlowStartConfig(
config.hasMinWeightPercent() ? config.getMinWeightPercent().getValue() : null,
config.hasAggression() ? config.getAggression().getDefaultValue() : null,
config.hasSlowStartWindow() ? Durations.toString(config.getSlowStartWindow()) : null
);
} catch (IllegalArgumentException ex) {
throw new ResourceInvalidException("Invalid duration in slow start slowStart: "
+ ex.getMessage());
}
}
/** /**
* Converts a wrr_locality {@link Any} configuration to service config format. * Converts a wrr_locality {@link Any} configuration to service config format.
*/ */

View File

@ -0,0 +1,64 @@
/*
* Copyright 2025 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.grpc.xds;
final class SlowStartConfig {
final double minWeightPercent;
final double aggression;
final long slowStartWindowNanos;
public static Builder newBuilder() {
return new Builder();
}
private SlowStartConfig(double minWeightPercent, double aggression, long slowStartWindowNanos) {
this.minWeightPercent = minWeightPercent;
this.aggression = aggression;
this.slowStartWindowNanos = slowStartWindowNanos;
}
static final class Builder {
private double minWeightPercent = 10.0;
private double aggression = 1.0;
private long slowStartWindowNanos = 0L;
private Builder() {
}
@SuppressWarnings("UnusedReturnValue")
Builder setMinWeightPercent(double minWeightPercent) {
this.minWeightPercent = minWeightPercent;
return this;
}
@SuppressWarnings("UnusedReturnValue")
Builder setAggression(double aggression) {
this.aggression = aggression;
return this;
}
@SuppressWarnings("UnusedReturnValue")
Builder setSlowStartWindowNanos(long slowStartWindowNanos) {
this.slowStartWindowNanos = slowStartWindowNanos;
return this;
}
SlowStartConfig build() {
return new SlowStartConfig(minWeightPercent, aggression, slowStartWindowNanos);
}
}
}

View File

@ -68,7 +68,11 @@ import java.util.logging.Logger;
* "\"oobReportingPeriod\":\"10s\"," + * "\"oobReportingPeriod\":\"10s\"," +
* "\"weightExpirationPeriod\":\"180s\"," + * "\"weightExpirationPeriod\":\"180s\"," +
* "\"errorUtilizationPenalty\":\"1.0\"," + * "\"errorUtilizationPenalty\":\"1.0\"," +
* "\"weightUpdatePeriod\":\"1s\"}}]}"; * "\"weightUpdatePeriod\":\"1s\"," +
* "\"slowStartConfig\":{" +
* "\"minWeightPercent\":10.0," +
* "\"aggression\":1.0," +
* "\"slowStartWindow\":\"30s\"}}}]}";
* serviceConfig = (Map<String, ?>) JsonParser.parse(wrrConfig); * serviceConfig = (Map<String, ?>) JsonParser.parse(wrrConfig);
* channel = ManagedChannelBuilder.forTarget("test:///lb.test.grpc.io") * channel = ManagedChannelBuilder.forTarget("test:///lb.test.grpc.io")
* .defaultServiceConfig(serviceConfig) * .defaultServiceConfig(serviceConfig)
@ -90,6 +94,7 @@ final class WeightedRoundRobinLoadBalancer extends MultiChildLoadBalancer {
private static final LongCounterMetricInstrument RR_FALLBACK_COUNTER; private static final LongCounterMetricInstrument RR_FALLBACK_COUNTER;
private static final LongCounterMetricInstrument ENDPOINT_WEIGHT_NOT_YET_USEABLE_COUNTER; private static final LongCounterMetricInstrument ENDPOINT_WEIGHT_NOT_YET_USEABLE_COUNTER;
private static final LongCounterMetricInstrument ENDPOINT_WEIGHT_STALE_COUNTER; private static final LongCounterMetricInstrument ENDPOINT_WEIGHT_STALE_COUNTER;
private static final LongCounterMetricInstrument ENDPOINT_SLOW_START_COUNTER;
private static final DoubleHistogramMetricInstrument ENDPOINT_WEIGHTS_HISTOGRAM; private static final DoubleHistogramMetricInstrument ENDPOINT_WEIGHTS_HISTOGRAM;
private static final Logger log = Logger.getLogger( private static final Logger log = Logger.getLogger(
WeightedRoundRobinLoadBalancer.class.getName()); WeightedRoundRobinLoadBalancer.class.getName());
@ -133,6 +138,14 @@ final class WeightedRoundRobinLoadBalancer extends MultiChildLoadBalancer {
Lists.newArrayList("grpc.target"), Lists.newArrayList("grpc.target"),
Lists.newArrayList("grpc.lb.locality", "grpc.lb.backend_service"), Lists.newArrayList("grpc.lb.locality", "grpc.lb.backend_service"),
false); false);
ENDPOINT_SLOW_START_COUNTER = metricInstrumentRegistry.registerLongCounter(
"grpc.lb.wrr.endpoints_in_slow_start",
"EXPERIMENTAL. Number of endpoints from each scheduler update that "
+ "are in slow start window",
"{endpoint}",
Lists.newArrayList("grpc.target"),
Lists.newArrayList("grpc.lb.locality", "grpc.lb.backend_service"),
false);
ENDPOINT_WEIGHTS_HISTOGRAM = metricInstrumentRegistry.registerDoubleHistogram( ENDPOINT_WEIGHTS_HISTOGRAM = metricInstrumentRegistry.registerDoubleHistogram(
"grpc.lb.wrr.endpoint_weights", "grpc.lb.wrr.endpoint_weights",
"EXPERIMENTAL. The histogram buckets will be endpoint weight ranges.", "EXPERIMENTAL. The histogram buckets will be endpoint weight ranges.",
@ -243,16 +256,21 @@ final class WeightedRoundRobinLoadBalancer extends MultiChildLoadBalancer {
private void updateWeight(WeightedRoundRobinPicker picker) { private void updateWeight(WeightedRoundRobinPicker picker) {
Helper helper = getHelper(); Helper helper = getHelper();
float[] newWeights = new float[picker.children.size()]; float[] newWeights = new float[picker.children.size()];
float[] newScales = new float[picker.children.size()];
AtomicInteger staleEndpoints = new AtomicInteger(); AtomicInteger staleEndpoints = new AtomicInteger();
AtomicInteger notYetUsableEndpoints = new AtomicInteger(); AtomicInteger notYetUsableEndpoints = new AtomicInteger();
AtomicInteger slowStartEndpoints = new AtomicInteger();
for (int i = 0; i < picker.children.size(); i++) { for (int i = 0; i < picker.children.size(); i++) {
double newWeight = ((WeightedChildLbState) picker.children.get(i)).getWeight(staleEndpoints, double newWeight = ((WeightedChildLbState) picker.children.get(i)).getWeight(staleEndpoints,
notYetUsableEndpoints); notYetUsableEndpoints);
double newScale = ((WeightedChildLbState) picker.children.get(i))
.getScale(slowStartEndpoints);
helper.getMetricRecorder() helper.getMetricRecorder()
.recordDoubleHistogram(ENDPOINT_WEIGHTS_HISTOGRAM, newWeight, .recordDoubleHistogram(ENDPOINT_WEIGHTS_HISTOGRAM, newWeight,
ImmutableList.of(helper.getChannelTarget()), ImmutableList.of(helper.getChannelTarget()),
ImmutableList.of(locality, backendService)); ImmutableList.of(locality, backendService));
newWeights[i] = newWeight > 0 ? (float) newWeight : 0.0f; newWeights[i] = newWeight > 0 ? (float) newWeight : 0.0f;
newScales[i] = newScale > 0 ? (float) newScale : 1.0f;
} }
if (staleEndpoints.get() > 0) { if (staleEndpoints.get() > 0) {
@ -267,7 +285,13 @@ final class WeightedRoundRobinLoadBalancer extends MultiChildLoadBalancer {
ImmutableList.of(helper.getChannelTarget()), ImmutableList.of(helper.getChannelTarget()),
ImmutableList.of(locality, backendService)); ImmutableList.of(locality, backendService));
} }
boolean weightsEffective = picker.updateWeight(newWeights); if (slowStartEndpoints.get() > 0) {
helper.getMetricRecorder()
.addLongCounter(ENDPOINT_SLOW_START_COUNTER, slowStartEndpoints.get(),
ImmutableList.of(helper.getChannelTarget()),
ImmutableList.of(locality, backendService));
}
boolean weightsEffective = picker.updateWeight(newWeights, newScales);
if (!weightsEffective) { if (!weightsEffective) {
helper.getMetricRecorder() helper.getMetricRecorder()
.addLongCounter(RR_FALLBACK_COUNTER, 1, ImmutableList.of(helper.getChannelTarget()), .addLongCounter(RR_FALLBACK_COUNTER, 1, ImmutableList.of(helper.getChannelTarget()),
@ -289,6 +313,7 @@ final class WeightedRoundRobinLoadBalancer extends MultiChildLoadBalancer {
private final Set<WrrSubchannel> subchannels = new HashSet<>(); private final Set<WrrSubchannel> subchannels = new HashSet<>();
private volatile long lastUpdated; private volatile long lastUpdated;
private volatile long nonEmptySince; private volatile long nonEmptySince;
private volatile long readySince;
private volatile double weight = 0; private volatile double weight = 0;
private OrcaReportListener orcaReportListener; private OrcaReportListener orcaReportListener;
@ -320,6 +345,25 @@ final class WeightedRoundRobinLoadBalancer extends MultiChildLoadBalancer {
} }
} }
private double getScale(AtomicInteger slowStartEndpoints) {
if (config == null || config.slowStartConfig == null) {
return 1;
}
long slowStartWindowNanos = config.slowStartConfig.slowStartWindowNanos;
if (slowStartWindowNanos <= 0) {
return 1;
}
long now = ticker.nanoTime();
if (now - readySince >= slowStartWindowNanos) {
return 1;
} else {
slowStartEndpoints.incrementAndGet();
double timeFactor = Math.max(now - readySince, 1.0) / slowStartWindowNanos;
double weightPercent = Math.pow(timeFactor, 1.0 / config.slowStartConfig.aggression);
return Math.max(config.slowStartConfig.minWeightPercent / 100.0, weightPercent);
}
}
public void addSubchannel(WrrSubchannel wrrSubchannel) { public void addSubchannel(WrrSubchannel wrrSubchannel) {
subchannels.add(wrrSubchannel); subchannels.add(wrrSubchannel);
} }
@ -439,6 +483,7 @@ final class WeightedRoundRobinLoadBalancer extends MultiChildLoadBalancer {
public void onSubchannelState(ConnectivityStateInfo newState) { public void onSubchannelState(ConnectivityStateInfo newState) {
if (newState.getState().equals(ConnectivityState.READY)) { if (newState.getState().equals(ConnectivityState.READY)) {
owner.nonEmptySince = infTime; owner.nonEmptySince = infTime;
owner.readySince = ticker.nanoTime();
} }
listener.onSubchannelState(newState); listener.onSubchannelState(newState);
} }
@ -517,8 +562,8 @@ final class WeightedRoundRobinLoadBalancer extends MultiChildLoadBalancer {
} }
/** Returns {@code true} if weights are different than round_robin. */ /** Returns {@code true} if weights are different than round_robin. */
private boolean updateWeight(float[] newWeights) { private boolean updateWeight(float[] newWeights, float[] newScales) {
this.scheduler = new StaticStrideScheduler(newWeights, sequence); this.scheduler = new StaticStrideScheduler(newWeights, newScales, sequence);
return !this.scheduler.usesRoundRobin(); return !this.scheduler.usesRoundRobin();
} }
@ -604,7 +649,7 @@ final class WeightedRoundRobinLoadBalancer extends MultiChildLoadBalancer {
private static final double K_MAX_RATIO = 10; private static final double K_MAX_RATIO = 10;
private static final double K_MIN_RATIO = 0.1; private static final double K_MIN_RATIO = 0.1;
StaticStrideScheduler(float[] weights, AtomicInteger sequence) { StaticStrideScheduler(float[] weights, float[] scales, AtomicInteger sequence) {
checkArgument(weights.length >= 1, "Couldn't build scheduler: requires at least one weight"); checkArgument(weights.length >= 1, "Couldn't build scheduler: requires at least one weight");
int numChannels = weights.length; int numChannels = weights.length;
int numWeightedChannels = 0; int numWeightedChannels = 0;
@ -643,12 +688,14 @@ final class WeightedRoundRobinLoadBalancer extends MultiChildLoadBalancer {
int weightLowerBound = (int) Math.ceil(scalingFactor * unscaledMeanWeight * K_MIN_RATIO); int weightLowerBound = (int) Math.ceil(scalingFactor * unscaledMeanWeight * K_MIN_RATIO);
short[] scaledWeights = new short[numChannels]; short[] scaledWeights = new short[numChannels];
for (int i = 0; i < numChannels; i++) { for (int i = 0; i < numChannels; i++) {
double curScalingFactor = scalingFactor * scales[i];
int weight;
if (weights[i] <= 0) { if (weights[i] <= 0) {
scaledWeights[i] = (short) Math.round(scalingFactor * unscaledMeanWeight); weight = (int) Math.round(curScalingFactor * unscaledMeanWeight);
} else { } else {
int weight = (int) Math.round(scalingFactor * Math.min(weights[i], unscaledMaxWeight)); weight = (int) Math.round(curScalingFactor * Math.min(weights[i], unscaledMaxWeight));
scaledWeights[i] = (short) Math.max(weight, weightLowerBound);
} }
scaledWeights[i] = (short) Math.max(weight, weightLowerBound);
} }
this.scaledWeights = scaledWeights; this.scaledWeights = scaledWeights;
@ -719,6 +766,7 @@ final class WeightedRoundRobinLoadBalancer extends MultiChildLoadBalancer {
final long oobReportingPeriodNanos; final long oobReportingPeriodNanos;
final long weightUpdatePeriodNanos; final long weightUpdatePeriodNanos;
final float errorUtilizationPenalty; final float errorUtilizationPenalty;
final SlowStartConfig slowStartConfig;
public static Builder newBuilder() { public static Builder newBuilder() {
return new Builder(); return new Builder();
@ -729,13 +777,15 @@ final class WeightedRoundRobinLoadBalancer extends MultiChildLoadBalancer {
boolean enableOobLoadReport, boolean enableOobLoadReport,
long oobReportingPeriodNanos, long oobReportingPeriodNanos,
long weightUpdatePeriodNanos, long weightUpdatePeriodNanos,
float errorUtilizationPenalty) { float errorUtilizationPenalty,
SlowStartConfig slowStartConfig) {
this.blackoutPeriodNanos = blackoutPeriodNanos; this.blackoutPeriodNanos = blackoutPeriodNanos;
this.weightExpirationPeriodNanos = weightExpirationPeriodNanos; this.weightExpirationPeriodNanos = weightExpirationPeriodNanos;
this.enableOobLoadReport = enableOobLoadReport; this.enableOobLoadReport = enableOobLoadReport;
this.oobReportingPeriodNanos = oobReportingPeriodNanos; this.oobReportingPeriodNanos = oobReportingPeriodNanos;
this.weightUpdatePeriodNanos = weightUpdatePeriodNanos; this.weightUpdatePeriodNanos = weightUpdatePeriodNanos;
this.errorUtilizationPenalty = errorUtilizationPenalty; this.errorUtilizationPenalty = errorUtilizationPenalty;
this.slowStartConfig = slowStartConfig;
} }
static final class Builder { static final class Builder {
@ -745,6 +795,7 @@ final class WeightedRoundRobinLoadBalancer extends MultiChildLoadBalancer {
long oobReportingPeriodNanos = 10_000_000_000L; // 10s long oobReportingPeriodNanos = 10_000_000_000L; // 10s
long weightUpdatePeriodNanos = 1_000_000_000L; // 1s long weightUpdatePeriodNanos = 1_000_000_000L; // 1s
float errorUtilizationPenalty = 1.0F; float errorUtilizationPenalty = 1.0F;
SlowStartConfig slowStartConfig = SlowStartConfig.newBuilder().build();
private Builder() { private Builder() {
@ -782,10 +833,16 @@ final class WeightedRoundRobinLoadBalancer extends MultiChildLoadBalancer {
return this; return this;
} }
@SuppressWarnings("UnusedReturnValue")
Builder setSlowStartConfig(SlowStartConfig slowStartConfig) {
this.slowStartConfig = slowStartConfig;
return this;
}
WeightedRoundRobinLoadBalancerConfig build() { WeightedRoundRobinLoadBalancerConfig build() {
return new WeightedRoundRobinLoadBalancerConfig(blackoutPeriodNanos, return new WeightedRoundRobinLoadBalancerConfig(blackoutPeriodNanos,
weightExpirationPeriodNanos, enableOobLoadReport, oobReportingPeriodNanos, weightExpirationPeriodNanos, enableOobLoadReport, oobReportingPeriodNanos,
weightUpdatePeriodNanos, errorUtilizationPenalty); weightUpdatePeriodNanos, errorUtilizationPenalty, slowStartConfig);
} }
} }
} }

View File

@ -78,6 +78,7 @@ public final class WeightedRoundRobinLoadBalancerProvider extends LoadBalancerPr
Boolean enableOobLoadReport = JsonUtil.getBoolean(rawConfig, "enableOobLoadReport"); Boolean enableOobLoadReport = JsonUtil.getBoolean(rawConfig, "enableOobLoadReport");
Long weightUpdatePeriodNanos = JsonUtil.getStringAsDuration(rawConfig, "weightUpdatePeriod"); Long weightUpdatePeriodNanos = JsonUtil.getStringAsDuration(rawConfig, "weightUpdatePeriod");
Float errorUtilizationPenalty = JsonUtil.getNumberAsFloat(rawConfig, "errorUtilizationPenalty"); Float errorUtilizationPenalty = JsonUtil.getNumberAsFloat(rawConfig, "errorUtilizationPenalty");
Map<String, ?> slowStartConfig = JsonUtil.getObject(rawConfig, "slowStartConfig");
WeightedRoundRobinLoadBalancerConfig.Builder configBuilder = WeightedRoundRobinLoadBalancerConfig.Builder configBuilder =
WeightedRoundRobinLoadBalancerConfig.newBuilder(); WeightedRoundRobinLoadBalancerConfig.newBuilder();
@ -102,6 +103,27 @@ public final class WeightedRoundRobinLoadBalancerProvider extends LoadBalancerPr
if (errorUtilizationPenalty != null) { if (errorUtilizationPenalty != null) {
configBuilder.setErrorUtilizationPenalty(errorUtilizationPenalty); configBuilder.setErrorUtilizationPenalty(errorUtilizationPenalty);
} }
if (slowStartConfig != null) {
configBuilder.setSlowStartConfig(parseSlowStartConfig(slowStartConfig));
}
return ConfigOrError.fromConfig(configBuilder.build()); return ConfigOrError.fromConfig(configBuilder.build());
} }
private SlowStartConfig parseSlowStartConfig(Map<String, ?> rawConfig) {
Double minWeightPercent = JsonUtil.getNumberAsDouble(rawConfig, "minWeightPercent");
Double aggression = JsonUtil.getNumberAsDouble(rawConfig, "aggression");
Long slowStartWindowNanos = JsonUtil.getStringAsDuration(rawConfig, "slowStartWindow");
SlowStartConfig.Builder configBuilder = SlowStartConfig.newBuilder();
if (slowStartWindowNanos != null) {
configBuilder.setSlowStartWindowNanos(slowStartWindowNanos);
}
if (aggression != null) {
configBuilder.setAggression(aggression);
}
if (minWeightPercent != null) {
configBuilder.setMinWeightPercent(minWeightPercent);
}
return configBuilder.build();
}
} }

View File

@ -17,7 +17,7 @@
set -e set -e
# import VERSION from the google internal copybara_version.txt for Envoy # import VERSION from the google internal copybara_version.txt for Envoy
VERSION=0b90f64539c88dc3d2a6792dc714e8207bce0c08 VERSION=464320b866ca5d2fddaa609a62d77d7d12f0f078
DOWNLOAD_URL="https://github.com/envoyproxy/envoy/archive/${VERSION}.tar.gz" DOWNLOAD_URL="https://github.com/envoyproxy/envoy/archive/${VERSION}.tar.gz"
DOWNLOAD_BASE_DIR="envoy-${VERSION}" DOWNLOAD_BASE_DIR="envoy-${VERSION}"
SOURCE_PROTO_BASE_DIR="${DOWNLOAD_BASE_DIR}/api" SOURCE_PROTO_BASE_DIR="${DOWNLOAD_BASE_DIR}/api"
@ -46,6 +46,7 @@ envoy/config/core/v3/http_uri.proto
envoy/config/core/v3/protocol.proto envoy/config/core/v3/protocol.proto
envoy/config/core/v3/proxy_protocol.proto envoy/config/core/v3/proxy_protocol.proto
envoy/config/core/v3/resolver.proto envoy/config/core/v3/resolver.proto
envoy/config/core/v3/socket_cmsg_headers.proto
envoy/config/core/v3/socket_option.proto envoy/config/core/v3/socket_option.proto
envoy/config/core/v3/substitution_format_string.proto envoy/config/core/v3/substitution_format_string.proto
envoy/config/core/v3/udp_socket_config.proto envoy/config/core/v3/udp_socket_config.proto
@ -97,6 +98,7 @@ envoy/service/load_stats/v3/lrs.proto
envoy/service/rate_limit_quota/v3/rlqs.proto envoy/service/rate_limit_quota/v3/rlqs.proto
envoy/service/status/v3/csds.proto envoy/service/status/v3/csds.proto
envoy/type/http/v3/path_transformation.proto envoy/type/http/v3/path_transformation.proto
envoy/type/matcher/v3/address.proto
envoy/type/matcher/v3/filter_state.proto envoy/type/matcher/v3/filter_state.proto
envoy/type/matcher/v3/http_inputs.proto envoy/type/matcher/v3/http_inputs.proto
envoy/type/matcher/v3/metadata.proto envoy/type/matcher/v3/metadata.proto

View File

@ -39,6 +39,14 @@ enum ClientResourceStatus {
// Client received this resource and replied with NACK. // Client received this resource and replied with NACK.
NACKED = 4; NACKED = 4;
// Client received an error from the control plane. The attached config
// dump is the most recent accepted one. If no config is accepted yet,
// the attached config dump will be empty.
RECEIVED_ERROR = 5;
// Client timed out waiting for the resource from the control plane.
TIMEOUT = 6;
} }
message UpdateFailureState { message UpdateFailureState {

View File

@ -152,35 +152,38 @@ message TraceableFilter {
"envoy.config.filter.accesslog.v2.TraceableFilter"; "envoy.config.filter.accesslog.v2.TraceableFilter";
} }
// Filters for random sampling of requests. // Filters requests based on runtime-configurable sampling rates.
message RuntimeFilter { message RuntimeFilter {
option (udpa.annotations.versioning).previous_message_type = option (udpa.annotations.versioning).previous_message_type =
"envoy.config.filter.accesslog.v2.RuntimeFilter"; "envoy.config.filter.accesslog.v2.RuntimeFilter";
// Runtime key to get an optional overridden numerator for use in the // Specifies a key used to look up a custom sampling rate from the runtime configuration. If a value is found for this
// ``percent_sampled`` field. If found in runtime, this value will replace the // key, it will override the default sampling rate specified in ``percent_sampled``.
// default numerator.
string runtime_key = 1 [(validate.rules).string = {min_len: 1}]; string runtime_key = 1 [(validate.rules).string = {min_len: 1}];
// The default sampling percentage. If not specified, defaults to 0% with // Defines the default sampling percentage when no runtime override is present. If not specified, the default is
// denominator of 100. // **0%** (with a denominator of 100).
type.v3.FractionalPercent percent_sampled = 2; type.v3.FractionalPercent percent_sampled = 2;
// By default, sampling pivots on the header // Controls how sampling decisions are made.
// :ref:`x-request-id<config_http_conn_man_headers_x-request-id>` being //
// present. If :ref:`x-request-id<config_http_conn_man_headers_x-request-id>` // - Default behavior (``false``):
// is present, the filter will consistently sample across multiple hosts based //
// on the runtime key value and the value extracted from // * Uses the :ref:`x-request-id<config_http_conn_man_headers_x-request-id>` as a consistent sampling pivot.
// :ref:`x-request-id<config_http_conn_man_headers_x-request-id>`. If it is // * When :ref:`x-request-id<config_http_conn_man_headers_x-request-id>` is present, sampling will be consistent
// missing, or ``use_independent_randomness`` is set to true, the filter will // across multiple hosts based on both the ``runtime_key`` and
// randomly sample based on the runtime key value alone. // :ref:`x-request-id<config_http_conn_man_headers_x-request-id>`.
// ``use_independent_randomness`` can be used for logging kill switches within // * Useful for tracking related requests across a distributed system.
// complex nested :ref:`AndFilter //
// <envoy_v3_api_msg_config.accesslog.v3.AndFilter>` and :ref:`OrFilter // - When set to ``true`` or :ref:`x-request-id<config_http_conn_man_headers_x-request-id>` is missing:
// <envoy_v3_api_msg_config.accesslog.v3.OrFilter>` blocks that are easier to //
// reason about from a probability perspective (i.e., setting to true will // * Sampling decisions are made randomly based only on the ``runtime_key``.
// cause the filter to behave like an independent random variable when // * Useful in complex filter configurations (like nested
// composed within logical operator filters). // :ref:`AndFilter<envoy_v3_api_msg_config.accesslog.v3.AndFilter>`/
// :ref:`OrFilter<envoy_v3_api_msg_config.accesslog.v3.OrFilter>` blocks) where independent probability
// calculations are desired.
// * Can be used to implement logging kill switches with predictable probability distributions.
//
bool use_independent_randomness = 3; bool use_independent_randomness = 3;
} }
@ -257,6 +260,7 @@ message ResponseFlagFilter {
in: "DF" in: "DF"
in: "DO" in: "DO"
in: "DR" in: "DR"
in: "UDO"
} }
} }
}]; }];

View File

@ -57,9 +57,7 @@ message Bootstrap {
// If a network based configuration source is specified for :ref:`cds_config // If a network based configuration source is specified for :ref:`cds_config
// <envoy_v3_api_field_config.bootstrap.v3.Bootstrap.DynamicResources.cds_config>`, it's necessary // <envoy_v3_api_field_config.bootstrap.v3.Bootstrap.DynamicResources.cds_config>`, it's necessary
// to have some initial cluster definitions available to allow Envoy to know // to have some initial cluster definitions available to allow Envoy to know
// how to speak to the management server. These cluster definitions may not // how to speak to the management server.
// use :ref:`EDS <arch_overview_dynamic_config_eds>` (i.e. they should be static
// IP or DNS-based).
repeated cluster.v3.Cluster clusters = 2; repeated cluster.v3.Cluster clusters = 2;
// These static secrets can be used by :ref:`SdsSecretConfig // These static secrets can be used by :ref:`SdsSecretConfig

View File

@ -652,7 +652,8 @@ message Cluster {
// If this is not set, we default to a merge window of 1000ms. To disable it, set the merge // If this is not set, we default to a merge window of 1000ms. To disable it, set the merge
// window to 0. // window to 0.
// //
// Note: merging does not apply to cluster membership changes (e.g.: adds/removes); this is // .. note::
// Merging does not apply to cluster membership changes (e.g.: adds/removes); this is
// because merging those updates isn't currently safe. See // because merging those updates isn't currently safe. See
// https://github.com/envoyproxy/envoy/pull/3941. // https://github.com/envoyproxy/envoy/pull/3941.
google.protobuf.Duration update_merge_window = 4; google.protobuf.Duration update_merge_window = 4;
@ -816,11 +817,13 @@ message Cluster {
string name = 1 [(validate.rules).string = {min_len: 1}]; string name = 1 [(validate.rules).string = {min_len: 1}];
// An optional alternative to the cluster name to be used for observability. This name is used // An optional alternative to the cluster name to be used for observability. This name is used
// emitting stats for the cluster and access logging the cluster name. This will appear as // for emitting stats for the cluster and access logging the cluster name. This will appear as
// additional information in configuration dumps of a cluster's current status as // additional information in configuration dumps of a cluster's current status as
// :ref:`observability_name <envoy_v3_api_field_admin.v3.ClusterStatus.observability_name>` // :ref:`observability_name <envoy_v3_api_field_admin.v3.ClusterStatus.observability_name>`
// and as an additional tag "upstream_cluster.name" while tracing. Note: Any ``:`` in the name // and as an additional tag "upstream_cluster.name" while tracing.
// will be converted to ``_`` when emitting statistics. This should not be confused with //
// .. note::
// Any ``:`` in the name will be converted to ``_`` when emitting statistics. This should not be confused with
// :ref:`Router Filter Header <config_http_filters_router_x-envoy-upstream-alt-stat-name>`. // :ref:`Router Filter Header <config_http_filters_router_x-envoy-upstream-alt-stat-name>`.
string alt_stat_name = 28 [(udpa.annotations.field_migrate).rename = "observability_name"]; string alt_stat_name = 28 [(udpa.annotations.field_migrate).rename = "observability_name"];
@ -942,6 +945,7 @@ message Cluster {
// "envoy.filters.network.thrift_proxy". See the extension's documentation for details on // "envoy.filters.network.thrift_proxy". See the extension's documentation for details on
// specific options. // specific options.
// [#next-major-version: make this a list of typed extensions.] // [#next-major-version: make this a list of typed extensions.]
// [#extension-category: envoy.upstream_options]
map<string, google.protobuf.Any> typed_extension_protocol_options = 36; map<string, google.protobuf.Any> typed_extension_protocol_options = 36;
// If the DNS refresh rate is specified and the cluster type is either // If the DNS refresh rate is specified and the cluster type is either
@ -953,8 +957,15 @@ message Cluster {
// :ref:`STRICT_DNS<envoy_v3_api_enum_value_config.cluster.v3.Cluster.DiscoveryType.STRICT_DNS>` // :ref:`STRICT_DNS<envoy_v3_api_enum_value_config.cluster.v3.Cluster.DiscoveryType.STRICT_DNS>`
// and :ref:`LOGICAL_DNS<envoy_v3_api_enum_value_config.cluster.v3.Cluster.DiscoveryType.LOGICAL_DNS>` // and :ref:`LOGICAL_DNS<envoy_v3_api_enum_value_config.cluster.v3.Cluster.DiscoveryType.LOGICAL_DNS>`
// this setting is ignored. // this setting is ignored.
google.protobuf.Duration dns_refresh_rate = 16 // This field is deprecated in favor of using the :ref:`cluster_type<envoy_v3_api_field_config.cluster.v3.Cluster.cluster_type>`
[(validate.rules).duration = {gt {nanos: 1000000}}]; // extension point and configuring it with :ref:`DnsCluster<envoy_v3_api_msg_extensions.clusters.dns.v3.DnsCluster>`.
// If :ref:`cluster_type<envoy_v3_api_field_config.cluster.v3.Cluster.cluster_type>` is configured with
// :ref:`DnsCluster<envoy_v3_api_msg_extensions.clusters.dns.v3.DnsCluster>`, this field will be ignored.
google.protobuf.Duration dns_refresh_rate = 16 [
deprecated = true,
(validate.rules).duration = {gt {nanos: 1000000}},
(envoy.annotations.deprecated_at_minor_version) = "3.0"
];
// DNS jitter can be optionally specified if the cluster type is either // DNS jitter can be optionally specified if the cluster type is either
// :ref:`STRICT_DNS<envoy_v3_api_enum_value_config.cluster.v3.Cluster.DiscoveryType.STRICT_DNS>`, // :ref:`STRICT_DNS<envoy_v3_api_enum_value_config.cluster.v3.Cluster.DiscoveryType.STRICT_DNS>`,
@ -965,7 +976,15 @@ message Cluster {
// :ref:`STRICT_DNS<envoy_v3_api_enum_value_config.cluster.v3.Cluster.DiscoveryType.STRICT_DNS>` // :ref:`STRICT_DNS<envoy_v3_api_enum_value_config.cluster.v3.Cluster.DiscoveryType.STRICT_DNS>`
// and :ref:`LOGICAL_DNS<envoy_v3_api_enum_value_config.cluster.v3.Cluster.DiscoveryType.LOGICAL_DNS>` // and :ref:`LOGICAL_DNS<envoy_v3_api_enum_value_config.cluster.v3.Cluster.DiscoveryType.LOGICAL_DNS>`
// this setting is ignored. // this setting is ignored.
google.protobuf.Duration dns_jitter = 58; // This field is deprecated in favor of using the :ref:`cluster_type<envoy_v3_api_field_config.cluster.v3.Cluster.cluster_type>`
// extension point and configuring it with :ref:`DnsCluster<envoy_v3_api_msg_extensions.clusters.dns.v3.DnsCluster>`.
// If :ref:`cluster_type<envoy_v3_api_field_config.cluster.v3.Cluster.cluster_type>` is configured with
// :ref:`DnsCluster<envoy_v3_api_msg_extensions.clusters.dns.v3.DnsCluster>`, this field will be ignored.
google.protobuf.Duration dns_jitter = 58 [
deprecated = true,
(validate.rules).duration = {gte {}},
(envoy.annotations.deprecated_at_minor_version) = "3.0"
];
// If the DNS failure refresh rate is specified and the cluster type is either // If the DNS failure refresh rate is specified and the cluster type is either
// :ref:`STRICT_DNS<envoy_v3_api_enum_value_config.cluster.v3.Cluster.DiscoveryType.STRICT_DNS>`, // :ref:`STRICT_DNS<envoy_v3_api_enum_value_config.cluster.v3.Cluster.DiscoveryType.STRICT_DNS>`,
@ -975,16 +994,31 @@ message Cluster {
// other than :ref:`STRICT_DNS<envoy_v3_api_enum_value_config.cluster.v3.Cluster.DiscoveryType.STRICT_DNS>` and // other than :ref:`STRICT_DNS<envoy_v3_api_enum_value_config.cluster.v3.Cluster.DiscoveryType.STRICT_DNS>` and
// :ref:`LOGICAL_DNS<envoy_v3_api_enum_value_config.cluster.v3.Cluster.DiscoveryType.LOGICAL_DNS>` this setting is // :ref:`LOGICAL_DNS<envoy_v3_api_enum_value_config.cluster.v3.Cluster.DiscoveryType.LOGICAL_DNS>` this setting is
// ignored. // ignored.
RefreshRate dns_failure_refresh_rate = 44; // This field is deprecated in favor of using the :ref:`cluster_type<envoy_v3_api_field_config.cluster.v3.Cluster.cluster_type>`
// extension point and configuring it with :ref:`DnsCluster<envoy_v3_api_msg_extensions.clusters.dns.v3.DnsCluster>`.
// If :ref:`cluster_type<envoy_v3_api_field_config.cluster.v3.Cluster.cluster_type>` is configured with
// :ref:`DnsCluster<envoy_v3_api_msg_extensions.clusters.dns.v3.DnsCluster>`, this field will be ignored.
RefreshRate dns_failure_refresh_rate = 44
[deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"];
// Optional configuration for setting cluster's DNS refresh rate. If the value is set to true, // Optional configuration for setting cluster's DNS refresh rate. If the value is set to true,
// cluster's DNS refresh rate will be set to resource record's TTL which comes from DNS // cluster's DNS refresh rate will be set to resource record's TTL which comes from DNS
// resolution. // resolution.
bool respect_dns_ttl = 39; // This field is deprecated in favor of using the :ref:`cluster_type<envoy_v3_api_field_config.cluster.v3.Cluster.cluster_type>`
// extension point and configuring it with :ref:`DnsCluster<envoy_v3_api_msg_extensions.clusters.dns.v3.DnsCluster>`.
// If :ref:`cluster_type<envoy_v3_api_field_config.cluster.v3.Cluster.cluster_type>` is configured with
// :ref:`DnsCluster<envoy_v3_api_msg_extensions.clusters.dns.v3.DnsCluster>`, this field will be ignored.
bool respect_dns_ttl = 39
[deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"];
// The DNS IP address resolution policy. If this setting is not specified, the // The DNS IP address resolution policy. If this setting is not specified, the
// value defaults to // value defaults to
// :ref:`AUTO<envoy_v3_api_enum_value_config.cluster.v3.Cluster.DnsLookupFamily.AUTO>`. // :ref:`AUTO<envoy_v3_api_enum_value_config.cluster.v3.Cluster.DnsLookupFamily.AUTO>`.
// For logical and strict dns cluster, this field is deprecated in favor of using the
// :ref:`cluster_type<envoy_v3_api_field_config.cluster.v3.Cluster.cluster_type>`
// extension point and configuring it with :ref:`DnsCluster<envoy_v3_api_msg_extensions.clusters.dns.v3.DnsCluster>`.
// If :ref:`cluster_type<envoy_v3_api_field_config.cluster.v3.Cluster.cluster_type>` is configured with
// :ref:`DnsCluster<envoy_v3_api_msg_extensions.clusters.dns.v3.DnsCluster>`, this field will be ignored.
DnsLookupFamily dns_lookup_family = 17 [(validate.rules).enum = {defined_only: true}]; DnsLookupFamily dns_lookup_family = 17 [(validate.rules).enum = {defined_only: true}];
// If DNS resolvers are specified and the cluster type is either // If DNS resolvers are specified and the cluster type is either
@ -1024,6 +1058,9 @@ message Cluster {
// During the transition period when both ``dns_resolution_config`` and ``typed_dns_resolver_config`` exists, // During the transition period when both ``dns_resolution_config`` and ``typed_dns_resolver_config`` exists,
// when ``typed_dns_resolver_config`` is in place, Envoy will use it and ignore ``dns_resolution_config``. // when ``typed_dns_resolver_config`` is in place, Envoy will use it and ignore ``dns_resolution_config``.
// When ``typed_dns_resolver_config`` is missing, the default behavior is in place. // When ``typed_dns_resolver_config`` is missing, the default behavior is in place.
// Also note that this field is deprecated for logical dns and strict dns clusters and will be ignored when
// :ref:`cluster_type<envoy_v3_api_field_config.cluster.v3.Cluster.cluster_type>` is configured with
// :ref:`DnsCluster<envoy_v3_api_msg_extensions.clusters.dns.v3.DnsCluster>`.
// [#extension-category: envoy.network.dns_resolver] // [#extension-category: envoy.network.dns_resolver]
core.v3.TypedExtensionConfig typed_dns_resolver_config = 55; core.v3.TypedExtensionConfig typed_dns_resolver_config = 55;
@ -1311,7 +1348,7 @@ message TrackClusterStats {
// If request_response_sizes is true, then the :ref:`histograms // If request_response_sizes is true, then the :ref:`histograms
// <config_cluster_manager_cluster_stats_request_response_sizes>` tracking header and body sizes // <config_cluster_manager_cluster_stats_request_response_sizes>` tracking header and body sizes
// of requests and responses will be published. // of requests and responses will be published. Additionally, number of headers in the requests and responses will be tracked.
bool request_response_sizes = 2; bool request_response_sizes = 2;
// If true, some stats will be emitted per-endpoint, similar to the stats in admin ``/clusters`` // If true, some stats will be emitted per-endpoint, similar to the stats in admin ``/clusters``

View File

@ -50,7 +50,7 @@ message EnvoyInternalAddress {
string endpoint_id = 2; string endpoint_id = 2;
} }
// [#next-free-field: 7] // [#next-free-field: 8]
message SocketAddress { message SocketAddress {
option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.core.SocketAddress"; option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.core.SocketAddress";
@ -97,6 +97,20 @@ message SocketAddress {
// allow both IPv4 and IPv6 connections, with peer IPv4 addresses mapped into // allow both IPv4 and IPv6 connections, with peer IPv4 addresses mapped into
// IPv6 space as ``::FFFF:<IPv4-address>``. // IPv6 space as ``::FFFF:<IPv4-address>``.
bool ipv4_compat = 6; bool ipv4_compat = 6;
// Filepath that specifies the Linux network namespace this socket will be created in (see ``man 7
// network_namespaces``). If this field is set, Envoy will create the socket in the specified
// network namespace.
//
// .. note::
// Setting this parameter requires Envoy to run with the ``CAP_NET_ADMIN`` capability.
//
// .. note::
// Currently only used for Listener sockets.
//
// .. attention::
// Network namespaces are only configurable on Linux. Otherwise, this field has no effect.
string network_namespace_filepath = 7;
} }
message TcpKeepalive { message TcpKeepalive {

View File

@ -266,7 +266,7 @@ message RuntimeUInt32 {
uint32 default_value = 2; uint32 default_value = 2;
// Runtime key to get value for comparison. This value is used if defined. // Runtime key to get value for comparison. This value is used if defined.
string runtime_key = 3 [(validate.rules).string = {min_len: 1}]; string runtime_key = 3;
} }
// Runtime derived percentage with a default when not specified. // Runtime derived percentage with a default when not specified.
@ -275,7 +275,7 @@ message RuntimePercent {
type.v3.Percent default_value = 1; type.v3.Percent default_value = 1;
// Runtime key to get value for comparison. This value is used if defined. // Runtime key to get value for comparison. This value is used if defined.
string runtime_key = 2 [(validate.rules).string = {min_len: 1}]; string runtime_key = 2;
} }
// Runtime derived double with a default when not specified. // Runtime derived double with a default when not specified.
@ -286,7 +286,7 @@ message RuntimeDouble {
double default_value = 1; double default_value = 1;
// Runtime key to get value for comparison. This value is used if defined. // Runtime key to get value for comparison. This value is used if defined.
string runtime_key = 2 [(validate.rules).string = {min_len: 1}]; string runtime_key = 2;
} }
// Runtime derived bool with a default when not specified. // Runtime derived bool with a default when not specified.
@ -300,15 +300,34 @@ message RuntimeFeatureFlag {
// Runtime key to get value for comparison. This value is used if defined. The boolean value must // Runtime key to get value for comparison. This value is used if defined. The boolean value must
// be represented via its // be represented via its
// `canonical JSON encoding <https://developers.google.com/protocol-buffers/docs/proto3#json>`_. // `canonical JSON encoding <https://developers.google.com/protocol-buffers/docs/proto3#json>`_.
string runtime_key = 2 [(validate.rules).string = {min_len: 1}]; string runtime_key = 2;
} }
// Please use :ref:`KeyValuePair <envoy_api_msg_config.core.v3.KeyValuePair>` instead.
// [#not-implemented-hide:]
message KeyValue { message KeyValue {
// The key of the key/value pair.
string key = 1 [
deprecated = true,
(validate.rules).string = {min_len: 1 max_bytes: 16384},
(envoy.annotations.deprecated_at_minor_version) = "3.0"
];
// The value of the key/value pair.
//
// The ``bytes`` type is used. This means if JSON or YAML is used to to represent the
// configuration, the value must be base64 encoded. This is unfriendly for users in most
// use scenarios of this message.
//
bytes value = 2 [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"];
}
message KeyValuePair {
// The key of the key/value pair. // The key of the key/value pair.
string key = 1 [(validate.rules).string = {min_len: 1 max_bytes: 16384}]; string key = 1 [(validate.rules).string = {min_len: 1 max_bytes: 16384}];
// The value of the key/value pair. // The value of the key/value pair.
bytes value = 2; google.protobuf.Value value = 2;
} }
// Key/value pair plus option to control append behavior. This is used to specify // Key/value pair plus option to control append behavior. This is used to specify
@ -339,8 +358,18 @@ message KeyValueAppend {
OVERWRITE_IF_EXISTS = 3; OVERWRITE_IF_EXISTS = 3;
} }
// Key/value pair entry that this option to append or overwrite. // The single key/value pair record to be appended or overridden. This field must be set.
KeyValue entry = 1 [(validate.rules).message = {required: true}]; KeyValuePair record = 3;
// Key/value pair entry that this option to append or overwrite. This field is deprecated
// and please use :ref:`record <envoy_v3_api_field_config.core.v3.KeyValueAppend.record>`
// as replacement.
// [#not-implemented-hide:]
KeyValue entry = 1 [
deprecated = true,
(validate.rules).message = {skip: true},
(envoy.annotations.deprecated_at_minor_version) = "3.0"
];
// Describes the action taken to append/overwrite the given value for an existing // Describes the action taken to append/overwrite the given value for an existing
// key or to only add this key if it's absent. // key or to only add this key if it's absent.
@ -349,10 +378,12 @@ message KeyValueAppend {
// Key/value pair to append or remove. // Key/value pair to append or remove.
message KeyValueMutation { message KeyValueMutation {
// Key/value pair to append or overwrite. Only one of ``append`` or ``remove`` can be set. // Key/value pair to append or overwrite. Only one of ``append`` or ``remove`` can be set or
// the configuration will be rejected.
KeyValueAppend append = 1; KeyValueAppend append = 1;
// Key to remove. Only one of ``append`` or ``remove`` can be set. // Key to remove. Only one of ``append`` or ``remove`` can be set or the configuration will be
// rejected.
string remove = 2 [(validate.rules).string = {max_bytes: 16384}]; string remove = 2 [(validate.rules).string = {max_bytes: 16384}];
} }

View File

@ -375,13 +375,13 @@ message HealthCheck {
// The default value for "healthy edge interval" is the same as the default interval. // The default value for "healthy edge interval" is the same as the default interval.
google.protobuf.Duration healthy_edge_interval = 16 [(validate.rules).duration = {gt {}}]; google.protobuf.Duration healthy_edge_interval = 16 [(validate.rules).duration = {gt {}}];
// Specifies the path to the :ref:`health check event log <arch_overview_health_check_logging>`.
//
// .. attention:: // .. attention::
// This field is deprecated in favor of the extension // This field is deprecated in favor of the extension
// :ref:`event_logger <envoy_v3_api_field_config.core.v3.HealthCheck.event_logger>` and // :ref:`event_logger <envoy_v3_api_field_config.core.v3.HealthCheck.event_logger>` and
// :ref:`event_log_path <envoy_v3_api_field_extensions.health_check.event_sinks.file.v3.HealthCheckEventFileSink.event_log_path>` // :ref:`event_log_path <envoy_v3_api_field_extensions.health_check.event_sinks.file.v3.HealthCheckEventFileSink.event_log_path>`
// in the file sink extension. // in the file sink extension.
//
// Specifies the path to the :ref:`health check event log <arch_overview_health_check_logging>`.
string event_log_path = 17 string event_log_path = 17
[deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"];

View File

@ -3,6 +3,7 @@ syntax = "proto3";
package envoy.config.core.v3; package envoy.config.core.v3;
import "envoy/config/core/v3/extension.proto"; import "envoy/config/core/v3/extension.proto";
import "envoy/type/matcher/v3/string.proto";
import "envoy/type/v3/percent.proto"; import "envoy/type/v3/percent.proto";
import "google/protobuf/duration.proto"; import "google/protobuf/duration.proto";
@ -63,8 +64,11 @@ message QuicProtocolOptions {
// <https://tools.ietf.org/html/draft-ietf-quic-transport-34#section-4.1>`_ size. Valid values range from // <https://tools.ietf.org/html/draft-ietf-quic-transport-34#section-4.1>`_ size. Valid values range from
// 1 to 16777216 (2^24, maximum supported by QUICHE) and defaults to 16777216 (16 * 1024 * 1024). // 1 to 16777216 (2^24, maximum supported by QUICHE) and defaults to 16777216 (16 * 1024 * 1024).
// //
// NOTE: 16384 (2^14) is the minimum window size supported in Google QUIC. If configured smaller than it, we will use 16384 instead. // .. note::
// QUICHE IETF Quic implementation supports 1 bytes window. We only support increasing the default window size now, so it's also the minimum. //
// 16384 (2^14) is the minimum window size supported in Google QUIC. If configured smaller than it, we will use
// 16384 instead. QUICHE IETF Quic implementation supports 1 bytes window. We only support increasing the default
// window size now, so it's also the minimum.
// //
// This field also acts as a soft limit on the number of bytes Envoy will buffer per-stream in the // This field also acts as a soft limit on the number of bytes Envoy will buffer per-stream in the
// QUIC stream send and receive buffers. Once the buffer reaches this pointer, watermark callbacks will fire to // QUIC stream send and receive buffers. Once the buffer reaches this pointer, watermark callbacks will fire to
@ -76,8 +80,11 @@ message QuicProtocolOptions {
// flow-control. Valid values rage from 1 to 25165824 (24MB, maximum supported by QUICHE) and defaults // flow-control. Valid values rage from 1 to 25165824 (24MB, maximum supported by QUICHE) and defaults
// to 25165824 (24 * 1024 * 1024). // to 25165824 (24 * 1024 * 1024).
// //
// NOTE: 16384 (2^14) is the minimum window size supported in Google QUIC. We only support increasing the default // .. note::
//
// 16384 (2^14) is the minimum window size supported in Google QUIC. We only support increasing the default
// window size now, so it's also the minimum. // window size now, so it's also the minimum.
//
google.protobuf.UInt32Value initial_connection_window_size = 3 google.protobuf.UInt32Value initial_connection_window_size = 3
[(validate.rules).uint32 = {lte: 25165824 gte: 1}]; [(validate.rules).uint32 = {lte: 25165824 gte: 1}];
@ -269,7 +276,7 @@ message HttpProtocolOptions {
// The default value for responses can be overridden by setting runtime key ``envoy.reloadable_features.max_response_headers_count``. // The default value for responses can be overridden by setting runtime key ``envoy.reloadable_features.max_response_headers_count``.
// Downstream requests that exceed this limit will receive a 431 response for HTTP/1.x and cause a stream // Downstream requests that exceed this limit will receive a 431 response for HTTP/1.x and cause a stream
// reset for HTTP/2. // reset for HTTP/2.
// Upstream responses that exceed this limit will result in a 503 response. // Upstream responses that exceed this limit will result in a 502 response.
google.protobuf.UInt32Value max_headers_count = 2 [(validate.rules).uint32 = {gte: 1}]; google.protobuf.UInt32Value max_headers_count = 2 [(validate.rules).uint32 = {gte: 1}];
// The maximum size of response headers. // The maximum size of response headers.
@ -281,9 +288,13 @@ message HttpProtocolOptions {
// :ref:`HTTP Connection Manager // :ref:`HTTP Connection Manager
// <envoy_v3_api_field_extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.common_http_protocol_options>`. // <envoy_v3_api_field_extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.common_http_protocol_options>`.
// //
// Note: currently some protocol codecs impose limits on the maximum size of a single header: // .. note::
// HTTP/2 (when using nghttp2) limits a single header to around 100kb. //
// HTTP/3 limits a single header to around 1024kb. // Currently some protocol codecs impose limits on the maximum size of a single header.
//
// * HTTP/2 (when using nghttp2) limits a single header to around 100kb.
// * HTTP/3 limits a single header to around 1024kb.
//
google.protobuf.UInt32Value max_response_headers_kb = 7 google.protobuf.UInt32Value max_response_headers_kb = 7
[(validate.rules).uint32 = {lte: 8192 gt: 0}]; [(validate.rules).uint32 = {lte: 8192 gt: 0}];
@ -293,9 +304,15 @@ message HttpProtocolOptions {
// Action to take when a client request with a header name containing underscore characters is received. // Action to take when a client request with a header name containing underscore characters is received.
// If this setting is not specified, the value defaults to ALLOW. // If this setting is not specified, the value defaults to ALLOW.
// Note: upstream responses are not affected by this setting. //
// Note: this only affects client headers. It does not affect headers added // .. note::
// by Envoy filters and does not have any impact if added to cluster config. //
// Upstream responses are not affected by this setting.
//
// .. note::
//
// This only affects client headers. It does not affect headers added by Envoy filters and does not have any
// impact if added to cluster config.
HeadersWithUnderscoresAction headers_with_underscores_action = 5; HeadersWithUnderscoresAction headers_with_underscores_action = 5;
// Optional maximum requests for both upstream and downstream connections. // Optional maximum requests for both upstream and downstream connections.
@ -305,7 +322,7 @@ message HttpProtocolOptions {
google.protobuf.UInt32Value max_requests_per_connection = 6; google.protobuf.UInt32Value max_requests_per_connection = 6;
} }
// [#next-free-field: 11] // [#next-free-field: 12]
message Http1ProtocolOptions { message Http1ProtocolOptions {
option (udpa.annotations.versioning).previous_message_type = option (udpa.annotations.versioning).previous_message_type =
"envoy.api.v2.core.Http1ProtocolOptions"; "envoy.api.v2.core.Http1ProtocolOptions";
@ -417,6 +434,14 @@ message Http1ProtocolOptions {
// <envoy_v3_api_field_extensions.http.header_validators.envoy_default.v3.HeaderValidatorConfig.restrict_http_methods>` // <envoy_v3_api_field_extensions.http.header_validators.envoy_default.v3.HeaderValidatorConfig.restrict_http_methods>`
// to reject custom methods. // to reject custom methods.
bool allow_custom_methods = 10 [(xds.annotations.v3.field_status).work_in_progress = true]; bool allow_custom_methods = 10 [(xds.annotations.v3.field_status).work_in_progress = true];
// Ignore HTTP/1.1 upgrade values matching any of the supplied matchers.
//
// .. note::
//
// ``h2c`` upgrades are always removed for backwards compatibility, regardless of the
// value in this setting.
repeated type.matcher.v3.StringMatcher ignore_http_11_upgrade = 11;
} }
message KeepaliveSettings { message KeepaliveSettings {
@ -449,7 +474,7 @@ message KeepaliveSettings {
[(validate.rules).duration = {gte {nanos: 1000000}}]; [(validate.rules).duration = {gte {nanos: 1000000}}];
} }
// [#next-free-field: 17] // [#next-free-field: 18]
message Http2ProtocolOptions { message Http2ProtocolOptions {
option (udpa.annotations.versioning).previous_message_type = option (udpa.annotations.versioning).previous_message_type =
"envoy.api.v2.core.Http2ProtocolOptions"; "envoy.api.v2.core.Http2ProtocolOptions";
@ -495,8 +520,10 @@ message Http2ProtocolOptions {
// (2^16 - 1, HTTP/2 default) to 2147483647 (2^31 - 1, HTTP/2 maximum) and defaults to 268435456 // (2^16 - 1, HTTP/2 default) to 2147483647 (2^31 - 1, HTTP/2 maximum) and defaults to 268435456
// (256 * 1024 * 1024). // (256 * 1024 * 1024).
// //
// NOTE: 65535 is the initial window size from HTTP/2 spec. We only support increasing the default // .. note::
// window size now, so it's also the minimum. //
// 65535 is the initial window size from HTTP/2 spec. We only support increasing the default window size now,
// so it's also the minimum.
// //
// This field also acts as a soft limit on the number of bytes Envoy will buffer per-stream in the // This field also acts as a soft limit on the number of bytes Envoy will buffer per-stream in the
// HTTP/2 codec buffers. Once the buffer reaches this pointer, watermark callbacks will fire to // HTTP/2 codec buffers. Once the buffer reaches this pointer, watermark callbacks will fire to
@ -633,6 +660,9 @@ message Http2ProtocolOptions {
// If unset, HTTP/2 codec is selected based on envoy.reloadable_features.http2_use_oghttp2. // If unset, HTTP/2 codec is selected based on envoy.reloadable_features.http2_use_oghttp2.
google.protobuf.BoolValue use_oghttp2_codec = 16 google.protobuf.BoolValue use_oghttp2_codec = 16
[(xds.annotations.v3.field_status).work_in_progress = true]; [(xds.annotations.v3.field_status).work_in_progress = true];
// Configure the maximum amount of metadata than can be handled per stream. Defaults to 1 MB.
google.protobuf.UInt64Value max_metadata_size = 17;
} }
// [#not-implemented-hide:] // [#not-implemented-hide:]
@ -644,7 +674,7 @@ message GrpcProtocolOptions {
} }
// A message which allows using HTTP/3. // A message which allows using HTTP/3.
// [#next-free-field: 7] // [#next-free-field: 8]
message Http3ProtocolOptions { message Http3ProtocolOptions {
QuicProtocolOptions quic_protocol_options = 1; QuicProtocolOptions quic_protocol_options = 1;
@ -671,6 +701,14 @@ message Http3ProtocolOptions {
// docs](https://github.com/envoyproxy/envoy/blob/main/source/docs/h2_metadata.md) for more // docs](https://github.com/envoyproxy/envoy/blob/main/source/docs/h2_metadata.md) for more
// information. // information.
bool allow_metadata = 6; bool allow_metadata = 6;
// [#not-implemented-hide:] Hiding until Envoy has full HTTP/3 upstream support.
// Still under implementation. DO NOT USE.
//
// Disables QPACK compression related features for HTTP/3 including:
// No huffman encoding, zero dynamic table capacity and no cookie crumbing.
// This can be useful for trading off CPU vs bandwidth when an upstream HTTP/3 connection multiplexes multiple downstream connections.
bool disable_qpack = 7;
} }
// A message to control transformations to the :scheme header // A message to control transformations to the :scheme header

View File

@ -32,6 +32,15 @@ message ProxyProtocolPassThroughTLVs {
repeated uint32 tlv_type = 2 [(validate.rules).repeated = {items {uint32 {lt: 256}}}]; repeated uint32 tlv_type = 2 [(validate.rules).repeated = {items {uint32 {lt: 256}}}];
} }
// Represents a single Type-Length-Value (TLV) entry.
message TlvEntry {
// The type of the TLV. Must be a uint8 (0-255) as per the Proxy Protocol v2 specification.
uint32 type = 1 [(validate.rules).uint32 = {lt: 256}];
// The value of the TLV. Must be at least one byte long.
bytes value = 2 [(validate.rules).bytes = {min_len: 1}];
}
message ProxyProtocolConfig { message ProxyProtocolConfig {
enum Version { enum Version {
// PROXY protocol version 1. Human readable format. // PROXY protocol version 1. Human readable format.
@ -47,4 +56,35 @@ message ProxyProtocolConfig {
// This config controls which TLVs can be passed to upstream if it is Proxy Protocol // This config controls which TLVs can be passed to upstream if it is Proxy Protocol
// V2 header. If there is no setting for this field, no TLVs will be passed through. // V2 header. If there is no setting for this field, no TLVs will be passed through.
ProxyProtocolPassThroughTLVs pass_through_tlvs = 2; ProxyProtocolPassThroughTLVs pass_through_tlvs = 2;
// This config allows additional TLVs to be included in the upstream PROXY protocol
// V2 header. Unlike ``pass_through_tlvs``, which passes TLVs from the downstream request,
// ``added_tlvs`` provides an extension mechanism for defining new TLVs that are included
// with the upstream request. These TLVs may not be present in the downstream request and
// can be defined at either the transport socket level or the host level to provide more
// granular control over the TLVs that are included in the upstream request.
//
// Host-level TLVs are specified in the ``metadata.typed_filter_metadata`` field under the
// ``envoy.transport_sockets.proxy_protocol`` namespace.
//
// .. literalinclude:: /_configs/repo/proxy_protocol.yaml
// :language: yaml
// :lines: 49-57
// :linenos:
// :lineno-start: 49
// :caption: :download:`proxy_protocol.yaml </_configs/repo/proxy_protocol.yaml>`
//
// **Precedence behavior**:
//
// - When a TLV is defined at both the host level and the transport socket level, the value
// from the host level configuration takes precedence. This allows users to define default TLVs
// at the transport socket level and override them at the host level.
// - Any TLV defined in the ``pass_through_tlvs`` field will be overridden by either the host-level
// or transport socket-level TLV.
repeated TlvEntry added_tlvs = 3;
}
message PerHostConfig {
// Enables per-host configuration for Proxy Protocol.
repeated TlvEntry added_tlvs = 1;
} }

View File

@ -22,7 +22,12 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE;
// Optional configuration options to be used with json_format. // Optional configuration options to be used with json_format.
message JsonFormatOptions { message JsonFormatOptions {
// The output JSON string properties will be sorted. // The output JSON string properties will be sorted.
bool sort_properties = 1; //
// .. note::
// As the properties are always sorted, this option has no effect and is deprecated.
//
bool sort_properties = 1
[deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"];
} }
// Configuration to use multiple :ref:`command operators <config_access_log_command_operators>` // Configuration to use multiple :ref:`command operators <config_access_log_command_operators>`
@ -101,6 +106,12 @@ message SubstitutionFormatString {
// * for ``text_format``, the output of the empty operator is changed from ``-`` to an // * for ``text_format``, the output of the empty operator is changed from ``-`` to an
// empty string, so that empty values are omitted entirely. // empty string, so that empty values are omitted entirely.
// * for ``json_format`` the keys with null values are omitted in the output structure. // * for ``json_format`` the keys with null values are omitted in the output structure.
//
// .. note::
// This option does not work perfectly with ``json_format`` as keys with ``null`` values
// will still be included in the output. See https://github.com/envoyproxy/envoy/issues/37941
// for more details.
//
bool omit_empty_values = 3; bool omit_empty_values = 3;
// Specify a ``content_type`` field. // Specify a ``content_type`` field.

View File

@ -113,7 +113,8 @@ message ClusterLoadAssignment {
// to determine the health of the priority level, or in other words assume each host has a weight of 1 for // to determine the health of the priority level, or in other words assume each host has a weight of 1 for
// this calculation. // this calculation.
// //
// Note: this is not currently implemented for // .. note::
// This is not currently implemented for
// :ref:`locality weighted load balancing <arch_overview_load_balancing_locality_weighted_lb>`. // :ref:`locality weighted load balancing <arch_overview_load_balancing_locality_weighted_lb>`.
bool weighted_priority_health = 6; bool weighted_priority_health = 6;
} }

View File

@ -9,6 +9,9 @@ import "envoy/config/core/v3/health_check.proto";
import "google/protobuf/wrappers.proto"; import "google/protobuf/wrappers.proto";
import "xds/core/v3/collection_entry.proto";
import "envoy/annotations/deprecation.proto";
import "udpa/annotations/status.proto"; import "udpa/annotations/status.proto";
import "udpa/annotations/versioning.proto"; import "udpa/annotations/versioning.proto";
import "validate/validate.proto"; import "validate/validate.proto";
@ -133,14 +136,24 @@ message LbEndpoint {
google.protobuf.UInt32Value load_balancing_weight = 4 [(validate.rules).uint32 = {gte: 1}]; google.protobuf.UInt32Value load_balancing_weight = 4 [(validate.rules).uint32 = {gte: 1}];
} }
// LbEndpoint list collection. Entries are `LbEndpoint` resources or references.
// [#not-implemented-hide:] // [#not-implemented-hide:]
// A configuration for a LEDS collection. message LbEndpointCollection {
xds.core.v3.CollectionEntry entries = 1;
}
// A configuration for an LEDS collection.
message LedsClusterLocalityConfig { message LedsClusterLocalityConfig {
// Configuration for the source of LEDS updates for a Locality. // Configuration for the source of LEDS updates for a Locality.
core.v3.ConfigSource leds_config = 1; core.v3.ConfigSource leds_config = 1;
// The xDS transport protocol glob collection resource name. // The name of the LbEndpoint collection resource.
// The service is only supported in delta xDS (incremental) mode. //
// If the name ends in ``/*``, it indicates an LbEndpoint glob collection,
// which is supported only in the xDS incremental protocol variants.
// Otherwise, it indicates an LbEndpointCollection list collection.
//
// Envoy currently supports only glob collections.
string leds_collection_name = 2; string leds_collection_name = 2;
} }
@ -165,18 +178,20 @@ message LocalityLbEndpoints {
core.v3.Metadata metadata = 9; core.v3.Metadata metadata = 9;
// The group of endpoints belonging to the locality specified. // The group of endpoints belonging to the locality specified.
// [#comment:TODO(adisuissa): Once LEDS is implemented this field needs to be // This is ignored if :ref:`leds_cluster_locality_config
// deprecated and replaced by ``load_balancer_endpoints``.] // <envoy_v3_api_field_config.endpoint.v3.LocalityLbEndpoints.leds_cluster_locality_config>` is set.
repeated LbEndpoint lb_endpoints = 2; repeated LbEndpoint lb_endpoints = 2;
// [#not-implemented-hide:]
oneof lb_config { oneof lb_config {
// The group of endpoints belonging to the locality. // [#not-implemented-hide:]
// [#comment:TODO(adisuissa): Once LEDS is implemented the ``lb_endpoints`` field // Not implemented and deprecated.
// needs to be deprecated.] LbEndpointList load_balancer_endpoints = 7
LbEndpointList load_balancer_endpoints = 7; [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"];
// LEDS Configuration for the current locality. // LEDS Configuration for the current locality.
// If this is set, the :ref:`lb_endpoints
// <envoy_v3_api_field_config.endpoint.v3.LocalityLbEndpoints.lb_endpoints>`
// field is ignored.
LedsClusterLocalityConfig leds_cluster_locality_config = 8; LedsClusterLocalityConfig leds_cluster_locality_config = 8;
} }

View File

@ -5,6 +5,7 @@ package envoy.config.listener.v3;
import "envoy/config/accesslog/v3/accesslog.proto"; import "envoy/config/accesslog/v3/accesslog.proto";
import "envoy/config/core/v3/address.proto"; import "envoy/config/core/v3/address.proto";
import "envoy/config/core/v3/base.proto"; import "envoy/config/core/v3/base.proto";
import "envoy/config/core/v3/config_source.proto";
import "envoy/config/core/v3/extension.proto"; import "envoy/config/core/v3/extension.proto";
import "envoy/config/core/v3/socket_option.proto"; import "envoy/config/core/v3/socket_option.proto";
import "envoy/config/listener/v3/api_listener.proto"; import "envoy/config/listener/v3/api_listener.proto";
@ -53,7 +54,7 @@ message ListenerCollection {
repeated xds.core.v3.CollectionEntry entries = 1; repeated xds.core.v3.CollectionEntry entries = 1;
} }
// [#next-free-field: 36] // [#next-free-field: 37]
message Listener { message Listener {
option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.Listener"; option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.Listener";
@ -115,6 +116,20 @@ message Listener {
message InternalListenerConfig { message InternalListenerConfig {
} }
// Configuration for filter chains discovery.
// [#not-implemented-hide:]
message FcdsConfig {
// Optional name to present to the filter chain discovery service. This may be an arbitrary name with arbitrary
// length. If a name is not provided, the listener's name is used. Refer to :ref:`filter_chains <envoy_v3_api_field_config.listener.v3.Listener.name>`.
// for details on how listener name is determined if unspecified. In addition, this may be a xdstp:// URL.
string name = 1;
// Configuration for the source of FCDS updates for this listener.
// .. note::
// This discovery service only supports ``AGGREGATED_GRPC`` API type.
core.v3.ConfigSource config_source = 2;
}
reserved 14, 23; reserved 14, 23;
// The unique name by which this listener is known. If no name is provided, // The unique name by which this listener is known. If no name is provided,
@ -147,6 +162,12 @@ message Listener {
// :ref:`FAQ entry <faq_how_to_setup_sni>`. // :ref:`FAQ entry <faq_how_to_setup_sni>`.
repeated FilterChain filter_chains = 3; repeated FilterChain filter_chains = 3;
// Discover filter chains configurations by external service. Dynamic discovery of filter chains is allowed
// while having statically configured filter chains, however, a filter chain name must be unique within a
// listener. If a discovered filter chain matches a name of an existing filter chain, it is discarded.
// [#not-implemented-hide:]
FcdsConfig fcds_config = 36;
// :ref:`Matcher API <arch_overview_matching_listener>` resolving the filter chain name from the // :ref:`Matcher API <arch_overview_matching_listener>` resolving the filter chain name from the
// network properties. This matcher is used as a replacement for the filter chain match condition // network properties. This matcher is used as a replacement for the filter chain match condition
// :ref:`filter_chain_match // :ref:`filter_chain_match
@ -247,10 +268,10 @@ message Listener {
google.protobuf.BoolValue freebind = 11; google.protobuf.BoolValue freebind = 11;
// Additional socket options that may not be present in Envoy source code or // Additional socket options that may not be present in Envoy source code or
// precompiled binaries. The socket options can be updated for a listener when // precompiled binaries.
// It is not allowed to update the socket options for any existing address if
// :ref:`enable_reuse_port <envoy_v3_api_field_config.listener.v3.Listener.enable_reuse_port>` // :ref:`enable_reuse_port <envoy_v3_api_field_config.listener.v3.Listener.enable_reuse_port>`
// is ``true``. Otherwise, if socket options change during a listener update the update will be rejected // is ``false`` to avoid the conflict when creating new sockets for the listener.
// to make it clear that the options were not updated.
repeated core.v3.SocketOption socket_options = 13; repeated core.v3.SocketOption socket_options = 13;
// Whether the listener should accept TCP Fast Open (TFO) connections. // Whether the listener should accept TCP Fast Open (TFO) connections.
@ -352,6 +373,11 @@ message Listener {
// accepted in later event loop iterations. // accepted in later event loop iterations.
// If no value is provided Envoy will accept all connections pending accept // If no value is provided Envoy will accept all connections pending accept
// from the kernel. // from the kernel.
//
// .. note::
//
// It is recommended to lower this value for better overload management and reduced per-event cost.
// Setting it to 1 is a viable option with no noticeable impact on performance.
google.protobuf.UInt32Value max_connections_to_accept_per_socket_event = 34 google.protobuf.UInt32Value max_connections_to_accept_per_socket_event = 34
[(validate.rules).uint32 = {gt: 0}]; [(validate.rules).uint32 = {gt: 0}];

View File

@ -206,8 +206,10 @@ message Policy {
// metadata should be sourced from, rather than only matching against dynamic metadata. // metadata should be sourced from, rather than only matching against dynamic metadata.
// //
// The matcher can be configured to look up metadata from: // The matcher can be configured to look up metadata from:
//
// * Dynamic metadata: Runtime metadata added by filters during request processing // * Dynamic metadata: Runtime metadata added by filters during request processing
// * Route metadata: Static metadata configured on the route entry // * Route metadata: Static metadata configured on the route entry
//
message SourcedMetadata { message SourcedMetadata {
// Metadata matcher configuration that defines what metadata to match against. This includes the filter name, // Metadata matcher configuration that defines what metadata to match against. This includes the filter name,
// metadata key path, and expected value. // metadata key path, and expected value.
@ -246,10 +248,14 @@ message Permission {
// When any is set, it matches any action. // When any is set, it matches any action.
bool any = 3 [(validate.rules).bool = {const: true}]; bool any = 3 [(validate.rules).bool = {const: true}];
// A header (or pseudo-header such as :path or :method) on the incoming HTTP request. Only // A header (or pseudo-header such as ``:path`` or ``:method``) on the incoming HTTP request. Only available
// available for HTTP request. // for HTTP request.
// Note: the pseudo-header :path includes the query and fragment string. Use the ``url_path`` //
// field if you want to match the URL path without the query and fragment string. // .. note::
//
// The pseudo-header ``:path`` includes the query and fragment string. Use the ``url_path`` field if you
// want to match the URL path without the query and fragment string.
//
route.v3.HeaderMatcher header = 4; route.v3.HeaderMatcher header = 4;
// A URL path on the incoming HTTP request. Only available for HTTP. // A URL path on the incoming HTTP request. Only available for HTTP.
@ -274,8 +280,7 @@ message Permission {
// the value of ``not_rule`` would not match, this permission would match. // the value of ``not_rule`` would not match, this permission would match.
Permission not_rule = 8; Permission not_rule = 8;
// The request server from the client's connection request. This is // The request server from the client's connection request. This is typically TLS SNI.
// typically TLS SNI.
// //
// .. attention:: // .. attention::
// //
@ -292,8 +297,7 @@ message Permission {
// * A :ref:`listener filter <arch_overview_listener_filters>` may // * A :ref:`listener filter <arch_overview_listener_filters>` may
// overwrite a connection's requested server name within Envoy. // overwrite a connection's requested server name within Envoy.
// //
// Please refer to :ref:`this FAQ entry <faq_how_to_setup_sni>` to learn to // Please refer to :ref:`this FAQ entry <faq_how_to_setup_sni>` to learn how to setup SNI.
// setup SNI.
type.matcher.v3.StringMatcher requested_server_name = 9; type.matcher.v3.StringMatcher requested_server_name = 9;
// Extension for configuring custom matchers for RBAC. // Extension for configuring custom matchers for RBAC.
@ -312,7 +316,7 @@ message Permission {
// Principal defines an identity or a group of identities for a downstream // Principal defines an identity or a group of identities for a downstream
// subject. // subject.
// [#next-free-field: 14] // [#next-free-field: 15]
message Principal { message Principal {
option (udpa.annotations.versioning).previous_message_type = "envoy.config.rbac.v2.Principal"; option (udpa.annotations.versioning).previous_message_type = "envoy.config.rbac.v2.Principal";
@ -326,6 +330,10 @@ message Principal {
} }
// Authentication attributes for a downstream. // Authentication attributes for a downstream.
// It is recommended to NOT use this type, but instead use
// :ref:`MTlsAuthenticated <envoy_v3_api_msg_extensions.rbac.principals.mtls_authenticated.v3.Config>`,
// configured via :ref:`custom <envoy_v3_api_field_config.rbac.v3.Principal.custom>`,
// which should be used for most use cases due to its improved security.
message Authenticated { message Authenticated {
option (udpa.annotations.versioning).previous_message_type = option (udpa.annotations.versioning).previous_message_type =
"envoy.config.rbac.v2.Principal.Authenticated"; "envoy.config.rbac.v2.Principal.Authenticated";
@ -334,25 +342,31 @@ message Principal {
// The name of the principal. If set, The URI SAN or DNS SAN in that order // The name of the principal. If set, The URI SAN or DNS SAN in that order
// is used from the certificate, otherwise the subject field is used. If // is used from the certificate, otherwise the subject field is used. If
// unset, it applies to any user that is authenticated. // unset, it applies to any user that is allowed by the downstream TLS configuration.
// If :ref:`require_client_certificate <envoy_v3_api_field_extensions.transport_sockets.tls.v3.DownstreamTlsContext.require_client_certificate>`
// is false or :ref:`trust_chain_verification <envoy_v3_api_field_extensions.transport_sockets.tls.v3.CertificateValidationContext.trust_chain_verification>`
// is set to :ref:`ACCEPT_UNTRUSTED <envoy_v3_api_enum_value_extensions.transport_sockets.tls.v3.CertificateValidationContext.TrustChainVerification.ACCEPT_UNTRUSTED>`,
// then no authentication is required.
type.matcher.v3.StringMatcher principal_name = 2; type.matcher.v3.StringMatcher principal_name = 2;
} }
oneof identifier { oneof identifier {
option (validate.required) = true; option (validate.required) = true;
// A set of identifiers that all must match in order to define the // A set of identifiers that all must match in order to define the downstream.
// downstream.
Set and_ids = 1; Set and_ids = 1;
// A set of identifiers at least one must match in order to define the // A set of identifiers at least one must match in order to define the downstream.
// downstream.
Set or_ids = 2; Set or_ids = 2;
// When any is set, it matches any downstream. // When any is set, it matches any downstream.
bool any = 3 [(validate.rules).bool = {const: true}]; bool any = 3 [(validate.rules).bool = {const: true}];
// Authenticated attributes that identify the downstream. // Authenticated attributes that identify the downstream.
// It is recommended to NOT use this field, but instead use
// :ref:`MTlsAuthenticated <envoy_v3_api_msg_extensions.rbac.principals.mtls_authenticated.v3.Config>`,
// configured via :ref:`custom <envoy_v3_api_field_config.rbac.v3.Principal.custom>`,
// which should be used for most use cases due to its improved security.
Authenticated authenticated = 4; Authenticated authenticated = 4;
// A CIDR block that describes the downstream IP. // A CIDR block that describes the downstream IP.
@ -366,24 +380,33 @@ message Principal {
[deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"];
// A CIDR block that describes the downstream remote/origin address. // A CIDR block that describes the downstream remote/origin address.
// Note: This is always the physical peer even if the //
// :ref:`remote_ip <envoy_v3_api_field_config.rbac.v3.Principal.remote_ip>` is // .. note::
// inferred from for example the x-forwarder-for header, proxy protocol, //
// etc. // This is always the physical peer even if the
// :ref:`remote_ip <envoy_v3_api_field_config.rbac.v3.Principal.remote_ip>` is inferred from the
// x-forwarder-for header, the proxy protocol, etc.
//
core.v3.CidrRange direct_remote_ip = 10; core.v3.CidrRange direct_remote_ip = 10;
// A CIDR block that describes the downstream remote/origin address. // A CIDR block that describes the downstream remote/origin address.
// Note: This may not be the physical peer and could be different from the //
// :ref:`direct_remote_ip // .. note::
// <envoy_v3_api_field_config.rbac.v3.Principal.direct_remote_ip>`. E.g, if the //
// remote ip is inferred from for example the x-forwarder-for header, proxy // This may not be the physical peer and could be different from the :ref:`direct_remote_ip
// protocol, etc. // <envoy_v3_api_field_config.rbac.v3.Principal.direct_remote_ip>`. E.g, if the remote ip is inferred from
// the x-forwarder-for header, the proxy protocol, etc.
//
core.v3.CidrRange remote_ip = 11; core.v3.CidrRange remote_ip = 11;
// A header (or pseudo-header such as :path or :method) on the incoming HTTP // A header (or pseudo-header such as ``:path`` or ``:method``) on the incoming HTTP request. Only available
// request. Only available for HTTP request. Note: the pseudo-header :path // for HTTP request.
// includes the query and fragment string. Use the ``url_path`` field if you //
// .. note::
//
// The pseudo-header ``:path`` includes the query and fragment string. Use the ``url_path`` field if you
// want to match the URL path without the query and fragment string. // want to match the URL path without the query and fragment string.
//
route.v3.HeaderMatcher header = 6; route.v3.HeaderMatcher header = 6;
// A URL path on the incoming HTTP request. Only available for HTTP. // A URL path on the incoming HTTP request. Only available for HTTP.
@ -405,6 +428,10 @@ message Principal {
// Matches against metadata from either dynamic state or route configuration. Preferred over the // Matches against metadata from either dynamic state or route configuration. Preferred over the
// ``metadata`` field as it provides more flexibility in metadata source selection. // ``metadata`` field as it provides more flexibility in metadata source selection.
SourcedMetadata sourced_metadata = 13; SourcedMetadata sourced_metadata = 13;
// Extension for configuring custom principals for RBAC.
// [#extension-category: envoy.rbac.principals]
core.v3.TypedExtensionConfig custom = 14;
} }
} }
@ -416,7 +443,7 @@ message Action {
// The action to take if the matcher matches. Every action either allows or denies a request, // The action to take if the matcher matches. Every action either allows or denies a request,
// and can also carry out action-specific operations. // and can also carry out action-specific operations.
// //
// Actions: // **Actions:**
// //
// * ``ALLOW``: If the request gets matched on ALLOW, it is permitted. // * ``ALLOW``: If the request gets matched on ALLOW, it is permitted.
// * ``DENY``: If the request gets matched on DENY, it is not permitted. // * ``DENY``: If the request gets matched on DENY, it is not permitted.
@ -425,7 +452,7 @@ message Action {
// ``envoy.common`` will be set to the value ``true``. // ``envoy.common`` will be set to the value ``true``.
// * If the request cannot get matched, it will fallback to ``DENY``. // * If the request cannot get matched, it will fallback to ``DENY``.
// //
// Log behavior: // **Log behavior:**
// //
// If the RBAC matcher contains at least one LOG action, the dynamic // If the RBAC matcher contains at least one LOG action, the dynamic
// metadata key ``access_log_hint`` will be set based on if the request // metadata key ``access_log_hint`` will be set based on if the request

View File

@ -5,6 +5,7 @@ package envoy.config.route.v3;
import "envoy/config/core/v3/base.proto"; import "envoy/config/core/v3/base.proto";
import "envoy/config/core/v3/extension.proto"; import "envoy/config/core/v3/extension.proto";
import "envoy/config/core/v3/proxy_protocol.proto"; import "envoy/config/core/v3/proxy_protocol.proto";
import "envoy/type/matcher/v3/filter_state.proto";
import "envoy/type/matcher/v3/metadata.proto"; import "envoy/type/matcher/v3/metadata.proto";
import "envoy/type/matcher/v3/regex.proto"; import "envoy/type/matcher/v3/regex.proto";
import "envoy/type/matcher/v3/string.proto"; import "envoy/type/matcher/v3/string.proto";
@ -500,6 +501,8 @@ message WeightedCluster {
// Configuration for a cluster specifier plugin. // Configuration for a cluster specifier plugin.
message ClusterSpecifierPlugin { message ClusterSpecifierPlugin {
// The name of the plugin and its opaque configuration. // The name of the plugin and its opaque configuration.
//
// [#extension-category: envoy.router.cluster_specifier_plugin]
core.v3.TypedExtensionConfig extension = 1 [(validate.rules).message = {required: true}]; core.v3.TypedExtensionConfig extension = 1 [(validate.rules).message = {required: true}];
// If is_optional is not set or is set to false and the plugin defined by this message is not a // If is_optional is not set or is set to false and the plugin defined by this message is not a
@ -510,7 +513,7 @@ message ClusterSpecifierPlugin {
bool is_optional = 2; bool is_optional = 2;
} }
// [#next-free-field: 16] // [#next-free-field: 17]
message RouteMatch { message RouteMatch {
option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.route.RouteMatch"; option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.route.RouteMatch";
@ -661,6 +664,12 @@ message RouteMatch {
// If the number of specified dynamic metadata matchers is nonzero, they all must match the // If the number of specified dynamic metadata matchers is nonzero, they all must match the
// dynamic metadata for a match to occur. // dynamic metadata for a match to occur.
repeated type.matcher.v3.MetadataMatcher dynamic_metadata = 13; repeated type.matcher.v3.MetadataMatcher dynamic_metadata = 13;
// Specifies a set of filter state matchers on which the route should match.
// The router will check the filter state against all the specified filter state matchers.
// If the number of specified filter state matchers is nonzero, they all must match the
// filter state for a match to occur.
repeated type.matcher.v3.FilterStateMatcher filter_state = 16;
} }
// Cors policy configuration. // Cors policy configuration.
@ -815,7 +824,10 @@ message RouteAction {
// value, the request will be mirrored. // value, the request will be mirrored.
core.v3.RuntimeFractionalPercent runtime_fraction = 3; core.v3.RuntimeFractionalPercent runtime_fraction = 3;
// Determines if the trace span should be sampled. Defaults to true. // Specifies whether the trace span for the shadow request should be sampled. If this field is not explicitly set,
// the shadow request will inherit the sampling decision of its parent span. This ensures consistency with the trace
// sampling policy of the original request and prevents oversampling, especially in scenarios where runtime sampling
// is disabled.
google.protobuf.BoolValue trace_sampled = 4; google.protobuf.BoolValue trace_sampled = 4;
// Disables appending the ``-shadow`` suffix to the shadowed ``Host`` header. Defaults to ``false``. // Disables appending the ``-shadow`` suffix to the shadowed ``Host`` header. Defaults to ``false``.
@ -1149,12 +1161,21 @@ message RouteAction {
// [#extension-category: envoy.path.rewrite] // [#extension-category: envoy.path.rewrite]
core.v3.TypedExtensionConfig path_rewrite_policy = 41; core.v3.TypedExtensionConfig path_rewrite_policy = 41;
// If one of the host rewrite specifiers is set and the
// :ref:`suppress_envoy_headers
// <envoy_v3_api_field_extensions.filters.http.router.v3.Router.suppress_envoy_headers>` flag is not
// set to true, the router filter will place the original host header value before
// rewriting into the :ref:`x-envoy-original-host
// <config_http_filters_router_x-envoy-original-host>` header.
//
// And if the
// :ref:`append_x_forwarded_host <envoy_v3_api_field_config.route.v3.RouteAction.append_x_forwarded_host>`
// is set to true, the original host value will also be appended to the
// :ref:`config_http_conn_man_headers_x-forwarded-host` header.
//
oneof host_rewrite_specifier { oneof host_rewrite_specifier {
// Indicates that during forwarding, the host header will be swapped with // Indicates that during forwarding, the host header will be swapped with
// this value. Using this option will append the // this value.
// :ref:`config_http_conn_man_headers_x-forwarded-host` header if
// :ref:`append_x_forwarded_host <envoy_v3_api_field_config.route.v3.RouteAction.append_x_forwarded_host>`
// is set.
string host_rewrite_literal = 6 string host_rewrite_literal = 6
[(validate.rules).string = {well_known_regex: HTTP_HEADER_VALUE strict: false}]; [(validate.rules).string = {well_known_regex: HTTP_HEADER_VALUE strict: false}];
@ -1164,18 +1185,12 @@ message RouteAction {
// type ``strict_dns`` or ``logical_dns``, // type ``strict_dns`` or ``logical_dns``,
// or when :ref:`hostname <envoy_v3_api_field_config.endpoint.v3.Endpoint.hostname>` // or when :ref:`hostname <envoy_v3_api_field_config.endpoint.v3.Endpoint.hostname>`
// field is not empty. Setting this to true with other cluster types // field is not empty. Setting this to true with other cluster types
// has no effect. Using this option will append the // has no effect.
// :ref:`config_http_conn_man_headers_x-forwarded-host` header if
// :ref:`append_x_forwarded_host <envoy_v3_api_field_config.route.v3.RouteAction.append_x_forwarded_host>`
// is set.
google.protobuf.BoolValue auto_host_rewrite = 7; google.protobuf.BoolValue auto_host_rewrite = 7;
// Indicates that during forwarding, the host header will be swapped with the content of given // Indicates that during forwarding, the host header will be swapped with the content of given
// downstream or :ref:`custom <config_http_conn_man_headers_custom_request_headers>` header. // downstream or :ref:`custom <config_http_conn_man_headers_custom_request_headers>` header.
// If header value is empty, host header is left intact. Using this option will append the // If header value is empty, host header is left intact.
// :ref:`config_http_conn_man_headers_x-forwarded-host` header if
// :ref:`append_x_forwarded_host <envoy_v3_api_field_config.route.v3.RouteAction.append_x_forwarded_host>`
// is set.
// //
// .. attention:: // .. attention::
// //
@ -1191,10 +1206,6 @@ message RouteAction {
// Indicates that during forwarding, the host header will be swapped with // Indicates that during forwarding, the host header will be swapped with
// the result of the regex substitution executed on path value with query and fragment removed. // the result of the regex substitution executed on path value with query and fragment removed.
// This is useful for transitioning variable content between path segment and subdomain. // This is useful for transitioning variable content between path segment and subdomain.
// Using this option will append the
// :ref:`config_http_conn_man_headers_x-forwarded-host` header if
// :ref:`append_x_forwarded_host <envoy_v3_api_field_config.route.v3.RouteAction.append_x_forwarded_host>`
// is set.
// //
// For example with the following config: // For example with the following config:
// //
@ -1868,10 +1879,11 @@ message VirtualCluster {
// Global rate limiting :ref:`architecture overview <arch_overview_global_rate_limit>`. // Global rate limiting :ref:`architecture overview <arch_overview_global_rate_limit>`.
// Also applies to Local rate limiting :ref:`using descriptors <config_http_filters_local_rate_limit_descriptors>`. // Also applies to Local rate limiting :ref:`using descriptors <config_http_filters_local_rate_limit_descriptors>`.
// [#next-free-field: 7]
message RateLimit { message RateLimit {
option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.route.RateLimit"; option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.route.RateLimit";
// [#next-free-field: 12] // [#next-free-field: 13]
message Action { message Action {
option (udpa.annotations.versioning).previous_message_type = option (udpa.annotations.versioning).previous_message_type =
"envoy.api.v2.route.RateLimit.Action"; "envoy.api.v2.route.RateLimit.Action";
@ -1928,9 +1940,48 @@ message RateLimit {
// The key to use in the descriptor entry. // The key to use in the descriptor entry.
string descriptor_key = 2 [(validate.rules).string = {min_len: 1}]; string descriptor_key = 2 [(validate.rules).string = {min_len: 1}];
// If set to true, Envoy skips the descriptor while calling rate limiting service // Controls the behavior when the specified header is not present in the request.
// when header is not present in the request. By default it skips calling the //
// rate limiting service if this header is not present in the request. // If set to ``false`` (default):
//
// * Envoy does **NOT** call the rate limiting service for this descriptor.
// * Useful if the header is optional and you prefer to skip rate limiting when it's absent.
//
// If set to ``true``:
//
// * Envoy calls the rate limiting service but omits this descriptor if the header is missing.
// * Useful if you want Envoy to enforce rate limiting even when the header is not present.
//
bool skip_if_absent = 3;
}
// The following descriptor entry is appended when a query parameter contains a key that matches the
// ``query_parameter_name``:
//
// .. code-block:: cpp
//
// ("<descriptor_key>", "<query_parameter_value_queried_from_query_parameter>")
message QueryParameters {
// The name of the query parameter to use for rate limiting. Value of this query parameter is used to populate
// the value of the descriptor entry for the descriptor_key.
string query_parameter_name = 1 [(validate.rules).string = {min_len: 1}];
// The key to use when creating the rate limit descriptor entry. his descriptor key will be used to identify the
// rate limit rule in the rate limiting service.
string descriptor_key = 2 [(validate.rules).string = {min_len: 1}];
// Controls the behavior when the specified query parameter is not present in the request.
//
// If set to ``false`` (default):
//
// * Envoy does **NOT** call the rate limiting service for this descriptor.
// * Useful if the query parameter is optional and you prefer to skip rate limiting when it's absent.
//
// If set to ``true``:
//
// * Envoy calls the rate limiting service but omits this descriptor if the query parameter is missing.
// * Useful if you want Envoy to enforce rate limiting even when the query parameter is not present.
//
bool skip_if_absent = 3; bool skip_if_absent = 3;
} }
@ -2065,9 +2116,19 @@ message RateLimit {
// Source of metadata // Source of metadata
Source source = 4 [(validate.rules).enum = {defined_only: true}]; Source source = 4 [(validate.rules).enum = {defined_only: true}];
// If set to true, Envoy skips the descriptor while calling rate limiting service // Controls the behavior when the specified ``metadata_key`` is empty and ``default_value`` is not set.
// when ``metadata_key`` is empty and ``default_value`` is not set. By default it skips calling the //
// rate limiting service in that case. // If set to ``false`` (default):
//
// * Envoy does **NOT** call the rate limiting service for this descriptor.
// * Useful if the metadata is optional and you prefer to skip rate limiting when it's absent.
//
// If set to ``true``:
//
// * Envoy calls the rate limiting service but omits this descriptor if the ``metadata_key`` is empty and
// ``default_value`` is missing.
// * Useful if you want Envoy to enforce rate limiting even when the metadata is not present.
//
bool skip_if_absent = 5; bool skip_if_absent = 5;
} }
@ -2110,6 +2171,9 @@ message RateLimit {
// Rate limit on request headers. // Rate limit on request headers.
RequestHeaders request_headers = 3; RequestHeaders request_headers = 3;
// Rate limit on query parameters.
QueryParameters query_parameters = 12;
// Rate limit on remote address. // Rate limit on remote address.
RemoteAddress remote_address = 4; RemoteAddress remote_address = 4;
@ -2168,6 +2232,33 @@ message RateLimit {
} }
} }
message HitsAddend {
// Fixed number of hits to add to the rate limit descriptor.
//
// One of the ``number`` or ``format`` fields should be set but not both.
google.protobuf.UInt64Value number = 1 [(validate.rules).uint64 = {lte: 1000000000}];
// Substitution format string to extract the number of hits to add to the rate limit descriptor.
// The same :ref:`format specifier <config_access_log_format>` as used for
// :ref:`HTTP access logging <config_access_log>` applies here.
//
// .. note::
//
// The format string must contains only single valid substitution field. If the format string
// not meets the requirement, the configuration will be rejected.
//
// The substitution field should generates a non-negative number or string representation of
// a non-negative number. The value of the non-negative number should be less than or equal
// to 1000000000 like the ``number`` field. If the output of the substitution field not meet
// the requirement, this will be treated as an error and the current descriptor will be ignored.
//
// For example, the ``%BYTES_RECEIVED%`` format string will be replaced with the number of bytes
// received in the request.
//
// One of the ``number`` or ``format`` fields should be set but not both.
string format = 2 [(validate.rules).string = {prefix: "%" suffix: "%" ignore_empty: true}];
}
// Refers to the stage set in the filter. The rate limit configuration only // Refers to the stage set in the filter. The rate limit configuration only
// applies to filters with the same stage number. The default stage number is // applies to filters with the same stage number. The default stage number is
// 0. // 0.
@ -2175,9 +2266,19 @@ message RateLimit {
// .. note:: // .. note::
// //
// The filter supports a range of 0 - 10 inclusively for stage numbers. // The filter supports a range of 0 - 10 inclusively for stage numbers.
//
// .. note::
// This is not supported if the rate limit action is configured in the ``typed_per_filter_config`` like
// :ref:`VirtualHost.typed_per_filter_config<envoy_v3_api_field_config.route.v3.VirtualHost.typed_per_filter_config>` or
// :ref:`Route.typed_per_filter_config<envoy_v3_api_field_config.route.v3.Route.typed_per_filter_config>`, etc.
google.protobuf.UInt32Value stage = 1 [(validate.rules).uint32 = {lte: 10}]; google.protobuf.UInt32Value stage = 1 [(validate.rules).uint32 = {lte: 10}];
// The key to be set in runtime to disable this rate limit configuration. // The key to be set in runtime to disable this rate limit configuration.
//
// .. note::
// This is not supported if the rate limit action is configured in the ``typed_per_filter_config`` like
// :ref:`VirtualHost.typed_per_filter_config<envoy_v3_api_field_config.route.v3.VirtualHost.typed_per_filter_config>` or
// :ref:`Route.typed_per_filter_config<envoy_v3_api_field_config.route.v3.Route.typed_per_filter_config>`, etc.
string disable_key = 2; string disable_key = 2;
// A list of actions that are to be applied for this rate limit configuration. // A list of actions that are to be applied for this rate limit configuration.
@ -2192,7 +2293,38 @@ message RateLimit {
// rate limit configuration. If the override value is invalid or cannot be resolved // rate limit configuration. If the override value is invalid or cannot be resolved
// from metadata, no override is provided. See :ref:`rate limit override // from metadata, no override is provided. See :ref:`rate limit override
// <config_http_filters_rate_limit_rate_limit_override>` for more information. // <config_http_filters_rate_limit_rate_limit_override>` for more information.
//
// .. note::
// This is not supported if the rate limit action is configured in the ``typed_per_filter_config`` like
// :ref:`VirtualHost.typed_per_filter_config<envoy_v3_api_field_config.route.v3.VirtualHost.typed_per_filter_config>` or
// :ref:`Route.typed_per_filter_config<envoy_v3_api_field_config.route.v3.Route.typed_per_filter_config>`, etc.
Override limit = 4; Override limit = 4;
// An optional hits addend to be appended to the descriptor produced by this rate limit
// configuration.
//
// .. note::
// This is only supported if the rate limit action is configured in the ``typed_per_filter_config`` like
// :ref:`VirtualHost.typed_per_filter_config<envoy_v3_api_field_config.route.v3.VirtualHost.typed_per_filter_config>` or
// :ref:`Route.typed_per_filter_config<envoy_v3_api_field_config.route.v3.Route.typed_per_filter_config>`, etc.
HitsAddend hits_addend = 5;
// If true, the rate limit request will be applied when the stream completes. The default value is false.
// This is useful when the rate limit budget needs to reflect the response context that is not available
// on the request path.
//
// For example, let's say the upstream service calculates the usage statistics and returns them in the response body
// and we want to utilize these numbers to apply the rate limit action for the subsequent requests.
// Combined with another filter that can set the desired addend based on the response (e.g. Lua filter),
// this can be used to subtract the usage statistics from the rate limit budget.
//
// A rate limit applied on the stream completion is "fire-and-forget" by nature, and rate limit is not enforced by this config.
// In other words, the current request won't be blocked when this is true, but the budget will be updated for the subsequent
// requests based on the action with this field set to true. Users should ensure that the rate limit is enforced by the actions
// applied on the request path, i.e. the ones with this field set to false.
//
// Currently, this is only supported by the HTTP global rate filter.
bool apply_on_stream_done = 6;
} }
// .. attention:: // .. attention::

View File

@ -109,14 +109,16 @@ message AccessLogCommon {
double sample_rate = 1 [(validate.rules).double = {lte: 1.0 gt: 0.0}]; double sample_rate = 1 [(validate.rules).double = {lte: 1.0 gt: 0.0}];
// This field is the remote/origin address on which the request from the user was received. // This field is the remote/origin address on which the request from the user was received.
// Note: This may not be the physical peer. E.g, if the remote address is inferred from for //
// example the x-forwarder-for header, proxy protocol, etc. // .. note::
// This may not be the actual peer address. For example, it might be derived from headers like ``x-forwarded-for``,
// the proxy protocol, or similar sources.
config.core.v3.Address downstream_remote_address = 2; config.core.v3.Address downstream_remote_address = 2;
// This field is the local/destination address on which the request from the user was received. // This field is the local/destination address on which the request from the user was received.
config.core.v3.Address downstream_local_address = 3; config.core.v3.Address downstream_local_address = 3;
// If the connection is secure,S this field will contain TLS properties. // If the connection is secure, this field will contain TLS properties.
TLSProperties tls_properties = 4; TLSProperties tls_properties = 4;
// The time that Envoy started servicing this request. This is effectively the time that the first // The time that Envoy started servicing this request. This is effectively the time that the first
@ -128,7 +130,7 @@ message AccessLogCommon {
google.protobuf.Duration time_to_last_rx_byte = 6; google.protobuf.Duration time_to_last_rx_byte = 6;
// Interval between the first downstream byte received and the first upstream byte sent. There may // Interval between the first downstream byte received and the first upstream byte sent. There may
// by considerable delta between ``time_to_last_rx_byte`` and this value due to filters. // be considerable delta between ``time_to_last_rx_byte`` and this value due to filters.
// Additionally, the same caveats apply as documented in ``time_to_last_downstream_tx_byte`` about // Additionally, the same caveats apply as documented in ``time_to_last_downstream_tx_byte`` about
// not accounting for kernel socket buffer time, etc. // not accounting for kernel socket buffer time, etc.
google.protobuf.Duration time_to_first_upstream_tx_byte = 7; google.protobuf.Duration time_to_first_upstream_tx_byte = 7;
@ -204,7 +206,7 @@ message AccessLogCommon {
map<string, google.protobuf.Any> filter_state_objects = 21; map<string, google.protobuf.Any> filter_state_objects = 21;
// A list of custom tags, which annotate logs with additional information. // A list of custom tags, which annotate logs with additional information.
// To configure this value, users should configure // To configure this value, see the documentation for
// :ref:`custom_tags <envoy_v3_api_field_extensions.access_loggers.grpc.v3.CommonGrpcAccessLogConfig.custom_tags>`. // :ref:`custom_tags <envoy_v3_api_field_extensions.access_loggers.grpc.v3.CommonGrpcAccessLogConfig.custom_tags>`.
map<string, string> custom_tags = 22; map<string, string> custom_tags = 22;
@ -225,18 +227,19 @@ message AccessLogCommon {
// This could be any format string that could be used to identify one stream. // This could be any format string that could be used to identify one stream.
string stream_id = 26; string stream_id = 26;
// If this log entry is final log entry that flushed after the stream completed or // Indicates whether this log entry is the final entry (flushed after the stream completed) or an intermediate entry
// intermediate log entry that flushed periodically during the stream. // (flushed periodically during the stream).
// There may be multiple intermediate log entries and only one final log entry for each //
// long-live stream (TCP connection, long-live HTTP2 stream). // For long-lived streams (e.g., TCP connections or long-lived HTTP/2 streams), there may be multiple intermediate
// And if it is necessary, unique ID or identifier can be added to the log entry // entries and only one final entry.
// :ref:`stream_id <envoy_v3_api_field_data.accesslog.v3.AccessLogCommon.stream_id>` to //
// correlate all these intermediate log entries and final log entry. // If needed, a unique identifier (see :ref:`stream_id <envoy_v3_api_field_data.accesslog.v3.AccessLogCommon.stream_id>`)
// can be used to correlate all intermediate and final log entries for the same stream.
// //
// .. attention:: // .. attention::
// //
// This field is deprecated in favor of ``access_log_type`` for better indication of the // This field is deprecated in favor of ``access_log_type``, which provides a clearer indication of the log entry
// type of the access log record. // type.
bool intermediate_log_entry = 27 bool intermediate_log_entry = 27
[deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"];
@ -246,19 +249,19 @@ message AccessLogCommon {
string downstream_transport_failure_reason = 28; string downstream_transport_failure_reason = 28;
// For HTTP: Total number of bytes sent to the downstream by the http stream. // For HTTP: Total number of bytes sent to the downstream by the http stream.
// For TCP: Total number of bytes sent to the downstream by the tcp proxy. // For TCP: Total number of bytes sent to the downstream by the :ref:`TCP Proxy <config_network_filters_tcp_proxy>`.
uint64 downstream_wire_bytes_sent = 29; uint64 downstream_wire_bytes_sent = 29;
// For HTTP: Total number of bytes received from the downstream by the http stream. Envoy over counts sizes of received HTTP/1.1 pipelined requests by adding up bytes of requests in the pipeline to the one currently being processed. // For HTTP: Total number of bytes received from the downstream by the http stream. Envoy over counts sizes of received HTTP/1.1 pipelined requests by adding up bytes of requests in the pipeline to the one currently being processed.
// For TCP: Total number of bytes received from the downstream by the tcp proxy. // For TCP: Total number of bytes received from the downstream by the :ref:`TCP Proxy <config_network_filters_tcp_proxy>`.
uint64 downstream_wire_bytes_received = 30; uint64 downstream_wire_bytes_received = 30;
// For HTTP: Total number of bytes sent to the upstream by the http stream. This value accumulates during upstream retries. // For HTTP: Total number of bytes sent to the upstream by the http stream. This value accumulates during upstream retries.
// For TCP: Total number of bytes sent to the upstream by the tcp proxy. // For TCP: Total number of bytes sent to the upstream by the :ref:`TCP Proxy <config_network_filters_tcp_proxy>`.
uint64 upstream_wire_bytes_sent = 31; uint64 upstream_wire_bytes_sent = 31;
// For HTTP: Total number of bytes received from the upstream by the http stream. // For HTTP: Total number of bytes received from the upstream by the http stream.
// For TCP: Total number of bytes sent to the upstream by the tcp proxy. // For TCP: Total number of bytes sent to the upstream by the :ref:`TCP Proxy <config_network_filters_tcp_proxy>`.
uint64 upstream_wire_bytes_received = 32; uint64 upstream_wire_bytes_received = 32;
// The type of the access log, which indicates when the log was recorded. // The type of the access log, which indicates when the log was recorded.
@ -297,7 +300,7 @@ message ResponseFlags {
// Indicates there was no healthy upstream. // Indicates there was no healthy upstream.
bool no_healthy_upstream = 2; bool no_healthy_upstream = 2;
// Indicates an there was an upstream request timeout. // Indicates there was an upstream request timeout.
bool upstream_request_timeout = 3; bool upstream_request_timeout = 3;
// Indicates local codec level reset was sent on the stream. // Indicates local codec level reset was sent on the stream.
@ -358,7 +361,7 @@ message ResponseFlags {
// Indicates that a filter configuration is not available. // Indicates that a filter configuration is not available.
bool no_filter_config_found = 22; bool no_filter_config_found = 22;
// Indicates that request or connection exceeded the downstream connection duration. // Indicates that the request or connection exceeded the downstream connection duration.
bool duration_timeout = 23; bool duration_timeout = 23;
// Indicates there was an HTTP protocol error in the upstream response. // Indicates there was an HTTP protocol error in the upstream response.
@ -480,7 +483,7 @@ message HTTPRequestProperties {
// do not already have a request ID. // do not already have a request ID.
string request_id = 9; string request_id = 9;
// Value of the ``X-Envoy-Original-Path`` request header. // Value of the ``x-envoy-original-path`` request header.
string original_path = 10; string original_path = 10;
// Size of the HTTP request headers in bytes. // Size of the HTTP request headers in bytes.

View File

@ -2,6 +2,8 @@ syntax = "proto3";
package envoy.extensions.clusters.aggregate.v3; package envoy.extensions.clusters.aggregate.v3;
import "envoy/config/core/v3/config_source.proto";
import "udpa/annotations/status.proto"; import "udpa/annotations/status.proto";
import "udpa/annotations/versioning.proto"; import "udpa/annotations/versioning.proto";
import "validate/validate.proto"; import "validate/validate.proto";
@ -25,3 +27,18 @@ message ClusterConfig {
// appear in this list. // appear in this list.
repeated string clusters = 1 [(validate.rules).repeated = {min_items: 1}]; repeated string clusters = 1 [(validate.rules).repeated = {min_items: 1}];
} }
// Configures an aggregate cluster whose
// :ref:`ClusterConfig <envoy_v3_api_msg_extensions.clusters.aggregate.v3.ClusterConfig>`
// is to be fetched from a separate xDS resource.
// [#extension: envoy.clusters.aggregate_resource]
// [#not-implemented-hide:]
message AggregateClusterResource {
// Configuration source specifier for the ClusterConfig resource.
// Only the aggregated protocol variants are supported; if configured
// otherwise, the cluster resource will be NACKed.
config.core.v3.ConfigSource config_source = 1 [(validate.rules).message = {required: true}];
// The name of the ClusterConfig resource to subscribe to.
string resource_name = 2 [(validate.rules).string = {min_len: 1}];
}

View File

@ -27,48 +27,53 @@ message RBAC {
option (udpa.annotations.versioning).previous_message_type = option (udpa.annotations.versioning).previous_message_type =
"envoy.config.filter.http.rbac.v2.RBAC"; "envoy.config.filter.http.rbac.v2.RBAC";
// Specify the RBAC rules to be applied globally. // The primary RBAC policy which will be applied globally, to all the incoming requests.
// If absent, no enforcing RBAC policy will be applied. //
// If present and empty, DENY. // * If absent, no RBAC enforcement occurs.
// If both rules and matcher are configured, rules will be ignored. // * If set but empty, all requests are denied.
//
// .. note::
//
// When both ``rules`` and ``matcher`` are configured, ``rules`` will be ignored.
//
config.rbac.v3.RBAC rules = 1 config.rbac.v3.RBAC rules = 1
[(udpa.annotations.field_migrate).oneof_promotion = "rules_specifier"]; [(udpa.annotations.field_migrate).oneof_promotion = "rules_specifier"];
// If specified, rules will emit stats with the given prefix. // If specified, rules will emit stats with the given prefix.
// This is useful to distinguish the stat when there are more than 1 RBAC filter configured with // This is useful for distinguishing metrics when multiple RBAC filters are configured.
// rules.
string rules_stat_prefix = 6; string rules_stat_prefix = 6;
// The match tree to use when resolving RBAC action for incoming requests. Requests do not // Match tree for evaluating RBAC actions on incoming requests. Requests not matching any matcher will be denied.
// match any matcher will be denied. //
// If absent, no enforcing RBAC matcher will be applied. // * If absent, no RBAC enforcement occurs.
// If present and empty, deny all requests. // * If set but empty, all requests are denied.
xds.type.matcher.v3.Matcher matcher = 4 [ //
(udpa.annotations.field_migrate).oneof_promotion = "rules_specifier", xds.type.matcher.v3.Matcher matcher = 4
(xds.annotations.v3.field_status).work_in_progress = true [(udpa.annotations.field_migrate).oneof_promotion = "rules_specifier"];
];
// Shadow rules are not enforced by the filter (i.e., returning a 403) // Shadow policy for testing RBAC rules without enforcing them. These rules generate stats and logs but do not deny
// but will emit stats and logs and can be used for rule testing. // requests. If absent, no shadow RBAC policy will be applied.
// If absent, no shadow RBAC policy will be applied. //
// If both shadow rules and shadow matcher are configured, shadow rules will be ignored. // .. note::
//
// When both ``shadow_rules`` and ``shadow_matcher`` are configured, ``shadow_rules`` will be ignored.
//
config.rbac.v3.RBAC shadow_rules = 2 config.rbac.v3.RBAC shadow_rules = 2
[(udpa.annotations.field_migrate).oneof_promotion = "shadow_rules_specifier"]; [(udpa.annotations.field_migrate).oneof_promotion = "shadow_rules_specifier"];
// The match tree to use for emitting stats and logs which can be used for rule testing for
// incoming requests.
// If absent, no shadow matcher will be applied. // If absent, no shadow matcher will be applied.
// Match tree for testing RBAC rules through stats and logs without enforcing them.
// If absent, no shadow matching occurs.
xds.type.matcher.v3.Matcher shadow_matcher = 5 [ xds.type.matcher.v3.Matcher shadow_matcher = 5 [
(udpa.annotations.field_migrate).oneof_promotion = "shadow_rules_specifier", (udpa.annotations.field_migrate).oneof_promotion = "shadow_rules_specifier",
(xds.annotations.v3.field_status).work_in_progress = true (xds.annotations.v3.field_status).work_in_progress = true
]; ];
// If specified, shadow rules will emit stats with the given prefix. // If specified, shadow rules will emit stats with the given prefix.
// This is useful to distinguish the stat when there are more than 1 RBAC filter configured with // This is useful for distinguishing metrics when multiple RBAC filters use shadow rules.
// shadow rules.
string shadow_rules_stat_prefix = 3; string shadow_rules_stat_prefix = 3;
// If track_per_rule_stats is true, counters will be published for each rule and shadow rule. // If ``track_per_rule_stats`` is ``true``, counters will be published for each rule and shadow rule.
bool track_per_rule_stats = 7; bool track_per_rule_stats = 7;
} }
@ -78,7 +83,7 @@ message RBACPerRoute {
reserved 1; reserved 1;
// Override the global configuration of the filter with this new config. // Per-route specific RBAC configuration that overrides the global RBAC configuration.
// If absent, the global RBAC policy will be disabled for this route. // If absent, RBAC policy will be disabled for this route.
RBAC rbac = 2; RBAC rbac = 2;
} }

View File

@ -119,11 +119,11 @@ message Router {
// for more details. // for more details.
bool suppress_grpc_request_failure_code_stats = 7; bool suppress_grpc_request_failure_code_stats = 7;
// Optional HTTP filters for the upstream HTTP filter chain.
//
// .. note:: // .. note::
// Upstream HTTP filters are currently in alpha. // Upstream HTTP filters are currently in alpha.
// //
// Optional HTTP filters for the upstream HTTP filter chain.
//
// These filters will be applied for all requests that pass through the router. // These filters will be applied for all requests that pass through the router.
// They will also be applied to shadowed requests. // They will also be applied to shadowed requests.
// Upstream HTTP filters cannot change route or cluster. // Upstream HTTP filters cannot change route or cluster.

View File

@ -99,33 +99,43 @@ message HttpConnectionManager {
ALWAYS_FORWARD_ONLY = 4; ALWAYS_FORWARD_ONLY = 4;
} }
// Determines the action for request that contain %2F, %2f, %5C or %5c sequences in the URI path. // Determines the action for request that contain ``%2F``, ``%2f``, ``%5C`` or ``%5c`` sequences in the URI path.
// This operation occurs before URL normalization and the merge slashes transformations if they were enabled. // This operation occurs before URL normalization and the merge slashes transformations if they were enabled.
enum PathWithEscapedSlashesAction { enum PathWithEscapedSlashesAction {
// Default behavior specific to implementation (i.e. Envoy) of this configuration option. // Default behavior specific to implementation (i.e. Envoy) of this configuration option.
// Envoy, by default, takes the KEEP_UNCHANGED action. // Envoy, by default, takes the KEEP_UNCHANGED action.
// NOTE: the implementation may change the default behavior at-will. //
// .. note::
//
// The implementation may change the default behavior at-will.
IMPLEMENTATION_SPECIFIC_DEFAULT = 0; IMPLEMENTATION_SPECIFIC_DEFAULT = 0;
// Keep escaped slashes. // Keep escaped slashes.
KEEP_UNCHANGED = 1; KEEP_UNCHANGED = 1;
// Reject client request with the 400 status. gRPC requests will be rejected with the INTERNAL (13) error code. // Reject client request with the 400 status. gRPC requests will be rejected with the INTERNAL (13) error code.
// The "httpN.downstream_rq_failed_path_normalization" counter is incremented for each rejected request. // The ``httpN.downstream_rq_failed_path_normalization`` counter is incremented for each rejected request.
REJECT_REQUEST = 2; REJECT_REQUEST = 2;
// Unescape %2F and %5C sequences and redirect request to the new path if these sequences were present. // Unescape ``%2F`` and ``%5C`` sequences and redirect request to the new path if these sequences were present.
// Redirect occurs after path normalization and merge slashes transformations if they were configured. // Redirect occurs after path normalization and merge slashes transformations if they were configured.
// NOTE: gRPC requests will be rejected with the INTERNAL (13) error code. //
// This option minimizes possibility of path confusion exploits by forcing request with unescaped slashes to // .. note::
// traverse all parties: downstream client, intermediate proxies, Envoy and upstream server. //
// The "httpN.downstream_rq_redirected_with_normalized_path" counter is incremented for each // gRPC requests will be rejected with the INTERNAL (13) error code. This option minimizes possibility of path
// redirected request. // confusion exploits by forcing request with unescaped slashes to traverse all parties: downstream client,
// intermediate proxies, Envoy and upstream server. The ``httpN.downstream_rq_redirected_with_normalized_path``
// counter is incremented for each redirected request.
//
UNESCAPE_AND_REDIRECT = 3; UNESCAPE_AND_REDIRECT = 3;
// Unescape %2F and %5C sequences. // Unescape ``%2F`` and ``%5C`` sequences.
// Note: this option should not be enabled if intermediaries perform path based access control as //
// it may lead to path confusion vulnerabilities. // .. note::
//
// This option should not be enabled if intermediaries perform path based access control as it may lead to path
// confusion vulnerabilities.
//
UNESCAPE_AND_FORWARD = 4; UNESCAPE_AND_FORWARD = 4;
} }
@ -185,14 +195,6 @@ message HttpConnectionManager {
// Configuration for an external tracing provider. // Configuration for an external tracing provider.
// If not specified, no tracing will be performed. // If not specified, no tracing will be performed.
//
// .. attention::
// Please be aware that ``envoy.tracers.opencensus`` provider can only be configured once
// in Envoy lifetime.
// Any attempts to reconfigure it or to use different configurations for different HCM filters
// will be rejected.
// Such a constraint is inherent to OpenCensus itself. It cannot be overcome without changes
// on OpenCensus side.
config.trace.v3.Tracing.Http provider = 9; config.trace.v3.Tracing.Http provider = 9;
// Create separate tracing span for each upstream request if true. And if this flag is set to true, // Create separate tracing span for each upstream request if true. And if this flag is set to true,
@ -266,13 +268,12 @@ message HttpConnectionManager {
// //
// .. warning:: // .. warning::
// //
// The current implementation of upgrade headers does not handle // The current implementation of upgrade headers does not handle multi-valued upgrade headers. Support for
// multi-valued upgrade headers. Support for multi-valued headers may be // multi-valued headers may be added in the future if needed.
// added in the future if needed.
// //
// .. warning:: // .. warning::
// The current implementation of upgrade headers does not work with HTTP/2 // The current implementation of upgrade headers does not work with HTTP/2 upstreams.
// upstreams. //
message UpgradeConfig { message UpgradeConfig {
option (udpa.annotations.versioning).previous_message_type = option (udpa.annotations.versioning).previous_message_type =
"envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager." "envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager."
@ -304,7 +305,10 @@ message HttpConnectionManager {
// <envoy_v3_api_field_config.route.v3.RouteAction.prefix_rewrite>`) will apply to the ``:path`` header // <envoy_v3_api_field_config.route.v3.RouteAction.prefix_rewrite>`) will apply to the ``:path`` header
// destined for the upstream. // destined for the upstream.
// //
// Note: access logging and tracing will show the original ``:path`` header. // .. note::
//
// Access logging and tracing will show the original ``:path`` header.
//
message PathNormalizationOptions { message PathNormalizationOptions {
// [#not-implemented-hide:] Normalization applies internally before any processing of requests by // [#not-implemented-hide:] Normalization applies internally before any processing of requests by
// HTTP filters, routing, and matching *and* will affect the forwarded ``:path`` header. Defaults // HTTP filters, routing, and matching *and* will affect the forwarded ``:path`` header. Defaults
@ -442,23 +446,23 @@ message HttpConnectionManager {
Tracing tracing = 7; Tracing tracing = 7;
// Additional settings for HTTP requests handled by the connection manager. These will be // Additional settings for HTTP requests handled by the connection manager. These will be
// applicable to both HTTP1 and HTTP2 requests. // applicable to both HTTP/1.1 and HTTP/2 requests.
config.core.v3.HttpProtocolOptions common_http_protocol_options = 35 config.core.v3.HttpProtocolOptions common_http_protocol_options = 35
[(udpa.annotations.security).configure_for_untrusted_downstream = true]; [(udpa.annotations.security).configure_for_untrusted_downstream = true];
// If set to true, Envoy will not start a drain timer for downstream HTTP1 connections after // If set to ``true``, Envoy will not initiate an immediate drain timer for downstream HTTP/1 connections
// :ref:`common_http_protocol_options.max_connection_duration // once :ref:`common_http_protocol_options.max_connection_duration
// <envoy_v3_api_field_config.core.v3.HttpProtocolOptions.max_connection_duration>` passes. // <envoy_v3_api_field_config.core.v3.HttpProtocolOptions.max_connection_duration>` is exceeded.
// Instead, Envoy will wait for the next downstream request, add connection:close to the response // Instead, Envoy will wait until the next downstream request arrives, add a ``connection: close`` header
// headers, then close the connection after the stream ends. // to the response, and then gracefully close the connection once the stream has completed.
// //
// This behavior is compliant with `RFC 9112 section 9.6 <https://www.rfc-editor.org/rfc/rfc9112#name-tear-down>`_ // This behavior adheres to `RFC 9112, Section 9.6 <https://www.rfc-editor.org/rfc/rfc9112#name-tear-down>`_.
// //
// If set to false, ``max_connection_duration`` will cause Envoy to enter the normal drain // If set to ``false``, exceeding ``max_connection_duration`` triggers Envoy's default drain behavior for HTTP/1,
// sequence for HTTP1 with Envoy eventually closing the connection (once there are no active // where the connection is eventually closed after all active streams finish.
// streams).
// //
// Has no effect if ``max_connection_duration`` is unset. Defaults to false. // This option has no effect if ``max_connection_duration`` is not configured.
// Defaults to ``false``.
bool http1_safe_max_connection_duration = 58; bool http1_safe_max_connection_duration = 58;
// Additional HTTP/1 settings that are passed to the HTTP/1 codec. // Additional HTTP/1 settings that are passed to the HTTP/1 codec.
@ -496,9 +500,13 @@ message HttpConnectionManager {
// The default value can be overridden by setting runtime key ``envoy.reloadable_features.max_request_headers_size_kb``. // The default value can be overridden by setting runtime key ``envoy.reloadable_features.max_request_headers_size_kb``.
// Requests that exceed this limit will receive a 431 response. // Requests that exceed this limit will receive a 431 response.
// //
// Note: currently some protocol codecs impose limits on the maximum size of a single header: // .. note::
// HTTP/2 (when using nghttp2) limits a single header to around 100kb. //
// HTTP/3 limits a single header to around 1024kb. // Currently some protocol codecs impose limits on the maximum size of a single header.
//
// * HTTP/2 (when using nghttp2) limits a single header to around 100kb.
// * HTTP/3 limits a single header to around 1024kb.
//
google.protobuf.UInt32Value max_request_headers_kb = 29 google.protobuf.UInt32Value max_request_headers_kb = 29
[(validate.rules).uint32 = {lte: 8192 gt: 0}]; [(validate.rules).uint32 = {lte: 8192 gt: 0}];
@ -576,31 +584,34 @@ message HttpConnectionManager {
// during which Envoy will wait for the peer to close (i.e., a TCP FIN/RST is received by Envoy // during which Envoy will wait for the peer to close (i.e., a TCP FIN/RST is received by Envoy
// from the downstream connection) prior to Envoy closing the socket associated with that // from the downstream connection) prior to Envoy closing the socket associated with that
// connection. // connection.
// NOTE: This timeout is enforced even when the socket associated with the downstream connection //
// is pending a flush of the write buffer. However, any progress made writing data to the socket // .. note::
// will restart the timer associated with this timeout. This means that the total grace period for //
// a socket in this state will be // This timeout is enforced even when the socket associated with the downstream connection is pending a flush of
// the write buffer. However, any progress made writing data to the socket will restart the timer associated with
// this timeout. This means that the total grace period for a socket in this state will be
// <total_time_waiting_for_write_buffer_flushes>+<delayed_close_timeout>. // <total_time_waiting_for_write_buffer_flushes>+<delayed_close_timeout>.
// //
// Delaying Envoy's connection close and giving the peer the opportunity to initiate the close // Delaying Envoy's connection close and giving the peer the opportunity to initiate the close
// sequence mitigates a race condition that exists when downstream clients do not drain/process // sequence mitigates a race condition that exists when downstream clients do not drain/process
// data in a connection's receive buffer after a remote close has been detected via a socket // data in a connection's receive buffer after a remote close has been detected via a socket
// write(). This race leads to such clients failing to process the response code sent by Envoy, // ``write()``. This race leads to such clients failing to process the response code sent by Envoy,
// which could result in erroneous downstream processing. // which could result in erroneous downstream processing.
// //
// If the timeout triggers, Envoy will close the connection's socket. // If the timeout triggers, Envoy will close the connection's socket.
// //
// The default timeout is 1000 ms if this option is not specified. // The default timeout is 1000 ms if this option is not specified.
// //
// .. NOTE:: // .. note::
// To be useful in avoiding the race condition described above, this timeout must be set // To be useful in avoiding the race condition described above, this timeout must be set
// to *at least* <max round trip time expected between clients and Envoy>+<100ms to account for // to *at least* <max round trip time expected between clients and Envoy>+<100ms to account for
// a reasonable "worst" case processing time for a full iteration of Envoy's event loop>. // a reasonable "worst" case processing time for a full iteration of Envoy's event loop>.
// //
// .. WARNING:: // .. warning::
// A value of 0 will completely disable delayed close processing. When disabled, the downstream // A value of ``0`` will completely disable delayed close processing. When disabled, the downstream
// connection's socket will be closed immediately after the write flush is completed or will // connection's socket will be closed immediately after the write flush is completed or will
// never close if the write flush does not complete. // never close if the write flush does not complete.
//
google.protobuf.Duration delayed_close_timeout = 26; google.protobuf.Duration delayed_close_timeout = 26;
// Configuration for :ref:`HTTP access logs <arch_overview_access_logs>` // Configuration for :ref:`HTTP access logs <arch_overview_access_logs>`
@ -657,20 +668,19 @@ message HttpConnectionManager {
// :ref:`config_http_conn_man_headers_x-forwarded-for` for more information. // :ref:`config_http_conn_man_headers_x-forwarded-for` for more information.
uint32 xff_num_trusted_hops = 19; uint32 xff_num_trusted_hops = 19;
// The configuration for the original IP detection extensions. // Configuration for original IP detection extensions.
// //
// When configured the extensions will be called along with the request headers // When these extensions are configured, Envoy will invoke them with the incoming request headers and
// and information about the downstream connection, such as the directly connected address. // details about the downstream connection, including the directly connected address. Each extension uses
// Each extension will then use these parameters to decide the request's effective remote address. // this information to determine the effective remote IP address for the request. If an extension cannot
// If an extension fails to detect the original IP address and isn't configured to reject // identify the original IP address and isn't set to reject the request, Envoy will sequentially attempt
// the request, the HCM will try the remaining extensions until one succeeds or rejects // the remaining extensions until one successfully determines the IP or explicitly rejects the request.
// the request. If the request isn't rejected nor any extension succeeds, the HCM will // If all extensions fail without rejection, Envoy defaults to using the directly connected remote address.
// fallback to using the remote address.
// //
// .. WARNING:: // .. warning::
// Extensions cannot be used in conjunction with :ref:`use_remote_address // These extensions cannot be configured simultaneously with :ref:`use_remote_address
// <envoy_v3_api_field_extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.use_remote_address>` // <envoy_v3_api_field_extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.use_remote_address>`
// nor :ref:`xff_num_trusted_hops // or :ref:`xff_num_trusted_hops
// <envoy_v3_api_field_extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.xff_num_trusted_hops>`. // <envoy_v3_api_field_extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.xff_num_trusted_hops>`.
// //
// [#extension-category: envoy.http.original_ip_detection] // [#extension-category: envoy.http.original_ip_detection]

View File

@ -2,6 +2,8 @@ syntax = "proto3";
package envoy.extensions.load_balancing_policies.client_side_weighted_round_robin.v3; package envoy.extensions.load_balancing_policies.client_side_weighted_round_robin.v3;
import "envoy/extensions/load_balancing_policies/common/v3/common.proto";
import "google/protobuf/duration.proto"; import "google/protobuf/duration.proto";
import "google/protobuf/wrappers.proto"; import "google/protobuf/wrappers.proto";
@ -32,10 +34,17 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE;
// weights using eps and qps. The weight of a given endpoint is computed as: // weights using eps and qps. The weight of a given endpoint is computed as:
// ``qps / (utilization + eps/qps * error_utilization_penalty)``. // ``qps / (utilization + eps/qps * error_utilization_penalty)``.
// //
// Note that Envoy will forward the ORCA response headers/trailers from the upstream
// cluster to the downstream client. This means that if the downstream client is also
// configured to use ``client_side_weighted_round_robin`` it will load balance against
// Envoy based on upstream weights. This can happen when Envoy is used as a reverse proxy.
// To avoid this issue you can configure the :ref:`header_mutation filter <envoy_v3_api_msg_extensions.filters.http.header_mutation.v3.HeaderMutation>` to remove
// the ORCA payload from the response headers/trailers.
//
// See the :ref:`load balancing architecture // See the :ref:`load balancing architecture
// overview<arch_overview_load_balancing_types>` for more information. // overview<arch_overview_load_balancing_types>` for more information.
// //
// [#next-free-field: 8] // [#next-free-field: 9]
message ClientSideWeightedRoundRobin { message ClientSideWeightedRoundRobin {
// Whether to enable out-of-band utilization reporting collection from // Whether to enable out-of-band utilization reporting collection from
// the endpoints. By default, per-request utilization reporting is used. // the endpoints. By default, per-request utilization reporting is used.
@ -75,4 +84,9 @@ message ClientSideWeightedRoundRobin {
// For map fields in the ORCA proto, the string will be of the form ``<map_field_name>.<map_key>``. For example, the string ``named_metrics.foo`` will mean to look for the key ``foo`` in the ORCA :ref:`named_metrics <envoy_v3_api_field_.xds.data.orca.v3.OrcaLoadReport.named_metrics>` field. // For map fields in the ORCA proto, the string will be of the form ``<map_field_name>.<map_key>``. For example, the string ``named_metrics.foo`` will mean to look for the key ``foo`` in the ORCA :ref:`named_metrics <envoy_v3_api_field_.xds.data.orca.v3.OrcaLoadReport.named_metrics>` field.
// If none of the specified metrics are present in the load report, then :ref:`cpu_utilization <envoy_v3_api_field_.xds.data.orca.v3.OrcaLoadReport.cpu_utilization>` is used instead. // If none of the specified metrics are present in the load report, then :ref:`cpu_utilization <envoy_v3_api_field_.xds.data.orca.v3.OrcaLoadReport.cpu_utilization>` is used instead.
repeated string metric_names_for_computing_utilization = 7; repeated string metric_names_for_computing_utilization = 7;
// Configuration for slow start mode.
// If this configuration is not set, slow start will not be not enabled.
// [#not-implemented-hide:]
common.v3.SlowStartConfig slow_start_config = 8;
} }

View File

@ -8,6 +8,7 @@ import "envoy/type/v3/percent.proto";
import "google/protobuf/duration.proto"; import "google/protobuf/duration.proto";
import "google/protobuf/wrappers.proto"; import "google/protobuf/wrappers.proto";
import "envoy/annotations/deprecation.proto";
import "udpa/annotations/status.proto"; import "udpa/annotations/status.proto";
import "validate/validate.proto"; import "validate/validate.proto";
@ -22,7 +23,25 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE;
message LocalityLbConfig { message LocalityLbConfig {
// Configuration for :ref:`zone aware routing // Configuration for :ref:`zone aware routing
// <arch_overview_load_balancing_zone_aware_routing>`. // <arch_overview_load_balancing_zone_aware_routing>`.
// [#next-free-field: 6]
message ZoneAwareLbConfig { message ZoneAwareLbConfig {
// Configures Envoy to always route requests to the local zone regardless of the
// upstream zone structure. In Envoy's default configuration, traffic is distributed proportionally
// across all upstream hosts while trying to maximize local routing when possible. The approach
// with force_local_zone aims to be more predictable and if there are upstream hosts in the local
// zone, they will receive all traffic.
// * :ref:`runtime values <config_cluster_manager_cluster_runtime_zone_routing>`.
// * :ref:`Zone aware routing support <arch_overview_load_balancing_zone_aware_routing>`.
message ForceLocalZone {
// Configures the minimum number of upstream hosts in the local zone required when force_local_zone
// is enabled. If the number of upstream hosts in the local zone is less than the specified value,
// Envoy will fall back to the default proportional-based distribution across localities.
// If not specified, the default is 1.
// * :ref:`runtime values <config_cluster_manager_cluster_runtime_zone_routing>`.
// * :ref:`Zone aware routing support <arch_overview_load_balancing_zone_aware_routing>`.
google.protobuf.UInt32Value min_size = 1;
}
// Configures percentage of requests that will be considered for zone aware routing // Configures percentage of requests that will be considered for zone aware routing
// if zone aware routing is configured. If not specified, the default is 100%. // if zone aware routing is configured. If not specified, the default is 100%.
// * :ref:`runtime values <config_cluster_manager_cluster_runtime_zone_routing>`. // * :ref:`runtime values <config_cluster_manager_cluster_runtime_zone_routing>`.
@ -41,6 +60,12 @@ message LocalityLbConfig {
// requests as if all hosts are unhealthy. This can help avoid potentially overwhelming a // requests as if all hosts are unhealthy. This can help avoid potentially overwhelming a
// failing service. // failing service.
bool fail_traffic_on_panic = 3; bool fail_traffic_on_panic = 3;
// If set to true, Envoy will force LocalityDirect routing if a local locality exists.
bool force_locality_direct_routing = 4
[deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"];
ForceLocalZone force_local_zone = 5;
} }
// Configuration for :ref:`locality weighted load balancing // Configuration for :ref:`locality weighted load balancing

View File

@ -24,7 +24,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE;
// [#protodoc-title: Common TLS configuration] // [#protodoc-title: Common TLS configuration]
// [#next-free-field: 6] // [#next-free-field: 7]
message TlsParameters { message TlsParameters {
option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.auth.TlsParameters"; option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.auth.TlsParameters";
@ -45,6 +45,23 @@ message TlsParameters {
TLSv1_3 = 4; TLSv1_3 = 4;
} }
enum CompliancePolicy {
// FIPS_202205 configures a TLS connection to use:
//
// * TLS 1.2 or 1.3
// * For TLS 1.2, only ECDHE_[RSA|ECDSA]_WITH_AES_*_GCM_SHA*.
// * For TLS 1.3, only AES-GCM
// * P-256 or P-384 for key agreement.
// * For server signatures, only ``PKCS#1/PSS`` with ``SHA256/384/512``, or ECDSA
// with P-256 or P-384.
//
// .. attention::
//
// Please refer to `BoringSSL policies <https://boringssl.googlesource.com/boringssl/+/refs/tags/0.20240913.0/include/openssl/ssl.h#5608>`_
// for details.
FIPS_202205 = 0;
}
// Minimum TLS protocol version. By default, it's ``TLSv1_2`` for both clients and servers. // Minimum TLS protocol version. By default, it's ``TLSv1_2`` for both clients and servers.
// //
// TLS protocol versions below TLSv1_2 require setting compatible ciphers with the // TLS protocol versions below TLSv1_2 require setting compatible ciphers with the
@ -157,6 +174,11 @@ message TlsParameters {
// rsa_pkcs1_sha1 // rsa_pkcs1_sha1
// ecdsa_sha1 // ecdsa_sha1
repeated string signature_algorithms = 5; repeated string signature_algorithms = 5;
// Compliance policies configure various aspects of the TLS based on the given policy.
// The policies are applied last during configuration and may override the other TLS
// parameters, or any previous policy.
repeated CompliancePolicy compliance_policies = 6 [(validate.rules).repeated = {max_items: 1}];
} }
// BoringSSL private key method configuration. The private key methods are used for external // BoringSSL private key method configuration. The private key methods are used for external
@ -232,12 +254,13 @@ message TlsCertificate {
config.core.v3.WatchedDirectory watched_directory = 7; config.core.v3.WatchedDirectory watched_directory = 7;
// BoringSSL private key method provider. This is an alternative to :ref:`private_key // BoringSSL private key method provider. This is an alternative to :ref:`private_key
// <envoy_v3_api_field_extensions.transport_sockets.tls.v3.TlsCertificate.private_key>` field. This can't be // <envoy_v3_api_field_extensions.transport_sockets.tls.v3.TlsCertificate.private_key>` field.
// marked as ``oneof`` due to API compatibility reasons. Setting both :ref:`private_key // When both :ref:`private_key <envoy_v3_api_field_extensions.transport_sockets.tls.v3.TlsCertificate.private_key>` and
// <envoy_v3_api_field_extensions.transport_sockets.tls.v3.TlsCertificate.private_key>` and // :ref:`private_key_provider <envoy_v3_api_field_extensions.transport_sockets.tls.v3.TlsCertificate.private_key_provider>` fields are set,
// :ref:`private_key_provider // ``private_key_provider`` takes precedence.
// <envoy_v3_api_field_extensions.transport_sockets.tls.v3.TlsCertificate.private_key_provider>` fields will result in an // If ``private_key_provider`` is unavailable and :ref:`fallback
// error. // <envoy_v3_api_field_extensions.transport_sockets.tls.v3.PrivateKeyProvider.fallback>`
// is enabled, ``private_key`` will be used.
PrivateKeyProvider private_key_provider = 6; PrivateKeyProvider private_key_provider = 6;
// The password to decrypt the TLS private key. If this field is not set, it is assumed that the // The password to decrypt the TLS private key. If this field is not set, it is assumed that the
@ -322,6 +345,13 @@ message SubjectAltNameMatcher {
// Matcher for SAN value. // Matcher for SAN value.
// //
// If the :ref:`san_type <envoy_v3_api_field_extensions.transport_sockets.tls.v3.SubjectAltNameMatcher.san_type>`
// is :ref:`DNS <envoy_v3_api_enum_value_extensions.transport_sockets.tls.v3.SubjectAltNameMatcher.SanType.DNS>`
// and the matcher type is :ref:`exact <envoy_v3_api_field_type.matcher.v3.StringMatcher.exact>`, DNS wildcards are evaluated
// according to the rules in https://www.rfc-editor.org/rfc/rfc6125#section-6.4.3.
// For example, ``*.example.com`` would match ``test.example.com`` but not ``example.com`` and not
// ``a.b.example.com``.
//
// The string matching for OTHER_NAME SAN values depends on their ASN.1 type: // The string matching for OTHER_NAME SAN values depends on their ASN.1 type:
// //
// * OBJECT: Validated against its dotted numeric notation (e.g., "1.2.3.4") // * OBJECT: Validated against its dotted numeric notation (e.g., "1.2.3.4")

View File

@ -22,8 +22,13 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE;
message GenericSecret { message GenericSecret {
option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.auth.GenericSecret"; option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.auth.GenericSecret";
// Secret of generic type and is available to filters. // Secret of generic type and is available to filters. It is expected
// that only only one of secret and secrets is set.
config.core.v3.DataSource secret = 1 [(udpa.annotations.sensitive) = true]; config.core.v3.DataSource secret = 1 [(udpa.annotations.sensitive) = true];
// For cases where multiple associated secrets need to be distributed together. It is expected
// that only only one of secret and secrets is set.
map<string, config.core.v3.DataSource> secrets = 2 [(udpa.annotations.sensitive) = true];
} }
message SdsSecretConfig { message SdsSecretConfig {

View File

@ -34,9 +34,8 @@ message UpstreamTlsContext {
// //
// .. attention:: // .. attention::
// //
// Server certificate verification is not enabled by default. Configure // Server certificate verification is not enabled by default. To enable verification, configure
// :ref:`trusted_ca<envoy_v3_api_field_extensions.transport_sockets.tls.v3.CertificateValidationContext.trusted_ca>` to enable // :ref:`trusted_ca<envoy_v3_api_field_extensions.transport_sockets.tls.v3.CertificateValidationContext.trusted_ca>`.
// verification.
CommonTlsContext common_tls_context = 1; CommonTlsContext common_tls_context = 1;
// SNI string to use when creating TLS backend connections. // SNI string to use when creating TLS backend connections.
@ -51,14 +50,13 @@ message UpstreamTlsContext {
// interacts with other validation options. // interacts with other validation options.
bool auto_host_sni = 6; bool auto_host_sni = 6;
// If true, replace any Subject Alternative Name validations with a validation for a DNS SAN matching // If true, replaces any Subject Alternative Name (SAN) validations with a validation for a DNS SAN matching
// the SNI value sent. Note that the validation will be against the actual requested SNI, regardless of how it // the SNI value sent. The validation uses the actual requested SNI, regardless of how the SNI is configured.
// is configured.
// //
// For the common case where an SNI value is sent and it is expected that the server certificate contains a SAN // For common cases where an SNI value is present and the server certificate should include a corresponding SAN,
// matching that SNI value, this option will do the correct SAN validation. // this option ensures the SAN is properly validated.
// //
// See :ref:`validation configuration <start_quick_start_securing_validation>` for how this interacts with // See the :ref:`validation configuration <start_quick_start_securing_validation>` for how this interacts with
// other validation options. // other validation options.
bool auto_sni_san_validation = 7; bool auto_sni_san_validation = 7;
@ -70,16 +68,19 @@ message UpstreamTlsContext {
bool allow_renegotiation = 3; bool allow_renegotiation = 3;
// Maximum number of session keys (Pre-Shared Keys for TLSv1.3+, Session IDs and Session Tickets // Maximum number of session keys (Pre-Shared Keys for TLSv1.3+, Session IDs and Session Tickets
// for TLSv1.2 and older) to store for the purpose of session resumption. // for TLSv1.2 and older) to be stored for session resumption.
// //
// Defaults to 1, setting this to 0 disables session resumption. // Defaults to 1, setting this to 0 disables session resumption.
google.protobuf.UInt32Value max_session_keys = 4; google.protobuf.UInt32Value max_session_keys = 4;
// This field is used to control the enforcement, whereby the handshake will fail if the keyUsage extension // Controls enforcement of the ``keyUsage`` extension in peer certificates. If set to ``true``, the handshake will fail if
// is present and incompatible with the TLS usage. Currently, the default value is false (i.e., enforcement off) // the ``keyUsage`` is incompatible with TLS usage.
// but it is expected to be changed to true by default in a future release. //
// ``ssl.was_key_usage_invalid`` in :ref:`listener metrics <config_listener_stats>` will be set for certificate // .. note::
// configurations that would fail if this option were set to true. // The default value is ``false`` (i.e., enforcement off). It is expected to change to ``true`` in a future release.
//
// The ``ssl.was_key_usage_invalid`` in :ref:`listener metrics <config_listener_stats>` metric will be incremented
// for configurations that would fail if this option were enabled.
google.protobuf.BoolValue enforce_rsa_key_usage = 5; google.protobuf.BoolValue enforce_rsa_key_usage = 5;
} }
@ -89,24 +90,16 @@ message DownstreamTlsContext {
"envoy.api.v2.auth.DownstreamTlsContext"; "envoy.api.v2.auth.DownstreamTlsContext";
enum OcspStaplePolicy { enum OcspStaplePolicy {
// OCSP responses are optional. If an OCSP response is absent // OCSP responses are optional. If absent or expired, the certificate is used without stapling.
// or expired, the associated certificate will be used for
// connections without an OCSP staple.
LENIENT_STAPLING = 0; LENIENT_STAPLING = 0;
// OCSP responses are optional. If an OCSP response is absent, // OCSP responses are optional. If absent, the certificate is used without stapling. If present but expired,
// the associated certificate will be used without an // the certificate is not used for subsequent connections. Connections are rejected if no suitable certificate
// OCSP staple. If a response is provided but is expired, // is found.
// the associated certificate will not be used for
// subsequent connections. If no suitable certificate is found,
// the connection is rejected.
STRICT_STAPLING = 1; STRICT_STAPLING = 1;
// OCSP responses are required. Configuration will fail if // OCSP responses are required. Connections fail if a certificate lacks a valid OCSP response. Expired responses
// a certificate is provided without an OCSP response. If a // prevent certificate use in new connections, and connections are rejected if no suitable certificate is available.
// response expires, the associated certificate will not be
// used connections. If no suitable certificate is found, the
// connection is rejected.
MUST_STAPLE = 2; MUST_STAPLE = 2;
} }
@ -139,46 +132,54 @@ message DownstreamTlsContext {
bool disable_stateless_session_resumption = 7; bool disable_stateless_session_resumption = 7;
} }
// If set to true, the TLS server will not maintain a session cache of TLS sessions. (This is // If ``true``, the TLS server will not maintain a session cache of TLS sessions.
// relevant only for TLSv1.2 and earlier.) //
// .. note::
// This applies only to TLSv1.2 and earlier.
//
bool disable_stateful_session_resumption = 10; bool disable_stateful_session_resumption = 10;
// If specified, ``session_timeout`` will change the maximum lifetime (in seconds) of the TLS session. // Maximum lifetime of TLS sessions. If specified, ``session_timeout`` will change the maximum lifetime
// Currently this value is used as a hint for the `TLS session ticket lifetime (for TLSv1.2) <https://tools.ietf.org/html/rfc5077#section-5.6>`_. // of the TLS session.
// Only seconds can be specified (fractional seconds are ignored). //
// This serves as a hint for the `TLS session ticket lifetime (for TLSv1.2) <https://tools.ietf.org/html/rfc5077#section-5.6>`_.
// Only whole seconds are considered; fractional seconds are ignored.
google.protobuf.Duration session_timeout = 6 [(validate.rules).duration = { google.protobuf.Duration session_timeout = 6 [(validate.rules).duration = {
lt {seconds: 4294967296} lt {seconds: 4294967296}
gte {} gte {}
}]; }];
// Config for whether to use certificates if they do not have // Configuration for handling certificates without an OCSP response or with expired responses.
// an accompanying OCSP response or if the response expires at runtime. //
// Defaults to LENIENT_STAPLING // Defaults to ``LENIENT_STAPLING``
OcspStaplePolicy ocsp_staple_policy = 8 [(validate.rules).enum = {defined_only: true}]; OcspStaplePolicy ocsp_staple_policy = 8 [(validate.rules).enum = {defined_only: true}];
// Multiple certificates are allowed in Downstream transport socket to serve different SNI. // Multiple certificates are allowed in Downstream transport socket to serve different SNI.
// If the client provides SNI but no such cert matched, it will decide to full scan certificates or not based on this config. // This option controls the behavior when no matching certificate is found for the received SNI value,
// Defaults to false. See more details in :ref:`Multiple TLS certificates <arch_overview_ssl_cert_select>`. // or no SNI value was sent. If enabled, all certificates will be evaluated for a match for non-SNI criteria
// such as key type and OCSP settings. If disabled, the first provided certificate will be used.
// Defaults to ``false``. See more details in :ref:`Multiple TLS certificates <arch_overview_ssl_cert_select>`.
google.protobuf.BoolValue full_scan_certs_on_sni_mismatch = 9; google.protobuf.BoolValue full_scan_certs_on_sni_mismatch = 9;
// By default, Envoy as a server uses its preferred cipher during the handshake. // If ``true``, the downstream client's preferred cipher is used during the handshake. If ``false``, Envoy
// Setting this to true would allow the downstream client's preferred cipher to be used instead. // uses its preferred cipher.
// Has no effect when using TLSv1_3. //
// .. note::
// This has no effect when using TLSv1_3.
//
bool prefer_client_ciphers = 11; bool prefer_client_ciphers = 11;
} }
// TLS key log configuration. // TLS key log configuration.
// The key log file format is "format used by NSS for its SSLKEYLOGFILE debugging output" (text taken from openssl man page) // The key log file format is "format used by NSS for its SSLKEYLOGFILE debugging output" (text taken from openssl man page)
message TlsKeyLog { message TlsKeyLog {
// The path to save the TLS key log. // Path to save the TLS key log.
string path = 1 [(validate.rules).string = {min_len: 1}]; string path = 1 [(validate.rules).string = {min_len: 1}];
// The local IP address that will be used to filter the connection which should save the TLS key log // Local IP address ranges to filter connections for TLS key logging. If not set, matches any local IP address.
// If it is not set, any local IP address will be matched.
repeated config.core.v3.CidrRange local_address_range = 2; repeated config.core.v3.CidrRange local_address_range = 2;
// The remote IP address that will be used to filter the connection which should save the TLS key log // Remote IP address ranges to filter connections for TLS key logging. If not set, matches any remote IP address.
// If it is not set, any remote IP address will be matched.
repeated config.core.v3.CidrRange remote_address_range = 3; repeated config.core.v3.CidrRange remote_address_range = 3;
} }
@ -187,8 +188,8 @@ message TlsKeyLog {
message CommonTlsContext { message CommonTlsContext {
option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.auth.CommonTlsContext"; option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.auth.CommonTlsContext";
// Config for Certificate provider to get certificates. This provider should allow certificates to be // Config for the Certificate Provider to fetch certificates. Certificates are fetched/refreshed asynchronously over
// fetched/refreshed over the network asynchronously with respect to the TLS handshake. // the network relative to the TLS handshake.
// //
// DEPRECATED: This message is not currently used, but if we ever do need it, we will want to // DEPRECATED: This message is not currently used, but if we ever do need it, we will want to
// move it out of CommonTlsContext and into common.proto, similar to the existing // move it out of CommonTlsContext and into common.proto, similar to the existing
@ -281,7 +282,7 @@ message CommonTlsContext {
// fetched/refreshed over the network asynchronously with respect to the TLS handshake. // fetched/refreshed over the network asynchronously with respect to the TLS handshake.
// //
// The same number and types of certificates as :ref:`tls_certificates <envoy_v3_api_field_extensions.transport_sockets.tls.v3.CommonTlsContext.tls_certificates>` // The same number and types of certificates as :ref:`tls_certificates <envoy_v3_api_field_extensions.transport_sockets.tls.v3.CommonTlsContext.tls_certificates>`
// are valid in the the certificates fetched through this setting. // are valid in the certificates fetched through this setting.
// //
// If ``tls_certificates`` or ``tls_certificate_provider_instance`` are set, this field // If ``tls_certificates`` or ``tls_certificate_provider_instance`` are set, this field
// is ignored. // is ignored.
@ -319,13 +320,17 @@ message CommonTlsContext {
// fetched/refreshed over the network asynchronously with respect to the TLS handshake. // fetched/refreshed over the network asynchronously with respect to the TLS handshake.
SdsSecretConfig validation_context_sds_secret_config = 7; SdsSecretConfig validation_context_sds_secret_config = 7;
// Combined certificate validation context holds a default CertificateValidationContext // Combines the default ``CertificateValidationContext`` with the SDS-provided dynamic context for certificate
// and SDS config. When SDS server returns dynamic CertificateValidationContext, both dynamic // validation.
// and default CertificateValidationContext are merged into a new CertificateValidationContext //
// for validation. This merge is done by Message::MergeFrom(), so dynamic // When the SDS server returns a dynamic ``CertificateValidationContext``, it is merged
// CertificateValidationContext overwrites singular fields in default // with the default context using ``Message::MergeFrom()``. The merging rules are as follows:
// CertificateValidationContext, and concatenates repeated fields to default //
// CertificateValidationContext, and logical OR is applied to boolean fields. // * **Singular Fields:** Dynamic fields override the default singular fields.
// * **Repeated Fields:** Dynamic repeated fields are concatenated with the default repeated fields.
// * **Boolean Fields:** Boolean fields are combined using a logical OR operation.
//
// The resulting ``CertificateValidationContext`` is used to perform certificate validation.
CombinedCertificateValidationContext combined_validation_context = 8; CombinedCertificateValidationContext combined_validation_context = 8;
// Certificate provider for fetching validation context. // Certificate provider for fetching validation context.

View File

@ -41,18 +41,29 @@ message ResourceName {
DynamicParameterConstraints dynamic_parameter_constraints = 2; DynamicParameterConstraints dynamic_parameter_constraints = 2;
} }
// [#not-implemented-hide:]
// An error associated with a specific resource name, returned to the
// client by the server.
message ResourceError {
// The name of the resource.
ResourceName resource_name = 1;
// The error reported for the resource.
google.rpc.Status error_detail = 2;
}
// A DiscoveryRequest requests a set of versioned resources of the same type for // A DiscoveryRequest requests a set of versioned resources of the same type for
// a given Envoy node on some API. // a given Envoy node on some API.
// [#next-free-field: 8] // [#next-free-field: 8]
message DiscoveryRequest { message DiscoveryRequest {
option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.DiscoveryRequest"; option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.DiscoveryRequest";
// The version_info provided in the request messages will be the version_info // The ``version_info`` provided in the request messages will be the ``version_info``
// received with the most recent successfully processed response or empty on // received with the most recent successfully processed response or empty on
// the first request. It is expected that no new request is sent after a // the first request. It is expected that no new request is sent after a
// response is received until the Envoy instance is ready to ACK/NACK the new // response is received until the Envoy instance is ready to ACK/NACK the new
// configuration. ACK/NACK takes place by returning the new API config version // configuration. ACK/NACK takes place by returning the new API config version
// as applied or the previous API config version respectively. Each type_url // as applied or the previous API config version respectively. Each ``type_url``
// (see below) has an independent version associated with it. // (see below) has an independent version associated with it.
string version_info = 1; string version_info = 1;
@ -61,10 +72,10 @@ message DiscoveryRequest {
// List of resources to subscribe to, e.g. list of cluster names or a route // List of resources to subscribe to, e.g. list of cluster names or a route
// configuration name. If this is empty, all resources for the API are // configuration name. If this is empty, all resources for the API are
// returned. LDS/CDS may have empty resource_names, which will cause all // returned. LDS/CDS may have empty ``resource_names``, which will cause all
// resources for the Envoy instance to be returned. The LDS and CDS responses // resources for the Envoy instance to be returned. The LDS and CDS responses
// will then imply a number of resources that need to be fetched via EDS/RDS, // will then imply a number of resources that need to be fetched via EDS/RDS,
// which will be explicitly enumerated in resource_names. // which will be explicitly enumerated in ``resource_names``.
repeated string resource_names = 3; repeated string resource_names = 3;
// [#not-implemented-hide:] // [#not-implemented-hide:]
@ -72,21 +83,27 @@ message DiscoveryRequest {
// parameters along with each resource name. Clients that populate this // parameters along with each resource name. Clients that populate this
// field must be able to handle responses from the server where resources // field must be able to handle responses from the server where resources
// are wrapped in a Resource message. // are wrapped in a Resource message.
// Note that it is legal for a request to have some resources listed //
// .. note::
// It is legal for a request to have some resources listed
// in ``resource_names`` and others in ``resource_locators``. // in ``resource_names`` and others in ``resource_locators``.
//
repeated ResourceLocator resource_locators = 7; repeated ResourceLocator resource_locators = 7;
// Type of the resource that is being requested, e.g. // Type of the resource that is being requested, e.g.
// "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment". This is implicit // ``type.googleapis.com/envoy.api.v2.ClusterLoadAssignment``. This is implicit
// in requests made via singleton xDS APIs such as CDS, LDS, etc. but is // in requests made via singleton xDS APIs such as CDS, LDS, etc. but is
// required for ADS. // required for ADS.
string type_url = 4; string type_url = 4;
// nonce corresponding to DiscoveryResponse being ACK/NACKed. See above // nonce corresponding to ``DiscoveryResponse`` being ACK/NACKed. See above
// discussion on version_info and the DiscoveryResponse nonce comment. This // discussion on ``version_info`` and the ``DiscoveryResponse`` nonce comment. This
// may be empty only if 1) this is a non-persistent-stream xDS such as HTTP, // may be empty only if:
// or 2) the client has not yet accepted an update in this xDS stream (unlike //
// * This is a non-persistent-stream xDS such as HTTP, or
// * The client has not yet accepted an update in this xDS stream (unlike
// delta, where it is populated only for new explicit ACKs). // delta, where it is populated only for new explicit ACKs).
//
string response_nonce = 5; string response_nonce = 5;
// This is populated when the previous :ref:`DiscoveryResponse <envoy_v3_api_msg_service.discovery.v3.DiscoveryResponse>` // This is populated when the previous :ref:`DiscoveryResponse <envoy_v3_api_msg_service.discovery.v3.DiscoveryResponse>`
@ -96,7 +113,7 @@ message DiscoveryRequest {
google.rpc.Status error_detail = 6; google.rpc.Status error_detail = 6;
} }
// [#next-free-field: 7] // [#next-free-field: 8]
message DiscoveryResponse { message DiscoveryResponse {
option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.DiscoveryResponse"; option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.DiscoveryResponse";
@ -109,35 +126,46 @@ message DiscoveryResponse {
// [#not-implemented-hide:] // [#not-implemented-hide:]
// Canary is used to support two Envoy command line flags: // Canary is used to support two Envoy command line flags:
// //
// * --terminate-on-canary-transition-failure. When set, Envoy is able to // * ``--terminate-on-canary-transition-failure``. When set, Envoy is able to
// terminate if it detects that configuration is stuck at canary. Consider // terminate if it detects that configuration is stuck at canary. Consider
// this example sequence of updates: // this example sequence of updates:
// - Management server applies a canary config successfully. //
// - Management server rolls back to a production config. // * Management server applies a canary config successfully.
// - Envoy rejects the new production config. // * Management server rolls back to a production config.
// * Envoy rejects the new production config.
//
// Since there is no sensible way to continue receiving configuration // Since there is no sensible way to continue receiving configuration
// updates, Envoy will then terminate and apply production config from a // updates, Envoy will then terminate and apply production config from a
// clean slate. // clean slate.
// * --dry-run-canary. When set, a canary response will never be applied, only //
// * ``--dry-run-canary``. When set, a canary response will never be applied, only
// validated via a dry run. // validated via a dry run.
//
bool canary = 3; bool canary = 3;
// Type URL for resources. Identifies the xDS API when muxing over ADS. // Type URL for resources. Identifies the xDS API when muxing over ADS.
// Must be consistent with the type_url in the 'resources' repeated Any (if non-empty). // Must be consistent with the ``type_url`` in the 'resources' repeated Any (if non-empty).
string type_url = 4; string type_url = 4;
// For gRPC based subscriptions, the nonce provides a way to explicitly ack a // For gRPC based subscriptions, the nonce provides a way to explicitly ack a
// specific DiscoveryResponse in a following DiscoveryRequest. Additional // specific ``DiscoveryResponse`` in a following ``DiscoveryRequest``. Additional
// messages may have been sent by Envoy to the management server for the // messages may have been sent by Envoy to the management server for the
// previous version on the stream prior to this DiscoveryResponse, that were // previous version on the stream prior to this ``DiscoveryResponse``, that were
// unprocessed at response send time. The nonce allows the management server // unprocessed at response send time. The nonce allows the management server
// to ignore any further DiscoveryRequests for the previous version until a // to ignore any further ``DiscoveryRequests`` for the previous version until a
// DiscoveryRequest bearing the nonce. The nonce is optional and is not // ``DiscoveryRequest`` bearing the nonce. The nonce is optional and is not
// required for non-stream based xDS implementations. // required for non-stream based xDS implementations.
string nonce = 5; string nonce = 5;
// The control plane instance that sent the response. // The control plane instance that sent the response.
config.core.v3.ControlPlane control_plane = 6; config.core.v3.ControlPlane control_plane = 6;
// [#not-implemented-hide:]
// Errors associated with specific resources. Clients are expected to
// remember the most recent error for a given resource across responses;
// the error condition is not considered to be cleared until a response is
// received that contains the resource in the 'resources' field.
repeated ResourceError resource_errors = 7;
} }
// DeltaDiscoveryRequest and DeltaDiscoveryResponse are used in a new gRPC // DeltaDiscoveryRequest and DeltaDiscoveryResponse are used in a new gRPC
@ -153,25 +181,28 @@ message DiscoveryResponse {
// connected to it. // connected to it.
// //
// In Delta xDS the nonce field is required and used to pair // In Delta xDS the nonce field is required and used to pair
// DeltaDiscoveryResponse to a DeltaDiscoveryRequest ACK or NACK. // ``DeltaDiscoveryResponse`` to a ``DeltaDiscoveryRequest`` ACK or NACK.
// Optionally, a response message level system_version_info is present for // Optionally, a response message level ``system_version_info`` is present for
// debugging purposes only. // debugging purposes only.
// //
// DeltaDiscoveryRequest plays two independent roles. Any DeltaDiscoveryRequest // ``DeltaDiscoveryRequest`` plays two independent roles. Any ``DeltaDiscoveryRequest``
// can be either or both of: [1] informing the server of what resources the // can be either or both of:
// client has gained/lost interest in (using resource_names_subscribe and //
// resource_names_unsubscribe), or [2] (N)ACKing an earlier resource update from // * Informing the server of what resources the client has gained/lost interest in
// the server (using response_nonce, with presence of error_detail making it a NACK). // (using ``resource_names_subscribe`` and ``resource_names_unsubscribe``), or
// Additionally, the first message (for a given type_url) of a reconnected gRPC stream // * (N)ACKing an earlier resource update from the server (using ``response_nonce``,
// with presence of ``error_detail`` making it a NACK).
//
// Additionally, the first message (for a given ``type_url``) of a reconnected gRPC stream
// has a third role: informing the server of the resources (and their versions) // has a third role: informing the server of the resources (and their versions)
// that the client already possesses, using the initial_resource_versions field. // that the client already possesses, using the ``initial_resource_versions`` field.
// //
// As with state-of-the-world, when multiple resource types are multiplexed (ADS), // As with state-of-the-world, when multiple resource types are multiplexed (ADS),
// all requests/acknowledgments/updates are logically walled off by type_url: // all requests/acknowledgments/updates are logically walled off by ``type_url``:
// a Cluster ACK exists in a completely separate world from a prior Route NACK. // a Cluster ACK exists in a completely separate world from a prior Route NACK.
// In particular, initial_resource_versions being sent at the "start" of every // In particular, ``initial_resource_versions`` being sent at the "start" of every
// gRPC stream actually entails a message for each type_url, each with its own // gRPC stream actually entails a message for each ``type_url``, each with its own
// initial_resource_versions. // ``initial_resource_versions``.
// [#next-free-field: 10] // [#next-free-field: 10]
message DeltaDiscoveryRequest { message DeltaDiscoveryRequest {
option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.DeltaDiscoveryRequest"; option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.DeltaDiscoveryRequest";
@ -187,23 +218,24 @@ message DeltaDiscoveryRequest {
// DeltaDiscoveryRequests allow the client to add or remove individual // DeltaDiscoveryRequests allow the client to add or remove individual
// resources to the set of tracked resources in the context of a stream. // resources to the set of tracked resources in the context of a stream.
// All resource names in the resource_names_subscribe list are added to the // All resource names in the ``resource_names_subscribe`` list are added to the
// set of tracked resources and all resource names in the resource_names_unsubscribe // set of tracked resources and all resource names in the ``resource_names_unsubscribe``
// list are removed from the set of tracked resources. // list are removed from the set of tracked resources.
// //
// *Unlike* state-of-the-world xDS, an empty resource_names_subscribe or // *Unlike* state-of-the-world xDS, an empty ``resource_names_subscribe`` or
// resource_names_unsubscribe list simply means that no resources are to be // ``resource_names_unsubscribe`` list simply means that no resources are to be
// added or removed to the resource list. // added or removed to the resource list.
// *Like* state-of-the-world xDS, the server must send updates for all tracked // *Like* state-of-the-world xDS, the server must send updates for all tracked
// resources, but can also send updates for resources the client has not subscribed to. // resources, but can also send updates for resources the client has not subscribed to.
// //
// NOTE: the server must respond with all resources listed in resource_names_subscribe, // .. note::
// The server must respond with all resources listed in ``resource_names_subscribe``,
// even if it believes the client has the most recent version of them. The reason: // even if it believes the client has the most recent version of them. The reason:
// the client may have dropped them, but then regained interest before it had a chance // the client may have dropped them, but then regained interest before it had a chance
// to send the unsubscribe message. See DeltaSubscriptionStateTest.RemoveThenAdd. // to send the unsubscribe message. See DeltaSubscriptionStateTest.RemoveThenAdd.
// //
// These two fields can be set in any DeltaDiscoveryRequest, including ACKs // These two fields can be set in any ``DeltaDiscoveryRequest``, including ACKs
// and initial_resource_versions. // and ``initial_resource_versions``.
// //
// A list of Resource names to add to the list of tracked resources. // A list of Resource names to add to the list of tracked resources.
repeated string resource_names_subscribe = 3; repeated string resource_names_subscribe = 3;
@ -214,31 +246,40 @@ message DeltaDiscoveryRequest {
// [#not-implemented-hide:] // [#not-implemented-hide:]
// Alternative to ``resource_names_subscribe`` field that allows specifying dynamic parameters // Alternative to ``resource_names_subscribe`` field that allows specifying dynamic parameters
// along with each resource name. // along with each resource name.
// Note that it is legal for a request to have some resources listed //
// .. note::
// It is legal for a request to have some resources listed
// in ``resource_names_subscribe`` and others in ``resource_locators_subscribe``. // in ``resource_names_subscribe`` and others in ``resource_locators_subscribe``.
//
repeated ResourceLocator resource_locators_subscribe = 8; repeated ResourceLocator resource_locators_subscribe = 8;
// [#not-implemented-hide:] // [#not-implemented-hide:]
// Alternative to ``resource_names_unsubscribe`` field that allows specifying dynamic parameters // Alternative to ``resource_names_unsubscribe`` field that allows specifying dynamic parameters
// along with each resource name. // along with each resource name.
// Note that it is legal for a request to have some resources listed //
// .. note::
// It is legal for a request to have some resources listed
// in ``resource_names_unsubscribe`` and others in ``resource_locators_unsubscribe``. // in ``resource_names_unsubscribe`` and others in ``resource_locators_unsubscribe``.
//
repeated ResourceLocator resource_locators_unsubscribe = 9; repeated ResourceLocator resource_locators_unsubscribe = 9;
// Informs the server of the versions of the resources the xDS client knows of, to enable the // Informs the server of the versions of the resources the xDS client knows of, to enable the
// client to continue the same logical xDS session even in the face of gRPC stream reconnection. // client to continue the same logical xDS session even in the face of gRPC stream reconnection.
// It will not be populated: [1] in the very first stream of a session, since the client will // It will not be populated:
// not yet have any resources, [2] in any message after the first in a stream (for a given //
// type_url), since the server will already be correctly tracking the client's state. // * In the very first stream of a session, since the client will not yet have any resources.
// (In ADS, the first message *of each type_url* of a reconnected stream populates this map.) // * In any message after the first in a stream (for a given ``type_url``), since the server will
// already be correctly tracking the client's state.
//
// (In ADS, the first message ``of each type_url`` of a reconnected stream populates this map.)
// The map's keys are names of xDS resources known to the xDS client. // The map's keys are names of xDS resources known to the xDS client.
// The map's values are opaque resource versions. // The map's values are opaque resource versions.
map<string, string> initial_resource_versions = 5; map<string, string> initial_resource_versions = 5;
// When the DeltaDiscoveryRequest is a ACK or NACK message in response // When the ``DeltaDiscoveryRequest`` is a ACK or NACK message in response
// to a previous DeltaDiscoveryResponse, the response_nonce must be the // to a previous ``DeltaDiscoveryResponse``, the ``response_nonce`` must be the
// nonce in the DeltaDiscoveryResponse. // nonce in the ``DeltaDiscoveryResponse``.
// Otherwise (unlike in DiscoveryRequest) response_nonce must be omitted. // Otherwise (unlike in ``DiscoveryRequest``) ``response_nonce`` must be omitted.
string response_nonce = 6; string response_nonce = 6;
// This is populated when the previous :ref:`DiscoveryResponse <envoy_v3_api_msg_service.discovery.v3.DiscoveryResponse>` // This is populated when the previous :ref:`DiscoveryResponse <envoy_v3_api_msg_service.discovery.v3.DiscoveryResponse>`
@ -247,7 +288,7 @@ message DeltaDiscoveryRequest {
google.rpc.Status error_detail = 7; google.rpc.Status error_detail = 7;
} }
// [#next-free-field: 9] // [#next-free-field: 10]
message DeltaDiscoveryResponse { message DeltaDiscoveryResponse {
option (udpa.annotations.versioning).previous_message_type = option (udpa.annotations.versioning).previous_message_type =
"envoy.api.v2.DeltaDiscoveryResponse"; "envoy.api.v2.DeltaDiscoveryResponse";
@ -256,31 +297,40 @@ message DeltaDiscoveryResponse {
string system_version_info = 1; string system_version_info = 1;
// The response resources. These are typed resources, whose types must match // The response resources. These are typed resources, whose types must match
// the type_url field. // the ``type_url`` field.
repeated Resource resources = 2; repeated Resource resources = 2;
// field id 3 IS available! // field id 3 IS available!
// Type URL for resources. Identifies the xDS API when muxing over ADS. // Type URL for resources. Identifies the xDS API when muxing over ADS.
// Must be consistent with the type_url in the Any within 'resources' if 'resources' is non-empty. // Must be consistent with the ``type_url`` in the Any within 'resources' if 'resources' is non-empty.
string type_url = 4; string type_url = 4;
// Resources names of resources that have be deleted and to be removed from the xDS Client. // Resource names of resources that have been deleted and to be removed from the xDS Client.
// Removed resources for missing resources can be ignored. // Removed resources for missing resources can be ignored.
repeated string removed_resources = 6; repeated string removed_resources = 6;
// Alternative to removed_resources that allows specifying which variant of // Alternative to ``removed_resources`` that allows specifying which variant of
// a resource is being removed. This variant must be used for any resource // a resource is being removed. This variant must be used for any resource
// for which dynamic parameter constraints were sent to the client. // for which dynamic parameter constraints were sent to the client.
repeated ResourceName removed_resource_names = 8; repeated ResourceName removed_resource_names = 8;
// The nonce provides a way for DeltaDiscoveryRequests to uniquely // The nonce provides a way for ``DeltaDiscoveryRequests`` to uniquely
// reference a DeltaDiscoveryResponse when (N)ACKing. The nonce is required. // reference a ``DeltaDiscoveryResponse`` when (N)ACKing. The nonce is required.
string nonce = 5; string nonce = 5;
// [#not-implemented-hide:] // [#not-implemented-hide:]
// The control plane instance that sent the response. // The control plane instance that sent the response.
config.core.v3.ControlPlane control_plane = 7; config.core.v3.ControlPlane control_plane = 7;
// [#not-implemented-hide:]
// Errors associated with specific resources.
//
// .. note::
// A resource in this field with a status of NOT_FOUND should be treated the same as
// a resource listed in the ``removed_resources`` or ``removed_resource_names`` fields.
//
repeated ResourceError resource_errors = 9;
} }
// A set of dynamic parameter constraints associated with a variant of an individual xDS resource. // A set of dynamic parameter constraints associated with a variant of an individual xDS resource.
@ -340,8 +390,11 @@ message Resource {
// [#not-implemented-hide:] // [#not-implemented-hide:]
message CacheControl { message CacheControl {
// If true, xDS proxies may not cache this resource. // If true, xDS proxies may not cache this resource.
// Note that this does not apply to clients other than xDS proxies, which must cache resources //
// .. note::
// This does not apply to clients other than xDS proxies, which must cache resources
// for their own use, regardless of the value of this field. // for their own use, regardless of the value of this field.
//
bool do_not_cache = 1; bool do_not_cache = 1;
} }
@ -371,7 +424,7 @@ message Resource {
// configuration for the resource will be removed. // configuration for the resource will be removed.
// //
// The TTL can be refreshed or changed by sending a response that doesn't change the resource // The TTL can be refreshed or changed by sending a response that doesn't change the resource
// version. In this case the resource field does not need to be populated, which allows for // version. In this case the ``resource`` field does not need to be populated, which allows for
// light-weight "heartbeat" updates to keep a resource with a TTL alive. // light-weight "heartbeat" updates to keep a resource with a TTL alive.
// //
// The TTL feature is meant to support configurations that should be removed in the event of // The TTL feature is meant to support configurations that should be removed in the event of

View File

@ -72,6 +72,11 @@ enum ClientConfigStatus {
// config dump is not the NACKed version, but the most recent accepted one. If // config dump is not the NACKed version, but the most recent accepted one. If
// no config is accepted yet, the attached config dump will be empty. // no config is accepted yet, the attached config dump will be empty.
CLIENT_NACKED = 3; CLIENT_NACKED = 3;
// Client received an error from the control plane. The attached config
// dump is the most recent accepted one. If no config is accepted yet,
// the attached config dump will be empty.
CLIENT_RECEIVED_ERROR = 4;
} }
// Request for client status of clients identified by a list of NodeMatchers. // Request for client status of clients identified by a list of NodeMatchers.

View File

@ -0,0 +1,22 @@
syntax = "proto3";
package envoy.type.matcher.v3;
import "xds/core/v3/cidr.proto";
import "udpa/annotations/status.proto";
option java_package = "io.envoyproxy.envoy.type.matcher.v3";
option java_outer_classname = "AddressProto";
option java_multiple_files = true;
option go_package = "github.com/envoyproxy/go-control-plane/envoy/type/matcher/v3;matcherv3";
option (udpa.annotations.file_status).package_version_status = ACTIVE;
// [#protodoc-title: Address Matcher]
// Match an IP against a repeated CIDR range. This matcher is intended to be
// used in other matchers, for example in the filter state matcher to match a
// filter state object as an IP.
message AddressMatcher {
repeated xds.core.v3.CidrRange ranges = 1;
}

View File

@ -2,6 +2,7 @@ syntax = "proto3";
package envoy.type.matcher.v3; package envoy.type.matcher.v3;
import "envoy/type/matcher/v3/address.proto";
import "envoy/type/matcher/v3/string.proto"; import "envoy/type/matcher/v3/string.proto";
import "udpa/annotations/status.proto"; import "udpa/annotations/status.proto";
@ -25,5 +26,8 @@ message FilterStateMatcher {
// Matches the filter state object as a string value. // Matches the filter state object as a string value.
StringMatcher string_match = 2; StringMatcher string_match = 2;
// Matches the filter state object as a ip Instance.
AddressMatcher address_match = 3;
} }
} }

View File

@ -16,11 +16,11 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE;
// [#protodoc-title: Metadata matcher] // [#protodoc-title: Metadata matcher]
// MetadataMatcher provides a general interface to check if a given value is matched in // ``MetadataMatcher`` provides a general interface to check if a given value is matched in
// :ref:`Metadata <envoy_v3_api_msg_config.core.v3.Metadata>`. It uses `filter` and `path` to retrieve the value // :ref:`Metadata <envoy_v3_api_msg_config.core.v3.Metadata>`. It uses ``filter`` and ``path`` to retrieve the value
// from the Metadata and then check if it's matched to the specified value. // from the ``Metadata`` and then check if it's matched to the specified value.
// //
// For example, for the following Metadata: // For example, for the following ``Metadata``:
// //
// .. code-block:: yaml // .. code-block:: yaml
// //
@ -41,8 +41,8 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE;
// - string_value: m // - string_value: m
// - string_value: n // - string_value: n
// //
// The following MetadataMatcher is matched as the path [a, b, c] will retrieve a string value "pro" // The following ``MetadataMatcher`` is matched as the path ``[a, b, c]`` will retrieve a string value ``pro``
// from the Metadata which is matched to the specified prefix match. // from the ``Metadata`` which is matched to the specified prefix match.
// //
// .. code-block:: yaml // .. code-block:: yaml
// //
@ -55,7 +55,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE;
// string_match: // string_match:
// prefix: pr // prefix: pr
// //
// The following MetadataMatcher is matched as the code will match one of the string values in the // The following ``MetadataMatcher`` is matched as the code will match one of the string values in the
// list at the path [a, t]. // list at the path [a, t].
// //
// .. code-block:: yaml // .. code-block:: yaml
@ -70,7 +70,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE;
// string_match: // string_match:
// exact: m // exact: m
// //
// An example use of MetadataMatcher is specifying additional metadata in envoy.filters.http.rbac to // An example use of ``MetadataMatcher`` is specifying additional metadata in ``envoy.filters.http.rbac`` to
// enforce access control based on dynamic metadata in a request. See :ref:`Permission // enforce access control based on dynamic metadata in a request. See :ref:`Permission
// <envoy_v3_api_msg_config.rbac.v3.Permission>` and :ref:`Principal // <envoy_v3_api_msg_config.rbac.v3.Permission>` and :ref:`Principal
// <envoy_v3_api_msg_config.rbac.v3.Principal>`. // <envoy_v3_api_msg_config.rbac.v3.Principal>`.
@ -79,8 +79,10 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE;
message MetadataMatcher { message MetadataMatcher {
option (udpa.annotations.versioning).previous_message_type = "envoy.type.matcher.MetadataMatcher"; option (udpa.annotations.versioning).previous_message_type = "envoy.type.matcher.MetadataMatcher";
// Specifies the segment in a path to retrieve value from Metadata. // Specifies the segment in a path to retrieve value from ``Metadata``.
// Note: Currently it's not supported to retrieve a value from a list in Metadata. This means that //
// .. note::
// Currently it's not supported to retrieve a value from a list in ``Metadata``. This means that
// if the segment key refers to a list, it has to be the last segment in a path. // if the segment key refers to a list, it has to be the last segment in a path.
message PathSegment { message PathSegment {
option (udpa.annotations.versioning).previous_message_type = option (udpa.annotations.versioning).previous_message_type =
@ -89,18 +91,18 @@ message MetadataMatcher {
oneof segment { oneof segment {
option (validate.required) = true; option (validate.required) = true;
// If specified, use the key to retrieve the value in a Struct. // If specified, use the key to retrieve the value in a ``Struct``.
string key = 1 [(validate.rules).string = {min_len: 1}]; string key = 1 [(validate.rules).string = {min_len: 1}];
} }
} }
// The filter name to retrieve the Struct from the Metadata. // The filter name to retrieve the ``Struct`` from the ``Metadata``.
string filter = 1 [(validate.rules).string = {min_len: 1}]; string filter = 1 [(validate.rules).string = {min_len: 1}];
// The path to retrieve the Value from the Struct. // The path to retrieve the ``Value`` from the ``Struct``.
repeated PathSegment path = 2 [(validate.rules).repeated = {min_items: 1}]; repeated PathSegment path = 2 [(validate.rules).repeated = {min_items: 1}];
// The MetadataMatcher is matched if the value retrieved by path is matched to this value. // The ``MetadataMatcher`` is matched if the value retrieved by path is matched to this value.
ValueMatcher value = 3 [(validate.rules).message = {required: true}]; ValueMatcher value = 3 [(validate.rules).message = {required: true}];
// If true, the match result will be inverted. // If true, the match result will be inverted.

View File

@ -38,7 +38,10 @@ message StringMatcher {
string exact = 1; string exact = 1;
// The input string must have the prefix specified here. // The input string must have the prefix specified here.
// Note: empty prefix is not allowed, please use regex instead. //
// .. note::
//
// Empty prefix match is not allowed, please use ``safe_regex`` instead.
// //
// Examples: // Examples:
// //
@ -46,7 +49,10 @@ message StringMatcher {
string prefix = 2 [(validate.rules).string = {min_len: 1}]; string prefix = 2 [(validate.rules).string = {min_len: 1}];
// The input string must have the suffix specified here. // The input string must have the suffix specified here.
// Note: empty prefix is not allowed, please use regex instead. //
// .. note::
//
// Empty suffix match is not allowed, please use ``safe_regex`` instead.
// //
// Examples: // Examples:
// //
@ -57,7 +63,10 @@ message StringMatcher {
RegexMatcher safe_regex = 5 [(validate.rules).message = {required: true}]; RegexMatcher safe_regex = 5 [(validate.rules).message = {required: true}];
// The input string must have the substring specified here. // The input string must have the substring specified here.
// Note: empty contains match is not allowed, please use regex instead. //
// .. note::
//
// Empty contains match is not allowed, please use ``safe_regex`` instead.
// //
// Examples: // Examples:
// //
@ -69,9 +78,10 @@ message StringMatcher {
xds.core.v3.TypedExtensionConfig custom = 8; xds.core.v3.TypedExtensionConfig custom = 8;
} }
// If true, indicates the exact/prefix/suffix/contains matching should be case insensitive. This // If ``true``, indicates the exact/prefix/suffix/contains matching should be case insensitive. This
// has no effect for the safe_regex match. // has no effect for the ``safe_regex`` match.
// For example, the matcher ``data`` will match both input string ``Data`` and ``data`` if set to true. // For example, the matcher ``data`` will match both input string ``Data`` and ``data`` if this option
// is set to ``true``.
bool ignore_case = 6; bool ignore_case = 6;
} }

View File

@ -14,10 +14,10 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE;
// [#protodoc-title: Metadata] // [#protodoc-title: Metadata]
// MetadataKey provides a general interface using ``key`` and ``path`` to retrieve value from // MetadataKey provides a way to retrieve values from
// :ref:`Metadata <envoy_v3_api_msg_config.core.v3.Metadata>`. // :ref:`Metadata <envoy_v3_api_msg_config.core.v3.Metadata>` using a ``key`` and a ``path``.
// //
// For example, for the following Metadata: // For example, consider the following Metadata:
// //
// .. code-block:: yaml // .. code-block:: yaml
// //
@ -28,7 +28,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE;
// xyz: // xyz:
// hello: envoy // hello: envoy
// //
// The following MetadataKey will retrieve a string value "bar" from the Metadata. // The following MetadataKey would retrieve the string value "bar" from the Metadata:
// //
// .. code-block:: yaml // .. code-block:: yaml
// //
@ -40,8 +40,8 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE;
message MetadataKey { message MetadataKey {
option (udpa.annotations.versioning).previous_message_type = "envoy.type.metadata.v2.MetadataKey"; option (udpa.annotations.versioning).previous_message_type = "envoy.type.metadata.v2.MetadataKey";
// Specifies the segment in a path to retrieve value from Metadata. // Specifies a segment in a path for retrieving values from Metadata.
// Currently it is only supported to specify the key, i.e. field name, as one segment of a path. // Currently, only key-based segments (field names) are supported.
message PathSegment { message PathSegment {
option (udpa.annotations.versioning).previous_message_type = option (udpa.annotations.versioning).previous_message_type =
"envoy.type.metadata.v2.MetadataKey.PathSegment"; "envoy.type.metadata.v2.MetadataKey.PathSegment";
@ -49,25 +49,27 @@ message MetadataKey {
oneof segment { oneof segment {
option (validate.required) = true; option (validate.required) = true;
// If specified, use the key to retrieve the value in a Struct. // If specified, use this key to retrieve the value in a Struct.
string key = 1 [(validate.rules).string = {min_len: 1}]; string key = 1 [(validate.rules).string = {min_len: 1}];
} }
} }
// The key name of Metadata to retrieve the Struct from the metadata. // The key name of the Metadata from which to retrieve the Struct.
// Typically, it represents a builtin subsystem or custom extension. // This typically represents a builtin subsystem or custom extension.
string key = 1 [(validate.rules).string = {min_len: 1}]; string key = 1 [(validate.rules).string = {min_len: 1}];
// The path to retrieve the Value from the Struct. It can be a prefix or a full path, // The path used to retrieve a specific Value from the Struct.
// e.g. ``[prop, xyz]`` for a struct or ``[prop, foo]`` for a string in the example, // This can be either a prefix or a full path, depending on the use case.
// which depends on the particular scenario. // For example, ``[prop, xyz]`` would retrieve a struct or ``[prop, foo]`` would retrieve a string
// in the example above.
// //
// Note: Due to that only the key type segment is supported, the path can not specify a list // .. note::
// Since only key-type segments are supported, a path cannot specify a list
// unless the list is the last segment. // unless the list is the last segment.
repeated PathSegment path = 2 [(validate.rules).repeated = {min_items: 1}]; repeated PathSegment path = 2 [(validate.rules).repeated = {min_items: 1}];
} }
// Describes what kind of metadata. // Describes different types of metadata sources.
message MetadataKind { message MetadataKind {
option (udpa.annotations.versioning).previous_message_type = option (udpa.annotations.versioning).previous_message_type =
"envoy.type.metadata.v2.MetadataKind"; "envoy.type.metadata.v2.MetadataKind";

View File

@ -38,6 +38,7 @@ xds/annotations/v3/sensitive.proto
xds/annotations/v3/status.proto xds/annotations/v3/status.proto
xds/annotations/v3/versioning.proto xds/annotations/v3/versioning.proto
xds/core/v3/authority.proto xds/core/v3/authority.proto
xds/core/v3/cidr.proto
xds/core/v3/collection_entry.proto xds/core/v3/collection_entry.proto
xds/core/v3/context_params.proto xds/core/v3/context_params.proto
xds/core/v3/cidr.proto xds/core/v3/cidr.proto