[API Gateway] Fix use of virtual resolvers in HTTPRoutes (#17055)
* [API Gateway] Fix use of virtual resolvers in routes * Add changelog entry
This commit is contained in:
parent
ae28875d55
commit
62b2aee20d
|
@ -0,0 +1,3 @@
|
||||||
|
```release-note:bug
|
||||||
|
gateways: Fix an bug where targeting a virtual service defined by a service-resolver was broken for HTTPRoutes.
|
||||||
|
```
|
|
@ -249,6 +249,13 @@ func targetForResolverNode(nodeName string, chains []*structs.CompiledDiscoveryC
|
||||||
splitterName := splitterPrefix + strings.TrimPrefix(nodeName, resolverPrefix)
|
splitterName := splitterPrefix + strings.TrimPrefix(nodeName, resolverPrefix)
|
||||||
|
|
||||||
for _, c := range chains {
|
for _, c := range chains {
|
||||||
|
targetChainPrefix := resolverPrefix + c.ServiceName + "."
|
||||||
|
if strings.HasPrefix(nodeName, targetChainPrefix) && len(c.Nodes) == 1 {
|
||||||
|
// we have a virtual resolver that just maps to another resolver, return
|
||||||
|
// the given node name
|
||||||
|
return c.StartNode
|
||||||
|
}
|
||||||
|
|
||||||
for name, node := range c.Nodes {
|
for name, node := range c.Nodes {
|
||||||
if node.IsSplitter() && strings.HasPrefix(splitterName, name) {
|
if node.IsSplitter() && strings.HasPrefix(splitterName, name) {
|
||||||
return name
|
return name
|
||||||
|
|
|
@ -599,6 +599,118 @@ func TestGatewayChainSynthesizer_Synthesize(t *testing.T) {
|
||||||
},
|
},
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
|
"HTTPRoute with virtual resolver": {
|
||||||
|
synthesizer: NewGatewayChainSynthesizer("dc1", "domain", "suffix", &structs.APIGatewayConfigEntry{
|
||||||
|
Kind: structs.APIGateway,
|
||||||
|
Name: "gateway",
|
||||||
|
}),
|
||||||
|
httpRoutes: []*structs.HTTPRouteConfigEntry{
|
||||||
|
{
|
||||||
|
Kind: structs.HTTPRoute,
|
||||||
|
Name: "http-route",
|
||||||
|
Rules: []structs.HTTPRouteRule{{
|
||||||
|
Services: []structs.HTTPService{{
|
||||||
|
Name: "foo",
|
||||||
|
}},
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
chain: &structs.CompiledDiscoveryChain{
|
||||||
|
ServiceName: "foo",
|
||||||
|
Namespace: "default",
|
||||||
|
Datacenter: "dc1",
|
||||||
|
StartNode: "resolver:foo-2.default.default.dc2",
|
||||||
|
Nodes: map[string]*structs.DiscoveryGraphNode{
|
||||||
|
"resolver:foo-2.default.default.dc2": {
|
||||||
|
Type: "resolver",
|
||||||
|
Name: "foo-2.default.default.dc2",
|
||||||
|
Resolver: &structs.DiscoveryResolver{
|
||||||
|
Target: "foo-2.default.default.dc2",
|
||||||
|
Default: true,
|
||||||
|
ConnectTimeout: 5000000000,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
extra: []*structs.CompiledDiscoveryChain{},
|
||||||
|
expectedIngressServices: []structs.IngressService{{
|
||||||
|
Name: "gateway-suffix-9b9265b",
|
||||||
|
Hosts: []string{"*"},
|
||||||
|
}},
|
||||||
|
expectedDiscoveryChains: []*structs.CompiledDiscoveryChain{{
|
||||||
|
ServiceName: "gateway-suffix-9b9265b",
|
||||||
|
Partition: "default",
|
||||||
|
Namespace: "default",
|
||||||
|
Datacenter: "dc1",
|
||||||
|
Protocol: "http",
|
||||||
|
StartNode: "router:gateway-suffix-9b9265b.default.default",
|
||||||
|
Nodes: map[string]*structs.DiscoveryGraphNode{
|
||||||
|
"router:gateway-suffix-9b9265b.default.default": {
|
||||||
|
Type: "router",
|
||||||
|
Name: "gateway-suffix-9b9265b.default.default",
|
||||||
|
Routes: []*structs.DiscoveryRoute{{
|
||||||
|
Definition: &structs.ServiceRoute{
|
||||||
|
Match: &structs.ServiceRouteMatch{
|
||||||
|
HTTP: &structs.ServiceRouteHTTPMatch{
|
||||||
|
PathPrefix: "/",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Destination: &structs.ServiceRouteDestination{
|
||||||
|
Service: "foo",
|
||||||
|
Partition: "default",
|
||||||
|
Namespace: "default",
|
||||||
|
RequestHeaders: &structs.HTTPHeaderModifiers{
|
||||||
|
Add: make(map[string]string),
|
||||||
|
Set: make(map[string]string),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
NextNode: "resolver:foo-2.default.default.dc2",
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
"resolver:foo.default.default.dc1": {
|
||||||
|
Type: "resolver",
|
||||||
|
Name: "foo.default.default.dc1",
|
||||||
|
Resolver: &structs.DiscoveryResolver{
|
||||||
|
Target: "foo.default.default.dc1",
|
||||||
|
Default: true,
|
||||||
|
ConnectTimeout: 5000000000,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"resolver:foo-2.default.default.dc2": {
|
||||||
|
Type: "resolver",
|
||||||
|
Name: "foo-2.default.default.dc2",
|
||||||
|
Resolver: &structs.DiscoveryResolver{
|
||||||
|
Target: "foo-2.default.default.dc2",
|
||||||
|
Default: true,
|
||||||
|
ConnectTimeout: 5000000000,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Targets: map[string]*structs.DiscoveryTarget{
|
||||||
|
"gateway-suffix-9b9265b.default.default.dc1": {
|
||||||
|
ID: "gateway-suffix-9b9265b.default.default.dc1",
|
||||||
|
Service: "gateway-suffix-9b9265b",
|
||||||
|
Datacenter: "dc1",
|
||||||
|
Partition: "default",
|
||||||
|
Namespace: "default",
|
||||||
|
ConnectTimeout: 5000000000,
|
||||||
|
SNI: "gateway-suffix-9b9265b.default.dc1.internal.domain",
|
||||||
|
Name: "gateway-suffix-9b9265b.default.dc1.internal.domain",
|
||||||
|
},
|
||||||
|
"foo.default.default.dc1": {
|
||||||
|
ID: "foo.default.default.dc1",
|
||||||
|
Service: "foo",
|
||||||
|
Datacenter: "dc1",
|
||||||
|
Partition: "default",
|
||||||
|
Namespace: "default",
|
||||||
|
ConnectTimeout: 5000000000,
|
||||||
|
SNI: "foo.default.dc1.internal.domain",
|
||||||
|
Name: "foo.default.dc1.internal.domain",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for name, tc := range cases {
|
for name, tc := range cases {
|
||||||
|
|
Loading…
Reference in New Issue