diff --git a/xds/googledirectpath/googlec2p.go b/xds/googledirectpath/googlec2p.go index 02b1add4cc0b..e842aaceded0 100644 --- a/xds/googledirectpath/googlec2p.go +++ b/xds/googledirectpath/googlec2p.go @@ -30,7 +30,6 @@ import ( "net/url" "time" - "google.golang.org/grpc" "google.golang.org/grpc/grpclog" "google.golang.org/grpc/internal/envconfig" "google.golang.org/grpc/internal/googlecloud" @@ -39,9 +38,6 @@ import ( "google.golang.org/grpc/resolver" "google.golang.org/grpc/xds/internal/xdsclient" "google.golang.org/grpc/xds/internal/xdsclient/bootstrap" - "google.golang.org/protobuf/types/known/structpb" - - v3corepb "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" _ "google.golang.org/grpc/xds" // To register xds resolvers and balancers. ) @@ -57,6 +53,7 @@ const ( gRPCUserAgentName = "gRPC Go" clientFeatureNoOverprovisioning = "envoy.lb.does_not_support_overprovisioning" + clientFeatureResourceWrapper = "xds.config.resource-in-sotw" ipv6CapableMetadataName = "TRAFFICDIRECTOR_DIRECTPATH_C2P_IPV6_CAPABLE" logPrefix = "[google-c2p-resolver]" @@ -102,30 +99,26 @@ func (c2pResolverBuilder) Build(t resolver.Target, cc resolver.ClientConn, opts go func() { zoneCh <- getZone(httpReqTimeout) }() go func() { ipv6CapableCh <- getIPv6Capable(httpReqTimeout) }() - balancerName := envconfig.C2PResolverTestOnlyTrafficDirectorURI - if balancerName == "" { - balancerName = tdURL + xdsServerURI := envconfig.C2PResolverTestOnlyTrafficDirectorURI + if xdsServerURI == "" { + xdsServerURI = tdURL } - serverConfig, err := bootstrap.ServerConfigFromJSON([]byte(fmt.Sprintf(` + + nodeCfg := newNodeConfig(<-zoneCh, <-ipv6CapableCh) + xdsServerCfg := newXdsServerConfig(xdsServerURI) + authoritiesCfg := newAuthoritiesConfig(xdsServerCfg) + + config, err := bootstrap.NewConfigFromContents([]byte(fmt.Sprintf(` { - "server_uri": "%s", - "channel_creds": [{"type": "google_default"}], - "server_features": ["xds_v3", "ignore_resource_deletion", "xds.config.resource-in-sotw"] - }`, balancerName))) + "xds_servers": [%s], + "client_default_listener_resource_name_template": "%%s", + "authorities": %s, + "node": %s + }`, xdsServerCfg, authoritiesCfg, nodeCfg))) + if err != nil { return nil, fmt.Errorf("failed to build bootstrap configuration: %v", err) } - config := &bootstrap.Config{ - XDSServer: serverConfig, - ClientDefaultListenerResourceNameTemplate: "%s", - Authorities: map[string]*bootstrap.Authority{ - c2pAuthority: { - XDSServer: serverConfig, - ClientListenerResourceNameTemplate: fmt.Sprintf("xdstp://%s/envoy.config.listener.v3.Listener/%%s", c2pAuthority), - }, - }, - NodeProto: newNode(<-zoneCh, <-ipv6CapableCh), - } // Create singleton xds client with this config. The xds client will be // used by the xds resolver later. @@ -166,30 +159,41 @@ func (r *c2pResolver) Close() { r.clientCloseFunc() } -var ipv6EnabledMetadata = &structpb.Struct{ - Fields: map[string]*structpb.Value{ - ipv6CapableMetadataName: structpb.NewBoolValue(true), - }, -} - var id = fmt.Sprintf("C2P-%d", grpcrand.Int()) -// newNode makes a copy of defaultNode, and populate it's Metadata and -// Locality fields. -func newNode(zone string, ipv6Capable bool) *v3corepb.Node { - ret := &v3corepb.Node{ - // Not all required fields are set in defaultNote. Metadata will be set - // if ipv6 is enabled. Locality will be set to the value from metadata. - Id: id, - UserAgentName: gRPCUserAgentName, - UserAgentVersionType: &v3corepb.Node_UserAgentVersion{UserAgentVersion: grpc.Version}, - ClientFeatures: []string{clientFeatureNoOverprovisioning}, - } - ret.Locality = &v3corepb.Locality{Zone: zone} +func newNodeConfig(zone string, ipv6Capable bool) string { + metadata := "" if ipv6Capable { - ret.Metadata = ipv6EnabledMetadata + metadata = fmt.Sprintf(`, "metadata": { "%s": true }`, ipv6CapableMetadataName) } - return ret + + return fmt.Sprintf(` + { + "id": "%s", + "locality": { + "zone": "%s" + } + %s + }`, id, zone, metadata) +} + +func newAuthoritiesConfig(xdsServer string) string { + return fmt.Sprintf(` + { + "%s": { + "xds_servers": [%s] + } + } + `, c2pAuthority, xdsServer) +} + +func newXdsServerConfig(xdsServerURI string) string { + return fmt.Sprintf(` + { + "server_uri": "%s", + "channel_creds": [{"type": "google_default"}], + "server_features": ["xds_v3", "ignore_resource_deletion", "xds.config.resource-in-sotw"] + }`, xdsServerURI) } // runDirectPath returns whether this resolver should use direct path. diff --git a/xds/googledirectpath/googlec2p_test.go b/xds/googledirectpath/googlec2p_test.go index a65d46a86375..da6cb87d1a5a 100644 --- a/xds/googledirectpath/googlec2p_test.go +++ b/xds/googledirectpath/googlec2p_test.go @@ -199,7 +199,7 @@ func TestBuildXDS(t *testing.T) { Locality: &v3corepb.Locality{Zone: testZone}, UserAgentName: gRPCUserAgentName, UserAgentVersionType: &v3corepb.Node_UserAgentVersion{UserAgentVersion: grpc.Version}, - ClientFeatures: []string{clientFeatureNoOverprovisioning}, + ClientFeatures: []string{clientFeatureNoOverprovisioning, clientFeatureResourceWrapper}, } if tt.ipv6 { wantNode.Metadata = &structpb.Struct{ diff --git a/xds/internal/xdsclient/bootstrap/bootstrap.go b/xds/internal/xdsclient/bootstrap/bootstrap.go index b4de5d513c1c..e27930357cfe 100644 --- a/xds/internal/xdsclient/bootstrap/bootstrap.go +++ b/xds/internal/xdsclient/bootstrap/bootstrap.go @@ -453,11 +453,9 @@ func NewConfig() (*Config, error) { return newConfigFromContents(data) } -// NewConfigFromContentsForTesting returns a new Config using the specified +// NewConfigFromContents returns a new Config using the specified // bootstrap file contents instead of reading the environment variable. -// -// This is only suitable for testing purposes. -func NewConfigFromContentsForTesting(data []byte) (*Config, error) { +func NewConfigFromContents(data []byte) (*Config, error) { return newConfigFromContents(data) } diff --git a/xds/internal/xdsclient/client_new.go b/xds/internal/xdsclient/client_new.go index 16c609fae280..4717983845d4 100644 --- a/xds/internal/xdsclient/client_new.go +++ b/xds/internal/xdsclient/client_new.go @@ -163,7 +163,7 @@ func getOrMakeClientForTesting(config []byte) (*clientRefCounted, error) { return c, nil } - bcfg, err := bootstrap.NewConfigFromContentsForTesting(config) + bcfg, err := bootstrap.NewConfigFromContents(config) if err != nil { return nil, fmt.Errorf("bootstrap config %s: %v", string(config), err) }