mirror of https://github.com/grpc/grpc-go.git
xdsclient: read bootstrap config before creating the first xDS client in DefaultPool (#8164)
This commit is contained in:
parent
1f6b0cff02
commit
c27e6dc312
|
@ -113,19 +113,7 @@ func init() {
|
|||
internal.TriggerXDSResourceNotFoundForTesting = triggerXDSResourceNotFoundForTesting
|
||||
xdsclientinternal.ResourceWatchStateForTesting = resourceWatchStateForTesting
|
||||
|
||||
// DefaultPool is initialized with bootstrap configuration from one of the
|
||||
// supported environment variables. If the environment variables are not
|
||||
// set, then fallback bootstrap configuration should be set before
|
||||
// attempting to create an xDS client, else xDS client creation will fail.
|
||||
config, err := bootstrap.GetConfiguration()
|
||||
if err != nil {
|
||||
if logger.V(2) {
|
||||
logger.Infof("Failed to read xDS bootstrap config from env vars: %v", err)
|
||||
}
|
||||
DefaultPool = &Pool{clients: make(map[string]*clientRefCounted)}
|
||||
return
|
||||
}
|
||||
DefaultPool = &Pool{clients: make(map[string]*clientRefCounted), config: config}
|
||||
DefaultPool = &Pool{clients: make(map[string]*clientRefCounted)}
|
||||
}
|
||||
|
||||
// newClientImpl returns a new xdsClient with the given config.
|
||||
|
|
|
@ -220,7 +220,25 @@ func (p *Pool) newRefCounted(name string, watchExpiryTimeout time.Duration, stre
|
|||
defer p.mu.Unlock()
|
||||
|
||||
if p.config == nil {
|
||||
return nil, nil, fmt.Errorf("xds: bootstrap configuration not set in the pool")
|
||||
if len(p.clients) != 0 || p != DefaultPool {
|
||||
// If the current pool `p` already contains xDS clients or it is not
|
||||
// the `DefaultPool`, the bootstrap config should have been already
|
||||
// present in the pool.
|
||||
return nil, nil, fmt.Errorf("xds: bootstrap configuration not set in the pool")
|
||||
}
|
||||
// If the current pool `p` is the `DefaultPool` and has no clients, it
|
||||
// might be the first time an xDS client is being created on it. So,
|
||||
// the bootstrap configuration is read from environment variables.
|
||||
//
|
||||
// DefaultPool is initialized with bootstrap configuration from one of the
|
||||
// supported environment variables. If the environment variables are not
|
||||
// set, then fallback bootstrap configuration should be set before
|
||||
// attempting to create an xDS client, else xDS client creation will fail.
|
||||
config, err := bootstrap.GetConfiguration()
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("xds: failed to read xDS bootstrap config from env vars: %v", err)
|
||||
}
|
||||
p.config = config
|
||||
}
|
||||
|
||||
if c := p.clients[name]; c != nil {
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2025 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package pool_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"google.golang.org/grpc/internal/grpctest"
|
||||
"google.golang.org/grpc/internal/testutils"
|
||||
"google.golang.org/grpc/internal/testutils/stats"
|
||||
"google.golang.org/grpc/internal/xds/bootstrap"
|
||||
"google.golang.org/grpc/xds/internal/xdsclient"
|
||||
)
|
||||
|
||||
type s struct {
|
||||
grpctest.Tester
|
||||
}
|
||||
|
||||
func Test(t *testing.T) {
|
||||
grpctest.RunSubTests(t, s{})
|
||||
}
|
||||
|
||||
// TestDefaultPool_LazyLoadBootstrapConfig verifies that the DefaultPool
|
||||
// lazily loads the bootstrap configuration from environment variables when
|
||||
// an xDS client is created for the first time.
|
||||
//
|
||||
// If tries to create the new client in DefaultPool at the start of test when
|
||||
// none of the env vars are set. This should fail.
|
||||
//
|
||||
// Then it sets the env var XDSBootstrapFileName and retry creating a client
|
||||
// in DefaultPool. This should succeed.
|
||||
func (s) TestDefaultPool_LazyLoadBootstrapConfig(t *testing.T) {
|
||||
_, closeFunc, err := xdsclient.DefaultPool.NewClient(t.Name(), &stats.NoopMetricsRecorder{})
|
||||
if err == nil {
|
||||
t.Fatalf("xdsclient.DefaultPool.NewClient() succeeded without setting bootstrap config env vars, want failure")
|
||||
}
|
||||
|
||||
bs, err := bootstrap.NewContentsForTesting(bootstrap.ConfigOptionsForTesting{
|
||||
Servers: []byte(fmt.Sprintf(`[{
|
||||
"server_uri": %q,
|
||||
"channel_creds": [{"type": "insecure"}]
|
||||
}]`, "non-existent-management-server")),
|
||||
Node: []byte(fmt.Sprintf(`{"id": "%s"}`, uuid.New().String())),
|
||||
CertificateProviders: map[string]json.RawMessage{
|
||||
"cert-provider-instance": json.RawMessage("{}"),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create bootstrap configuration: %v", err)
|
||||
}
|
||||
|
||||
testutils.CreateBootstrapFileForTesting(t, bs)
|
||||
if cfg := xdsclient.DefaultPool.BootstrapConfigForTesting(); cfg != nil {
|
||||
t.Fatalf("DefaultPool.BootstrapConfigForTesting() = %v, want nil", cfg)
|
||||
}
|
||||
|
||||
_, closeFunc, err = xdsclient.DefaultPool.NewClient(t.Name(), &stats.NoopMetricsRecorder{})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create xDS client: %v", err)
|
||||
}
|
||||
defer func() {
|
||||
closeFunc()
|
||||
xdsclient.DefaultPool.UnsetBootstrapConfigForTesting()
|
||||
}()
|
||||
|
||||
if xdsclient.DefaultPool.BootstrapConfigForTesting() == nil {
|
||||
t.Fatalf("DefaultPool.BootstrapConfigForTesting() = nil, want non-nil")
|
||||
}
|
||||
}
|
|
@ -178,7 +178,7 @@ func (s) TestNewServer_Failure(t *testing.T) {
|
|||
{
|
||||
desc: "bootstrap env var not set",
|
||||
serverOpts: []grpc.ServerOption{grpc.Creds(xdsCreds), BootstrapContentsForTesting(nil)},
|
||||
wantErr: "bootstrap configuration not set in the pool",
|
||||
wantErr: "failed to read xDS bootstrap config from env vars",
|
||||
},
|
||||
{
|
||||
desc: "empty bootstrap config",
|
||||
|
|
Loading…
Reference in New Issue