Repository: grpc/grpc-go
File: internal/xds/bootstrap/bootstrap.go (Go)

Code before:

// The following fields correspond 1:1 with the JSON schema for ServerConfig.
type serverConfigJSON struct {
	ServerURI      string         `json:"server_uri,omitempty"`
	ChannelCreds   []ChannelCreds `json:"channel_creds,omitempty"`
	ServerFeatures []string       `json:"server_features,omitempty"`
}

// MarshalJSON returns marshaled JSON bytes corresponding to this server config.
func (sc *ServerConfig) MarshalJSON() ([]byte, error) {
	server := &serverConfigJSON{
		ServerURI:      sc.serverURI,
		ChannelCreds:   sc.channelCreds,
		ServerFeatures: sc.serverFeatures,
	}
	return json.Marshal(server)
}

// dialer captures the Dialer method specified via the credentials bundle.
// Deprecated and to be deleted. Use extradDialOptions which takes precedence over this.
type dialer interface {
	// Dialer specifies how to dial the xDS server.
	Dialer(context.Context, string) (net.Conn, error)
}

// extraDialOptions captures custom dial options specified via the credentials bundle.
type extraDialOptions interface {
	DialOptions() []grpc.DialOption
}

// UnmarshalJSON takes the json data (a server) and unmarshals it to the struct.
func (sc *ServerConfig) UnmarshalJSON(data []byte) error {
	server := serverConfigJSON{}
	if err := json.Unmarshal(data, &server); err != nil {
		return fmt.Errorf("xds: failed to JSON unmarshal server configuration during bootstrap: %v, config:\n%s", err, string(data))
	}

	sc.serverURI = server.ServerURI
	sc.channelCreds = server.ChannelCreds
	sc.serverFeatures = server.ServerFeatures

	for _, cc := range server.ChannelCreds {
		// We stop at the first credential type that we support.
		c := bootstrap.GetCredentials(cc.Type)
		if c == nil {
			continue
		}
		bundle, cancel, err := c.Build(cc.Config)
		if err != nil {
			return fmt.Errorf("failed to build credentials bundle from bootstrap for %q: %v", cc.Type, err)
		}

Review comment (security):
dial options can be anything right? like `WithStatsHandler`, `WithContextDialer` etc.? I think `WithContextDialer` will be specified via credentials bundle?

Code after:
type serverConfigJSON struct {
	ServerURI      string         `json:"server_uri,omitempty"`
	ChannelCreds   []ChannelCreds `json:"channel_creds,omitempty"`
	ServerFeatures []string       `json:"server_features,omitempty"`
}

// MarshalJSON returns marshaled JSON bytes corresponding to this server config.
func (sc *ServerConfig) MarshalJSON() ([]byte, error) {
	server := &serverConfigJSON{
		ServerURI:      sc.serverURI,
		ChannelCreds:   sc.channelCreds,
		ServerFeatures: sc.serverFeatures,
	}
	return json.Marshal(server)
}

// dialer captures the Dialer method specified via the credentials bundle.
// Deprecated: use extradDialOptions. Will take precedence over this.
type dialer interface {
	// Dialer specifies how to dial the xDS server.
	Dialer(context.Context, string) (net.Conn, error)
}

// extraDialOptions captures custom dial options specified via
// credentials.Bundle.
type extraDialOptions interface {
	DialOptions() []grpc.DialOption
}

// UnmarshalJSON takes the json data (a server) and unmarshals it to the struct.
func (sc *ServerConfig) UnmarshalJSON(data []byte) error {
	server := serverConfigJSON{}
	if err := json.Unmarshal(data, &server); err != nil {
		return fmt.Errorf("xds: failed to JSON unmarshal server configuration during bootstrap: %v, config:\n%s", err, string(data))
	}

	sc.serverURI = server.ServerURI
	sc.channelCreds = server.ChannelCreds
	sc.serverFeatures = server.ServerFeatures

	for _, cc := range server.ChannelCreds {
		// We stop at the first credential type that we support.
		c := bootstrap.GetCredentials(cc.Type)
		if c == nil {
			continue
		}
		bundle, cancel, err := c.Build(cc.Config)
		if err != nil {
			return fmt.Errorf("failed to build credentials bundle from bootstrap for %q: %v", cc.Type, err)
		}
		sc.selectedCreds = cc