@@ -35,12 +35,15 @@ import (
3535 "google.golang.org/grpc/codes"
3636 estats "google.golang.org/grpc/experimental/stats"
3737 "google.golang.org/grpc/internal"
38+ "google.golang.org/grpc/internal/envconfig"
3839 iresolver "google.golang.org/grpc/internal/resolver"
3940 iringhash "google.golang.org/grpc/internal/ringhash"
4041 "google.golang.org/grpc/internal/testutils"
4142 "google.golang.org/grpc/internal/testutils/xds/e2e"
43+ "google.golang.org/grpc/internal/xds/balancer/clusterimpl"
4244 "google.golang.org/grpc/internal/xds/balancer/clustermanager"
4345 "google.golang.org/grpc/internal/xds/bootstrap"
46+ serverFeature "google.golang.org/grpc/internal/xds/clients/xdsclient"
4447 rinternal "google.golang.org/grpc/internal/xds/resolver/internal"
4548 "google.golang.org/grpc/internal/xds/xdsclient"
4649 "google.golang.org/grpc/internal/xds/xdsclient/xdsresource/version"
@@ -1297,3 +1300,153 @@ func (s) TestConfigSelector_FailureCases(t *testing.T) {
12971300func newDurationP (d time.Duration ) * time.Duration {
12981301 return & d
12991302}
1303+
1304+ // TestResolver_AutoHostRewrite verifies the propagation of the AutoHostRewrite
1305+ // field from the xDS resolver.
1306+ //
1307+ // Per gRFC A81, this feature should only be active if two conditions met:
1308+ // 1. The environment variable (XDSAuthorityRewrite) is enabled.
1309+ // 2. The xDS server is marked as "trusted_xds_server" in the bootstrap config.
1310+ func (s ) TestResolver_AutoHostRewrite (t * testing.T ) {
1311+ for _ , tt := range []struct {
1312+ name string
1313+ autoHostRewrite bool
1314+ envconfig bool
1315+ serverfeature serverFeature.ServerFeature
1316+ wantAutoHostRewrite bool
1317+ }{
1318+ {
1319+ name : "EnvVarDisabled_NonTrustedServer_AutoHostRewriteOff" ,
1320+ autoHostRewrite : false ,
1321+ envconfig : false ,
1322+ wantAutoHostRewrite : false ,
1323+ },
1324+ {
1325+ name : "EnvVarDisabled_NonTrustedServer_AutoHostRewriteOn" ,
1326+ autoHostRewrite : true ,
1327+ envconfig : false ,
1328+ wantAutoHostRewrite : false ,
1329+ },
1330+ {
1331+ name : "EnvVarDisabled_TrustedServer_AutoHostRewriteOff" ,
1332+ autoHostRewrite : false ,
1333+ envconfig : false ,
1334+ serverfeature : serverFeature .ServerFeatureTrustedXDSServer ,
1335+ wantAutoHostRewrite : false ,
1336+ },
1337+ {
1338+ name : "EnvVarDisabled_TrustedServer_AutoHostRewriteOn" ,
1339+ autoHostRewrite : true ,
1340+ envconfig : false ,
1341+ serverfeature : serverFeature .ServerFeatureTrustedXDSServer ,
1342+ wantAutoHostRewrite : false ,
1343+ },
1344+ {
1345+ name : "EnvVarEnabled_NonTrustedServer_AutoHostRewriteOff" ,
1346+ autoHostRewrite : false ,
1347+ envconfig : true ,
1348+ wantAutoHostRewrite : false ,
1349+ },
1350+ {
1351+ name : "EnvVarEnabled_NonTrustedServer_AutoHostRewriteOn" ,
1352+ autoHostRewrite : true ,
1353+ envconfig : true ,
1354+ wantAutoHostRewrite : false ,
1355+ },
1356+ {
1357+ name : "EnvVarEnabled_TrustedServer_AutoHostRewriteOff" ,
1358+ autoHostRewrite : false ,
1359+ envconfig : true ,
1360+ serverfeature : serverFeature .ServerFeatureTrustedXDSServer ,
1361+ wantAutoHostRewrite : false ,
1362+ },
1363+ {
1364+ name : "EnvVarEnabled_TrustedServer_AutoHostRewriteOn" ,
1365+ autoHostRewrite : true ,
1366+ envconfig : true ,
1367+ serverfeature : serverFeature .ServerFeatureTrustedXDSServer ,
1368+ wantAutoHostRewrite : true ,
1369+ },
1370+ } {
1371+ t .Run (tt .name , func (t * testing.T ) {
1372+ testutils .SetEnvConfig (t , & envconfig .XDSAuthorityRewrite , tt .envconfig )
1373+
1374+ // Spin up an xDS management server for the test.
1375+ ctx , cancel := context .WithTimeout (context .Background (), defaultTestTimeout )
1376+ defer cancel ()
1377+ nodeID := uuid .New ().String ()
1378+ mgmtServer := e2e .StartManagementServer (t , e2e.ManagementServerOptions {AllowResourceSubset : true })
1379+ defer mgmtServer .Stop ()
1380+
1381+ // Configure the management server with a good listener resource and a
1382+ // route configuration resource, as specified by the test case.
1383+ resources := e2e.UpdateOptions {
1384+ NodeID : nodeID ,
1385+ Listeners : []* v3listenerpb.Listener {e2e .DefaultClientListener (defaultTestServiceName , defaultTestRouteConfigName )},
1386+ Routes : []* v3routepb.RouteConfiguration {{
1387+ Name : defaultTestRouteConfigName ,
1388+ VirtualHosts : []* v3routepb.VirtualHost {{
1389+ Domains : []string {defaultTestServiceName },
1390+ Routes : []* v3routepb.Route {{
1391+ Match : & v3routepb.RouteMatch {PathSpecifier : & v3routepb.RouteMatch_Prefix {Prefix : "/" }},
1392+ Action : & v3routepb.Route_Route {Route : & v3routepb.RouteAction {
1393+ ClusterSpecifier : & v3routepb.RouteAction_WeightedClusters {WeightedClusters : & v3routepb.WeightedCluster {
1394+ Clusters : []* v3routepb.WeightedCluster_ClusterWeight {
1395+ {
1396+ Name : defaultTestClusterName ,
1397+ Weight : & wrapperspb.UInt32Value {Value : 100 },
1398+ },
1399+ },
1400+ }},
1401+ HostRewriteSpecifier : & v3routepb.RouteAction_AutoHostRewrite {
1402+ AutoHostRewrite : & wrapperspb.BoolValue {Value : tt .autoHostRewrite },
1403+ },
1404+ }},
1405+ }},
1406+ }},
1407+ }},
1408+ SkipValidation : true ,
1409+ }
1410+
1411+ if err := mgmtServer .Update (ctx , resources ); err != nil {
1412+ t .Fatal (err )
1413+ }
1414+
1415+ trustedXdsServer := "[]"
1416+ if tt .serverfeature == serverFeature .ServerFeatureTrustedXDSServer {
1417+ trustedXdsServer = `["trusted_xds_server"]`
1418+ }
1419+
1420+ opts := bootstrap.ConfigOptionsForTesting {
1421+ Servers : []byte (fmt .Sprintf (`[{
1422+ "server_uri": %q,
1423+ "channel_creds": [{"type": "insecure"}],
1424+ "server_features": %s
1425+ }]` , mgmtServer .Address , trustedXdsServer )),
1426+ Node : []byte (fmt .Sprintf (`{"id": "%s"}` , nodeID )),
1427+ }
1428+
1429+ contents , err := bootstrap .NewContentsForTesting (opts )
1430+ if err != nil {
1431+ t .Fatalf ("Failed to create bootstrap configuration: %v" , err )
1432+ }
1433+
1434+ // Build the resolver and read the config selector out of it.
1435+ stateCh , _ , _ := buildResolverForTarget (t , resolver.Target {URL : * testutils .MustParseURL ("xds:///" + defaultTestServiceName )}, contents )
1436+ cs := verifyUpdateFromResolver (ctx , t , stateCh , "" )
1437+
1438+ res , err := cs .SelectConfig (iresolver.RPCInfo {
1439+ Context : ctx ,
1440+ Method : "/service/method" ,
1441+ })
1442+ if err != nil {
1443+ t .Fatalf ("cs.SelectConfig(): %v" , err )
1444+ }
1445+
1446+ gotAutoHostRewrite := clusterimpl .AutoHostRewriteForTesting (res .Context )
1447+ if gotAutoHostRewrite != tt .wantAutoHostRewrite {
1448+ t .Fatalf ("Got autoHostRewrite: %v, want: %v" , gotAutoHostRewrite , tt .wantAutoHostRewrite )
1449+ }
1450+ })
1451+ }
1452+ }
0 commit comments