Skip to content

googlec2p: use the bootstrap parsing code to generate parsed bootstrap config instead of handcrafting it #7040

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Mar 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 47 additions & 43 deletions xds/googledirectpath/googlec2p.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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.
)
Expand All @@ -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]"
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion xds/googledirectpath/googlec2p_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand Down
6 changes: 2 additions & 4 deletions xds/internal/xdsclient/bootstrap/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down
2 changes: 1 addition & 1 deletion xds/internal/xdsclient/client_new.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down