Enable xDS credentials (#424)

* Enable xDS credentials

This change should be relatively straightforward. It is a noop outside of the
context of xDS (as demonstrated by the fact that the tests all pass), but it
enables xDS-provided certificates (i.e. the ones that would be
provided/specified in GRPC_XDS_BOOTSTRAP). See proposal
[A29](https://github.com/grpc/proposal/blob/master/A29-xds-tls-security.md#go)
for additional detail.

* Only enable xds credentials if the target is an xDS target

* Update after merge
This commit is contained in:
Paul Chesnais 2024-02-12 13:49:16 -05:00 committed by GitHub
parent 184c8f70b5
commit 5592211a41
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 21 additions and 11 deletions

View File

@ -28,6 +28,7 @@ import (
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials"
"google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/credentials/insecure"
xdsCredentials "google.golang.org/grpc/credentials/xds"
"google.golang.org/grpc/metadata" "google.golang.org/grpc/metadata"
protov2 "google.golang.org/protobuf/proto" protov2 "google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/descriptorpb" "google.golang.org/protobuf/types/descriptorpb"
@ -609,6 +610,21 @@ func ServerTransportCredentials(cacertFile, serverCertFile, serverKeyFile string
// and blocking until the returned connection is ready. If the given credentials are nil, the // and blocking until the returned connection is ready. If the given credentials are nil, the
// connection will be insecure (plain-text). // connection will be insecure (plain-text).
func BlockingDial(ctx context.Context, network, address string, creds credentials.TransportCredentials, opts ...grpc.DialOption) (*grpc.ClientConn, error) { func BlockingDial(ctx context.Context, network, address string, creds credentials.TransportCredentials, opts ...grpc.DialOption) (*grpc.ClientConn, error) {
if creds == nil {
creds = insecure.NewCredentials()
}
var err error
if strings.HasPrefix(address, "xds:///") {
// The xds:/// prefix is used to signal to the gRPC client to use an xDS server to resolve the
// target. The relevant credentials will be automatically pulled from the GRPC_XDS_BOOTSTRAP or
// GRPC_XDS_BOOTSTRAP_CONFIG env vars.
creds, err = xdsCredentials.NewClientCredentials(xdsCredentials.ClientOptions{FallbackCreds: creds})
if err != nil {
return nil, err
}
}
// grpc.Dial doesn't provide any information on permanent connection errors (like // grpc.Dial doesn't provide any information on permanent connection errors (like
// TLS handshake failures). So in order to provide good error messages, we need a // TLS handshake failures). So in order to provide good error messages, we need a
// custom dialer that can provide that info. That means we manage the TLS handshake. // custom dialer that can provide that info. That means we manage the TLS handshake.
@ -624,12 +640,11 @@ func BlockingDial(ctx context.Context, network, address string, creds credential
// custom credentials and dialer will notify on error via the // custom credentials and dialer will notify on error via the
// writeResult function // writeResult function
if creds != nil {
creds = &errSignalingCreds{ creds = &errSignalingCreds{
TransportCredentials: creds, TransportCredentials: creds,
writeResult: writeResult, writeResult: writeResult,
} }
}
dialer := func(ctx context.Context, address string) (net.Conn, error) { dialer := func(ctx context.Context, address string) (net.Conn, error) {
// NB: We *could* handle the TLS handshake ourselves, in the custom // NB: We *could* handle the TLS handshake ourselves, in the custom
// dialer (instead of customizing both the dialer and the credentials). // dialer (instead of customizing both the dialer and the credentials).
@ -655,13 +670,8 @@ func BlockingDial(ctx context.Context, network, address string, creds credential
opts = append([]grpc.DialOption{grpc.FailOnNonTempDialError(true)}, opts...) opts = append([]grpc.DialOption{grpc.FailOnNonTempDialError(true)}, opts...)
// But we don't want caller to be able to override these two, so we put // But we don't want caller to be able to override these two, so we put
// them *after* the explicitly provided options. // them *after* the explicitly provided options.
opts = append(opts, grpc.WithBlock(), grpc.WithContextDialer(dialer)) opts = append(opts, grpc.WithBlock(), grpc.WithContextDialer(dialer), grpc.WithTransportCredentials(creds))
if creds == nil {
opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials()))
} else {
opts = append(opts, grpc.WithTransportCredentials(creds))
}
conn, err := grpc.DialContext(ctx, address, opts...) conn, err := grpc.DialContext(ctx, address, opts...)
var res interface{} var res interface{}
if err != nil { if err != nil {