mirror of https://github.com/hashicorp/consul
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1125 lines
25 KiB
1125 lines
25 KiB
package structs |
|
|
|
import ( |
|
"testing" |
|
|
|
"github.com/stretchr/testify/require" |
|
) |
|
|
|
func TestIngressGatewayConfigEntry(t *testing.T) { |
|
defaultMeta := DefaultEnterpriseMetaInDefaultPartition() |
|
|
|
cases := map[string]configEntryTestcase{ |
|
"normalize: empty protocol": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "", |
|
Services: []IngressService{}, |
|
}, |
|
}, |
|
}, |
|
expected: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "tcp", |
|
Services: []IngressService{}, |
|
}, |
|
}, |
|
EnterpriseMeta: *defaultMeta, |
|
}, |
|
normalizeOnly: true, |
|
}, |
|
"normalize: lowercase protocols": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "TCP", |
|
Services: []IngressService{}, |
|
}, |
|
{ |
|
Port: 1112, |
|
Protocol: "HtTP", |
|
Services: []IngressService{}, |
|
}, |
|
}, |
|
}, |
|
expected: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "tcp", |
|
Services: []IngressService{}, |
|
}, |
|
{ |
|
Port: 1112, |
|
Protocol: "http", |
|
Services: []IngressService{}, |
|
}, |
|
}, |
|
EnterpriseMeta: *defaultMeta, |
|
}, |
|
normalizeOnly: true, |
|
}, |
|
"port conflict": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "tcp", |
|
Services: []IngressService{ |
|
{ |
|
Name: "mysql", |
|
}, |
|
}, |
|
}, |
|
{ |
|
Port: 1111, |
|
Protocol: "tcp", |
|
Services: []IngressService{ |
|
{ |
|
Name: "postgres", |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
validateErr: "port 1111 declared on two listeners", |
|
}, |
|
"http features: wildcard": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "http", |
|
Services: []IngressService{ |
|
{ |
|
Name: "*", |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
"http features: wildcard service on invalid protocol": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "tcp", |
|
Services: []IngressService{ |
|
{ |
|
Name: "*", |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
validateErr: "Wildcard service name is only valid for protocol", |
|
}, |
|
"http features: multiple services": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "http", |
|
Services: []IngressService{ |
|
{ |
|
Name: "db1", |
|
}, |
|
{ |
|
Name: "db2", |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
"http features: multiple services on tcp listener": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "tcp", |
|
Services: []IngressService{ |
|
{ |
|
Name: "db1", |
|
}, |
|
{ |
|
Name: "db2", |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
validateErr: "Multiple services per listener are only supported for L7", |
|
}, |
|
// ========================== |
|
"tcp listener requires a defined service": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "tcp", |
|
Services: []IngressService{}, |
|
}, |
|
}, |
|
}, |
|
validateErr: "No service declared for listener with port 1111", |
|
}, |
|
"http listener requires a defined service": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "http", |
|
Services: []IngressService{}, |
|
}, |
|
}, |
|
}, |
|
validateErr: "No service declared for listener with port 1111", |
|
}, |
|
"empty service name not supported": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "tcp", |
|
Services: []IngressService{ |
|
{}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
validateErr: "Service name cannot be blank", |
|
}, |
|
"protocol validation": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "asdf", |
|
Services: []IngressService{ |
|
{ |
|
Name: "db", |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
validateErr: "protocol must be 'tcp', 'http', 'http2', or 'grpc'. 'asdf' is an unsupported protocol", |
|
}, |
|
"hosts cannot be set on a tcp listener": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "tcp", |
|
Services: []IngressService{ |
|
{ |
|
Name: "db", |
|
Hosts: []string{"db.example.com"}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
validateErr: "Associating hosts to a service is not supported for the tcp protocol", |
|
}, |
|
"hosts cannot be set on a wildcard specifier": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "http", |
|
Services: []IngressService{ |
|
{ |
|
Name: "*", |
|
Hosts: []string{"db.example.com"}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
validateErr: "Associating hosts to a wildcard service is not supported", |
|
}, |
|
"hosts must be unique per listener": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "http", |
|
Services: []IngressService{ |
|
{ |
|
Name: "db", |
|
Hosts: []string{"test.example.com"}, |
|
}, |
|
{ |
|
Name: "api", |
|
Hosts: []string{"test.example.com"}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
validateErr: "Hosts must be unique within a specific listener", |
|
}, |
|
"hosts must be a valid DNS name": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "http", |
|
Services: []IngressService{ |
|
{ |
|
Name: "db", |
|
Hosts: []string{"example..com"}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
validateErr: `Host "example..com" must be a valid DNS hostname`, |
|
}, |
|
"wildcard specifier is only allowed in the leftmost label": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "http", |
|
Services: []IngressService{ |
|
{ |
|
Name: "db", |
|
Hosts: []string{"*.example.com"}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
"wildcard specifier is not allowed in non-leftmost labels": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "http", |
|
Services: []IngressService{ |
|
{ |
|
Name: "db", |
|
Hosts: []string{"example.*.com"}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
validateErr: `Host "example.*.com" is not valid, a wildcard specifier is only allowed as the leftmost label`, |
|
}, |
|
"wildcard specifier is not allowed in leftmost labels as a partial": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "http", |
|
Services: []IngressService{ |
|
{ |
|
Name: "db", |
|
Hosts: []string{"*-test.example.com"}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
validateErr: `Host "*-test.example.com" is not valid, a wildcard specifier is only allowed as the leftmost label`, |
|
}, |
|
"wildcard specifier is allowed for hosts when TLS is disabled": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "http", |
|
Services: []IngressService{ |
|
{ |
|
Name: "db", |
|
Hosts: []string{"*"}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
"wildcard specifier is not allowed for hosts when TLS is enabled": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
TLS: GatewayTLSConfig{ |
|
Enabled: true, |
|
}, |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "http", |
|
Services: []IngressService{ |
|
{ |
|
Name: "db", |
|
Hosts: []string{"*"}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
validateErr: `Host '*' is not allowed when TLS is enabled, all hosts must be valid DNS records to add as a DNSSAN`, |
|
}, |
|
"request header manip allowed for http(ish) protocol": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "http", |
|
Services: []IngressService{ |
|
{ |
|
Name: "web", |
|
RequestHeaders: &HTTPHeaderModifiers{ |
|
Set: map[string]string{"x-foo": "bar"}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
{ |
|
Port: 2222, |
|
Protocol: "http2", |
|
Services: []IngressService{ |
|
{ |
|
Name: "web2", |
|
ResponseHeaders: &HTTPHeaderModifiers{ |
|
Set: map[string]string{"x-foo": "bar"}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
{ |
|
Port: 3333, |
|
Protocol: "grpc", |
|
Services: []IngressService{ |
|
{ |
|
Name: "api", |
|
ResponseHeaders: &HTTPHeaderModifiers{ |
|
Remove: []string{"x-grpc-internal"}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
expectUnchanged: true, |
|
}, |
|
"request header manip not allowed for non-http protocol": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "tcp", |
|
Services: []IngressService{ |
|
{ |
|
Name: "db", |
|
RequestHeaders: &HTTPHeaderModifiers{ |
|
Set: map[string]string{"x-foo": "bar"}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
validateErr: "request headers only valid for http", |
|
}, |
|
"response header manip not allowed for non-http protocol": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "tcp", |
|
Services: []IngressService{ |
|
{ |
|
Name: "db", |
|
ResponseHeaders: &HTTPHeaderModifiers{ |
|
Remove: []string{"x-foo"}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
validateErr: "response headers only valid for http", |
|
}, |
|
"duplicate services not allowed": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "http", |
|
Services: []IngressService{ |
|
{ |
|
Name: "web", |
|
}, |
|
{ |
|
Name: "web", |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
// Match only the last part of the exected error because the service name |
|
// differs between Ent and OSS default/default/web vs web |
|
validateErr: "cannot be added multiple times (listener on port 1111)", |
|
}, |
|
"TLS.SDS kitchen sink": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
TLS: GatewayTLSConfig{ |
|
SDS: &GatewayTLSSDSConfig{ |
|
ClusterName: "secret-service1", |
|
CertResource: "some-ns/ingress-default", |
|
}, |
|
}, |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "http", |
|
TLS: &GatewayTLSConfig{ |
|
SDS: &GatewayTLSSDSConfig{ |
|
ClusterName: "secret-service2", |
|
CertResource: "some-ns/ingress-1111", |
|
}, |
|
}, |
|
Services: []IngressService{ |
|
{ |
|
Name: "web", |
|
Hosts: []string{"*"}, |
|
TLS: &GatewayServiceTLSConfig{ |
|
SDS: &GatewayTLSSDSConfig{ |
|
ClusterName: "secret-service3", |
|
CertResource: "some-ns/web", |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
"TLS.SDS gateway-level": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
TLS: GatewayTLSConfig{ |
|
SDS: &GatewayTLSSDSConfig{ |
|
ClusterName: "secret-service1", |
|
CertResource: "some-ns/ingress-default", |
|
}, |
|
}, |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "tcp", |
|
Services: []IngressService{ |
|
{ |
|
Name: "db", |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
expectUnchanged: true, |
|
}, |
|
"TLS.SDS listener-level": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "tcp", |
|
TLS: &GatewayTLSConfig{ |
|
SDS: &GatewayTLSSDSConfig{ |
|
ClusterName: "secret-service1", |
|
CertResource: "some-ns/db1", |
|
}, |
|
}, |
|
Services: []IngressService{ |
|
{ |
|
Name: "db1", |
|
}, |
|
}, |
|
}, |
|
{ |
|
Port: 2222, |
|
Protocol: "tcp", |
|
TLS: &GatewayTLSConfig{ |
|
SDS: &GatewayTLSSDSConfig{ |
|
ClusterName: "secret-service2", |
|
CertResource: "some-ns/db2", |
|
}, |
|
}, |
|
Services: []IngressService{ |
|
{ |
|
Name: "db2", |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
expectUnchanged: true, |
|
}, |
|
"TLS.SDS gateway-level cluster only": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
TLS: GatewayTLSConfig{ |
|
SDS: &GatewayTLSSDSConfig{ |
|
ClusterName: "secret-service", |
|
}, |
|
}, |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "tcp", |
|
TLS: &GatewayTLSConfig{ |
|
SDS: &GatewayTLSSDSConfig{ |
|
CertResource: "some-ns/db1", |
|
}, |
|
}, |
|
Services: []IngressService{ |
|
{ |
|
Name: "db1", |
|
}, |
|
}, |
|
}, |
|
{ |
|
Port: 2222, |
|
Protocol: "tcp", |
|
TLS: &GatewayTLSConfig{ |
|
SDS: &GatewayTLSSDSConfig{ |
|
CertResource: "some-ns/db2", |
|
}, |
|
}, |
|
Services: []IngressService{ |
|
{ |
|
Name: "db2", |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
expectUnchanged: true, |
|
}, |
|
"TLS.SDS mixed TLS and non-TLS listeners": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
// No Gateway level TLS.Enabled or SDS config |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "tcp", |
|
TLS: &GatewayTLSConfig{ |
|
SDS: &GatewayTLSSDSConfig{ |
|
ClusterName: "sds-cluster", |
|
CertResource: "some-ns/db1", |
|
}, |
|
}, |
|
Services: []IngressService{ |
|
{ |
|
Name: "db1", |
|
}, |
|
}, |
|
}, |
|
{ |
|
Port: 2222, |
|
Protocol: "tcp", |
|
// No TLS config |
|
Services: []IngressService{ |
|
{ |
|
Name: "db2", |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
expectUnchanged: true, |
|
}, |
|
"TLS.SDS only service-level mixed": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
// No Gateway level TLS.Enabled or SDS config |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "http", |
|
// No TLS config |
|
Services: []IngressService{ |
|
{ |
|
Name: "web", |
|
Hosts: []string{"www.example.com"}, |
|
TLS: &GatewayServiceTLSConfig{ |
|
SDS: &GatewayTLSSDSConfig{ |
|
ClusterName: "sds-cluster", |
|
CertResource: "web-cert", |
|
}, |
|
}, |
|
}, |
|
{ |
|
Name: "api", |
|
Hosts: []string{"api.example.com"}, |
|
TLS: &GatewayServiceTLSConfig{ |
|
SDS: &GatewayTLSSDSConfig{ |
|
ClusterName: "sds-cluster", |
|
CertResource: "api-cert", |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
{ |
|
Port: 2222, |
|
Protocol: "http", |
|
// No TLS config |
|
Services: []IngressService{ |
|
{ |
|
Name: "db2", |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
expectUnchanged: true, |
|
}, |
|
"TLS.SDS requires cluster if gateway-level cert specified": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
TLS: GatewayTLSConfig{ |
|
SDS: &GatewayTLSSDSConfig{ |
|
CertResource: "foo", |
|
}, |
|
}, |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "tcp", |
|
Services: []IngressService{ |
|
{ |
|
Name: "db", |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
validateErr: "TLS.SDS.ClusterName is required if CertResource is set", |
|
}, |
|
"TLS.SDS listener requires cluster if there is no gateway-level one": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
|
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "tcp", |
|
TLS: &GatewayTLSConfig{ |
|
SDS: &GatewayTLSSDSConfig{ |
|
CertResource: "foo", |
|
}, |
|
}, |
|
Services: []IngressService{ |
|
{ |
|
Name: "db", |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
validateErr: "TLS.SDS.ClusterName is required if CertResource is set", |
|
}, |
|
"TLS.SDS listener requires a cert resource if gw ClusterName set": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
TLS: GatewayTLSConfig{ |
|
SDS: &GatewayTLSSDSConfig{ |
|
ClusterName: "foo", |
|
}, |
|
}, |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "tcp", |
|
Services: []IngressService{ |
|
{ |
|
Name: "db", |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
validateErr: "TLS.SDS.CertResource is required if ClusterName is set for gateway (listener on port 1111)", |
|
}, |
|
"TLS.SDS listener requires a cert resource if listener ClusterName set": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
|
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "tcp", |
|
TLS: &GatewayTLSConfig{ |
|
SDS: &GatewayTLSSDSConfig{ |
|
ClusterName: "foo", |
|
}, |
|
}, |
|
Services: []IngressService{ |
|
{ |
|
Name: "db", |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
validateErr: "TLS.SDS.CertResource is required if ClusterName is set for listener (listener on port 1111)", |
|
}, |
|
"TLS.SDS at service level is not supported without Hosts set": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
|
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "http", |
|
Services: []IngressService{ |
|
{ |
|
Name: "*", |
|
TLS: &GatewayServiceTLSConfig{ |
|
SDS: &GatewayTLSSDSConfig{ |
|
CertResource: "foo", |
|
ClusterName: "sds-cluster", |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
// Note we don't assert the last part `(service \"*\" on listener on port 1111)` |
|
// since the service name is normalized differently on OSS and Ent |
|
validateErr: "A service specifying TLS.SDS.CertResource must have at least one item in Hosts", |
|
}, |
|
"TLS.SDS at service level needs a cluster from somewhere": { |
|
entry: &IngressGatewayConfigEntry{ |
|
Kind: "ingress-gateway", |
|
Name: "ingress-web", |
|
|
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "http", |
|
Services: []IngressService{ |
|
{ |
|
Name: "foo", |
|
Hosts: []string{"foo.example.com"}, |
|
TLS: &GatewayServiceTLSConfig{ |
|
SDS: &GatewayTLSSDSConfig{ |
|
CertResource: "foo", |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
// Note we don't assert the last part `(service \"foo\" on listener on port 1111)` |
|
// since the service name is normalized differently on OSS and Ent |
|
validateErr: "TLS.SDS.ClusterName is required if CertResource is set", |
|
}, |
|
} |
|
|
|
testConfigEntryNormalizeAndValidate(t, cases) |
|
} |
|
|
|
func TestIngressConfigEntry_ListRelatedServices(t *testing.T) { |
|
type testcase struct { |
|
entry IngressGatewayConfigEntry |
|
expectServices []ServiceID |
|
} |
|
|
|
cases := map[string]testcase{ |
|
"one exact": { |
|
entry: IngressGatewayConfigEntry{ |
|
Kind: IngressGateway, |
|
Name: "ingress-web", |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "tcp", |
|
Services: []IngressService{ |
|
{Name: "web"}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
expectServices: []ServiceID{NewServiceID("web", nil)}, |
|
}, |
|
"one wild": { |
|
entry: IngressGatewayConfigEntry{ |
|
Kind: IngressGateway, |
|
Name: "ingress-web", |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "tcp", |
|
Services: []IngressService{ |
|
{Name: "*"}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
expectServices: nil, |
|
}, |
|
"kitchen sink": { |
|
entry: IngressGatewayConfigEntry{ |
|
Kind: IngressGateway, |
|
Name: "ingress-web", |
|
Listeners: []IngressListener{ |
|
{ |
|
Port: 1111, |
|
Protocol: "tcp", |
|
Services: []IngressService{ |
|
{Name: "api"}, |
|
{Name: "web"}, |
|
}, |
|
}, |
|
{ |
|
Port: 2222, |
|
Protocol: "tcp", |
|
Services: []IngressService{ |
|
{Name: "web"}, |
|
{Name: "*"}, |
|
{Name: "db"}, |
|
{Name: "blah"}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
expectServices: []ServiceID{ |
|
NewServiceID("api", nil), |
|
NewServiceID("blah", nil), |
|
NewServiceID("db", nil), |
|
NewServiceID("web", nil), |
|
}, |
|
}, |
|
} |
|
|
|
for name, tc := range cases { |
|
tc := tc |
|
t.Run(name, func(t *testing.T) { |
|
got := tc.entry.ListRelatedServices() |
|
require.Equal(t, tc.expectServices, got) |
|
}) |
|
} |
|
} |
|
|
|
func TestTerminatingGatewayConfigEntry(t *testing.T) { |
|
cases := map[string]configEntryTestcase{ |
|
"service conflict": { |
|
entry: &TerminatingGatewayConfigEntry{ |
|
Kind: "terminating-gateway", |
|
Name: "terminating-gw-west", |
|
Services: []LinkedService{ |
|
{ |
|
Name: "foo", |
|
}, |
|
{ |
|
Name: "foo", |
|
}, |
|
}, |
|
}, |
|
validateErr: "specified more than once", |
|
}, |
|
"blank service name": { |
|
entry: &TerminatingGatewayConfigEntry{ |
|
Kind: "terminating-gateway", |
|
Name: "terminating-gw-west", |
|
Services: []LinkedService{ |
|
{ |
|
Name: "", |
|
}, |
|
}, |
|
}, |
|
validateErr: "Service name cannot be blank.", |
|
}, |
|
"not all TLS options provided-1": { |
|
entry: &TerminatingGatewayConfigEntry{ |
|
Kind: "terminating-gateway", |
|
Name: "terminating-gw-west", |
|
Services: []LinkedService{ |
|
{ |
|
Name: "web", |
|
CertFile: "client.crt", |
|
}, |
|
}, |
|
}, |
|
validateErr: "must have a CertFile, CAFile, and KeyFile", |
|
}, |
|
"not all TLS options provided-2": { |
|
entry: &TerminatingGatewayConfigEntry{ |
|
Kind: "terminating-gateway", |
|
Name: "terminating-gw-west", |
|
Services: []LinkedService{ |
|
{ |
|
Name: "web", |
|
KeyFile: "tls.key", |
|
}, |
|
}, |
|
}, |
|
validateErr: "must have a CertFile, CAFile, and KeyFile", |
|
}, |
|
"all TLS options provided": { |
|
entry: &TerminatingGatewayConfigEntry{ |
|
Kind: "terminating-gateway", |
|
Name: "terminating-gw-west", |
|
Services: []LinkedService{ |
|
{ |
|
Name: "web", |
|
CAFile: "ca.crt", |
|
CertFile: "client.crt", |
|
KeyFile: "tls.key", |
|
}, |
|
}, |
|
}, |
|
}, |
|
"only providing ca file is allowed": { |
|
entry: &TerminatingGatewayConfigEntry{ |
|
Kind: "terminating-gateway", |
|
Name: "terminating-gw-west", |
|
Services: []LinkedService{ |
|
{ |
|
Name: "web", |
|
CAFile: "ca.crt", |
|
}, |
|
}, |
|
}, |
|
}, |
|
} |
|
testConfigEntryNormalizeAndValidate(t, cases) |
|
} |
|
|
|
func TestGatewayService_Addresses(t *testing.T) { |
|
cases := []struct { |
|
name string |
|
input GatewayService |
|
argument []string |
|
expected []string |
|
}{ |
|
{ |
|
name: "port is zero", |
|
input: GatewayService{}, |
|
expected: nil, |
|
}, |
|
{ |
|
name: "no hosts with empty array", |
|
input: GatewayService{ |
|
Port: 8080, |
|
}, |
|
expected: nil, |
|
}, |
|
{ |
|
name: "no hosts with default", |
|
input: GatewayService{ |
|
Port: 8080, |
|
}, |
|
argument: []string{ |
|
"service.ingress.dc.domain", |
|
"service.ingress.dc.alt.domain", |
|
"service.ingress.dc.alt.domain.", |
|
}, |
|
expected: []string{ |
|
"service.ingress.dc.domain:8080", |
|
"service.ingress.dc.alt.domain:8080", |
|
"service.ingress.dc.alt.domain:8080", |
|
}, |
|
}, |
|
{ |
|
name: "user-defined hosts", |
|
input: GatewayService{ |
|
Port: 8080, |
|
Hosts: []string{"*.test.example.com", "other.example.com", "other.example.com."}, |
|
}, |
|
argument: []string{ |
|
"service.ingress.dc.domain", |
|
"service.ingress.alt.domain", |
|
}, |
|
expected: []string{"*.test.example.com:8080", "other.example.com:8080", "other.example.com:8080"}, |
|
}, |
|
} |
|
|
|
for _, tc := range cases { |
|
t.Run(tc.name, func(t *testing.T) { |
|
addresses := tc.input.Addresses(tc.argument) |
|
require.ElementsMatch(t, tc.expected, addresses) |
|
}) |
|
} |
|
}
|
|
|