Skip to content

Commit e883c48

Browse files
committed
Add support for backendref service appProtocol
1 parent fbc098b commit e883c48

File tree

8 files changed

+532
-19
lines changed

8 files changed

+532
-19
lines changed

internal/controller/state/conditions/conditions.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ const (
3333
// Route rules has a backendRef with an unsupported value.
3434
RouteReasonBackendRefUnsupportedValue v1.RouteConditionReason = "UnsupportedValue"
3535

36+
// RouteReasonBackendRefUnsupportedProtocol is used with the "ResolvedRefs" condition when one of the
37+
// Route rules has a backendRef with an unsupported protocol.
38+
RouteReasonBackendRefUnsupportedProtocol v1.RouteConditionReason = "UnsupportedProtocol"
39+
3640
// RouteReasonInvalidGateway is used with the "Accepted" (false) condition when the Gateway the Route
3741
// references is invalid.
3842
RouteReasonInvalidGateway v1.RouteConditionReason = "InvalidGateway"
@@ -398,6 +402,17 @@ func NewRouteBackendRefUnsupportedValue(msg string) Condition {
398402
}
399403
}
400404

405+
// NewRouteBackendRefUnsupportedProtocol returns a Condition that indicates that the Route has a backendRef with
406+
// an unsupported protocol.
407+
func NewRouteBackendRefUnsupportedProtocol(msg string) Condition {
408+
return Condition{
409+
Type: string(v1.RouteConditionResolvedRefs),
410+
Status: metav1.ConditionFalse,
411+
Reason: string(RouteReasonBackendRefUnsupportedValue),
412+
Message: msg,
413+
}
414+
}
415+
401416
// NewRouteInvalidGateway returns a Condition that indicates that the Route is not Accepted because the Gateway it
402417
// references is invalid.
403418
func NewRouteInvalidGateway() Condition {

internal/controller/state/graph/backend_refs.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ import (
1717
"github.com/nginx/nginx-gateway-fabric/internal/framework/helpers"
1818
)
1919

20+
const (
21+
AppProtocolTypeH2C string = "kubernetes.io/h2c"
22+
AppProtocolTypeWS string = "kubernetes.io/ws"
23+
AppProtocolTypeWSS string = "kubernetes.io/wss"
24+
)
25+
2026
// BackendRef is an internal representation of a backendRef in an HTTP/GRPC/TLSRoute.
2127
type BackendRef struct {
2228
// BackendTLSPolicy is the BackendTLSPolicy of the Service which is referenced by the backendRef.
@@ -200,6 +206,33 @@ func createBackendRef(
200206
return backendRef, append(conds, conditions.NewRouteBackendRefUnsupportedValue(err.Error()))
201207
}
202208

209+
if svcPort.AppProtocol != nil {
210+
valid = validateRouteBackendRefAppProtocol(route.RouteType, *svcPort.AppProtocol, backendTLSPolicy)
211+
if !valid {
212+
backendRef := BackendRef{
213+
SvcNsName: svcNsName,
214+
BackendTLSPolicy: backendTLSPolicy,
215+
ServicePort: svcPort,
216+
Weight: weight,
217+
Valid: false,
218+
IsMirrorBackend: ref.MirrorBackendIdx != nil,
219+
InvalidForGateways: invalidForGateways,
220+
}
221+
222+
err := fmt.Errorf(
223+
"route type %s does not support service port appProtocol %s",
224+
route.RouteType,
225+
*svcPort.AppProtocol,
226+
).Error()
227+
228+
if route.RouteType == RouteTypeHTTP && *svcPort.AppProtocol == AppProtocolTypeWSS && backendTLSPolicy == nil {
229+
err += "; missing corresponding BackendTLSPolicy"
230+
}
231+
232+
return backendRef, append(conds, conditions.NewRouteBackendRefUnsupportedProtocol(err))
233+
}
234+
}
235+
203236
backendRef := BackendRef{
204237
SvcNsName: svcNsName,
205238
BackendTLSPolicy: backendTLSPolicy,
@@ -414,6 +447,24 @@ func validateBackendRef(
414447
return true, conditions.Condition{}
415448
}
416449

450+
func validateRouteBackendRefAppProtocol(
451+
routeType RouteType,
452+
appProtocol string,
453+
backendTLSPolicy *BackendTLSPolicy,
454+
) (valid bool) {
455+
// Currently we only support recognition of the Kubernetes Standard Application Protocols defined in KEP-3726.
456+
switch appProtocol {
457+
case AppProtocolTypeH2C:
458+
return routeType == RouteTypeHTTP || routeType == RouteTypeGRPC
459+
case AppProtocolTypeWS:
460+
return routeType == RouteTypeHTTP
461+
case AppProtocolTypeWSS:
462+
return (routeType == RouteTypeHTTP && backendTLSPolicy != nil) || routeType == RouteTypeTLS
463+
}
464+
465+
return true
466+
}
467+
417468
func validateWeight(weight int32) error {
418469
const (
419470
minWeight = 0

0 commit comments

Comments
 (0)