Support http and https appProtocol for Kubernetes Service

This commit is contained in:
Will Da Silva 2024-10-09 10:26:04 -04:00 committed by GitHub
parent c441d04788
commit e9d677f8cb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 47 additions and 17 deletions

View file

@ -96,6 +96,7 @@ spec:
- name: web
protocol: TCP
port: 8080
appProtocol: http
targetPort: web
selector:
app: containous
@ -131,6 +132,8 @@ metadata:
spec:
ports:
- name: websecure
protocol: TCP
appProtocol: https
port: 443
targetPort: websecure
selector:

View file

@ -2,6 +2,7 @@ package gateway
import (
"context"
"errors"
"fmt"
"net"
"strconv"
@ -337,14 +338,15 @@ func (p *Provider) loadGRPCServers(namespace string, route *gatev1.GRPCRoute, ba
}
}
if svcPort.AppProtocol != nil && *svcPort.AppProtocol != appProtocolH2C {
protocol, err := getGRPCServiceProtocol(svcPort)
if err != nil {
return nil, &metav1.Condition{
Type: string(gatev1.RouteConditionResolvedRefs),
Status: metav1.ConditionFalse,
ObservedGeneration: route.Generation,
LastTransitionTime: metav1.Now(),
Reason: string(gatev1.RouteReasonUnsupportedProtocol),
Message: fmt.Sprintf("Cannot load GRPCBackendRef %s/%s: only kubernetes.io/h2c appProtocol is supported", namespace, backendRef.Name),
Message: fmt.Sprintf("Cannot load GRPCBackendRef %s/%s: only \"kubernetes.io/h2c\" and \"https\" appProtocol is supported", namespace, backendRef.Name),
}
}
@ -353,7 +355,7 @@ func (p *Provider) loadGRPCServers(namespace string, route *gatev1.GRPCRoute, ba
for _, ba := range backendAddresses {
lb.Servers = append(lb.Servers, dynamic.Server{
URL: fmt.Sprintf("h2c://%s", net.JoinHostPort(ba.IP, strconv.Itoa(int(ba.Port)))),
URL: fmt.Sprintf("%s://%s", protocol, net.JoinHostPort(ba.IP, strconv.Itoa(int(ba.Port)))),
})
}
return lb, nil
@ -408,3 +410,22 @@ func buildGRPCHeaderRules(headers []gatev1.GRPCHeaderMatch) []string {
return rules
}
func getGRPCServiceProtocol(portSpec corev1.ServicePort) (string, error) {
if portSpec.Protocol != corev1.ProtocolTCP {
return "", errors.New("only TCP protocol is supported")
}
if portSpec.AppProtocol == nil {
return schemeH2C, nil
}
switch ap := *portSpec.AppProtocol; ap {
case appProtocolH2C:
return schemeH2C, nil
case appProtocolHTTPS:
return schemeHTTPS, nil
default:
return "", fmt.Errorf("unsupported application protocol %s", ap)
}
}

View file

@ -468,7 +468,7 @@ func (p *Provider) loadHTTPServers(namespace string, route *gatev1.HTTPRoute, ba
}
}
protocol, err := getProtocol(svcPort)
protocol, err := getHTTPServiceProtocol(svcPort)
if err != nil {
return nil, corev1.ServicePort{}, &metav1.Condition{
Type: string(gatev1.RouteConditionResolvedRefs),
@ -721,7 +721,7 @@ func createRequestRedirect(filter *gatev1.HTTPRequestRedirectFilter, pathMatch g
var port *string
filterScheme := ptr.Deref(filter.Scheme, "")
if filterScheme == "http" || filterScheme == "https" {
if filterScheme == schemeHTTP || filterScheme == schemeHTTPS {
port = ptr.To("")
}
if filter.Port != nil {
@ -783,26 +783,26 @@ func createURLRewrite(filter *gatev1.HTTPURLRewriteFilter, pathMatch gatev1.HTTP
}, nil
}
func getProtocol(portSpec corev1.ServicePort) (string, error) {
func getHTTPServiceProtocol(portSpec corev1.ServicePort) (string, error) {
if portSpec.Protocol != corev1.ProtocolTCP {
return "", errors.New("only TCP protocol is supported")
}
if portSpec.AppProtocol == nil {
protocol := "http"
if portSpec.Port == 443 || strings.HasPrefix(portSpec.Name, "https") {
protocol = "https"
protocol := schemeHTTP
if portSpec.Port == 443 || strings.HasPrefix(portSpec.Name, schemeHTTPS) {
protocol = schemeHTTPS
}
return protocol, nil
}
switch ap := *portSpec.AppProtocol; ap {
case appProtocolH2C:
return "h2c", nil
case appProtocolWS:
return "http", nil
case appProtocolWSS:
return "https", nil
return schemeH2C, nil
case appProtocolHTTP, appProtocolWS:
return schemeHTTP, nil
case appProtocolHTTPS, appProtocolWSS:
return schemeHTTPS, nil
default:
return "", fmt.Errorf("unsupported application protocol %s", ap)
}

View file

@ -50,9 +50,15 @@ const (
kindTLSRoute = "TLSRoute"
kindService = "Service"
appProtocolH2C = "kubernetes.io/h2c"
appProtocolWS = "kubernetes.io/ws"
appProtocolWSS = "kubernetes.io/wss"
appProtocolHTTP = "http"
appProtocolHTTPS = "https"
appProtocolH2C = "kubernetes.io/h2c"
appProtocolWS = "kubernetes.io/ws"
appProtocolWSS = "kubernetes.io/wss"
schemeHTTP = "http"
schemeHTTPS = "https"
schemeH2C = "h2c"
)
// Provider holds configurations of the provider.