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: don't fail when creating the service if mergeGateway is enabled and multiple gateways have the same port. #2751

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions internal/gatewayapi/translator.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ func (t *Translator) InitIRs(gateways []*GatewayContext, resources *Resources) (

if isMergeGatewaysEnabled(resources) {
t.MergeGateways = true
gwXdsIR.MergeGateways = true
irKey = string(t.GatewayClassName)

maps.Copy(labels, GatewayClassOwnerLabel(string(t.GatewayClassName)))
Expand Down
39 changes: 23 additions & 16 deletions internal/infrastructure/kubernetes/proxy/resource_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,31 +67,38 @@
// Service returns the expected Service based on the provided infra.
func (r *ResourceRender) Service() (*corev1.Service, error) {
var ports []corev1.ServicePort
configuredPorts := map[int32]bool{}
for _, listener := range r.infra.Listeners {
for _, port := range listener.Ports {
target := intstr.IntOrString{IntVal: port.ContainerPort}
protocol := corev1.ProtocolTCP
if port.Protocol == ir.UDPProtocolType {
protocol = corev1.ProtocolUDP
}

p := corev1.ServicePort{
Name: ExpectedResourceHashedName(port.Name),
Protocol: protocol,
Port: port.ServicePort,
TargetPort: target,
}
ports = append(ports, p)
if alreadyHasHttp3, found := configuredPorts[port.ContainerPort]; !found || !alreadyHasHttp3 {

Check failure on line 74 in internal/infrastructure/kubernetes/proxy/resource_provider.go

View workflow job for this annotation

GitHub Actions / lint

ST1003: var alreadyHasHttp3 should be alreadyHasHTTP3 (stylecheck)
if !found {
protocol := corev1.ProtocolTCP
if port.Protocol == ir.UDPProtocolType {
protocol = corev1.ProtocolUDP
}

if port.Protocol == ir.HTTPSProtocolType {
if listener.HTTP3 != nil {
p := corev1.ServicePort{
Name: ExpectedResourceHashedName(port.Name + "-h3"),
Protocol: corev1.ProtocolUDP,
Name: ExpectedResourceHashedName(port.Name),
Protocol: protocol,
Port: port.ServicePort,
TargetPort: target,
}
ports = append(ports, p)
configuredPorts[port.ServicePort] = false
}

if port.Protocol == ir.HTTPSProtocolType {
if listener.HTTP3 != nil && !alreadyHasHttp3 {
p := corev1.ServicePort{
Name: ExpectedResourceHashedName(port.Name + "-h3"),
Protocol: corev1.ProtocolUDP,
Port: port.ServicePort,
TargetPort: target,
}
ports = append(ports, p)
configuredPorts[port.ServicePort] = true
}
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions internal/ir/xds.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ type Xds struct {
UDP []*UDPListener `json:"udp,omitempty" yaml:"udp,omitempty"`
// EnvoyPatchPolicies is the intermediate representation of the EnvoyPatchPolicy resource
EnvoyPatchPolicies []*EnvoyPatchPolicy `json:"envoyPatchPolicies,omitempty" yaml:"envoyPatchPolicies,omitempty"`
// MergeGateways indicates if this IR should be translated to work in the merged gateways scenario
MergeGateways bool `json:"mergeGateways,omitempty" yaml:"mergeGateways,omitempty"`
}

// Equal implements the Comparable interface used by watchable.DeepEqual to skip unnecessary updates.
Expand Down
28 changes: 15 additions & 13 deletions internal/xds/translator/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ func buildXdsQuicListener(name, address string, port uint32, accesslog *ir.Acces
}

func (t *Translator) addXdsHTTPFilterChain(xdsListener *listenerv3.Listener, irListener *ir.HTTPListener,
accesslog *ir.AccessLog, tracing *ir.Tracing, http3Listener bool) error {
accesslog *ir.AccessLog, tracing *ir.Tracing, http3Listener bool, mergeGateways bool) error {
al := buildXdsAccessLog(accesslog, false)

hcmTracing, err := buildHCMTracing(tracing)
Expand Down Expand Up @@ -274,20 +274,22 @@ func (t *Translator) addXdsHTTPFilterChain(xdsListener *listenerv3.Listener, irL
}},
}

if irListener.TLS != nil {
var tSocket *corev3.TransportSocket
if http3Listener {
tSocket, err = buildDownstreamQUICTransportSocket(irListener.TLS)
if err != nil {
return err
}
} else {
tSocket, err = buildXdsDownstreamTLSSocket(irListener.TLS)
if err != nil {
return err
if irListener.TLS != nil || mergeGateways {
if irListener.TLS != nil {
var tSocket *corev3.TransportSocket
if http3Listener {
tSocket, err = buildDownstreamQUICTransportSocket(irListener.TLS)
if err != nil {
return err
}
} else {
tSocket, err = buildXdsDownstreamTLSSocket(irListener.TLS)
if err != nil {
return err
}
}
filterChain.TransportSocket = tSocket
}
filterChain.TransportSocket = tSocket
if err := addServerNamesMatch(xdsListener, filterChain, irListener.Hostnames); err != nil {
return err
}
Expand Down
17 changes: 7 additions & 10 deletions internal/xds/translator/translator.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func (t *Translator) Translate(ir *ir.Xds) (*types.ResourceVersionTable, error)
// to collect all errors and reflect them in the status of the CRDs.
var errs error
if err := t.processHTTPListenerXdsTranslation(
tCtx, ir.HTTP, ir.AccessLog, ir.Tracing, ir.Metrics); err != nil {
tCtx, ir.HTTP, ir.AccessLog, ir.Tracing, ir.Metrics, ir.MergeGateways); err != nil {
errs = errors.Join(errs, err)
}

Expand Down Expand Up @@ -115,12 +115,12 @@ func (t *Translator) processHTTPListenerXdsTranslation(
accessLog *ir.AccessLog,
tracing *ir.Tracing,
metrics *ir.Metrics,
mergeGateways bool,
) error {
// The XDS translation is done in a best-effort manner, so we collect all
// errors and return them at the end.
var errs error
for _, httpListener := range httpListeners {
addFilterChain := true
var xdsRouteCfg *routev3.RouteConfiguration

// Search for an existing listener, if it does not exist, create one.
Expand Down Expand Up @@ -149,7 +149,6 @@ func (t *Translator) processHTTPListenerXdsTranslation(
// If an existing listener exists, dont create a new filter chain
// for HTTP traffic, match on the Domains field within VirtualHosts
// within the same RouteConfiguration instead
addFilterChain = false
xdsRouteCfg = findXdsRouteConfig(tCtx, routeName)
if xdsRouteCfg == nil {
// skip this listener if failed to find xds route config
Expand All @@ -159,15 +158,13 @@ func (t *Translator) processHTTPListenerXdsTranslation(
}
}

if addFilterChain {
if err := t.addXdsHTTPFilterChain(xdsListener, httpListener, accessLog, tracing, false); err != nil {
if err := t.addXdsHTTPFilterChain(xdsListener, httpListener, accessLog, tracing, false, mergeGateways); err != nil {
return err
}
if enabledHTTP3 {
if err := t.addXdsHTTPFilterChain(quicXDSListener, httpListener, accessLog, tracing, true, mergeGateways); err != nil {
return err
}
if enabledHTTP3 {
if err := t.addXdsHTTPFilterChain(quicXDSListener, httpListener, accessLog, tracing, true); err != nil {
return err
}
}
}

// Create a route config if we have not found one yet
Expand Down
Loading