diff --git a/pkg/annotations/ingress_annotations.go b/pkg/annotations/ingress_annotations.go index 20198d7c8..aba1360ae 100644 --- a/pkg/annotations/ingress_annotations.go +++ b/pkg/annotations/ingress_annotations.go @@ -27,6 +27,9 @@ const ( // Null means Host specified in the request to Application Gateway is used to connect to the backend. BackendHostNameKey = ApplicationGatewayPrefix + "/backend-hostname" + // OverrideBackendHostNameKey defines the key to enable/disable host name overriding. + OverrideBackendHostNameKey = ApplicationGatewayPrefix + "/override-backend-host" + // HealthProbeHostKey defines the key for Host which should be used as a target for health probe. HealthProbeHostKey = ApplicationGatewayPrefix + "/health-probe-hostname" @@ -158,11 +161,16 @@ func BackendPathPrefix(ing *networking.Ingress) (string, error) { return parseString(ing, BackendPathPrefixKey) } -// BackendHostName override hostname +// BackendHostName specific domain name to override the backend hostname with func BackendHostName(ing *networking.Ingress) (string, error) { return parseString(ing, BackendHostNameKey) } +// OverrideBackendHostName whether to override the backend hostname or not +func OverrideBackendHostName(ing *networking.Ingress) (string, error) { + return parseBool(ing, OverrideBackendHostNameKey) +} + // HealthProbeHostName probe hostname override func HealthProbeHostName(ing *networking.Ingress) (string, error) { return parseString(ing, HealthProbeHostKey) diff --git a/pkg/annotations/ingress_annotations_test.go b/pkg/annotations/ingress_annotations_test.go index 9c2afdbba..179c0ed10 100644 --- a/pkg/annotations/ingress_annotations_test.go +++ b/pkg/annotations/ingress_annotations_test.go @@ -48,6 +48,7 @@ var _ = Describe("Test ingress annotation functions", func() { "appgw.ingress.kubernetes.io/connection-draining-timeout": "3456", "appgw.ingress.kubernetes.io/backend-path-prefix": "prefix-here", "appgw.ingress.kubernetes.io/backend-hostname": "www.backend.com", + "appgw.ingress.kubernetes.io/overrride-backend-hostname": "true", "appgw.ingress.kubernetes.io/hostname-extension": "www.bye.com, www.b*.com", "appgw.ingress.kubernetes.io/appgw-ssl-certificate": "appgw-cert", "appgw.ingress.kubernetes.io/appgw-ssl-profile": "legacy-tls", @@ -340,6 +341,20 @@ var _ = Describe("Test ingress annotation functions", func() { }) }) + Context("test OverrideBackendHostName", func() { + It("returns error when ingress has no annotations", func() { + ing := &networking.Ingress{} + actual, err := OverrideBackendHostName(ing) + Expect(err).To(HaveOccurred()) + Expect(actual).To(Equal("")) + }) + It("returns true with correct annotation", func() { + actual, err := OverrideBackendHostName(ing) + Expect(err).ToNot(HaveOccurred()) + Expect(actual).To(Equal(true)) + }) + }) + Context("test IsSslRedirect", func() { It("returns error when ingress has no annotations", func() { ing := &networking.Ingress{} diff --git a/pkg/appgw/backendhttpsettings.go b/pkg/appgw/backendhttpsettings.go index 247ccb847..86ffcf7a5 100644 --- a/pkg/appgw/backendhttpsettings.go +++ b/pkg/appgw/backendhttpsettings.go @@ -321,16 +321,29 @@ func (c *appGwConfigBuilder) generateHTTPSettings(backendID backendIdentifier, p c.recorder.Event(backendID.Ingress, v1.EventTypeWarning, events.ReasonInvalidAnnotation, err.Error()) } - // To use an HTTP setting with a trusted root certificate, we must either override with a specific domain name or choose "Pick host name from backend target". - if httpSettings.TrustedRootCertificates != nil { - if httpSettings.Protocol == n.ApplicationGatewayProtocolHTTPS && len(*httpSettings.TrustedRootCertificates) > 0 { - if httpSettings.HostName != nil && len(*httpSettings.HostName) > 0 { - httpSettings.PickHostNameFromBackendAddress = to.BoolPtr(false) - } else { - httpSettings.PickHostNameFromBackendAddress = to.BoolPtr(true) + if overrideBackendHostName, err := annotations.OverrideBackendHostName(backendID.Ingress); err == nil { + if httpSettings.HostName != nil && !overrideBackendHostName { + // TODO Warn about pointless setting of hostname + } else if httpSettings.HostName != nil && overrideBackendHostName { + httpSettings.PickHostNameFromBackendAddress = to.BoolPtr(false) + } else if httpSettings.HostName == nil && overrideBackendHostName { + httpSettings.PickHostNameFromBackendAddress = to.BoolPtr(true) + } + } else if err != nil && !controllererrors.IsErrorCode(err, controllererrors.ErrorMissingAnnotation) { + c.recorder.Event(backendID.Ingress, v1.EventTypeWarning, events.ReasonInvalidAnnotation, err.Error()) + } else if err != nil && controllererrors.IsErrorCode(err, controllererrors.ErrorMissingAnnotation) { + // When overrideBackendHostName is unset, fallback to original behaviour: + + // To use an HTTP setting with a trusted root certificate, we must either override with a specific domain name or choose "Pick host name from backend target". + if httpSettings.TrustedRootCertificates != nil { + if httpSettings.Protocol == n.ApplicationGatewayProtocolHTTPS && len(*httpSettings.TrustedRootCertificates) > 0 { + if httpSettings.HostName != nil && len(*httpSettings.HostName) > 0 { + httpSettings.PickHostNameFromBackendAddress = to.BoolPtr(false) + } else { + httpSettings.PickHostNameFromBackendAddress = to.BoolPtr(true) + } } } } - return httpSettings }