Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: infraIR duplicate port translation for merged gateways #3061

Merged
merged 9 commits into from
Apr 7, 2024
73 changes: 38 additions & 35 deletions internal/gatewayapi/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ type ListenersTranslator interface {
}

func (t *Translator) ProcessListeners(gateways []*GatewayContext, xdsIR XdsIRMap, infraIR InfraIRMap, resources *Resources) {
// Infra IR proxy ports must be unique.
foundPorts := make(map[string][]*protocolPort)
t.validateConflictedLayer7Listeners(gateways)
t.validateConflictedLayer4Listeners(gateways, gwapiv1.TCPProtocolType, gwapiv1.TLSProtocolType)
t.validateConflictedLayer4Listeners(gateways, gwapiv1.UDPProtocolType)
Expand All @@ -35,8 +37,6 @@ func (t *Translator) ProcessListeners(gateways []*GatewayContext, xdsIR XdsIRMap
// and compute status for each, and add valid ones
// to the Xds IR.
for _, gateway := range gateways {
// Infra IR proxy ports must be unique.
var foundPorts []*protocolPort
irKey := t.getIRKey(gateway.Gateway)

if resources.EnvoyProxy != nil {
Expand Down Expand Up @@ -93,7 +93,6 @@ func (t *Translator) ProcessListeners(gateways []*GatewayContext, xdsIR XdsIRMap
if !isReady {
continue
}

// Add the listener to the Xds IR
servicePort := &protocolPort{protocol: listener.Protocol, port: int32(listener.Port)}
containerPort := servicePortToContainerPort(servicePort.port)
Expand Down Expand Up @@ -122,42 +121,46 @@ func (t *Translator) ProcessListeners(gateways []*GatewayContext, xdsIR XdsIRMap

// Add the listener to the Infra IR. Infra IR ports must have a unique port number per layer-4 protocol
// (TCP or UDP).
if !containsPort(foundPorts, servicePort) {
foundPorts = append(foundPorts, servicePort)
var proto ir.ProtocolType
switch listener.Protocol {
case gwapiv1.HTTPProtocolType:
proto = ir.HTTPProtocolType
case gwapiv1.HTTPSProtocolType:
proto = ir.HTTPSProtocolType
case gwapiv1.TLSProtocolType:
proto = ir.TLSProtocolType
case gwapiv1.TCPProtocolType:
proto = ir.TCPProtocolType
case gwapiv1.UDPProtocolType:
proto = ir.UDPProtocolType
}
if !containsPort(foundPorts[irKey], servicePort) {
t.processInfraIRListener(listener, infraIR, irKey, servicePort)
foundPorts[irKey] = append(foundPorts[irKey], servicePort)
}
}
}
}

infraPortName := string(listener.Name)
if t.MergeGateways {
infraPortName = irHTTPListenerName(listener)
}
infraPort := ir.ListenerPort{
Name: infraPortName,
Protocol: proto,
ServicePort: servicePort.port,
ContainerPort: containerPort,
}
func (t *Translator) processInfraIRListener(listener *ListenerContext, infraIR InfraIRMap, irKey string, servicePort *protocolPort) {
var proto ir.ProtocolType
switch listener.Protocol {
case gwapiv1.HTTPProtocolType:
proto = ir.HTTPProtocolType
case gwapiv1.HTTPSProtocolType:
proto = ir.HTTPSProtocolType
case gwapiv1.TLSProtocolType:
proto = ir.TLSProtocolType
case gwapiv1.TCPProtocolType:
proto = ir.TCPProtocolType
case gwapiv1.UDPProtocolType:
proto = ir.UDPProtocolType
}

proxyListener := &ir.ProxyListener{
Name: irHTTPListenerName(listener),
Ports: []ir.ListenerPort{infraPort},
}
infraPortName := string(listener.Name)
if t.MergeGateways {
infraPortName = irHTTPListenerName(listener)
}
infraPort := ir.ListenerPort{
Name: infraPortName,
Protocol: proto,
ServicePort: servicePort.port,
ContainerPort: servicePortToContainerPort(servicePort.port),
}

infraIR[irKey].Proxy.Listeners = append(infraIR[irKey].Proxy.Listeners, proxyListener)
}
}
proxyListener := &ir.ProxyListener{
Name: irHTTPListenerName(listener),
Ports: []ir.ListenerPort{infraPort},
}

infraIR[irKey].Proxy.Listeners = append(infraIR[irKey].Proxy.Listeners, proxyListener)
}

func processAccessLog(envoyproxy *egv1a1.EnvoyProxy) *ir.AccessLog {
Expand Down
7 changes: 0 additions & 7 deletions internal/gatewayapi/testdata/conflicting-policies.out.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -218,13 +218,6 @@ infraIR:
name: default/gateway-1/http
protocol: HTTP
servicePort: 80
- address: null
name: default/mfqjpuycbgjrtdww/http
ports:
- containerPort: 10080
name: default/mfqjpuycbgjrtdww/http
protocol: HTTP
servicePort: 80
metadata:
labels:
gateway.envoyproxy.io/owning-gatewayclass: envoy-gateway-class
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
envoyproxy:
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
namespace: envoy-gateway-system
name: test
spec:
mergeGateways: true
gateways:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
name: gateway-1
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
listeners:
- name: http
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: Same
- name: http-2
hostname: company.com
port: 8888
protocol: HTTP
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
name: gateway-2
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
listeners:
- name: http-3
port: 8888
protocol: HTTP
allowedRoutes:
namespaces:
from: Same
- name: http-4
hostname: example.com
port: 8888
protocol: HTTP
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
gateways:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
creationTimestamp: null
name: gateway-1
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
listeners:
- allowedRoutes:
namespaces:
from: Same
name: http
port: 80
protocol: HTTP
- hostname: company.com
name: http-2
port: 8888
protocol: HTTP
status:
listeners:
- attachedRoutes: 0
conditions:
- lastTransitionTime: null
message: Sending translated listener configuration to the data plane
reason: Programmed
status: "True"
type: Programmed
- lastTransitionTime: null
message: Listener has been successfully translated
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: null
message: Listener references have been resolved
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
name: http
supportedKinds:
- group: gateway.networking.k8s.io
kind: HTTPRoute
- group: gateway.networking.k8s.io
kind: GRPCRoute
- attachedRoutes: 0
conditions:
- lastTransitionTime: null
message: Sending translated listener configuration to the data plane
reason: Programmed
status: "True"
type: Programmed
- lastTransitionTime: null
message: Listener has been successfully translated
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: null
message: Listener references have been resolved
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
name: http-2
supportedKinds:
- group: gateway.networking.k8s.io
kind: HTTPRoute
- group: gateway.networking.k8s.io
kind: GRPCRoute
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
creationTimestamp: null
name: gateway-2
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
listeners:
- allowedRoutes:
namespaces:
from: Same
name: http-3
port: 8888
protocol: HTTP
- hostname: example.com
name: http-4
port: 8888
protocol: HTTP
status:
listeners:
- attachedRoutes: 0
conditions:
- lastTransitionTime: null
message: Sending translated listener configuration to the data plane
reason: Programmed
status: "True"
type: Programmed
- lastTransitionTime: null
message: Listener has been successfully translated
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: null
message: Listener references have been resolved
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
name: http-3
supportedKinds:
- group: gateway.networking.k8s.io
kind: HTTPRoute
- group: gateway.networking.k8s.io
kind: GRPCRoute
- attachedRoutes: 0
conditions:
- lastTransitionTime: null
message: Sending translated listener configuration to the data plane
reason: Programmed
status: "True"
type: Programmed
- lastTransitionTime: null
message: Listener has been successfully translated
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: null
message: Listener references have been resolved
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
name: http-4
supportedKinds:
- group: gateway.networking.k8s.io
kind: HTTPRoute
- group: gateway.networking.k8s.io
kind: GRPCRoute
infraIR:
envoy-gateway-class:
proxy:
config:
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
creationTimestamp: null
name: test
namespace: envoy-gateway-system
spec:
logging: {}
mergeGateways: true
status: {}
listeners:
- address: null
name: envoy-gateway/gateway-1/http
ports:
- containerPort: 10080
name: envoy-gateway/gateway-1/http
protocol: HTTP
servicePort: 80
- address: null
name: envoy-gateway/gateway-1/http-2
ports:
- containerPort: 8888
name: envoy-gateway/gateway-1/http-2
protocol: HTTP
servicePort: 8888
metadata:
labels:
gateway.envoyproxy.io/owning-gatewayclass: envoy-gateway-class
name: envoy-gateway-class
xdsIR:
envoy-gateway-class:
accessLog:
text:
- path: /dev/stdout
http:
- address: 0.0.0.0
hostnames:
- '*'
isHTTP2: false
name: envoy-gateway/gateway-1/http
path:
escapedSlashesAction: UnescapeAndRedirect
mergeSlashes: true
port: 10080
- address: 0.0.0.0
hostnames:
- company.com
isHTTP2: false
name: envoy-gateway/gateway-1/http-2
path:
escapedSlashesAction: UnescapeAndRedirect
mergeSlashes: true
port: 8888
- address: 0.0.0.0
hostnames:
- '*'
isHTTP2: false
name: envoy-gateway/gateway-2/http-3
path:
escapedSlashesAction: UnescapeAndRedirect
mergeSlashes: true
port: 8888
- address: 0.0.0.0
hostnames:
- example.com
isHTTP2: false
name: envoy-gateway/gateway-2/http-4
path:
escapedSlashesAction: UnescapeAndRedirect
mergeSlashes: true
port: 8888
Loading