xds: Modify return value of getClusterFromRouteConfiguration (#3534)
This commit is contained in:
@ -48,9 +48,9 @@ func (v2c *v2Client) handleRDSResponse(resp *xdspb.DiscoveryResponse) error {
|
|||||||
v2c.logger.Infof("Resource with name: %v, type: %T, contains: %v. Picking routes for current watching hostname %v", rc.GetName(), rc, rc, v2c.hostname)
|
v2c.logger.Infof("Resource with name: %v, type: %T, contains: %v. Picking routes for current watching hostname %v", rc.GetName(), rc, rc, v2c.hostname)
|
||||||
|
|
||||||
// Use the hostname (resourceName for LDS) to find the routes.
|
// Use the hostname (resourceName for LDS) to find the routes.
|
||||||
cluster := getClusterFromRouteConfiguration(rc, hostname)
|
cluster, err := getClusterFromRouteConfiguration(rc, hostname)
|
||||||
if cluster == "" {
|
if cluster == "" {
|
||||||
return fmt.Errorf("xds: received invalid RouteConfiguration in RDS response: %+v", rc)
|
return fmt.Errorf("xds: received invalid RouteConfiguration in RDS response: %+v with err: %v", rc, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we get here, it means that this resource was a good one.
|
// If we get here, it means that this resource was a good one.
|
||||||
@ -62,7 +62,8 @@ func (v2c *v2Client) handleRDSResponse(resp *xdspb.DiscoveryResponse) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// getClusterFromRouteConfiguration checks if the provided RouteConfiguration
|
// getClusterFromRouteConfiguration checks if the provided RouteConfiguration
|
||||||
// meets the expected criteria. If so, it returns a non-empty clusterName.
|
// meets the expected criteria. If so, it returns a non-empty clusterName with
|
||||||
|
// nil error.
|
||||||
//
|
//
|
||||||
// A RouteConfiguration resource is considered valid when only if it contains a
|
// A RouteConfiguration resource is considered valid when only if it contains a
|
||||||
// VirtualHost whose domain field matches the server name from the URI passed
|
// VirtualHost whose domain field matches the server name from the URI passed
|
||||||
@ -75,8 +76,7 @@ func (v2c *v2Client) handleRDSResponse(resp *xdspb.DiscoveryResponse) error {
|
|||||||
// only look at the last route in the list (the default route), whose match
|
// only look at the last route in the list (the default route), whose match
|
||||||
// field must be empty and whose route field must be set. Inside that route
|
// field must be empty and whose route field must be set. Inside that route
|
||||||
// message, the cluster field will contain the clusterName we are looking for.
|
// message, the cluster field will contain the clusterName we are looking for.
|
||||||
func getClusterFromRouteConfiguration(rc *xdspb.RouteConfiguration, host string) string {
|
func getClusterFromRouteConfiguration(rc *xdspb.RouteConfiguration, host string) (string, error) {
|
||||||
// TODO: return error for better error logging and nack.
|
|
||||||
//
|
//
|
||||||
// Currently this returns "" on error, and the caller will return an error.
|
// Currently this returns "" on error, and the caller will return an error.
|
||||||
// But the error doesn't contain details of why the response is invalid
|
// But the error doesn't contain details of why the response is invalid
|
||||||
@ -87,22 +87,22 @@ func getClusterFromRouteConfiguration(rc *xdspb.RouteConfiguration, host string)
|
|||||||
vh := findBestMatchingVirtualHost(host, rc.GetVirtualHosts())
|
vh := findBestMatchingVirtualHost(host, rc.GetVirtualHosts())
|
||||||
if vh == nil {
|
if vh == nil {
|
||||||
// No matching virtual host found.
|
// No matching virtual host found.
|
||||||
return ""
|
return "", fmt.Errorf("no matching virtual host found")
|
||||||
}
|
}
|
||||||
if len(vh.Routes) == 0 {
|
if len(vh.Routes) == 0 {
|
||||||
// The matched virtual host has no routes, this is invalid because there
|
// The matched virtual host has no routes, this is invalid because there
|
||||||
// should be at least one default route.
|
// should be at least one default route.
|
||||||
return ""
|
return "", fmt.Errorf("matched virtual host has no routes")
|
||||||
}
|
}
|
||||||
dr := vh.Routes[len(vh.Routes)-1]
|
dr := vh.Routes[len(vh.Routes)-1]
|
||||||
if match := dr.GetMatch(); match == nil || (match.GetPrefix() != "" && match.GetPrefix() != "/") {
|
if match := dr.GetMatch(); match == nil || (match.GetPrefix() != "" && match.GetPrefix() != "/") {
|
||||||
// The matched virtual host is invalid. Match is not "" or "/".
|
// The matched virtual host is invalid. Match is not "" or "/".
|
||||||
return ""
|
return "", fmt.Errorf("matched virtual host is invalid")
|
||||||
}
|
}
|
||||||
if route := dr.GetRoute(); route != nil {
|
if route := dr.GetRoute(); route != nil {
|
||||||
return route.GetCluster()
|
return route.GetCluster(), nil
|
||||||
}
|
}
|
||||||
return ""
|
return "", fmt.Errorf("matched route is nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
type domainMatchType int
|
type domainMatchType int
|
||||||
|
@ -34,16 +34,19 @@ func (s) TestRDSGetClusterFromRouteConfiguration(t *testing.T) {
|
|||||||
name string
|
name string
|
||||||
rc *xdspb.RouteConfiguration
|
rc *xdspb.RouteConfiguration
|
||||||
wantCluster string
|
wantCluster string
|
||||||
|
wantError bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "no-virtual-hosts-in-rc",
|
name: "no-virtual-hosts-in-rc",
|
||||||
rc: emptyRouteConfig,
|
rc: emptyRouteConfig,
|
||||||
wantCluster: "",
|
wantCluster: "",
|
||||||
|
wantError: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "no-domains-in-rc",
|
name: "no-domains-in-rc",
|
||||||
rc: noDomainsInRouteConfig,
|
rc: noDomainsInRouteConfig,
|
||||||
wantCluster: "",
|
wantCluster: "",
|
||||||
|
wantError: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "non-matching-domain-in-rc",
|
name: "non-matching-domain-in-rc",
|
||||||
@ -53,6 +56,7 @@ func (s) TestRDSGetClusterFromRouteConfiguration(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
wantCluster: "",
|
wantCluster: "",
|
||||||
|
wantError: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "no-routes-in-rc",
|
name: "no-routes-in-rc",
|
||||||
@ -62,6 +66,7 @@ func (s) TestRDSGetClusterFromRouteConfiguration(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
wantCluster: "",
|
wantCluster: "",
|
||||||
|
wantError: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "default-route-match-field-is-nil",
|
name: "default-route-match-field-is-nil",
|
||||||
@ -82,6 +87,7 @@ func (s) TestRDSGetClusterFromRouteConfiguration(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
wantCluster: "",
|
wantCluster: "",
|
||||||
|
wantError: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "default-route-match-field-is-non-nil",
|
name: "default-route-match-field-is-non-nil",
|
||||||
@ -99,6 +105,7 @@ func (s) TestRDSGetClusterFromRouteConfiguration(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
wantCluster: "",
|
wantCluster: "",
|
||||||
|
wantError: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "default-route-routeaction-field-is-nil",
|
name: "default-route-routeaction-field-is-nil",
|
||||||
@ -111,6 +118,7 @@ func (s) TestRDSGetClusterFromRouteConfiguration(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
wantCluster: "",
|
wantCluster: "",
|
||||||
|
wantError: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "default-route-cluster-field-is-empty",
|
name: "default-route-cluster-field-is-empty",
|
||||||
@ -131,11 +139,13 @@ func (s) TestRDSGetClusterFromRouteConfiguration(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
wantCluster: "",
|
wantCluster: "",
|
||||||
|
wantError: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "good-route-config-with-empty-string-route",
|
name: "good-route-config-with-empty-string-route",
|
||||||
rc: goodRouteConfig1,
|
rc: goodRouteConfig1,
|
||||||
wantCluster: goodClusterName1,
|
wantCluster: goodClusterName1,
|
||||||
|
wantError: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// default route's match is not empty string, but "/".
|
// default route's match is not empty string, but "/".
|
||||||
@ -156,7 +166,8 @@ func (s) TestRDSGetClusterFromRouteConfiguration(t *testing.T) {
|
|||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
if gotCluster := getClusterFromRouteConfiguration(test.rc, goodLDSTarget1); gotCluster != test.wantCluster {
|
gotCluster, gotError := getClusterFromRouteConfiguration(test.rc, goodLDSTarget1)
|
||||||
|
if gotCluster != test.wantCluster || (gotError != nil) != test.wantError {
|
||||||
t.Errorf("getClusterFromRouteConfiguration(%+v, %v) = %v, want %v", test.rc, goodLDSTarget1, gotCluster, test.wantCluster)
|
t.Errorf("getClusterFromRouteConfiguration(%+v, %v) = %v, want %v", test.rc, goodLDSTarget1, gotCluster, test.wantCluster)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
Reference in New Issue
Block a user