@@ -84,6 +84,39 @@ func (cc ChannelCreds) String() string {
8484 return cc .Type + "-" + string (b )
8585}
8686
87+ // ServerConfigs represents a collection of server configurations.
88+ type ServerConfigs []* ServerConfig
89+
90+ // Equal returns true if scs equals other.
91+ func (scs * ServerConfigs ) Equal (other * ServerConfigs ) bool {
92+ if len (* scs ) != len (* other ) {
93+ return false
94+ }
95+ for i := range * scs {
96+ if ! (* scs )[i ].Equal ((* other )[i ]) {
97+ return false
98+ }
99+ }
100+ return true
101+ }
102+
103+ // UnmarshalJSON takes the json data (a list of server configurations) and
104+ // unmarshals it to the struct.
105+ func (scs * ServerConfigs ) UnmarshalJSON (data []byte ) error {
106+ servers := []* ServerConfig {}
107+ if err := json .Unmarshal (data , & servers ); err != nil {
108+ return fmt .Errorf ("xds: failed to JSON unmarshal server configurations during bootstrap: %v, config:\n %s" , err , string (data ))
109+ }
110+ // Only use the first server config if fallback support is disabled.
111+ if ! envconfig .XDSFallbackSupport {
112+ if len (servers ) > 1 {
113+ servers = servers [:1 ]
114+ }
115+ }
116+ * scs = servers
117+ return nil
118+ }
119+
87120// Authority contains configuration for an xDS control plane authority.
88121//
89122// This type does not implement custom JSON marshal/unmarshal logic because it
@@ -104,7 +137,7 @@ type Authority struct {
104137 // "xdstp://<authority_name>/envoy.config.listener.v3.Listener/%s".
105138 ClientListenerResourceNameTemplate string `json:"client_listener_resource_name_template,omitempty"`
106139 // XDSServers contains the list of server configurations for this authority.
107- XDSServers [] * ServerConfig `json:"xds_servers,omitempty"`
140+ XDSServers ServerConfigs `json:"xds_servers,omitempty"`
108141}
109142
110143// Equal returns true if a equals other.
@@ -116,7 +149,7 @@ func (a *Authority) Equal(other *Authority) bool {
116149 return false
117150 case a .ClientListenerResourceNameTemplate != other .ClientListenerResourceNameTemplate :
118151 return false
119- case ! slices . EqualFunc ( a .XDSServers , other . XDSServers , func ( a , b * ServerConfig ) bool { return a . Equal (b ) } ):
152+ case ! a .XDSServers . Equal (& other . XDSServers ):
120153 return false
121154 }
122155 return true
@@ -315,7 +348,7 @@ func ServerConfigForTesting(opts ServerConfigTestingOptions) (*ServerConfig, err
315348// Config is the internal representation of the bootstrap configuration provided
316349// to the xDS client.
317350type Config struct {
318- xDSServers [] * ServerConfig
351+ xDSServers ServerConfigs
319352 cpcs map [string ]certproviderNameAndConfig
320353 serverListenerResourceNameTemplate string
321354 clientDefaultListenerResourceNameTemplate string
@@ -405,7 +438,7 @@ func (c *Config) Equal(other *Config) bool {
405438 return true
406439 case (c != nil ) != (other != nil ):
407440 return false
408- case ! slices . EqualFunc ( c .xDSServers , other . xDSServers , func ( a , b * ServerConfig ) bool { return a . Equal (b ) } ):
441+ case ! c .xDSServers . Equal (& other . xDSServers ):
409442 return false
410443 case ! maps .EqualFunc (c .certProviderConfigs , other .certProviderConfigs , func (a , b * certprovider.BuildableConfig ) bool { return a .String () == b .String () }):
411444 return false
@@ -429,7 +462,7 @@ func (c *Config) String() string {
429462
430463// The following fields correspond 1:1 with the JSON schema for Config.
431464type configJSON struct {
432- XDSServers [] * ServerConfig `json:"xds_servers,omitempty"`
465+ XDSServers ServerConfigs `json:"xds_servers,omitempty"`
433466 CertificateProviders map [string ]certproviderNameAndConfig `json:"certificate_providers,omitempty"`
434467 ServerListenerResourceNameTemplate string `json:"server_listener_resource_name_template,omitempty"`
435468 ClientDefaultListenerResourceNameTemplate string `json:"client_default_listener_resource_name_template,omitempty"`
0 commit comments