diff --git a/agent/consul/discoverychain/compile.go b/agent/consul/discoverychain/compile.go index 95efc1753031..0e94a87e5668 100644 --- a/agent/consul/discoverychain/compile.go +++ b/agent/consul/discoverychain/compile.go @@ -821,6 +821,14 @@ RESOLVE_AGAIN: // If using external SNI the service is fundamentally external. if target.External { + if resolver.Redirect != nil { + return nil, &structs.ConfigEntryGraphError{ + Message: fmt.Sprintf( + "service %q has an external SNI set; cannot define redirects for external services", + target.Service, + ), + } + } if len(resolver.Subsets) > 0 { return nil, &structs.ConfigEntryGraphError{ Message: fmt.Sprintf( diff --git a/agent/consul/discoverychain/compile_test.go b/agent/consul/discoverychain/compile_test.go index f808943f5e1e..ee68c405c16b 100644 --- a/agent/consul/discoverychain/compile_test.go +++ b/agent/consul/discoverychain/compile_test.go @@ -64,6 +64,7 @@ func TestCompile(t *testing.T) { "redirect to missing subset": testcase_RedirectToMissingSubset(), "resolver with failover and external sni": testcase_Resolver_ExternalSNI_FailoverNotAllowed(), "resolver with subsets and external sni": testcase_Resolver_ExternalSNI_SubsetsNotAllowed(), + "resolver with redirect and external sni": testcase_Resolver_ExternalSNI_RedirectNotAllowed(), // overrides "resolver with protocol from override": testcase_ResolverProtocolOverride(), @@ -1518,6 +1519,29 @@ func testcase_Resolver_ExternalSNI_SubsetsNotAllowed() compileTestCase { } } +func testcase_Resolver_ExternalSNI_RedirectNotAllowed() compileTestCase { + entries := newEntries() + entries.AddServices(&structs.ServiceConfigEntry{ + Kind: structs.ServiceDefaults, + Name: "main", + ExternalSNI: "main.some.other.service.mesh", + }) + entries.AddResolvers(&structs.ServiceResolverConfigEntry{ + Kind: "service-resolver", + Name: "main", + ConnectTimeout: 33 * time.Second, + Redirect: &structs.ServiceResolverRedirect{ + Datacenter: "dc2", + }, + }) + + return compileTestCase{ + entries: entries, + expectErr: `service "main" has an external SNI set; cannot define redirects for external services`, + expectGraphErr: true, + } +} + func testcase_MultiDatacenterCanary() compileTestCase { entries := newEntries() setServiceProtocol(entries, "main", "http")