diff --git a/.changelog/11187.txt b/.changelog/11187.txt new file mode 100644 index 000000000000..cde072ebb62c --- /dev/null +++ b/.changelog/11187.txt @@ -0,0 +1,3 @@ +```release-note:improvement +consul/connect: Allow `http2` and `grpc` protocols in ingress gateways +``` diff --git a/nomad/structs/services.go b/nomad/structs/services.go index 8b1afa61e303..d4760fe525c3 100644 --- a/nomad/structs/services.go +++ b/nomad/structs/services.go @@ -1728,7 +1728,7 @@ func (s *ConsulIngressService) Equals(o *ConsulIngressService) bool { return helper.CompareSliceSetString(s.Hosts, o.Hosts) } -func (s *ConsulIngressService) Validate(isHTTP bool) error { +func (s *ConsulIngressService) Validate(protocol string) error { if s == nil { return nil } @@ -1737,25 +1737,25 @@ func (s *ConsulIngressService) Validate(isHTTP bool) error { return errors.New("Consul Ingress Service requires a name") } - // Validation of wildcard service name and hosts varies on whether the protocol - // for the gateway is HTTP. + // Validation of wildcard service name and hosts varies depending on the + // protocol for the gateway. // https://www.consul.io/docs/connect/config-entries/ingress-gateway#hosts - switch isHTTP { - case true: + switch protocol { + case "tcp": if s.Name == "*" { - return nil + return errors.New(`Consul Ingress Service doesn't support wildcard name for "tcp" protocol`) } - if len(s.Hosts) == 0 { - return errors.New("Consul Ingress Service requires one or more hosts when using HTTP protocol") + if len(s.Hosts) != 0 { + return errors.New(`Consul Ingress Service doesn't support associating hosts to a service for the "tcp" protocol`) } - case false: + default: if s.Name == "*" { - return errors.New("Consul Ingress Service supports wildcard names only with HTTP protocol") + return nil } - if len(s.Hosts) > 0 { - return errors.New("Consul Ingress Service supports hosts only when using HTTP protocol") + if len(s.Hosts) == 0 { + return fmt.Errorf("Consul Ingress Service requires one or more hosts when using %q protocol", protocol) } } @@ -1815,9 +1815,9 @@ func (l *ConsulIngressListener) Validate() error { return fmt.Errorf("Consul Ingress Listener requires valid Port") } - protocols := []string{"http", "tcp"} + protocols := []string{"tcp", "http", "http2", "grpc"} if !helper.SliceStringContains(protocols, l.Protocol) { - return fmt.Errorf(`Consul Ingress Listener requires protocol of "http" or "tcp", got %q`, l.Protocol) + return fmt.Errorf(`Consul Ingress Listener requires protocol of %s, got %q`, strings.Join(protocols, ", "), l.Protocol) } if len(l.Services) == 0 { @@ -1825,7 +1825,7 @@ func (l *ConsulIngressListener) Validate() error { } for _, service := range l.Services { - if err := service.Validate(l.Protocol == "http"); err != nil { + if err := service.Validate(l.Protocol); err != nil { return err } } diff --git a/nomad/structs/services_test.go b/nomad/structs/services_test.go index 49e31b502dc2..9375366d7e5f 100644 --- a/nomad/structs/services_test.go +++ b/nomad/structs/services_test.go @@ -1122,29 +1122,29 @@ func TestConsulIngressService_Validate(t *testing.T) { t.Run("invalid name", func(t *testing.T) { err := (&ConsulIngressService{ Name: "", - }).Validate(true) + }).Validate("http") require.EqualError(t, err, "Consul Ingress Service requires a name") }) t.Run("http missing hosts", func(t *testing.T) { err := (&ConsulIngressService{ Name: "service1", - }).Validate(true) - require.EqualError(t, err, "Consul Ingress Service requires one or more hosts when using HTTP protocol") + }).Validate("http") + require.EqualError(t, err, `Consul Ingress Service requires one or more hosts when using "http" protocol`) }) t.Run("tcp extraneous hosts", func(t *testing.T) { err := (&ConsulIngressService{ Name: "service1", Hosts: []string{"host1"}, - }).Validate(false) - require.EqualError(t, err, "Consul Ingress Service supports hosts only when using HTTP protocol") + }).Validate("tcp") + require.EqualError(t, err, `Consul Ingress Service doesn't support associating hosts to a service for the "tcp" protocol`) }) t.Run("ok tcp", func(t *testing.T) { err := (&ConsulIngressService{ Name: "service1", - }).Validate(false) + }).Validate("tcp") require.NoError(t, err) }) @@ -1152,22 +1152,22 @@ func TestConsulIngressService_Validate(t *testing.T) { err := (&ConsulIngressService{ Name: "service1", Hosts: []string{"host1"}, - }).Validate(true) + }).Validate("http") require.NoError(t, err) }) t.Run("http with wildcard service", func(t *testing.T) { err := (&ConsulIngressService{ Name: "*", - }).Validate(true) + }).Validate("http") 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") + }).Validate("tcp") + require.EqualError(t, err, `Consul Ingress Service doesn't support wildcard name for "tcp" protocol`) }) } @@ -1193,7 +1193,7 @@ func TestConsulIngressListener_Validate(t *testing.T) { Name: "service1", }}, }).Validate() - require.EqualError(t, err, `Consul Ingress Listener requires protocol of "http" or "tcp", got "gopher"`) + require.EqualError(t, err, `Consul Ingress Listener requires protocol of tcp, http, http2, grpc, got "gopher"`) }) t.Run("no services", func(t *testing.T) {