[API Gateway] Validate listener name is not empty (#16340)

* [API Gateway] Validate listener name is not empty

* Update docstrings and test
This commit is contained in:
Andrew Stucki 2023-02-21 14:12:19 -05:00 committed by GitHub
parent 8997f2bff1
commit 7f9ec78932
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 46 additions and 6 deletions

View File

@ -2,6 +2,7 @@ package structs
import (
"fmt"
"regexp"
"sort"
"strings"
@ -778,9 +779,14 @@ func (e *APIGatewayConfigEntry) Validate() error {
return e.validateListeners()
}
var listenerNameRegex = regexp.MustCompile(`^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$`)
func (e *APIGatewayConfigEntry) validateListenerNames() error {
listeners := make(map[string]struct{})
for _, listener := range e.Listeners {
if len(listener.Name) < 1 || !listenerNameRegex.MatchString(listener.Name) {
return fmt.Errorf("listener name %q is invalid, must be at least 1 character and contain only letters, numbers, or dashes", listener.Name)
}
if _, found := listeners[listener.Name]; found {
return fmt.Errorf("found multiple listeners with the name %q", listener.Name)
}
@ -861,9 +867,8 @@ const (
// APIGatewayListener represents an individual listener for an APIGateway
type APIGatewayListener struct {
// Name is the optional name of the listener in a given gateway. This is
// optional but must be unique within a gateway; therefore, if a gateway
// has more than a single listener, all but one must specify a Name.
// Name is the name of the listener in a given gateway. This must be
// unique within a gateway.
Name string
// Hostname is the host name that a listener should be bound to. If
// unspecified, the listener accepts requests for all hostnames.

View File

@ -1143,12 +1143,40 @@ func TestAPIGateway_Listeners(t *testing.T) {
},
validateErr: "multiple listeners with the name",
},
"empty listener name": {
entry: &APIGatewayConfigEntry{
Kind: "api-gateway",
Name: "api-gw-one",
Listeners: []APIGatewayListener{
{
Port: 80,
Protocol: "tcp",
},
},
},
validateErr: "listener name \"\" is invalid, must be at least 1 character and contain only letters, numbers, or dashes",
},
"invalid listener name": {
entry: &APIGatewayConfigEntry{
Kind: "api-gateway",
Name: "api-gw-one",
Listeners: []APIGatewayListener{
{
Port: 80,
Protocol: "tcp",
Name: "/",
},
},
},
validateErr: "listener name \"/\" is invalid, must be at least 1 character and contain only letters, numbers, or dashes",
},
"merged listener protocol conflict": {
entry: &APIGatewayConfigEntry{
Kind: "api-gateway",
Name: "api-gw-two",
Listeners: []APIGatewayListener{
{
Name: "listener-one",
Port: 80,
Protocol: ListenerProtocolHTTP,
},
@ -1167,6 +1195,7 @@ func TestAPIGateway_Listeners(t *testing.T) {
Name: "api-gw-three",
Listeners: []APIGatewayListener{
{
Name: "listener",
Port: 80,
Hostname: "host.one",
},
@ -1185,6 +1214,7 @@ func TestAPIGateway_Listeners(t *testing.T) {
Name: "api-gw-four",
Listeners: []APIGatewayListener{
{
Name: "listener",
Port: 80,
Hostname: "host.one",
Protocol: APIGatewayListenerProtocol("UDP"),
@ -1199,6 +1229,7 @@ func TestAPIGateway_Listeners(t *testing.T) {
Name: "api-gw-five",
Listeners: []APIGatewayListener{
{
Name: "listener",
Port: 80,
Hostname: "host.one",
Protocol: APIGatewayListenerProtocol("tcp"),
@ -1213,6 +1244,7 @@ func TestAPIGateway_Listeners(t *testing.T) {
Name: "api-gw-six",
Listeners: []APIGatewayListener{
{
Name: "listener",
Port: -1,
Protocol: APIGatewayListenerProtocol("tcp"),
},
@ -1226,6 +1258,7 @@ func TestAPIGateway_Listeners(t *testing.T) {
Name: "api-gw-seven",
Listeners: []APIGatewayListener{
{
Name: "listener",
Port: 80,
Hostname: "*.*.host.one",
Protocol: APIGatewayListenerProtocol("http"),
@ -1240,6 +1273,7 @@ func TestAPIGateway_Listeners(t *testing.T) {
Name: "api-gw-eight",
Listeners: []APIGatewayListener{
{
Name: "listener",
Port: 80,
Hostname: "host.one",
Protocol: APIGatewayListenerProtocol("http"),
@ -1259,6 +1293,7 @@ func TestAPIGateway_Listeners(t *testing.T) {
Name: "api-gw-nine",
Listeners: []APIGatewayListener{
{
Name: "listener",
Port: 80,
Hostname: "host.one",
Protocol: APIGatewayListenerProtocol("http"),

View File

@ -268,9 +268,8 @@ func (g *APIGatewayConfigEntry) GetModifyIndex() uint64 { return g.ModifyInd
// APIGatewayListener represents an individual listener for an APIGateway
type APIGatewayListener struct {
// Name is the optional name of the listener in a given gateway. This is
// optional, however, it must be unique. Therefore, if a gateway has more
// than a single listener, all but one must specify a Name.
// Name is the name of the listener in a given gateway. This must be
// unique within a gateway.
Name string
// Hostname is the host name that a listener should be bound to, if
// unspecified, the listener accepts requests for all hostnames.

View File

@ -9,6 +9,7 @@ listeners = [
{
port = 9999
protocol = "tcp"
name = "listener"
}
]
'