diff --git a/agent/consul/state/catalog.go b/agent/consul/state/catalog.go index b89f2c727e..ce40fda3e0 100644 --- a/agent/consul/state/catalog.go +++ b/agent/consul/state/catalog.go @@ -3757,14 +3757,15 @@ func terminatingConfigGatewayServices( return false, nil, fmt.Errorf("failed to get gateway service kind for service %s: %v", svc.Name, err) } mapping := &structs.GatewayService{ - Gateway: gateway, - Service: structs.NewServiceName(svc.Name, &svc.EnterpriseMeta), - GatewayKind: structs.ServiceKindTerminatingGateway, - KeyFile: svc.KeyFile, - CertFile: svc.CertFile, - CAFile: svc.CAFile, - SNI: svc.SNI, - ServiceKind: kind, + Gateway: gateway, + Service: structs.NewServiceName(svc.Name, &svc.EnterpriseMeta), + GatewayKind: structs.ServiceKindTerminatingGateway, + KeyFile: svc.KeyFile, + CertFile: svc.CertFile, + CAFile: svc.CAFile, + SNI: svc.SNI, + ServiceKind: kind, + AutoHostRewrite: !svc.DisableAutoHostRewrite, } gatewayServices = append(gatewayServices, mapping) diff --git a/agent/consul/state/catalog_test.go b/agent/consul/state/catalog_test.go index f18b9beae8..f85844909e 100644 --- a/agent/consul/state/catalog_test.go +++ b/agent/consul/state/catalog_test.go @@ -9089,3 +9089,43 @@ func assertDeepEqual(t *testing.T, x, y interface{}, opts ...cmp.Option) { t.Fatalf("assertion failed: values are not equal\n--- expected\n+++ actual\n%v", diff) } } + +func Test_terminatingConfigGatewayServices(t *testing.T) { + s := testConfigStateStore(t) + + cfg := &structs.TerminatingGatewayConfigEntry{ + Kind: structs.TerminatingGateway, + Name: "terminating-gateway", + Services: []structs.LinkedService{ + { + Name: "service-default-behavior", + }, + { + Name: "service-disabled-behavior", + DisableAutoHostRewrite: true, + }, + }, + } + + expected := structs.GatewayServices{ + &structs.GatewayService{ + Gateway: structs.ServiceName{Name: "terminating-gateway"}, + Service: structs.ServiceName{Name: "service-default-behavior"}, + GatewayKind: "terminating-gateway", + AutoHostRewrite: true, + }, + &structs.GatewayService{ + Gateway: structs.ServiceName{Name: "terminating-gateway"}, + Service: structs.ServiceName{Name: "service-disabled-behavior"}, + GatewayKind: "terminating-gateway", + AutoHostRewrite: false, + }, + } + + txn := s.db.Txn(false) + + _, services, err := terminatingConfigGatewayServices(txn, structs.ServiceName{Name: "terminating-gateway"}, cfg, nil) + require.NoError(t, err) + require.Equal(t, services, expected) + +} diff --git a/agent/proxycfg/snapshot.go b/agent/proxycfg/snapshot.go index 8f407c1afc..68769467df 100644 --- a/agent/proxycfg/snapshot.go +++ b/agent/proxycfg/snapshot.go @@ -220,6 +220,11 @@ type configSnapshotTerminatingGateway struct { // a service altogether we then cancel watching that service for its endpoints. WatchedServices map[structs.ServiceName]context.CancelFunc + // AutoHostRewriteServices is a map of service name to a bool that determines + // if the terminating gateway service should auto rewrite the host + // header before forwarding the request. + AutoHostRewriteServices map[structs.ServiceName]bool + // WatchedIntentions is a map of service name to a cancel function. // This cancel function is tied to the watch of intentions for linked services. // As with WatchedServices, intention watches will be cancelled when services diff --git a/agent/proxycfg/terminating_gateway.go b/agent/proxycfg/terminating_gateway.go index a465808390..a164c43419 100644 --- a/agent/proxycfg/terminating_gateway.go +++ b/agent/proxycfg/terminating_gateway.go @@ -57,6 +57,7 @@ func (s *handlerTerminatingGateway) initialize(ctx context.Context) (ConfigSnaps } snap.TerminatingGateway.WatchedServices = make(map[structs.ServiceName]context.CancelFunc) + snap.TerminatingGateway.AutoHostRewriteServices = make(map[structs.ServiceName]bool) snap.TerminatingGateway.WatchedIntentions = make(map[structs.ServiceName]context.CancelFunc) snap.TerminatingGateway.Intentions = make(map[structs.ServiceName]structs.SimplifiedIntentions) snap.TerminatingGateway.WatchedLeaves = make(map[structs.ServiceName]context.CancelFunc) diff --git a/agent/structs/config_entry_gateways.go b/agent/structs/config_entry_gateways.go index e3ccfbbb35..7f3af21932 100644 --- a/agent/structs/config_entry_gateways.go +++ b/agent/structs/config_entry_gateways.go @@ -518,6 +518,9 @@ type LinkedService struct { // SNI is the optional name to specify during the TLS handshake with a linked service SNI string `json:",omitempty"` + //DisableAutoHostRewrite disables terminating gateways auto host rewrite feature when set to true. + DisableAutoHostRewrite bool `json:",omitempty"` + acl.EnterpriseMeta `hcl:",squash" mapstructure:",squash"` } @@ -668,6 +671,7 @@ type GatewayService struct { FromWildcard bool `json:",omitempty"` ServiceKind GatewayServiceKind `json:",omitempty"` RaftIndex + AutoHostRewrite bool `json:",omitempty"` } type GatewayServices []*GatewayService diff --git a/agent/xds/routes.go b/agent/xds/routes.go index 3d05e2a21a..4c124ae081 100644 --- a/agent/xds/routes.go +++ b/agent/xds/routes.go @@ -158,11 +158,12 @@ func (s *ResourceGenerator) routesForTerminatingGateway(cfgSnap *proxycfg.Config "error", err, ) } + autoHostRewrite := cfgSnap.TerminatingGateway.AutoHostRewriteServices[svc] if !structs.IsProtocolHTTPLike(cfg.Protocol) { // Routes can only be defined for HTTP services continue } - routes, err := s.makeRoutes(cfgSnap, svc, clusterName, true) + routes, err := s.makeRoutes(cfgSnap, svc, clusterName, autoHostRewrite) if err != nil { return nil, err } @@ -231,7 +232,7 @@ func (s *ResourceGenerator) makeRoutes( // If there is a service-resolver for this service then also setup routes for each subset for name := range resolver.Subsets { clusterName = connect.ServiceSNI(svc.Name, name, svc.NamespaceOrDefault(), svc.PartitionOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain) - route, err := makeNamedDefaultRouteWithLB(clusterName, lb, resolver.RequestTimeout, true) + route, err := makeNamedDefaultRouteWithLB(clusterName, lb, resolver.RequestTimeout, autoHostRewrite) if err != nil { s.Logger.Error("failed to make route", "cluster", clusterName, "error", err) return nil, err diff --git a/api/config_entry_gateways.go b/api/config_entry_gateways.go index baf274e2da..ba2bac19ef 100644 --- a/api/config_entry_gateways.go +++ b/api/config_entry_gateways.go @@ -195,6 +195,9 @@ type TerminatingGatewayConfigEntry struct { type LinkedService struct { // Referencing other partitions is not supported. + //DisableAutoHostRewrite disables terminating gateways auto host rewrite feature when set to true. + DisableAutoHostRewrite bool `json:",omitempty"` + // Namespace is where the service is registered. Namespace string `json:",omitempty"`