Skip to content

Commit f142fa1

Browse files
xds: Support deprecated tls_certificate_certificate_provider_instance field
Add backward compatibility for deprecated certificate provider field 11 (tls_certificate_certificate_provider_instance) by falling back to it when field 14 (tls_certificate_provider_instance) is not present. This matches the behavior of grpc-go and grpc-cpp, enabling compatibility with Istio which sends the deprecated field for backward compatibility with older Envoy versions. Amp-Thread-ID: https://ampcode.com/threads/T-a71beee4-6f09-48fb-a8f8-9f2e09c1623f Co-authored-by: Amp <amp@ampcode.com>
1 parent 6da93db commit f142fa1

File tree

5 files changed

+107
-2
lines changed

5 files changed

+107
-2
lines changed

xds/src/main/java/io/grpc/xds/XdsClusterResource.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,12 @@ private static String getIdentityCertInstanceName(CommonTlsContext commonTlsCont
541541
if (commonTlsContext.hasTlsCertificateProviderInstance()) {
542542
return commonTlsContext.getTlsCertificateProviderInstance().getInstanceName();
543543
}
544-
return null;
544+
// Fall back to deprecated field (field 11) for backward compatibility with Istio
545+
@SuppressWarnings("deprecation")
546+
String instanceName = commonTlsContext.hasTlsCertificateCertificateProviderInstance()
547+
? commonTlsContext.getTlsCertificateCertificateProviderInstance().getInstanceName()
548+
: null;
549+
return instanceName;
545550
}
546551

547552
private static String getRootCertInstanceName(CommonTlsContext commonTlsContext) {

xds/src/main/java/io/grpc/xds/internal/security/CommonTlsContextUtil.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ public static boolean hasCertProviderInstance(CommonTlsContext commonTlsContext)
2828
if (commonTlsContext == null) {
2929
return false;
3030
}
31+
@SuppressWarnings("deprecation")
32+
boolean hasDeprecatedField = commonTlsContext.hasTlsCertificateCertificateProviderInstance();
3133
return commonTlsContext.hasTlsCertificateProviderInstance()
34+
|| hasDeprecatedField
3235
|| hasValidationProviderInstance(commonTlsContext);
3336
}
3437

@@ -53,6 +56,18 @@ public static CommonTlsContext.CertificateProviderInstance convert(
5356
.setCertificateName(pluginInstance.getCertificateName()).build();
5457
}
5558

59+
/**
60+
* Converts deprecated {@link CommonTlsContext.CertificateProviderInstance} (field 11) to
61+
* internal {@link CommonTlsContext.CertificateProviderInstance}.
62+
* This supports a deprecated field for backward compatibility (primarily for Istio)
63+
*/
64+
public static CommonTlsContext.CertificateProviderInstance convertDeprecated(
65+
CommonTlsContext.CertificateProviderInstance deprecatedInstance) {
66+
return CommonTlsContext.CertificateProviderInstance.newBuilder()
67+
.setInstanceName(deprecatedInstance.getInstanceName())
68+
.setCertificateName(deprecatedInstance.getCertificateName()).build();
69+
}
70+
5671
public static boolean isUsingSystemRootCerts(CommonTlsContext commonTlsContext) {
5772
if (commonTlsContext.hasCombinedValidationContext()) {
5873
return commonTlsContext.getCombinedValidationContext().getDefaultValidationContext()

xds/src/main/java/io/grpc/xds/internal/security/certprovider/CertProviderSslContextProvider.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,14 @@ protected static CertificateProviderInstance getCertProviderInstance(
113113
if (commonTlsContext.hasTlsCertificateProviderInstance()) {
114114
return CommonTlsContextUtil.convert(commonTlsContext.getTlsCertificateProviderInstance());
115115
}
116-
return null;
116+
// Fall back to deprecated field for backward compatibility with Istio
117+
@SuppressWarnings("deprecation")
118+
CertificateProviderInstance deprecatedInstance =
119+
commonTlsContext.hasTlsCertificateCertificateProviderInstance()
120+
? CommonTlsContextUtil.convertDeprecated(
121+
commonTlsContext.getTlsCertificateCertificateProviderInstance())
122+
: null;
123+
return deprecatedInstance;
117124
}
118125

119126
@Nullable

xds/src/test/java/io/grpc/xds/internal/security/CommonTlsContextTestsUtil.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,32 @@ private static CommonTlsContext buildCommonTlsContextForCertProviderInstance(
232232
return builder.build();
233233
}
234234

235+
/** Helper method to build CommonTlsContext using deprecated certificate provider field. */
236+
public static CommonTlsContext buildCommonTlsContextWithDeprecatedCertProviderInstance(
237+
String certInstanceName,
238+
String certName,
239+
String rootInstanceName,
240+
String rootCertName,
241+
Iterable<String> alpnProtocols,
242+
CertificateValidationContext staticCertValidationContext) {
243+
CommonTlsContext.Builder builder = CommonTlsContext.newBuilder();
244+
if (certInstanceName != null) {
245+
// Use deprecated field (field 11) instead of current field (field 14)
246+
builder =
247+
builder.setTlsCertificateCertificateProviderInstance(
248+
CommonTlsContext.CertificateProviderInstance.newBuilder()
249+
.setInstanceName(certInstanceName)
250+
.setCertificateName(certName));
251+
}
252+
builder =
253+
addCertificateValidationContext(
254+
builder, rootInstanceName, rootCertName, staticCertValidationContext);
255+
if (alpnProtocols != null) {
256+
builder.addAllAlpnProtocols(alpnProtocols);
257+
}
258+
return builder.build();
259+
}
260+
235261
private static CommonTlsContext buildNewCommonTlsContextForCertProviderInstance(
236262
String certInstanceName,
237263
String certName,

xds/src/test/java/io/grpc/xds/internal/security/certprovider/CertProviderClientSslContextProviderTest.java

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,58 @@ public void testProviderForClient_rootInstanceNull_but_isUsingSystemRootCerts_va
470470
.build(), false);
471471
}
472472

473+
@Test
474+
public void testProviderForClient_deprecatedCertProviderField() throws Exception {
475+
final CertificateProvider.DistributorWatcher[] watcherCaptor =
476+
new CertificateProvider.DistributorWatcher[1];
477+
TestCertificateProvider.createAndRegisterProviderProvider(
478+
certificateProviderRegistry, watcherCaptor, "testca", 0);
479+
480+
// Build UpstreamTlsContext using deprecated field
481+
EnvoyServerProtoData.UpstreamTlsContext upstreamTlsContext =
482+
new EnvoyServerProtoData.UpstreamTlsContext(
483+
CommonTlsContextTestsUtil.buildCommonTlsContextWithDeprecatedCertProviderInstance(
484+
"gcp_id",
485+
"cert-default",
486+
"gcp_id",
487+
"root-default",
488+
/* alpnProtocols= */ null,
489+
/* staticCertValidationContext= */ null));
490+
491+
Bootstrapper.BootstrapInfo bootstrapInfo = CommonBootstrapperTestUtils.getTestBootstrapInfo();
492+
CertProviderClientSslContextProvider provider =
493+
(CertProviderClientSslContextProvider)
494+
certProviderClientSslContextProviderFactory.getProvider(
495+
upstreamTlsContext,
496+
bootstrapInfo.node().toEnvoyProtoNode(),
497+
bootstrapInfo.certProviders());
498+
499+
assertThat(provider.savedKey).isNull();
500+
assertThat(provider.savedCertChain).isNull();
501+
assertThat(provider.savedTrustedRoots).isNull();
502+
assertThat(provider.getSslContextAndTrustManager()).isNull();
503+
504+
// Generate cert update
505+
watcherCaptor[0].updateCertificate(
506+
CommonCertProviderTestUtils.getPrivateKey(CLIENT_KEY_FILE),
507+
ImmutableList.of(getCertFromResourceName(CLIENT_PEM_FILE)));
508+
assertThat(provider.savedKey).isNotNull();
509+
assertThat(provider.savedCertChain).isNotNull();
510+
assertThat(provider.getSslContextAndTrustManager()).isNull();
511+
512+
// Generate root cert update
513+
watcherCaptor[0].updateTrustedRoots(ImmutableList.of(getCertFromResourceName(CA_PEM_FILE)));
514+
assertThat(provider.getSslContextAndTrustManager()).isNotNull();
515+
assertThat(provider.savedKey).isNull();
516+
assertThat(provider.savedCertChain).isNull();
517+
assertThat(provider.savedTrustedRoots).isNull();
518+
519+
TestCallback testCallback =
520+
CommonTlsContextTestsUtil.getValueThruCallback(provider);
521+
522+
doChecksOnSslContext(false, testCallback.updatedSslContext, /* expectedApnProtos= */ null);
523+
}
524+
473525
static class QueuedExecutor implements Executor {
474526
/** A list of Runnables to be run in order. */
475527
@VisibleForTesting final Queue<Runnable> runQueue = new ConcurrentLinkedQueue<>();

0 commit comments

Comments
 (0)