From 3f317e2172121ea71fc9caf0fcba57ee39c079d1 Mon Sep 17 00:00:00 2001 From: Seth Hoenig Date: Tue, 27 Apr 2021 13:25:12 -0600 Subject: [PATCH] consul/connect: fix bug where ingress gateways could not use wildcard services This PR fixes a bug where Nomad was more restrictive on Ingress Gateway Configuration Entry definitions than Consul. Before, Nomad would not allow for declaring IGCEs with http listeners with service name "*", which is a special feature allowable by Consul. Note: to make http protocol work, a service-default must be defined setting the protocol to http for each service. Fixes: #9729 --- CHANGELOG.md | 1 + nomad/structs/services.go | 27 ++++++++++++++++++++++----- nomad/structs/services_test.go | 14 ++++++++++++++ 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d8b505b0d15b..cb109a53fc79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ BUG FIXES: * cli: Remove extra linefeeds in monitor.log files written by `nomad operator debug`. [[GH-10252](https://github.com/hashicorp/nomad/issues/10252)] * client: Fixed log formatting when killing tasks. [[GH-10135](https://github.com/hashicorp/nomad/issues/10135)] * client: Fixed a bug where small files would be assigned the wrong content type. [[GH-10348](https://github.com/hashicorp/nomad/pull/10348)] + * consul/connect: Fixed a bug where HTTP ingress gateways could not use wildcard names. [[GH-10457](https://github.com/hashicorp/nomad/pull/10457)] * csi: Fixed a bug where volume with IDs that are a substring prefix of another volume could use the wrong volume for feasibility checking. [[GH-10158](https://github.com/hashicorp/nomad/issues/10158)] * scheduler: Fixed a bug where Nomad reports negative or incorrect running children counts for periodic jobs. [[GH-10145](https://github.com/hashicorp/nomad/issues/10145)] * scheduler: Fixed a bug where jobs requesting multiple CSI volumes could be incorrectly scheduled if only one of the volumes passed feasibility checking. [[GH-10143](https://github.com/hashicorp/nomad/issues/10143)] diff --git a/nomad/structs/services.go b/nomad/structs/services.go index e4bb039bccb3..7fcf363d1b70 100644 --- a/nomad/structs/services.go +++ b/nomad/structs/services.go @@ -2,6 +2,7 @@ package structs import ( "crypto/sha1" + "errors" "fmt" "hash" "io" @@ -1645,13 +1646,29 @@ func (s *ConsulIngressService) Validate(isHTTP bool) error { } if s.Name == "" { - return fmt.Errorf("Consul Ingress Service requires a name") + return errors.New("Consul Ingress Service requires a name") } - if isHTTP && len(s.Hosts) == 0 { - return fmt.Errorf("Consul Ingress Service requires one or more hosts when using HTTP protocol") - } else if !isHTTP && len(s.Hosts) > 0 { - return fmt.Errorf("Consul Ingress Service supports hosts only when using HTTP protocol") + // Validation of wildcard service name and hosts varies on whether the protocol + // for the gateway is HTTP. + // https://www.consul.io/docs/connect/config-entries/ingress-gateway#hosts + switch isHTTP { + case true: + if s.Name == "*" { + return nil + } + + if len(s.Hosts) == 0 { + return errors.New("Consul Ingress Service requires one or more hosts when using HTTP protocol") + } + case false: + if s.Name == "*" { + return errors.New("Consul Ingress Service supports wildcard names only with HTTP protocol") + } + + if len(s.Hosts) > 0 { + return errors.New("Consul Ingress Service supports hosts only when using HTTP protocol") + } } return nil diff --git a/nomad/structs/services_test.go b/nomad/structs/services_test.go index 73c3951d31fb..6535f8c2e2fb 100644 --- a/nomad/structs/services_test.go +++ b/nomad/structs/services_test.go @@ -1106,6 +1106,20 @@ func TestConsulIngressService_Validate(t *testing.T) { }).Validate(true) require.NoError(t, err) }) + + t.Run("http with wildcard service", func(t *testing.T) { + err := (&ConsulIngressService{ + Name: "*", + }).Validate(true) + require.NoError(t, err) + }) + + t.Run("tcp with wildcard service", func(t *testing.T) { + err := (&ConsulIngressService{ + Name: "*", + }).Validate(false) + require.EqualError(t, err, "Consul Ingress Service supports wildcard names only with HTTP protocol") + }) } func TestConsulIngressListener_Validate(t *testing.T) {