diff --git a/encoding/proto/proto.go b/encoding/proto/proto.go index e1230fdd358..3009b35afe7 100644 --- a/encoding/proto/proto.go +++ b/encoding/proto/proto.go @@ -21,6 +21,8 @@ package proto import ( + "fmt" + "github.com/golang/protobuf/proto" "google.golang.org/grpc/encoding" ) @@ -36,11 +38,19 @@ func init() { type codec struct{} func (codec) Marshal(v interface{}) ([]byte, error) { - return proto.Marshal(v.(proto.Message)) + vv, ok := v.(proto.Message) + if !ok { + return nil, fmt.Errorf("failed to marshal, message is %T, want proto.Message", v) + } + return proto.Marshal(vv) } func (codec) Unmarshal(data []byte, v interface{}) error { - return proto.Unmarshal(data, v.(proto.Message)) + vv, ok := v.(proto.Message) + if !ok { + return fmt.Errorf("failed to unmarshal, message is %T, want proto.Message", v) + } + return proto.Unmarshal(data, vv) } func (codec) Name() string { diff --git a/vet.sh b/vet.sh index b41df6dc860..4012b051d8d 100755 --- a/vet.sh +++ b/vet.sh @@ -28,7 +28,7 @@ cleanup() { } trap cleanup EXIT -PATH="${GOPATH}/bin:${GOROOT}/bin:${PATH}" +PATH="${HOME}/go/bin:${GOROOT}/bin:${PATH}" if [[ "$1" = "-install" ]]; then # Check for module support diff --git a/xds/internal/client/client_cds_test.go b/xds/internal/client/client_cds_test.go index 5d2366d6488..56fa679db01 100644 --- a/xds/internal/client/client_cds_test.go +++ b/xds/internal/client/client_cds_test.go @@ -223,7 +223,65 @@ func (s) TestValidateCluster_Success(t *testing.T) { } } +func (s) TestValidateClusterWithSecurityConfig_EnvVarOff(t *testing.T) { + // Turn off the env var protection for client-side security. + origClientSideSecurityEnvVar := env.ClientSideSecuritySupport + env.ClientSideSecuritySupport = false + defer func() { env.ClientSideSecuritySupport = origClientSideSecurityEnvVar }() + + cluster := &v3clusterpb.Cluster{ + ClusterDiscoveryType: &v3clusterpb.Cluster_Type{Type: v3clusterpb.Cluster_EDS}, + EdsClusterConfig: &v3clusterpb.Cluster_EdsClusterConfig{ + EdsConfig: &v3corepb.ConfigSource{ + ConfigSourceSpecifier: &v3corepb.ConfigSource_Ads{ + Ads: &v3corepb.AggregatedConfigSource{}, + }, + }, + ServiceName: serviceName, + }, + LbPolicy: v3clusterpb.Cluster_ROUND_ROBIN, + TransportSocket: &v3corepb.TransportSocket{ + Name: "envoy.transport_sockets.tls", + ConfigType: &v3corepb.TransportSocket_TypedConfig{ + TypedConfig: &anypb.Any{ + TypeUrl: version.V3UpstreamTLSContextURL, + Value: func() []byte { + tls := &v3tlspb.UpstreamTlsContext{ + CommonTlsContext: &v3tlspb.CommonTlsContext{ + ValidationContextType: &v3tlspb.CommonTlsContext_ValidationContextCertificateProviderInstance{ + ValidationContextCertificateProviderInstance: &v3tlspb.CommonTlsContext_CertificateProviderInstance{ + InstanceName: "rootInstance", + CertificateName: "rootCert", + }, + }, + }, + } + mtls, _ := proto.Marshal(tls) + return mtls + }(), + }, + }, + }, + } + wantUpdate := ClusterUpdate{ + ServiceName: serviceName, + EnableLRS: false, + } + gotUpdate, err := validateCluster(cluster) + if err != nil { + t.Errorf("validateCluster() failed: %v", err) + } + if diff := cmp.Diff(wantUpdate, gotUpdate); diff != "" { + t.Errorf("validateCluster() returned unexpected diff (-want, got):\n%s", diff) + } +} + func (s) TestValidateClusterWithSecurityConfig(t *testing.T) { + // Turn on the env var protection for client-side security. + origClientSideSecurityEnvVar := env.ClientSideSecuritySupport + env.ClientSideSecuritySupport = true + defer func() { env.ClientSideSecuritySupport = origClientSideSecurityEnvVar }() + const ( identityPluginInstance = "identityPluginInstance" identityCertName = "identityCert" diff --git a/xds/internal/client/client_xds.go b/xds/internal/client/client_xds.go index e2a008200a6..a292442a0a1 100644 --- a/xds/internal/client/client_xds.go +++ b/xds/internal/client/client_xds.go @@ -410,10 +410,16 @@ func validateCluster(cluster *v3clusterpb.Cluster) (ClusterUpdate, error) { return emptyUpdate, fmt.Errorf("xds: unexpected lbPolicy %v in response: %+v", cluster.GetLbPolicy(), cluster) } - sc, err := securityConfigFromCluster(cluster) - if err != nil { - return emptyUpdate, err + // Process security configuration received from the control plane iff the + // corresponding environment variable is set. + var sc *SecurityConfig + if env.ClientSideSecuritySupport { + var err error + if sc, err = securityConfigFromCluster(cluster); err != nil { + return emptyUpdate, err + } } + return ClusterUpdate{ ServiceName: cluster.GetEdsClusterConfig().GetServiceName(), EnableLRS: cluster.GetLrsServer().GetSelf() != nil, diff --git a/xds/internal/env/env.go b/xds/internal/env/env.go index c4b46bae171..3b28912587b 100644 --- a/xds/internal/env/env.go +++ b/xds/internal/env/env.go @@ -26,10 +26,11 @@ import ( ) const ( - bootstrapFileNameEnv = "GRPC_XDS_BOOTSTRAP" - xdsV3SupportEnv = "GRPC_XDS_EXPERIMENTAL_V3_SUPPORT" - circuitBreakingSupportEnv = "GRPC_XDS_EXPERIMENTAL_CIRCUIT_BREAKING" - timeoutSupportEnv = "GRPC_XDS_EXPERIMENTAL_ENABLE_TIMEOUT" + bootstrapFileNameEnv = "GRPC_XDS_BOOTSTRAP" + xdsV3SupportEnv = "GRPC_XDS_EXPERIMENTAL_V3_SUPPORT" + circuitBreakingSupportEnv = "GRPC_XDS_EXPERIMENTAL_CIRCUIT_BREAKING" + timeoutSupportEnv = "GRPC_XDS_EXPERIMENTAL_ENABLE_TIMEOUT" + clientSideSecuritySupportEnv = "GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT" ) var ( @@ -49,4 +50,11 @@ var ( // route actions is enabled. This can be enabled by setting the // environment variable "GRPC_XDS_EXPERIMENTAL_ENABLE_TIMEOUT" to "true". TimeoutSupport = strings.EqualFold(os.Getenv(timeoutSupportEnv), "true") + // ClientSideSecuritySupport is used to control processing of security + // configuration on the client-side. + // + // Note that there is no env var protection for the server-side because we + // have a brand new API on the server-side and users explicitly need to use + // the new API to get security integration on the server. + ClientSideSecuritySupport = strings.EqualFold(os.Getenv(clientSideSecuritySupportEnv), "true") )