mirror of https://github.com/grpc/grpc-java.git
xds: add all validations related to security as described in A29 gRFC (#8331)
This commit is contained in:
parent
f3642422b4
commit
38cba5c8dd
|
|
@ -51,6 +51,8 @@ import io.envoyproxy.envoy.config.route.v3.RetryPolicy.RetryBackOff;
|
|||
import io.envoyproxy.envoy.config.route.v3.RouteConfiguration;
|
||||
import io.envoyproxy.envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager;
|
||||
import io.envoyproxy.envoy.extensions.filters.network.http_connection_manager.v3.Rds;
|
||||
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.CertificateValidationContext;
|
||||
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.CommonTlsContext;
|
||||
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext;
|
||||
import io.envoyproxy.envoy.type.v3.FractionalPercent;
|
||||
import io.envoyproxy.envoy.type.v3.FractionalPercent.DenominatorType;
|
||||
|
|
@ -363,7 +365,11 @@ final class ClientXdsClient extends AbstractXdsClient {
|
|||
}
|
||||
|
||||
EnvoyServerProtoData.DownstreamTlsContext downstreamTlsContext = null;
|
||||
if (TRANSPORT_SOCKET_NAME_TLS.equals(proto.getTransportSocket().getName())) {
|
||||
if (proto.hasTransportSocket()) {
|
||||
if (!TRANSPORT_SOCKET_NAME_TLS.equals(proto.getTransportSocket().getName())) {
|
||||
throw new ResourceInvalidException("transport-socket with name "
|
||||
+ proto.getTransportSocket().getName() + " not supported.");
|
||||
}
|
||||
DownstreamTlsContext downstreamTlsContextProto;
|
||||
try {
|
||||
downstreamTlsContextProto =
|
||||
|
|
@ -374,7 +380,7 @@ final class ClientXdsClient extends AbstractXdsClient {
|
|||
}
|
||||
downstreamTlsContext =
|
||||
EnvoyServerProtoData.DownstreamTlsContext.fromEnvoyProtoDownstreamTlsContext(
|
||||
downstreamTlsContextProto);
|
||||
validateDownstreamTlsContext(downstreamTlsContextProto));
|
||||
}
|
||||
|
||||
String name = proto.getName();
|
||||
|
|
@ -392,6 +398,182 @@ final class ClientXdsClient extends AbstractXdsClient {
|
|||
);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
|
||||
validateDownstreamTlsContext(
|
||||
io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
|
||||
downstreamTlsContext)
|
||||
throws ResourceInvalidException {
|
||||
if (downstreamTlsContext.hasCommonTlsContext()) {
|
||||
validateCommonTlsContext(downstreamTlsContext.getCommonTlsContext(), true);
|
||||
} else {
|
||||
throw new ResourceInvalidException(
|
||||
"common-tls-context is required in downstream-tls-context");
|
||||
}
|
||||
if (downstreamTlsContext.hasRequireSni()) {
|
||||
throw new ResourceInvalidException(
|
||||
"downstream-tls-context with require-sni is not supported");
|
||||
}
|
||||
if (downstreamTlsContext.hasSessionTicketKeys()) {
|
||||
throw new ResourceInvalidException(
|
||||
"downstream-tls-context with session_ticket_keys is not supported");
|
||||
}
|
||||
if (downstreamTlsContext.hasSessionTicketKeysSdsSecretConfig()) {
|
||||
throw new ResourceInvalidException(
|
||||
"downstream-tls-context with session_ticket_keys_sds_secret_config is not supported");
|
||||
}
|
||||
if (downstreamTlsContext.hasDisableStatelessSessionResumption()) {
|
||||
throw new ResourceInvalidException(
|
||||
"downstream-tls-context with disable_stateless_session_resumption is not supported");
|
||||
}
|
||||
if (downstreamTlsContext.hasSessionTimeout()) {
|
||||
throw new ResourceInvalidException(
|
||||
"downstream-tls-context with session_timeout is not supported");
|
||||
}
|
||||
DownstreamTlsContext.OcspStaplePolicy ocspStaplePolicy = downstreamTlsContext
|
||||
.getOcspStaplePolicy();
|
||||
if (ocspStaplePolicy != null
|
||||
&& ocspStaplePolicy != DownstreamTlsContext.OcspStaplePolicy.UNRECOGNIZED
|
||||
&& ocspStaplePolicy != DownstreamTlsContext.OcspStaplePolicy.LENIENT_STAPLING) {
|
||||
throw new ResourceInvalidException(
|
||||
"downstream-tls-context with ocsp_staple_policy value " + ocspStaplePolicy.name()
|
||||
+ " is not supported");
|
||||
}
|
||||
return downstreamTlsContext;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
|
||||
validateUpstreamTlsContext(
|
||||
io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext upstreamTlsContext)
|
||||
throws ResourceInvalidException {
|
||||
if (upstreamTlsContext.hasCommonTlsContext()) {
|
||||
validateCommonTlsContext(upstreamTlsContext.getCommonTlsContext(), false);
|
||||
} else {
|
||||
throw new ResourceInvalidException("common-tls-context is required in upstream-tls-context");
|
||||
}
|
||||
if (!Strings.isNullOrEmpty(upstreamTlsContext.getSni())) {
|
||||
throw new ResourceInvalidException("upstream-tls-context with sni is not supported");
|
||||
}
|
||||
if (upstreamTlsContext.getAllowRenegotiation()) {
|
||||
throw new ResourceInvalidException(
|
||||
"upstream-tls-context with allow_renegotiation is not supported");
|
||||
}
|
||||
if (upstreamTlsContext.hasMaxSessionKeys()) {
|
||||
throw new ResourceInvalidException(
|
||||
"upstream-tls-context with max_session_keys is not supported");
|
||||
}
|
||||
return upstreamTlsContext;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static void validateCommonTlsContext(
|
||||
CommonTlsContext commonTlsContext, boolean server) throws ResourceInvalidException {
|
||||
if (commonTlsContext.hasCustomHandshaker()) {
|
||||
throw new ResourceInvalidException(
|
||||
"common-tls-context with custom_handshaker is not supported");
|
||||
}
|
||||
if (commonTlsContext.hasTlsParams()) {
|
||||
throw new ResourceInvalidException("common-tls-context with tls_params is not supported");
|
||||
}
|
||||
if (commonTlsContext.hasValidationContext()) {
|
||||
throw new ResourceInvalidException(
|
||||
"common-tls-context with validation_context is not supported");
|
||||
}
|
||||
if (commonTlsContext.hasValidationContextSdsSecretConfig()) {
|
||||
throw new ResourceInvalidException(
|
||||
"common-tls-context with validation_context_sds_secret_config is not supported");
|
||||
}
|
||||
if (commonTlsContext.hasValidationContextCertificateProvider()) {
|
||||
throw new ResourceInvalidException(
|
||||
"common-tls-context with validation_context_certificate_provider is not supported");
|
||||
}
|
||||
if (commonTlsContext.hasValidationContextCertificateProviderInstance()) {
|
||||
throw new ResourceInvalidException(
|
||||
"common-tls-context with validation_context_certificate_provider_instance is not"
|
||||
+ " supported");
|
||||
}
|
||||
if (!commonTlsContext.hasTlsCertificateCertificateProviderInstance()) {
|
||||
if (server) {
|
||||
throw new ResourceInvalidException(
|
||||
"tls_certificate_certificate_provider_instance is required in downstream-tls-context");
|
||||
}
|
||||
if (commonTlsContext.getTlsCertificatesCount() > 0) {
|
||||
throw new ResourceInvalidException(
|
||||
"common-tls-context with tls_certificates is not supported");
|
||||
}
|
||||
if (commonTlsContext.getTlsCertificateSdsSecretConfigsCount() > 0) {
|
||||
throw new ResourceInvalidException(
|
||||
"common-tls-context with tls_certificate_sds_secret_configs is not supported");
|
||||
}
|
||||
if (commonTlsContext.hasTlsCertificateCertificateProvider()) {
|
||||
throw new ResourceInvalidException(
|
||||
"common-tls-context with tls_certificate_certificate_provider is not supported");
|
||||
}
|
||||
}
|
||||
if (!commonTlsContext.hasCombinedValidationContext()) {
|
||||
if (!server) {
|
||||
throw new ResourceInvalidException(
|
||||
"combined_validation_context is required in upstream-tls-context");
|
||||
}
|
||||
} else {
|
||||
CommonTlsContext.CombinedCertificateValidationContext combinedCertificateValidationContext
|
||||
= commonTlsContext.getCombinedValidationContext();
|
||||
if (!combinedCertificateValidationContext.hasValidationContextCertificateProviderInstance()) {
|
||||
throw new ResourceInvalidException(
|
||||
"validation_context_certificate_provider_instance is required in"
|
||||
+ " combined_validation_context");
|
||||
}
|
||||
if (combinedCertificateValidationContext.hasDefaultValidationContext()) {
|
||||
if (server) {
|
||||
throw new ResourceInvalidException(
|
||||
"default_validation_context only allowed in upstream_tls_context");
|
||||
}
|
||||
CertificateValidationContext certificateValidationContext
|
||||
= combinedCertificateValidationContext.getDefaultValidationContext();
|
||||
if (certificateValidationContext.hasTrustedCa()) {
|
||||
throw new ResourceInvalidException(
|
||||
"trusted_ca in default_validation_context is not supported");
|
||||
}
|
||||
if (certificateValidationContext.hasWatchedDirectory()) {
|
||||
throw new ResourceInvalidException(
|
||||
"watched_directory in default_validation_context is not supported");
|
||||
}
|
||||
if (certificateValidationContext.getVerifyCertificateSpkiCount() > 0) {
|
||||
throw new ResourceInvalidException(
|
||||
"verify_certificate_spki in default_validation_context is not supported");
|
||||
}
|
||||
if (certificateValidationContext.getVerifyCertificateHashCount() > 0) {
|
||||
throw new ResourceInvalidException(
|
||||
"verify_certificate_hash in default_validation_context is not supported");
|
||||
}
|
||||
if (certificateValidationContext.hasRequireSignedCertificateTimestamp()) {
|
||||
throw new ResourceInvalidException(
|
||||
"require_signed_certificate_timestamp in default_validation_context is not "
|
||||
+ "supported");
|
||||
}
|
||||
if (certificateValidationContext.hasCrl()) {
|
||||
throw new ResourceInvalidException("crl in default_validation_context is not supported");
|
||||
}
|
||||
if (certificateValidationContext.getAllowExpiredCertificate()) {
|
||||
throw new ResourceInvalidException(
|
||||
"allow_expired_certificate in default_validation_context is not supported");
|
||||
}
|
||||
CertificateValidationContext.TrustChainVerification trustChainVerification
|
||||
= certificateValidationContext.getTrustChainVerification();
|
||||
if (trustChainVerification != null && trustChainVerification
|
||||
!= CertificateValidationContext.TrustChainVerification.VERIFY_TRUST_CHAIN) {
|
||||
throw new ResourceInvalidException(
|
||||
"Only VERIFY_TRUST_CHAIN for trust_chain_verification supported");
|
||||
}
|
||||
if (certificateValidationContext.hasCustomValidatorConfig()) {
|
||||
throw new ResourceInvalidException(
|
||||
"custom_validator_config in default_validation_context is not supported");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkForUniqueness(Set<FilterChainMatch> uniqueSet,
|
||||
FilterChainMatch filterChainMatch) throws ResourceInvalidException {
|
||||
if (uniqueSet != null) {
|
||||
|
|
@ -1336,14 +1518,18 @@ final class ClientXdsClient extends AbstractXdsClient {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (cluster.hasTransportSocket()
|
||||
&& TRANSPORT_SOCKET_NAME_TLS.equals(cluster.getTransportSocket().getName())) {
|
||||
if (cluster.hasTransportSocket()) {
|
||||
if (!TRANSPORT_SOCKET_NAME_TLS.equals(cluster.getTransportSocket().getName())) {
|
||||
return StructOrError.fromError("transport-socket with name "
|
||||
+ cluster.getTransportSocket().getName() + " not supported.");
|
||||
}
|
||||
try {
|
||||
upstreamTlsContext = UpstreamTlsContext.fromEnvoyProtoUpstreamTlsContext(
|
||||
validateUpstreamTlsContext(
|
||||
unpackCompatibleType(cluster.getTransportSocket().getTypedConfig(),
|
||||
io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext.class,
|
||||
TYPE_URL_UPSTREAM_TLS_CONTEXT, TYPE_URL_UPSTREAM_TLS_CONTEXT_V2));
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
TYPE_URL_UPSTREAM_TLS_CONTEXT, TYPE_URL_UPSTREAM_TLS_CONTEXT_V2)));
|
||||
} catch (InvalidProtocolBufferException | ResourceInvalidException e) {
|
||||
return StructOrError.fromError(
|
||||
"Cluster " + clusterName + ": malformed UpstreamTlsContext: " + e);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import static com.google.common.truth.Truth.assertThat;
|
|||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.protobuf.Any;
|
||||
import com.google.protobuf.BoolValue;
|
||||
import com.google.protobuf.Duration;
|
||||
import com.google.protobuf.StringValue;
|
||||
import com.google.protobuf.UInt32Value;
|
||||
import com.google.protobuf.UInt64Value;
|
||||
|
|
@ -36,12 +37,15 @@ import io.envoyproxy.envoy.config.core.v3.Address;
|
|||
import io.envoyproxy.envoy.config.core.v3.AggregatedConfigSource;
|
||||
import io.envoyproxy.envoy.config.core.v3.CidrRange;
|
||||
import io.envoyproxy.envoy.config.core.v3.ConfigSource;
|
||||
import io.envoyproxy.envoy.config.core.v3.DataSource;
|
||||
import io.envoyproxy.envoy.config.core.v3.HttpProtocolOptions;
|
||||
import io.envoyproxy.envoy.config.core.v3.Locality;
|
||||
import io.envoyproxy.envoy.config.core.v3.RuntimeFractionalPercent;
|
||||
import io.envoyproxy.envoy.config.core.v3.SocketAddress;
|
||||
import io.envoyproxy.envoy.config.core.v3.TrafficDirection;
|
||||
import io.envoyproxy.envoy.config.core.v3.TransportSocket;
|
||||
import io.envoyproxy.envoy.config.core.v3.TypedExtensionConfig;
|
||||
import io.envoyproxy.envoy.config.core.v3.WatchedDirectory;
|
||||
import io.envoyproxy.envoy.config.endpoint.v3.Endpoint;
|
||||
import io.envoyproxy.envoy.config.listener.v3.Filter;
|
||||
import io.envoyproxy.envoy.config.listener.v3.FilterChain;
|
||||
|
|
@ -73,6 +77,14 @@ import io.envoyproxy.envoy.extensions.filters.http.router.v3.Router;
|
|||
import io.envoyproxy.envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager;
|
||||
import io.envoyproxy.envoy.extensions.filters.network.http_connection_manager.v3.HttpFilter;
|
||||
import io.envoyproxy.envoy.extensions.filters.network.http_connection_manager.v3.Rds;
|
||||
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.CertificateValidationContext;
|
||||
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.CommonTlsContext;
|
||||
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext;
|
||||
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.SdsSecretConfig;
|
||||
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.TlsCertificate;
|
||||
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.TlsParameters;
|
||||
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.TlsSessionTicketKeys;
|
||||
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext;
|
||||
import io.envoyproxy.envoy.type.matcher.v3.RegexMatchAndSubstitute;
|
||||
import io.envoyproxy.envoy.type.matcher.v3.RegexMatcher;
|
||||
import io.envoyproxy.envoy.type.matcher.v3.RegexMatcher.GoogleRE2;
|
||||
|
|
@ -1233,7 +1245,6 @@ public class ClientXdsClientDataTest {
|
|||
FilterChain.newBuilder()
|
||||
.setName("filter-chain-1")
|
||||
.setFilterChainMatch(filterChainMatch1)
|
||||
.setTransportSocket(TransportSocket.getDefaultInstance())
|
||||
.addFilters(filter1)
|
||||
.build();
|
||||
Filter filter2 = buildHttpConnectionManagerFilter(
|
||||
|
|
@ -1251,7 +1262,6 @@ public class ClientXdsClientDataTest {
|
|||
FilterChain.newBuilder()
|
||||
.setName("filter-chain-2")
|
||||
.setFilterChainMatch(filterChainMatch2)
|
||||
.setTransportSocket(TransportSocket.getDefaultInstance())
|
||||
.addFilters(filter2)
|
||||
.build();
|
||||
Listener listener =
|
||||
|
|
@ -1282,7 +1292,6 @@ public class ClientXdsClientDataTest {
|
|||
FilterChain.newBuilder()
|
||||
.setName("filter-chain-1")
|
||||
.setFilterChainMatch(filterChainMatch1)
|
||||
.setTransportSocket(TransportSocket.getDefaultInstance())
|
||||
.addFilters(filter1)
|
||||
.build();
|
||||
Filter filter2 = buildHttpConnectionManagerFilter(
|
||||
|
|
@ -1300,7 +1309,6 @@ public class ClientXdsClientDataTest {
|
|||
FilterChain.newBuilder()
|
||||
.setName("filter-chain-2")
|
||||
.setFilterChainMatch(filterChainMatch2)
|
||||
.setTransportSocket(TransportSocket.getDefaultInstance())
|
||||
.addFilters(filter2)
|
||||
.build();
|
||||
Listener listener =
|
||||
|
|
@ -1332,7 +1340,6 @@ public class ClientXdsClientDataTest {
|
|||
FilterChain.newBuilder()
|
||||
.setName("filter-chain-1")
|
||||
.setFilterChainMatch(filterChainMatch1)
|
||||
.setTransportSocket(TransportSocket.getDefaultInstance())
|
||||
.addFilters(filter1)
|
||||
.build();
|
||||
Filter filter2 = buildHttpConnectionManagerFilter(
|
||||
|
|
@ -1351,7 +1358,6 @@ public class ClientXdsClientDataTest {
|
|||
FilterChain.newBuilder()
|
||||
.setName("filter-chain-2")
|
||||
.setFilterChainMatch(filterChainMatch2)
|
||||
.setTransportSocket(TransportSocket.getDefaultInstance())
|
||||
.addFilters(filter2)
|
||||
.build();
|
||||
Listener listener =
|
||||
|
|
@ -1467,6 +1473,519 @@ public class ClientXdsClientDataTest {
|
|||
assertThat(parsedFilterChain1.getName()).isNotEqualTo(parsedFilterChain2.getName());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void validateCommonTlsContext_tlsParams() throws ResourceInvalidException {
|
||||
CommonTlsContext commonTlsContext = CommonTlsContext.newBuilder()
|
||||
.setTlsParams(TlsParameters.getDefaultInstance())
|
||||
.build();
|
||||
thrown.expect(ResourceInvalidException.class);
|
||||
thrown.expectMessage("common-tls-context with tls_params is not supported");
|
||||
ClientXdsClient.validateCommonTlsContext(commonTlsContext, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateCommonTlsContext_customHandshaker() throws ResourceInvalidException {
|
||||
CommonTlsContext commonTlsContext = CommonTlsContext.newBuilder()
|
||||
.setCustomHandshaker(TypedExtensionConfig.getDefaultInstance())
|
||||
.build();
|
||||
thrown.expect(ResourceInvalidException.class);
|
||||
thrown.expectMessage("common-tls-context with custom_handshaker is not supported");
|
||||
ClientXdsClient.validateCommonTlsContext(commonTlsContext, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateCommonTlsContext_validationContext() throws ResourceInvalidException {
|
||||
CommonTlsContext commonTlsContext = CommonTlsContext.newBuilder()
|
||||
.setValidationContext(CertificateValidationContext.getDefaultInstance())
|
||||
.build();
|
||||
thrown.expect(ResourceInvalidException.class);
|
||||
thrown.expectMessage("common-tls-context with validation_context is not supported");
|
||||
ClientXdsClient.validateCommonTlsContext(commonTlsContext, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateCommonTlsContext_validationContextSdsSecretConfig()
|
||||
throws ResourceInvalidException {
|
||||
CommonTlsContext commonTlsContext = CommonTlsContext.newBuilder()
|
||||
.setValidationContextSdsSecretConfig(SdsSecretConfig.getDefaultInstance())
|
||||
.build();
|
||||
thrown.expect(ResourceInvalidException.class);
|
||||
thrown.expectMessage(
|
||||
"common-tls-context with validation_context_sds_secret_config is not supported");
|
||||
ClientXdsClient.validateCommonTlsContext(commonTlsContext, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateCommonTlsContext_validationContextCertificateProvider()
|
||||
throws ResourceInvalidException {
|
||||
CommonTlsContext commonTlsContext = CommonTlsContext.newBuilder()
|
||||
.setValidationContextCertificateProvider(
|
||||
CommonTlsContext.CertificateProvider.getDefaultInstance())
|
||||
.build();
|
||||
thrown.expect(ResourceInvalidException.class);
|
||||
thrown.expectMessage(
|
||||
"common-tls-context with validation_context_certificate_provider is not supported");
|
||||
ClientXdsClient.validateCommonTlsContext(commonTlsContext, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateCommonTlsContext_validationContextCertificateProviderInstance()
|
||||
throws ResourceInvalidException {
|
||||
CommonTlsContext commonTlsContext = CommonTlsContext.newBuilder()
|
||||
.setValidationContextCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance())
|
||||
.build();
|
||||
thrown.expect(ResourceInvalidException.class);
|
||||
thrown.expectMessage(
|
||||
"common-tls-context with validation_context_certificate_provider_instance is not "
|
||||
+ "supported");
|
||||
ClientXdsClient.validateCommonTlsContext(commonTlsContext, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateCommonTlsContext_tlsCertificateProviderInstance_isRequiredForServer()
|
||||
throws ResourceInvalidException {
|
||||
CommonTlsContext commonTlsContext = CommonTlsContext.newBuilder()
|
||||
.build();
|
||||
thrown.expect(ResourceInvalidException.class);
|
||||
thrown.expectMessage(
|
||||
"tls_certificate_certificate_provider_instance is required in downstream-tls-context");
|
||||
ClientXdsClient.validateCommonTlsContext(commonTlsContext, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateCommonTlsContext_tlsCertificatesCount() throws ResourceInvalidException {
|
||||
CommonTlsContext commonTlsContext = CommonTlsContext.newBuilder()
|
||||
.addTlsCertificates(TlsCertificate.getDefaultInstance())
|
||||
.build();
|
||||
thrown.expect(ResourceInvalidException.class);
|
||||
thrown.expectMessage("common-tls-context with tls_certificates is not supported");
|
||||
ClientXdsClient.validateCommonTlsContext(commonTlsContext, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateCommonTlsContext_tlsCertificateSdsSecretConfigsCount()
|
||||
throws ResourceInvalidException {
|
||||
CommonTlsContext commonTlsContext = CommonTlsContext.newBuilder()
|
||||
.addTlsCertificateSdsSecretConfigs(SdsSecretConfig.getDefaultInstance())
|
||||
.build();
|
||||
thrown.expect(ResourceInvalidException.class);
|
||||
thrown.expectMessage(
|
||||
"common-tls-context with tls_certificate_sds_secret_configs is not supported");
|
||||
ClientXdsClient.validateCommonTlsContext(commonTlsContext, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateCommonTlsContext_tlsCertificateCertificateProvider()
|
||||
throws ResourceInvalidException {
|
||||
CommonTlsContext commonTlsContext = CommonTlsContext.newBuilder()
|
||||
.setTlsCertificateCertificateProvider(
|
||||
CommonTlsContext.CertificateProvider.getDefaultInstance())
|
||||
.build();
|
||||
thrown.expect(ResourceInvalidException.class);
|
||||
thrown.expectMessage(
|
||||
"common-tls-context with tls_certificate_certificate_provider is not supported");
|
||||
ClientXdsClient.validateCommonTlsContext(commonTlsContext, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateCommonTlsContext_combinedValidationContext_isRequiredForClient()
|
||||
throws ResourceInvalidException {
|
||||
CommonTlsContext commonTlsContext = CommonTlsContext.newBuilder()
|
||||
.build();
|
||||
thrown.expect(ResourceInvalidException.class);
|
||||
thrown.expectMessage("combined_validation_context is required in upstream-tls-context");
|
||||
ClientXdsClient.validateCommonTlsContext(commonTlsContext, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateCommonTlsContext_combinedValidationContextWithoutCertProviderInstance()
|
||||
throws ResourceInvalidException {
|
||||
CommonTlsContext commonTlsContext = CommonTlsContext.newBuilder()
|
||||
.setCombinedValidationContext(
|
||||
CommonTlsContext.CombinedCertificateValidationContext.getDefaultInstance())
|
||||
.build();
|
||||
thrown.expect(ResourceInvalidException.class);
|
||||
thrown.expectMessage(
|
||||
"validation_context_certificate_provider_instance is required in "
|
||||
+ "combined_validation_context");
|
||||
ClientXdsClient.validateCommonTlsContext(commonTlsContext, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateCommonTlsContext_combinedValContextWithDefaultValContextForServer()
|
||||
throws ResourceInvalidException {
|
||||
CommonTlsContext commonTlsContext = CommonTlsContext.newBuilder()
|
||||
.setCombinedValidationContext(
|
||||
CommonTlsContext.CombinedCertificateValidationContext.newBuilder()
|
||||
.setValidationContextCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance())
|
||||
.setDefaultValidationContext(CertificateValidationContext.getDefaultInstance()))
|
||||
.setTlsCertificateCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance())
|
||||
.build();
|
||||
thrown.expect(ResourceInvalidException.class);
|
||||
thrown.expectMessage("default_validation_context only allowed in upstream_tls_context");
|
||||
ClientXdsClient.validateCommonTlsContext(commonTlsContext, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateCommonTlsContext_combinedValContextWithDefaultValidationContextTrustedCa()
|
||||
throws ResourceInvalidException {
|
||||
CommonTlsContext commonTlsContext = CommonTlsContext.newBuilder()
|
||||
.setCombinedValidationContext(
|
||||
CommonTlsContext.CombinedCertificateValidationContext.newBuilder()
|
||||
.setValidationContextCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance())
|
||||
.setDefaultValidationContext(CertificateValidationContext.newBuilder()
|
||||
.setTrustedCa(DataSource.getDefaultInstance())))
|
||||
.setTlsCertificateCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance())
|
||||
.build();
|
||||
thrown.expect(ResourceInvalidException.class);
|
||||
thrown.expectMessage("trusted_ca in default_validation_context is not supported");
|
||||
ClientXdsClient.validateCommonTlsContext(commonTlsContext, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateCommonTlsContext_combinedValContextWithDefaultValContextWatchedDirectory()
|
||||
throws ResourceInvalidException {
|
||||
CommonTlsContext commonTlsContext = CommonTlsContext.newBuilder()
|
||||
.setCombinedValidationContext(
|
||||
CommonTlsContext.CombinedCertificateValidationContext.newBuilder()
|
||||
.setValidationContextCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance())
|
||||
.setDefaultValidationContext(CertificateValidationContext.newBuilder()
|
||||
.setWatchedDirectory(WatchedDirectory.getDefaultInstance())))
|
||||
.setTlsCertificateCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance())
|
||||
.build();
|
||||
thrown.expect(ResourceInvalidException.class);
|
||||
thrown.expectMessage("watched_directory in default_validation_context is not supported");
|
||||
ClientXdsClient.validateCommonTlsContext(commonTlsContext, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateCommonTlsContext_combinedValContextWithDefaultValContextVerifyCertSpki()
|
||||
throws ResourceInvalidException {
|
||||
CommonTlsContext commonTlsContext = CommonTlsContext.newBuilder()
|
||||
.setCombinedValidationContext(
|
||||
CommonTlsContext.CombinedCertificateValidationContext.newBuilder()
|
||||
.setValidationContextCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance())
|
||||
.setDefaultValidationContext(
|
||||
CertificateValidationContext.newBuilder().addVerifyCertificateSpki("foo")))
|
||||
.setTlsCertificateCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance())
|
||||
.build();
|
||||
thrown.expect(ResourceInvalidException.class);
|
||||
thrown.expectMessage("verify_certificate_spki in default_validation_context is not "
|
||||
+ "supported");
|
||||
ClientXdsClient.validateCommonTlsContext(commonTlsContext, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateCommonTlsContext_combinedValContextWithDefaultValContextVerifyCertHash()
|
||||
throws ResourceInvalidException {
|
||||
CommonTlsContext commonTlsContext = CommonTlsContext.newBuilder()
|
||||
.setCombinedValidationContext(
|
||||
CommonTlsContext.CombinedCertificateValidationContext.newBuilder()
|
||||
.setValidationContextCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance())
|
||||
.setDefaultValidationContext(
|
||||
CertificateValidationContext.newBuilder().addVerifyCertificateHash("foo")))
|
||||
.setTlsCertificateCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance())
|
||||
.build();
|
||||
thrown.expect(ResourceInvalidException.class);
|
||||
thrown.expectMessage("verify_certificate_hash in default_validation_context is not "
|
||||
+ "supported");
|
||||
ClientXdsClient.validateCommonTlsContext(commonTlsContext, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateCommonTlsContext_combinedValContextDfltValContextRequireSignedCertTimestamp()
|
||||
throws ResourceInvalidException {
|
||||
CommonTlsContext commonTlsContext = CommonTlsContext.newBuilder()
|
||||
.setCombinedValidationContext(
|
||||
CommonTlsContext.CombinedCertificateValidationContext.newBuilder()
|
||||
.setValidationContextCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance())
|
||||
.setDefaultValidationContext(CertificateValidationContext.newBuilder()
|
||||
.setRequireSignedCertificateTimestamp(BoolValue.of(true))))
|
||||
.setTlsCertificateCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance())
|
||||
.build();
|
||||
thrown.expect(ResourceInvalidException.class);
|
||||
thrown.expectMessage(
|
||||
"require_signed_certificate_timestamp in default_validation_context is not "
|
||||
+ "supported");
|
||||
ClientXdsClient.validateCommonTlsContext(commonTlsContext, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateCommonTlsContext_combinedValidationContextWithDefaultValidationContextCrl()
|
||||
throws ResourceInvalidException {
|
||||
CommonTlsContext commonTlsContext = CommonTlsContext.newBuilder()
|
||||
.setCombinedValidationContext(
|
||||
CommonTlsContext.CombinedCertificateValidationContext.newBuilder()
|
||||
.setValidationContextCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance())
|
||||
.setDefaultValidationContext(CertificateValidationContext.newBuilder()
|
||||
.setCrl(DataSource.getDefaultInstance())))
|
||||
.setTlsCertificateCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance())
|
||||
.build();
|
||||
thrown.expect(ResourceInvalidException.class);
|
||||
thrown.expectMessage("crl in default_validation_context is not supported");
|
||||
ClientXdsClient.validateCommonTlsContext(commonTlsContext, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateCommonTlsContext_combinedValContextWithDefaultValContextAllowExpiredCert()
|
||||
throws ResourceInvalidException {
|
||||
CommonTlsContext commonTlsContext = CommonTlsContext.newBuilder()
|
||||
.setCombinedValidationContext(
|
||||
CommonTlsContext.CombinedCertificateValidationContext.newBuilder()
|
||||
.setValidationContextCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance())
|
||||
.setDefaultValidationContext(
|
||||
CertificateValidationContext.newBuilder().setAllowExpiredCertificate(true)))
|
||||
.setTlsCertificateCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance())
|
||||
.build();
|
||||
thrown.expect(ResourceInvalidException.class);
|
||||
thrown
|
||||
.expectMessage("allow_expired_certificate in default_validation_context is not "
|
||||
+ "supported");
|
||||
ClientXdsClient.validateCommonTlsContext(commonTlsContext, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateCommonTlsContext_combinedValContextWithDfltValContextTrustChainVerification()
|
||||
throws ResourceInvalidException {
|
||||
CommonTlsContext commonTlsContext = CommonTlsContext.newBuilder()
|
||||
.setCombinedValidationContext(
|
||||
CommonTlsContext.CombinedCertificateValidationContext.newBuilder()
|
||||
.setValidationContextCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance())
|
||||
.setDefaultValidationContext(CertificateValidationContext.newBuilder()
|
||||
.setTrustChainVerification(
|
||||
CertificateValidationContext.TrustChainVerification.ACCEPT_UNTRUSTED)))
|
||||
.setTlsCertificateCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance())
|
||||
.build();
|
||||
thrown.expect(ResourceInvalidException.class);
|
||||
thrown.expectMessage("Only VERIFY_TRUST_CHAIN for trust_chain_verification supported");
|
||||
ClientXdsClient.validateCommonTlsContext(commonTlsContext, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateCommonTlsContext_combinedValContextWithDfltValContextCustomValidatorConfig()
|
||||
throws ResourceInvalidException {
|
||||
CommonTlsContext commonTlsContext = CommonTlsContext.newBuilder()
|
||||
.setCombinedValidationContext(
|
||||
CommonTlsContext.CombinedCertificateValidationContext.newBuilder()
|
||||
.setValidationContextCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance())
|
||||
.setDefaultValidationContext(CertificateValidationContext.newBuilder()
|
||||
.setCustomValidatorConfig(TypedExtensionConfig.getDefaultInstance())))
|
||||
.setTlsCertificateCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance())
|
||||
.build();
|
||||
thrown.expect(ResourceInvalidException.class);
|
||||
thrown.expectMessage("custom_validator_config in default_validation_context is not "
|
||||
+ "supported");
|
||||
ClientXdsClient.validateCommonTlsContext(commonTlsContext, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateDownstreamTlsContext_noCommonTlsContext() throws ResourceInvalidException {
|
||||
DownstreamTlsContext downstreamTlsContext = DownstreamTlsContext.getDefaultInstance();
|
||||
thrown.expect(ResourceInvalidException.class);
|
||||
thrown.expectMessage("common-tls-context is required in downstream-tls-context");
|
||||
ClientXdsClient.validateDownstreamTlsContext(downstreamTlsContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateDownstreamTlsContext_hasRequireSni() throws ResourceInvalidException {
|
||||
CommonTlsContext commonTlsContext = CommonTlsContext.newBuilder()
|
||||
.setCombinedValidationContext(
|
||||
CommonTlsContext.CombinedCertificateValidationContext.newBuilder()
|
||||
.setValidationContextCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance()))
|
||||
.setTlsCertificateCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance())
|
||||
.build();
|
||||
DownstreamTlsContext downstreamTlsContext = DownstreamTlsContext.newBuilder()
|
||||
.setCommonTlsContext(commonTlsContext)
|
||||
.setRequireSni(BoolValue.of(true))
|
||||
.build();
|
||||
thrown.expect(ResourceInvalidException.class);
|
||||
thrown.expectMessage("downstream-tls-context with require-sni is not supported");
|
||||
ClientXdsClient.validateDownstreamTlsContext(downstreamTlsContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateDownstreamTlsContext_hasSessionTikcetKeys() throws ResourceInvalidException {
|
||||
CommonTlsContext commonTlsContext = CommonTlsContext.newBuilder()
|
||||
.setCombinedValidationContext(
|
||||
CommonTlsContext.CombinedCertificateValidationContext.newBuilder()
|
||||
.setValidationContextCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance()))
|
||||
.setTlsCertificateCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance())
|
||||
.build();
|
||||
DownstreamTlsContext downstreamTlsContext = DownstreamTlsContext.newBuilder()
|
||||
.setCommonTlsContext(commonTlsContext)
|
||||
.setSessionTicketKeys(TlsSessionTicketKeys.getDefaultInstance())
|
||||
.build();
|
||||
thrown.expect(ResourceInvalidException.class);
|
||||
thrown.expectMessage("downstream-tls-context with session_ticket_keys is not supported");
|
||||
ClientXdsClient.validateDownstreamTlsContext(downstreamTlsContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateDownstreamTlsContext_hasSessionTikcetKeysSdsSecretConfig()
|
||||
throws ResourceInvalidException {
|
||||
CommonTlsContext commonTlsContext = CommonTlsContext.newBuilder()
|
||||
.setCombinedValidationContext(
|
||||
CommonTlsContext.CombinedCertificateValidationContext.newBuilder()
|
||||
.setValidationContextCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance()))
|
||||
.setTlsCertificateCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance())
|
||||
.build();
|
||||
DownstreamTlsContext downstreamTlsContext = DownstreamTlsContext.newBuilder()
|
||||
.setCommonTlsContext(commonTlsContext)
|
||||
.setSessionTicketKeysSdsSecretConfig(SdsSecretConfig.getDefaultInstance())
|
||||
.build();
|
||||
thrown.expect(ResourceInvalidException.class);
|
||||
thrown.expectMessage(
|
||||
"downstream-tls-context with session_ticket_keys_sds_secret_config is not supported");
|
||||
ClientXdsClient.validateDownstreamTlsContext(downstreamTlsContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateDownstreamTlsContext_hasDisableStatelessSessionResumption()
|
||||
throws ResourceInvalidException {
|
||||
CommonTlsContext commonTlsContext = CommonTlsContext.newBuilder()
|
||||
.setCombinedValidationContext(
|
||||
CommonTlsContext.CombinedCertificateValidationContext.newBuilder()
|
||||
.setValidationContextCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance()))
|
||||
.setTlsCertificateCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance())
|
||||
.build();
|
||||
DownstreamTlsContext downstreamTlsContext = DownstreamTlsContext.newBuilder()
|
||||
.setCommonTlsContext(commonTlsContext)
|
||||
.setDisableStatelessSessionResumption(true)
|
||||
.build();
|
||||
thrown.expect(ResourceInvalidException.class);
|
||||
thrown.expectMessage(
|
||||
"downstream-tls-context with disable_stateless_session_resumption is not supported");
|
||||
ClientXdsClient.validateDownstreamTlsContext(downstreamTlsContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateDownstreamTlsContext_hasSessionTimeout() throws ResourceInvalidException {
|
||||
CommonTlsContext commonTlsContext = CommonTlsContext.newBuilder()
|
||||
.setCombinedValidationContext(
|
||||
CommonTlsContext.CombinedCertificateValidationContext.newBuilder()
|
||||
.setValidationContextCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance()))
|
||||
.setTlsCertificateCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance())
|
||||
.build();
|
||||
DownstreamTlsContext downstreamTlsContext = DownstreamTlsContext.newBuilder()
|
||||
.setCommonTlsContext(commonTlsContext)
|
||||
.setSessionTimeout(Duration.getDefaultInstance())
|
||||
.build();
|
||||
thrown.expect(ResourceInvalidException.class);
|
||||
thrown.expectMessage("downstream-tls-context with session_timeout is not supported");
|
||||
ClientXdsClient.validateDownstreamTlsContext(downstreamTlsContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateDownstreamTlsContext_hasOcspStaplePolicy() throws ResourceInvalidException {
|
||||
CommonTlsContext commonTlsContext = CommonTlsContext.newBuilder()
|
||||
.setCombinedValidationContext(
|
||||
CommonTlsContext.CombinedCertificateValidationContext.newBuilder()
|
||||
.setValidationContextCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance()))
|
||||
.setTlsCertificateCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance())
|
||||
.build();
|
||||
DownstreamTlsContext downstreamTlsContext = DownstreamTlsContext.newBuilder()
|
||||
.setCommonTlsContext(commonTlsContext)
|
||||
.setOcspStaplePolicy(DownstreamTlsContext.OcspStaplePolicy.STRICT_STAPLING)
|
||||
.build();
|
||||
thrown.expect(ResourceInvalidException.class);
|
||||
thrown.expectMessage(
|
||||
"downstream-tls-context with ocsp_staple_policy value STRICT_STAPLING is not supported");
|
||||
ClientXdsClient.validateDownstreamTlsContext(downstreamTlsContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateUpstreamTlsContext_noCommonTlsContext() throws ResourceInvalidException {
|
||||
UpstreamTlsContext upstreamTlsContext = UpstreamTlsContext.getDefaultInstance();
|
||||
thrown.expect(ResourceInvalidException.class);
|
||||
thrown.expectMessage("common-tls-context is required in upstream-tls-context");
|
||||
ClientXdsClient.validateUpstreamTlsContext(upstreamTlsContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateUpstreamTlsContext_sni() throws ResourceInvalidException {
|
||||
CommonTlsContext commonTlsContext = CommonTlsContext.newBuilder()
|
||||
.setCombinedValidationContext(
|
||||
CommonTlsContext.CombinedCertificateValidationContext.newBuilder()
|
||||
.setValidationContextCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance()))
|
||||
.build();
|
||||
UpstreamTlsContext upstreamTlsContext = UpstreamTlsContext.newBuilder()
|
||||
.setCommonTlsContext(commonTlsContext)
|
||||
.setSni("foo")
|
||||
.build();
|
||||
thrown.expect(ResourceInvalidException.class);
|
||||
thrown.expectMessage("upstream-tls-context with sni is not supported");
|
||||
ClientXdsClient.validateUpstreamTlsContext(upstreamTlsContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateUpstreamTlsContext_allowRenegotiation() throws ResourceInvalidException {
|
||||
CommonTlsContext commonTlsContext = CommonTlsContext.newBuilder()
|
||||
.setCombinedValidationContext(
|
||||
CommonTlsContext.CombinedCertificateValidationContext.newBuilder()
|
||||
.setValidationContextCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance()))
|
||||
.build();
|
||||
UpstreamTlsContext upstreamTlsContext = UpstreamTlsContext.newBuilder()
|
||||
.setCommonTlsContext(commonTlsContext)
|
||||
.setAllowRenegotiation(true)
|
||||
.build();
|
||||
thrown.expect(ResourceInvalidException.class);
|
||||
thrown.expectMessage("upstream-tls-context with allow_renegotiation is not supported");
|
||||
ClientXdsClient.validateUpstreamTlsContext(upstreamTlsContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateUpstreamTlsContext_maxSessionKeys() throws ResourceInvalidException {
|
||||
CommonTlsContext commonTlsContext = CommonTlsContext.newBuilder()
|
||||
.setCombinedValidationContext(
|
||||
CommonTlsContext.CombinedCertificateValidationContext.newBuilder()
|
||||
.setValidationContextCertificateProviderInstance(
|
||||
CommonTlsContext.CertificateProviderInstance.getDefaultInstance()))
|
||||
.build();
|
||||
UpstreamTlsContext upstreamTlsContext = UpstreamTlsContext.newBuilder()
|
||||
.setCommonTlsContext(commonTlsContext)
|
||||
.setMaxSessionKeys(UInt32Value.getDefaultInstance())
|
||||
.build();
|
||||
thrown.expect(ResourceInvalidException.class);
|
||||
thrown.expectMessage("upstream-tls-context with max_session_keys is not supported");
|
||||
ClientXdsClient.validateUpstreamTlsContext(upstreamTlsContext);
|
||||
}
|
||||
|
||||
private static Filter buildHttpConnectionManagerFilter(HttpFilter... httpFilters) {
|
||||
return Filter.newBuilder()
|
||||
.setName("envoy.http_connection_manager")
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ import com.google.protobuf.Any;
|
|||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import com.google.protobuf.Message;
|
||||
import io.envoyproxy.envoy.config.route.v3.FilterConfig;
|
||||
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.SdsSecretConfig;
|
||||
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.CommonTlsContext;
|
||||
import io.grpc.BindableService;
|
||||
import io.grpc.Context;
|
||||
import io.grpc.Context.CancellableContext;
|
||||
|
|
@ -193,7 +193,9 @@ public abstract class ClientXdsClientTestBase {
|
|||
|
||||
// CDS test resources.
|
||||
private final Any testClusterRoundRobin =
|
||||
Any.pack(mf.buildEdsCluster(CDS_RESOURCE, null, "round_robin", null, false, null, null));
|
||||
Any.pack(mf.buildEdsCluster(CDS_RESOURCE, null, "round_robin", null, false, null,
|
||||
"envoy.transport_sockets.tls", null
|
||||
));
|
||||
|
||||
// EDS test resources.
|
||||
private final Message lbEndpointHealthy =
|
||||
|
|
@ -990,9 +992,10 @@ public abstract class ClientXdsClientTestBase {
|
|||
Message hcmFilter = mf.buildHttpConnectionManagerFilter(
|
||||
RDS_RESOURCE, null, Collections.<Message>emptyList());
|
||||
Message downstreamTlsContext = CommonTlsContextTestsUtil.buildTestDownstreamTlsContext(
|
||||
"google-sds-config-default", "ROOTCA");
|
||||
"google-sds-config-default", "ROOTCA", false);
|
||||
Message filterChain = mf.buildFilterChain(
|
||||
Collections.<String>emptyList(), downstreamTlsContext, hcmFilter);
|
||||
Collections.<String>emptyList(), downstreamTlsContext, "envoy.transport_sockets.tls",
|
||||
hcmFilter);
|
||||
Any packedListener =
|
||||
Any.pack(mf.buildListenerWithFilterChain(LISTENER_RESOURCE, 7000, "0.0.0.0", filterChain));
|
||||
|
||||
|
|
@ -1024,7 +1027,8 @@ public abstract class ClientXdsClientTestBase {
|
|||
"route-bar.googleapis.com", mf.buildOpaqueVirtualHosts(VHOST_SIZE)),
|
||||
Collections.<Message>emptyList());
|
||||
filterChain = mf.buildFilterChain(
|
||||
Collections.<String>emptyList(), downstreamTlsContext, hcmFilter);
|
||||
Collections.<String>emptyList(), downstreamTlsContext, "envoy.transport_sockets.tls",
|
||||
hcmFilter);
|
||||
packedListener =
|
||||
Any.pack(mf.buildListenerWithFilterChain(LISTENER_RESOURCE, 7000, "0.0.0.0", filterChain));
|
||||
call.sendResponse(LDS, packedListener, VERSION_2, "0001");
|
||||
|
|
@ -1090,9 +1094,9 @@ public abstract class ClientXdsClientTestBase {
|
|||
|
||||
List<Any> clusters = ImmutableList.of(
|
||||
Any.pack(mf.buildEdsCluster("cluster-bar.googleapis.com", null, "round_robin", null,
|
||||
false, null, null)),
|
||||
false, null, "envoy.transport_sockets.tls", null)),
|
||||
Any.pack(mf.buildEdsCluster("cluster-baz.googleapis.com", null, "round_robin", null,
|
||||
false, null, null)));
|
||||
false, null, "envoy.transport_sockets.tls", null)));
|
||||
call.sendResponse(CDS, clusters, VERSION_1, "0000");
|
||||
|
||||
// Client sent an ACK CDS request.
|
||||
|
|
@ -1165,9 +1169,15 @@ public abstract class ClientXdsClientTestBase {
|
|||
|
||||
// CDS -> {A, B, C}, version 1
|
||||
ImmutableMap<String, Any> resourcesV1 = ImmutableMap.of(
|
||||
"A", Any.pack(mf.buildEdsCluster("A", "A.1", "round_robin", null, false, null, null)),
|
||||
"B", Any.pack(mf.buildEdsCluster("B", "B.1", "round_robin", null, false, null, null)),
|
||||
"C", Any.pack(mf.buildEdsCluster("C", "C.1", "round_robin", null, false, null, null)));
|
||||
"A", Any.pack(mf.buildEdsCluster("A", "A.1", "round_robin", null, false, null,
|
||||
"envoy.transport_sockets.tls", null
|
||||
)),
|
||||
"B", Any.pack(mf.buildEdsCluster("B", "B.1", "round_robin", null, false, null,
|
||||
"envoy.transport_sockets.tls", null
|
||||
)),
|
||||
"C", Any.pack(mf.buildEdsCluster("C", "C.1", "round_robin", null, false, null,
|
||||
"envoy.transport_sockets.tls", null
|
||||
)));
|
||||
call.sendResponse(CDS, resourcesV1.values().asList(), VERSION_1, "0000");
|
||||
// {A, B, C} -> ACK, version 1
|
||||
verifyResourceMetadataAcked(CDS, "A", resourcesV1.get("A"), VERSION_1, TIME_INCREMENT);
|
||||
|
|
@ -1178,7 +1188,9 @@ public abstract class ClientXdsClientTestBase {
|
|||
// CDS -> {A, B}, version 2
|
||||
// Failed to parse endpoint B
|
||||
ImmutableMap<String, Any> resourcesV2 = ImmutableMap.of(
|
||||
"A", Any.pack(mf.buildEdsCluster("A", "A.2", "round_robin", null, false, null, null)),
|
||||
"A", Any.pack(mf.buildEdsCluster("A", "A.2", "round_robin", null, false, null,
|
||||
"envoy.transport_sockets.tls", null
|
||||
)),
|
||||
"B", Any.pack(mf.buildClusterInvalid("B")));
|
||||
call.sendResponse(CDS, resourcesV2.values().asList(), VERSION_2, "0001");
|
||||
// {A, B} -> NACK, version 1, rejected version 2, rejected reason: Failed to parse B
|
||||
|
|
@ -1193,8 +1205,12 @@ public abstract class ClientXdsClientTestBase {
|
|||
|
||||
// CDS -> {B, C} version 3
|
||||
ImmutableMap<String, Any> resourcesV3 = ImmutableMap.of(
|
||||
"B", Any.pack(mf.buildEdsCluster("B", "B.3", "round_robin", null, false, null, null)),
|
||||
"C", Any.pack(mf.buildEdsCluster("C", "C.3", "round_robin", null, false, null, null)));
|
||||
"B", Any.pack(mf.buildEdsCluster("B", "B.3", "round_robin", null, false, null,
|
||||
"envoy.transport_sockets.tls", null
|
||||
)),
|
||||
"C", Any.pack(mf.buildEdsCluster("C", "C.3", "round_robin", null, false, null,
|
||||
"envoy.transport_sockets.tls", null
|
||||
)));
|
||||
call.sendResponse(CDS, resourcesV3.values().asList(), VERSION_3, "0002");
|
||||
// {A} -> NACK, version 1, rejected version 2, rejected reason: Failed to parse B
|
||||
// {B, C} -> ACK, version 3
|
||||
|
|
@ -1231,7 +1247,9 @@ public abstract class ClientXdsClientTestBase {
|
|||
DiscoveryRpcCall call = startResourceWatcher(CDS, CDS_RESOURCE, cdsResourceWatcher);
|
||||
Message ringHashConfig = mf.buildRingHashLbConfig("xx_hash", 10L, 100L);
|
||||
Any clusterRingHash = Any.pack(
|
||||
mf.buildEdsCluster(CDS_RESOURCE, null, "ring_hash", ringHashConfig, false, null, null));
|
||||
mf.buildEdsCluster(CDS_RESOURCE, null, "ring_hash", ringHashConfig, false, null,
|
||||
"envoy.transport_sockets.tls", null
|
||||
));
|
||||
call.sendResponse(ResourceType.CDS, clusterRingHash, VERSION_1, "0000");
|
||||
|
||||
// Client sent an ACK CDS request.
|
||||
|
|
@ -1278,7 +1296,7 @@ public abstract class ClientXdsClientTestBase {
|
|||
DiscoveryRpcCall call = startResourceWatcher(CDS, CDS_RESOURCE, cdsResourceWatcher);
|
||||
Any clusterCircuitBreakers = Any.pack(
|
||||
mf.buildEdsCluster(CDS_RESOURCE, null, "round_robin", null, false, null,
|
||||
mf.buildCircuitBreakers(50, 200)));
|
||||
"envoy.transport_sockets.tls", mf.buildCircuitBreakers(50, 200)));
|
||||
call.sendResponse(CDS, clusterCircuitBreakers, VERSION_1, "0000");
|
||||
|
||||
// Client sent an ACK CDS request.
|
||||
|
|
@ -1302,41 +1320,81 @@ public abstract class ClientXdsClientTestBase {
|
|||
*/
|
||||
@Test
|
||||
public void cdsResponseWithUpstreamTlsContext() {
|
||||
Assume.assumeTrue(useProtocolV3());
|
||||
DiscoveryRpcCall call = startResourceWatcher(CDS, CDS_RESOURCE, cdsResourceWatcher);
|
||||
|
||||
// Management server sends back CDS response with UpstreamTlsContext.
|
||||
Any clusterEds =
|
||||
Any.pack(mf.buildEdsCluster(CDS_RESOURCE, "eds-cluster-foo.googleapis.com", "round_robin",
|
||||
null, true,
|
||||
mf.buildUpstreamTlsContext("secret1", "unix:/var/uds2"), null));
|
||||
mf.buildUpstreamTlsContext("secret1", "cert1"), "envoy.transport_sockets.tls", null));
|
||||
List<Any> clusters = ImmutableList.of(
|
||||
Any.pack(mf.buildLogicalDnsCluster("cluster-bar.googleapis.com",
|
||||
"dns-service-bar.googleapis.com", 443, "round_robin", null, false, null, null)),
|
||||
clusterEds,
|
||||
Any.pack(mf.buildEdsCluster("cluster-baz.googleapis.com", null, "round_robin", null, false,
|
||||
null, null)));
|
||||
null, "envoy.transport_sockets.tls", null)));
|
||||
call.sendResponse(CDS, clusters, VERSION_1, "0000");
|
||||
|
||||
// Client sent an ACK CDS request.
|
||||
call.verifyRequest(CDS, CDS_RESOURCE, VERSION_1, "0000", NODE);
|
||||
verify(cdsResourceWatcher, times(1)).onChanged(cdsUpdateCaptor.capture());
|
||||
CdsUpdate cdsUpdate = cdsUpdateCaptor.getValue();
|
||||
SdsSecretConfig validationContextSdsSecretConfig =
|
||||
cdsUpdate.upstreamTlsContext().getCommonTlsContext().getValidationContextSdsSecretConfig();
|
||||
assertThat(validationContextSdsSecretConfig.getName()).isEqualTo("secret1");
|
||||
assertThat(
|
||||
Iterables.getOnlyElement(
|
||||
validationContextSdsSecretConfig
|
||||
.getSdsConfig()
|
||||
.getApiConfigSource()
|
||||
.getGrpcServicesList())
|
||||
.getGoogleGrpc()
|
||||
.getTargetUri())
|
||||
.isEqualTo("unix:/var/uds2");
|
||||
CommonTlsContext.CertificateProviderInstance certificateProviderInstance =
|
||||
cdsUpdate.upstreamTlsContext().getCommonTlsContext().getCombinedValidationContext()
|
||||
.getValidationContextCertificateProviderInstance();
|
||||
assertThat(certificateProviderInstance.getInstanceName()).isEqualTo("secret1");
|
||||
assertThat(certificateProviderInstance.getCertificateName()).isEqualTo("cert1");
|
||||
verifyResourceMetadataAcked(CDS, CDS_RESOURCE, clusterEds, VERSION_1, TIME_INCREMENT);
|
||||
verifySubscribedResourcesMetadataSizes(0, 1, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* CDS response containing bad UpstreamTlsContext for a cluster.
|
||||
*/
|
||||
@Test
|
||||
public void cdsResponseErrorHandling_badUpstreamTlsContext() {
|
||||
Assume.assumeTrue(useProtocolV3());
|
||||
DiscoveryRpcCall call = startResourceWatcher(CDS, CDS_RESOURCE, cdsResourceWatcher);
|
||||
|
||||
// Management server sends back CDS response with UpstreamTlsContext.
|
||||
List<Any> clusters = ImmutableList.of(Any
|
||||
.pack(mf.buildEdsCluster(CDS_RESOURCE, "eds-cluster-foo.googleapis.com", "round_robin",
|
||||
null, true,
|
||||
mf.buildUpstreamTlsContext(null, null), "envoy.transport_sockets.tls", null)));
|
||||
call.sendResponse(CDS, clusters, VERSION_1, "0000");
|
||||
|
||||
// The response NACKed with errors indicating indices of the failed resources.
|
||||
call.verifyRequestNack(CDS, CDS_RESOURCE, "", "0000", NODE, ImmutableList.of(
|
||||
"CDS response Cluster 'cluster.googleapis.com' validation error: "
|
||||
+ "Cluster cluster.googleapis.com: malformed UpstreamTlsContext: "
|
||||
+ "io.grpc.xds.ClientXdsClient$ResourceInvalidException: "
|
||||
+ "combined_validation_context is required in upstream-tls-context"));
|
||||
verifyNoInteractions(cdsResourceWatcher);
|
||||
}
|
||||
|
||||
/**
|
||||
* CDS response containing UpstreamTlsContext with bad transportSocketName for a cluster.
|
||||
*/
|
||||
@Test
|
||||
public void cdsResponseErrorHandling_badTransportSocketName() {
|
||||
Assume.assumeTrue(useProtocolV3());
|
||||
DiscoveryRpcCall call = startResourceWatcher(CDS, CDS_RESOURCE, cdsResourceWatcher);
|
||||
|
||||
// Management server sends back CDS response with UpstreamTlsContext.
|
||||
List<Any> clusters = ImmutableList.of(Any
|
||||
.pack(mf.buildEdsCluster(CDS_RESOURCE, "eds-cluster-foo.googleapis.com", "round_robin",
|
||||
null, true,
|
||||
mf.buildUpstreamTlsContext("secret1", "cert1"), "envoy.transport_sockets.bad", null)));
|
||||
call.sendResponse(CDS, clusters, VERSION_1, "0000");
|
||||
|
||||
// The response NACKed with errors indicating indices of the failed resources.
|
||||
call.verifyRequestNack(CDS, CDS_RESOURCE, "", "0000", NODE, ImmutableList.of(
|
||||
"CDS response Cluster 'cluster.googleapis.com' validation error: "
|
||||
+ "transport-socket with name envoy.transport_sockets.bad not supported."));
|
||||
verifyNoInteractions(cdsResourceWatcher);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cachedCdsResource_data() {
|
||||
DiscoveryRpcCall call = startResourceWatcher(CDS, CDS_RESOURCE, cdsResourceWatcher);
|
||||
|
|
@ -1403,7 +1461,9 @@ public abstract class ClientXdsClientTestBase {
|
|||
// Updated CDS response.
|
||||
String edsService = "eds-service-bar.googleapis.com";
|
||||
Any clusterEds = Any.pack(
|
||||
mf.buildEdsCluster(CDS_RESOURCE, edsService, "round_robin", null, true, null, null));
|
||||
mf.buildEdsCluster(CDS_RESOURCE, edsService, "round_robin", null, true, null,
|
||||
"envoy.transport_sockets.tls", null
|
||||
));
|
||||
call.sendResponse(CDS, clusterEds, VERSION_2, "0001");
|
||||
call.verifyRequest(CDS, CDS_RESOURCE, VERSION_2, "0001", NODE);
|
||||
verify(cdsResourceWatcher, times(2)).onChanged(cdsUpdateCaptor.capture());
|
||||
|
|
@ -1477,7 +1537,7 @@ public abstract class ClientXdsClientTestBase {
|
|||
Any.pack(mf.buildLogicalDnsCluster(CDS_RESOURCE, dnsHostAddr, dnsHostPort, "round_robin",
|
||||
null, false, null, null)),
|
||||
Any.pack(mf.buildEdsCluster(cdsResourceTwo, edsService, "round_robin", null, true, null,
|
||||
null)));
|
||||
"envoy.transport_sockets.tls", null)));
|
||||
call.sendResponse(CDS, clusters, VERSION_1, "0000");
|
||||
verify(cdsResourceWatcher).onChanged(cdsUpdateCaptor.capture());
|
||||
CdsUpdate cdsUpdate = cdsUpdateCaptor.getValue();
|
||||
|
|
@ -1736,9 +1796,11 @@ public abstract class ClientXdsClientTestBase {
|
|||
|
||||
DiscoveryRpcCall call = resourceDiscoveryCalls.poll();
|
||||
List<Any> clusters = ImmutableList.of(
|
||||
Any.pack(mf.buildEdsCluster(resource, null, "round_robin", null, true, null, null)),
|
||||
Any.pack(mf.buildEdsCluster(resource, null, "round_robin", null, true, null,
|
||||
"envoy.transport_sockets.tls", null
|
||||
)),
|
||||
Any.pack(mf.buildEdsCluster(CDS_RESOURCE, EDS_RESOURCE, "round_robin", null, false, null,
|
||||
null)));
|
||||
"envoy.transport_sockets.tls", null)));
|
||||
call.sendResponse(CDS, clusters, VERSION_1, "0000");
|
||||
verify(cdsWatcher).onChanged(cdsUpdateCaptor.capture());
|
||||
CdsUpdate cdsUpdate = cdsUpdateCaptor.getValue();
|
||||
|
|
@ -1784,8 +1846,10 @@ public abstract class ClientXdsClientTestBase {
|
|||
|
||||
clusters = ImmutableList.of(
|
||||
Any.pack(mf.buildEdsCluster(resource, null, "round_robin", null, true, null,
|
||||
null)), // no change
|
||||
Any.pack(mf.buildEdsCluster(CDS_RESOURCE, null, "round_robin", null, false, null, null)));
|
||||
"envoy.transport_sockets.tls", null)), // no change
|
||||
Any.pack(mf.buildEdsCluster(CDS_RESOURCE, null, "round_robin", null, false, null,
|
||||
"envoy.transport_sockets.tls", null
|
||||
)));
|
||||
call.sendResponse(CDS, clusters, VERSION_2, "0001");
|
||||
verify(cdsResourceWatcher, times(2)).onChanged(cdsUpdateCaptor.capture());
|
||||
assertThat(cdsUpdateCaptor.getValue().edsServiceName()).isNull();
|
||||
|
|
@ -2100,9 +2164,10 @@ public abstract class ClientXdsClientTestBase {
|
|||
Message hcmFilter = mf.buildHttpConnectionManagerFilter(
|
||||
"route-foo.googleapis.com", null, Collections.<Message>emptyList());
|
||||
Message downstreamTlsContext = CommonTlsContextTestsUtil.buildTestDownstreamTlsContext(
|
||||
"google-sds-config-default", "ROOTCA");
|
||||
"google-sds-config-default", "ROOTCA", false);
|
||||
Message filterChain = mf.buildFilterChain(
|
||||
Collections.<String>emptyList(), downstreamTlsContext, hcmFilter);
|
||||
Collections.<String>emptyList(), downstreamTlsContext, "envoy.transport_sockets.tls",
|
||||
hcmFilter);
|
||||
Message listener =
|
||||
mf.buildListenerWithFilterChain(LISTENER_RESOURCE, 7000, "0.0.0.0", filterChain);
|
||||
List<Any> listeners = ImmutableList.of(Any.pack(listener));
|
||||
|
|
@ -2133,9 +2198,10 @@ public abstract class ClientXdsClientTestBase {
|
|||
Message hcmFilter = mf.buildHttpConnectionManagerFilter(
|
||||
"route-foo.googleapis.com", null, Collections.<Message>emptyList());
|
||||
Message downstreamTlsContext = CommonTlsContextTestsUtil.buildTestDownstreamTlsContext(
|
||||
"google-sds-config-default", "ROOTCA");
|
||||
"google-sds-config-default", "ROOTCA", false);
|
||||
Message filterChain = mf.buildFilterChain(
|
||||
Collections.singletonList("managed-mtls"), downstreamTlsContext, hcmFilter);
|
||||
Collections.singletonList("managed-mtls"), downstreamTlsContext,
|
||||
"envoy.transport_sockets.tls", hcmFilter);
|
||||
Message listener = mf.buildListenerWithFilterChain(
|
||||
"grpc/server?xds.resource.listening_address=0.0.0.0:8000", 7000, "0.0.0.0", filterChain);
|
||||
List<Any> listeners = ImmutableList.of(Any.pack(listener));
|
||||
|
|
@ -2150,6 +2216,53 @@ public abstract class ClientXdsClientTestBase {
|
|||
assertThat(fakeClock.getPendingTasks(LDS_RESOURCE_FETCH_TIMEOUT_TASK_FILTER)).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void serverSideListenerResponseErrorHandling_badDownstreamTlsContext() {
|
||||
Assume.assumeTrue(useProtocolV3());
|
||||
ClientXdsClientTestBase.DiscoveryRpcCall call =
|
||||
startResourceWatcher(LDS, LISTENER_RESOURCE, ldsResourceWatcher);
|
||||
Message hcmFilter = mf.buildHttpConnectionManagerFilter(
|
||||
"route-foo.googleapis.com", null, Collections.<Message>emptyList());
|
||||
Message downstreamTlsContext = CommonTlsContextTestsUtil.buildTestDownstreamTlsContext(
|
||||
null, null,false);
|
||||
Message filterChain = mf.buildFilterChain(
|
||||
Collections.<String>emptyList(), downstreamTlsContext, "envoy.transport_sockets.tls",
|
||||
hcmFilter);
|
||||
Message listener =
|
||||
mf.buildListenerWithFilterChain(LISTENER_RESOURCE, 7000, "0.0.0.0", filterChain);
|
||||
List<Any> listeners = ImmutableList.of(Any.pack(listener));
|
||||
call.sendResponse(ResourceType.LDS, listeners, "0", "0000");
|
||||
// The response NACKed with errors indicating indices of the failed resources.
|
||||
call.verifyRequestNack(LDS, LISTENER_RESOURCE, "", "0000", NODE, ImmutableList.of(
|
||||
"LDS response Listener \'grpc/server?xds.resource.listening_address=0.0.0.0:7000\' "
|
||||
+ "validation error: common-tls-context is required in downstream-tls-context"));
|
||||
verifyNoInteractions(ldsResourceWatcher);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void serverSideListenerResponseErrorHandling_badTransportSocketName() {
|
||||
Assume.assumeTrue(useProtocolV3());
|
||||
ClientXdsClientTestBase.DiscoveryRpcCall call =
|
||||
startResourceWatcher(LDS, LISTENER_RESOURCE, ldsResourceWatcher);
|
||||
Message hcmFilter = mf.buildHttpConnectionManagerFilter(
|
||||
"route-foo.googleapis.com", null, Collections.<Message>emptyList());
|
||||
Message downstreamTlsContext = CommonTlsContextTestsUtil.buildTestDownstreamTlsContext(
|
||||
"cert1", "cert2",false);
|
||||
Message filterChain = mf.buildFilterChain(
|
||||
Collections.<String>emptyList(), downstreamTlsContext, "envoy.transport_sockets.bad1",
|
||||
hcmFilter);
|
||||
Message listener =
|
||||
mf.buildListenerWithFilterChain(LISTENER_RESOURCE, 7000, "0.0.0.0", filterChain);
|
||||
List<Any> listeners = ImmutableList.of(Any.pack(listener));
|
||||
call.sendResponse(ResourceType.LDS, listeners, "0", "0000");
|
||||
// The response NACKed with errors indicating indices of the failed resources.
|
||||
call.verifyRequestNack(LDS, LISTENER_RESOURCE, "", "0000", NODE, ImmutableList.of(
|
||||
"LDS response Listener \'grpc/server?xds.resource.listening_address=0.0.0.0:7000\' "
|
||||
+ "validation error: "
|
||||
+ "transport-socket with name envoy.transport_sockets.bad1 not supported."));
|
||||
verifyNoInteractions(ldsResourceWatcher);
|
||||
}
|
||||
|
||||
private DiscoveryRpcCall startResourceWatcher(
|
||||
ResourceType type, String name, ResourceWatcher watcher) {
|
||||
FakeClock.TaskFilter timeoutTaskFilter;
|
||||
|
|
@ -2268,7 +2381,8 @@ public abstract class ClientXdsClientTestBase {
|
|||
|
||||
protected abstract Message buildEdsCluster(String clusterName, @Nullable String edsServiceName,
|
||||
String lbPolicy, @Nullable Message ringHashLbConfig, boolean enableLrs,
|
||||
@Nullable Message upstreamTlsContext, @Nullable Message circuitBreakers);
|
||||
@Nullable Message upstreamTlsContext, String transportSocketName,
|
||||
@Nullable Message circuitBreakers);
|
||||
|
||||
protected abstract Message buildLogicalDnsCluster(String clusterName, String dnsHostAddr,
|
||||
int dnsHostPort, String lbPolicy, @Nullable Message ringHashLbConfig, boolean enableLrs,
|
||||
|
|
@ -2280,7 +2394,7 @@ public abstract class ClientXdsClientTestBase {
|
|||
protected abstract Message buildRingHashLbConfig(String hashFunction, long minRingSize,
|
||||
long maxRingSize);
|
||||
|
||||
protected abstract Message buildUpstreamTlsContext(String secretName, String targetUri);
|
||||
protected abstract Message buildUpstreamTlsContext(String instanceName, String certName);
|
||||
|
||||
protected abstract Message buildCircuitBreakers(int highPriorityMaxRequests,
|
||||
int defaultPriorityMaxRequests);
|
||||
|
|
@ -2305,7 +2419,8 @@ public abstract class ClientXdsClientTestBase {
|
|||
protected abstract Message buildDropOverload(String category, int dropPerMillion);
|
||||
|
||||
protected abstract Message buildFilterChain(
|
||||
List<String> alpn, Message tlsContext, Message... filters);
|
||||
List<String> alpn, Message tlsContext, String transportSocketName,
|
||||
Message... filters);
|
||||
|
||||
protected abstract Message buildListenerWithFilterChain(
|
||||
String name, int portValue, String address, Message... filterChains);
|
||||
|
|
|
|||
|
|
@ -393,7 +393,8 @@ public class ClientXdsClientV2Test extends ClientXdsClientTestBase {
|
|||
@Override
|
||||
protected Message buildEdsCluster(String clusterName, @Nullable String edsServiceName,
|
||||
String lbPolicy, @Nullable Message ringHashLbConfig, boolean enableLrs,
|
||||
@Nullable Message upstreamTlsContext, @Nullable Message circuitBreakers) {
|
||||
@Nullable Message upstreamTlsContext, String transportSocketName,
|
||||
@Nullable Message circuitBreakers) {
|
||||
Cluster.Builder builder = initClusterBuilder(clusterName, lbPolicy, ringHashLbConfig,
|
||||
enableLrs, upstreamTlsContext, circuitBreakers);
|
||||
builder.setType(DiscoveryType.EDS);
|
||||
|
|
@ -493,10 +494,10 @@ public class ClientXdsClientV2Test extends ClientXdsClientTestBase {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected Message buildUpstreamTlsContext(String secretName, String targetUri) {
|
||||
protected Message buildUpstreamTlsContext(String instanceName, String certName) {
|
||||
GrpcService grpcService =
|
||||
GrpcService.newBuilder()
|
||||
.setGoogleGrpc(GoogleGrpc.newBuilder().setTargetUri(targetUri))
|
||||
.setGoogleGrpc(GoogleGrpc.newBuilder().setTargetUri(certName))
|
||||
.build();
|
||||
ConfigSource sdsConfig =
|
||||
ConfigSource.newBuilder()
|
||||
|
|
@ -504,7 +505,7 @@ public class ClientXdsClientV2Test extends ClientXdsClientTestBase {
|
|||
.build();
|
||||
SdsSecretConfig validationContextSdsSecretConfig =
|
||||
SdsSecretConfig.newBuilder()
|
||||
.setName(secretName)
|
||||
.setName(instanceName)
|
||||
.setSdsConfig(sdsConfig)
|
||||
.build();
|
||||
return UpstreamTlsContext.newBuilder()
|
||||
|
|
@ -618,7 +619,8 @@ public class ClientXdsClientV2Test extends ClientXdsClientTestBase {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected Message buildFilterChain(List<String> alpn, Message tlsContext, Message... filters) {
|
||||
protected Message buildFilterChain(List<String> alpn, Message tlsContext,
|
||||
String transportSocketName, Message... filters) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,10 +42,7 @@ import io.envoyproxy.envoy.config.cluster.v3.Cluster.RingHashLbConfig;
|
|||
import io.envoyproxy.envoy.config.cluster.v3.Cluster.RingHashLbConfig.HashFunction;
|
||||
import io.envoyproxy.envoy.config.core.v3.Address;
|
||||
import io.envoyproxy.envoy.config.core.v3.AggregatedConfigSource;
|
||||
import io.envoyproxy.envoy.config.core.v3.ApiConfigSource;
|
||||
import io.envoyproxy.envoy.config.core.v3.ConfigSource;
|
||||
import io.envoyproxy.envoy.config.core.v3.GrpcService;
|
||||
import io.envoyproxy.envoy.config.core.v3.GrpcService.GoogleGrpc;
|
||||
import io.envoyproxy.envoy.config.core.v3.HealthStatus;
|
||||
import io.envoyproxy.envoy.config.core.v3.Locality;
|
||||
import io.envoyproxy.envoy.config.core.v3.Node;
|
||||
|
|
@ -81,7 +78,6 @@ import io.envoyproxy.envoy.extensions.filters.network.http_connection_manager.v3
|
|||
import io.envoyproxy.envoy.extensions.filters.network.http_connection_manager.v3.HttpFilter;
|
||||
import io.envoyproxy.envoy.extensions.filters.network.http_connection_manager.v3.Rds;
|
||||
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.CommonTlsContext;
|
||||
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.SdsSecretConfig;
|
||||
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext;
|
||||
import io.envoyproxy.envoy.service.discovery.v3.AggregatedDiscoveryServiceGrpc.AggregatedDiscoveryServiceImplBase;
|
||||
import io.envoyproxy.envoy.service.discovery.v3.DiscoveryRequest;
|
||||
|
|
@ -437,9 +433,10 @@ public class ClientXdsClientV3Test extends ClientXdsClientTestBase {
|
|||
@Override
|
||||
protected Message buildEdsCluster(String clusterName, @Nullable String edsServiceName,
|
||||
String lbPolicy, @Nullable Message ringHashLbConfig, boolean enableLrs,
|
||||
@Nullable Message upstreamTlsContext, @Nullable Message circuitBreakers) {
|
||||
@Nullable Message upstreamTlsContext, String transportSocketName,
|
||||
@Nullable Message circuitBreakers) {
|
||||
Cluster.Builder builder = initClusterBuilder(clusterName, lbPolicy, ringHashLbConfig,
|
||||
enableLrs, upstreamTlsContext, circuitBreakers);
|
||||
enableLrs, upstreamTlsContext, transportSocketName, circuitBreakers);
|
||||
builder.setType(DiscoveryType.EDS);
|
||||
EdsClusterConfig.Builder edsClusterConfigBuilder = EdsClusterConfig.newBuilder();
|
||||
edsClusterConfigBuilder.setEdsConfig(
|
||||
|
|
@ -456,7 +453,7 @@ public class ClientXdsClientV3Test extends ClientXdsClientTestBase {
|
|||
int dnsHostPort, String lbPolicy, @Nullable Message ringHashLbConfig, boolean enableLrs,
|
||||
@Nullable Message upstreamTlsContext, @Nullable Message circuitBreakers) {
|
||||
Cluster.Builder builder = initClusterBuilder(clusterName, lbPolicy, ringHashLbConfig,
|
||||
enableLrs, upstreamTlsContext, circuitBreakers);
|
||||
enableLrs, upstreamTlsContext, "envoy.transport_sockets.tls", circuitBreakers);
|
||||
builder.setType(DiscoveryType.LOGICAL_DNS);
|
||||
builder.setLoadAssignment(
|
||||
ClusterLoadAssignment.newBuilder().addEndpoints(
|
||||
|
|
@ -492,7 +489,8 @@ public class ClientXdsClientV3Test extends ClientXdsClientTestBase {
|
|||
|
||||
private Cluster.Builder initClusterBuilder(String clusterName, String lbPolicy,
|
||||
@Nullable Message ringHashLbConfig, boolean enableLrs,
|
||||
@Nullable Message upstreamTlsContext, @Nullable Message circuitBreakers) {
|
||||
@Nullable Message upstreamTlsContext, String transportSocketName,
|
||||
@Nullable Message circuitBreakers) {
|
||||
Cluster.Builder builder = Cluster.newBuilder();
|
||||
builder.setName(clusterName);
|
||||
if (lbPolicy.equals("round_robin")) {
|
||||
|
|
@ -511,7 +509,7 @@ public class ClientXdsClientV3Test extends ClientXdsClientTestBase {
|
|||
if (upstreamTlsContext != null) {
|
||||
builder.setTransportSocket(
|
||||
TransportSocket.newBuilder()
|
||||
.setName("envoy.transport_sockets.tls")
|
||||
.setName(transportSocketName)
|
||||
.setTypedConfig(Any.pack(upstreamTlsContext)));
|
||||
}
|
||||
if (circuitBreakers != null) {
|
||||
|
|
@ -537,24 +535,22 @@ public class ClientXdsClientV3Test extends ClientXdsClientTestBase {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected Message buildUpstreamTlsContext(String secretName, String targetUri) {
|
||||
GrpcService grpcService =
|
||||
GrpcService.newBuilder()
|
||||
.setGoogleGrpc(GoogleGrpc.newBuilder().setTargetUri(targetUri))
|
||||
.build();
|
||||
ConfigSource sdsConfig =
|
||||
ConfigSource.newBuilder()
|
||||
.setApiConfigSource(ApiConfigSource.newBuilder().addGrpcServices(grpcService))
|
||||
.build();
|
||||
SdsSecretConfig validationContextSdsSecretConfig =
|
||||
SdsSecretConfig.newBuilder()
|
||||
.setName(secretName)
|
||||
.setSdsConfig(sdsConfig)
|
||||
.build();
|
||||
protected Message buildUpstreamTlsContext(String instanceName, String certName) {
|
||||
CommonTlsContext.Builder commonTlsContextBuilder = CommonTlsContext.newBuilder();
|
||||
if (instanceName != null && certName != null) {
|
||||
CommonTlsContext.CertificateProviderInstance providerInstance =
|
||||
CommonTlsContext.CertificateProviderInstance.newBuilder()
|
||||
.setInstanceName(instanceName)
|
||||
.setCertificateName(certName)
|
||||
.build();
|
||||
CommonTlsContext.CombinedCertificateValidationContext combined =
|
||||
CommonTlsContext.CombinedCertificateValidationContext.newBuilder()
|
||||
.setValidationContextCertificateProviderInstance(providerInstance)
|
||||
.build();
|
||||
commonTlsContextBuilder.setCombinedValidationContext(combined);
|
||||
}
|
||||
return UpstreamTlsContext.newBuilder()
|
||||
.setCommonTlsContext(
|
||||
CommonTlsContext.newBuilder()
|
||||
.setValidationContextSdsSecretConfig(validationContextSdsSecretConfig))
|
||||
.setCommonTlsContext(commonTlsContextBuilder)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
|
@ -664,7 +660,8 @@ public class ClientXdsClientV3Test extends ClientXdsClientTestBase {
|
|||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
protected FilterChain buildFilterChain(
|
||||
List<String> alpn, Message tlsContext, Message... filters) {
|
||||
List<String> alpn, Message tlsContext, String transportSocketName,
|
||||
Message... filters) {
|
||||
FilterChainMatch filterChainMatch =
|
||||
FilterChainMatch.newBuilder().addAllApplicationProtocols(alpn).build();
|
||||
Filter[] filterArray = new Filter[filters.length];
|
||||
|
|
@ -677,7 +674,7 @@ public class ClientXdsClientV3Test extends ClientXdsClientTestBase {
|
|||
tlsContext == null
|
||||
? TransportSocket.getDefaultInstance()
|
||||
: TransportSocket.newBuilder()
|
||||
.setName("envoy.transport_sockets.tls")
|
||||
.setName(transportSocketName)
|
||||
.setTypedConfig(Any.pack(tlsContext))
|
||||
.build())
|
||||
.addAllFilters(Arrays.asList(filterArray))
|
||||
|
|
|
|||
|
|
@ -84,12 +84,14 @@ public class CommonTlsContextTestsUtil {
|
|||
: CertificateValidationContext.newBuilder()
|
||||
.addAllMatchSubjectAltNames(matchSubjectAltNames)
|
||||
.build();
|
||||
if (validationCertificateProviderInstance != null && certValidationContext != null) {
|
||||
if (validationCertificateProviderInstance != null) {
|
||||
CombinedCertificateValidationContext.Builder combinedBuilder =
|
||||
CombinedCertificateValidationContext.newBuilder()
|
||||
.setDefaultValidationContext(certValidationContext)
|
||||
.setValidationContextCertificateProviderInstance(
|
||||
validationCertificateProviderInstance);
|
||||
if (certValidationContext != null) {
|
||||
combinedBuilder = combinedBuilder.setDefaultValidationContext(certValidationContext);
|
||||
}
|
||||
builder.setCombinedValidationContext(combinedBuilder);
|
||||
} else if (validationCertificateProviderInstance != null) {
|
||||
builder
|
||||
|
|
@ -106,12 +108,14 @@ public class CommonTlsContextTestsUtil {
|
|||
/** Helper method to build DownstreamTlsContext for multiple test classes. */
|
||||
static DownstreamTlsContext buildDownstreamTlsContext(
|
||||
CommonTlsContext commonTlsContext, boolean requireClientCert) {
|
||||
DownstreamTlsContext downstreamTlsContext =
|
||||
DownstreamTlsContext.Builder downstreamTlsContextBuilder =
|
||||
DownstreamTlsContext.newBuilder()
|
||||
.setCommonTlsContext(commonTlsContext)
|
||||
.setRequireClientCertificate(BoolValue.of(requireClientCert))
|
||||
.build();
|
||||
return downstreamTlsContext;
|
||||
.setRequireClientCertificate(BoolValue.of(requireClientCert));
|
||||
if (commonTlsContext != null) {
|
||||
downstreamTlsContextBuilder = downstreamTlsContextBuilder
|
||||
.setCommonTlsContext(commonTlsContext);
|
||||
}
|
||||
return downstreamTlsContextBuilder.build();
|
||||
}
|
||||
|
||||
/** Helper method to build DownstreamTlsContext for multiple test classes. */
|
||||
|
|
@ -137,23 +141,25 @@ public class CommonTlsContextTestsUtil {
|
|||
|
||||
/** Helper method for creating DownstreamTlsContext values with names. */
|
||||
public static DownstreamTlsContext buildTestDownstreamTlsContext(
|
||||
String certName, String validationContextCertName) {
|
||||
return buildDownstreamTlsContext(
|
||||
buildCommonTlsContextWithAdditionalValues(
|
||||
"cert-instance-name", certName,
|
||||
"val-cert-instance-name", validationContextCertName,
|
||||
Arrays.asList(
|
||||
StringMatcher.newBuilder()
|
||||
.setExact("spiffe://grpc-sds-testing.svc.id.goog/ns/default/sa/bob")
|
||||
.build()),
|
||||
Arrays.asList("managed-tls")),
|
||||
/* requireClientCert= */ false);
|
||||
String certName, String validationContextCertName, boolean useSans) {
|
||||
CommonTlsContext commonTlsContext = null;
|
||||
if (certName != null || validationContextCertName != null || useSans) {
|
||||
commonTlsContext = buildCommonTlsContextWithAdditionalValues(
|
||||
"cert-instance-name", certName,
|
||||
"val-cert-instance-name", validationContextCertName,
|
||||
useSans ? Arrays.asList(
|
||||
StringMatcher.newBuilder()
|
||||
.setExact("spiffe://grpc-sds-testing.svc.id.goog/ns/default/sa/bob")
|
||||
.build()) : null,
|
||||
Arrays.asList("managed-tls"));
|
||||
}
|
||||
return buildDownstreamTlsContext(commonTlsContext, /* requireClientCert= */ false);
|
||||
}
|
||||
|
||||
public static EnvoyServerProtoData.DownstreamTlsContext buildTestInternalDownstreamTlsContext(
|
||||
String certName, String validationContextName) {
|
||||
return EnvoyServerProtoData.DownstreamTlsContext.fromEnvoyProtoDownstreamTlsContext(
|
||||
buildTestDownstreamTlsContext(certName, validationContextName));
|
||||
buildTestDownstreamTlsContext(certName, validationContextName, true));
|
||||
}
|
||||
|
||||
public static String getTempFileNameForResourcesFile(String resFile) throws IOException {
|
||||
|
|
|
|||
Loading…
Reference in New Issue