Skip to content

Commit 5aa5a7a

Browse files
authored
feat: Support configuring routes with Gateway API (#61)
* feat: Support configuring routes with Gateway API 1. Fix the Gateway API CRDs support in the API server. 2. Generate a basic GatewayClass and Gateway resource during preparation. 3. Fix the XDS cache issue causing delayed push of Gateway API configuration updates. * Remove PILOT_ENABLE_XDS_CACHE=false since the bug has been fixed
1 parent df03080 commit 5aa5a7a

File tree

4 files changed

+200
-22
lines changed

4 files changed

+200
-22
lines changed

compose/.env

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ NACOS_PASSWORD=''
88
NACOS_DATA_ENC_KEY='0123456789abcdef0123456789abcdef'
99
NACOS_SERVER_TAG='v2.2.3'
1010
HIGRESS_RUNNER_TAG='0.0.3'
11-
HIGRESS_API_SERVER_TAG='0.0.13'
11+
HIGRESS_API_SERVER_TAG='0.0.14'
1212
HIGRESS_CONTROLLER_TAG='1.3.5'
1313
HIGRESS_PILOT_TAG='1.3.5'
1414
HIGRESS_GATEWAY_TAG='1.3.5'

compose/scripts/prepare.sh

+94-3
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,12 @@ checkConfigExists() {
3333
if [[ "$configGroupVersion" == *"/"* ]]; then
3434
uriPrefix="/apis"
3535
fi
36-
local url="${API_SERVER_BASE_URL}{$uriPrefix}/${configGroupVersion}/namespaces/${namespace}/${configType}/${configName}"
36+
local url;
37+
if [ -z "$namespace" ]; then
38+
url="${API_SERVER_BASE_URL}${uriPrefix}/${configGroupVersion}/${configType}/${configName}"
39+
else
40+
url="${API_SERVER_BASE_URL}${uriPrefix}/${configGroupVersion}/namespaces/${namespace}/${configType}/${configName}"
41+
fi
3742
statusCode=$(curl -s -o /dev/null -w "%{http_code}" "${url}" -k)
3843
if [ $statusCode -eq 200 ]; then
3944
return 0
@@ -60,7 +65,12 @@ getConfig() {
6065
if [[ "$configGroupVersion" == *"/"* ]]; then
6166
uriPrefix="/apis"
6267
fi
63-
local url="${API_SERVER_BASE_URL}{$uriPrefix}/${configGroupVersion}/namespaces/${namespace}/${configType}/${configName}"
68+
local url;
69+
if [ -z "$namespace" ]; then
70+
url="${API_SERVER_BASE_URL}${uriPrefix}/${configGroupVersion}/${configType}/${configName}"
71+
else
72+
url="${API_SERVER_BASE_URL}${uriPrefix}/${configGroupVersion}/namespaces/${namespace}/${configType}/${configName}"
73+
fi
6474
local tmpFile=$(mktemp /tmp/higress-precheck-config.XXXXXXXXX.cfg)
6575
local statusCode=$(curl -s -o "$tmpFile" -w "%{http_code}" "${url}" -k -H "Accept: application/yaml")
6676
if [ $statusCode -eq 200 ]; then
@@ -92,7 +102,12 @@ publishConfig() {
92102
if [[ "$configGroupVersion" == *"/"* ]]; then
93103
uriPrefix="/apis"
94104
fi
95-
local url="${API_SERVER_BASE_URL}{$uriPrefix}/${configGroupVersion}/namespaces/${namespace}/${configType}"
105+
local url;
106+
if [ -z "$namespace" ]; then
107+
url="${API_SERVER_BASE_URL}${uriPrefix}/${configGroupVersion}/${configType}"
108+
else
109+
url="${API_SERVER_BASE_URL}${uriPrefix}/${configGroupVersion}/namespaces/${namespace}/${configType}"
110+
fi
96111
statusCode="$(curl -s -o /dev/null -w "%{http_code}" "$url" -k -X POST -H "Content-Type: application/yaml" -d "$content")"
97112
if [ $statusCode -ne 201 ]; then
98113
echo " Publishing config ${configType}.${configName} to namespace ${namespace} failed with ${statusCode}"
@@ -218,6 +233,7 @@ data:
218233
{"authority":"%REQ(:AUTHORITY)%","bytes_received":"%BYTES_RECEIVED%","bytes_sent":"%BYTES_SENT%","downstream_local_address":"%DOWNSTREAM_LOCAL_ADDRESS%","downstream_remote_address":"%DOWNSTREAM_REMOTE_ADDRESS%","duration":"%DURATION%","istio_policy_status":"%DYNAMIC_METADATA(istio.mixer:status)%","method":"%REQ(:METHOD)%","path":"%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%","protocol":"%PROTOCOL%","request_id":"%REQ(X-REQUEST-ID)%","requested_server_name":"%REQUESTED_SERVER_NAME%","response_code":"%RESPONSE_CODE%","response_flags":"%RESPONSE_FLAGS%","route_name":"%ROUTE_NAME%","start_time":"%START_TIME%","trace_id":"%REQ(X-B3-TRACEID)%","upstream_cluster":"%UPSTREAM_CLUSTER%","upstream_host":"%UPSTREAM_HOST%","upstream_local_address":"%UPSTREAM_LOCAL_ADDRESS%","upstream_service_time":"%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%","upstream_transport_failure_reason":"%UPSTREAM_TRANSPORT_FAILURE_REASON%","user_agent":"%REQ(USER-AGENT)%","x_forwarded_for":"%REQ(X-FORWARDED-FOR)%"}
219234
configSources:
220235
- address: xds://controller:15051
236+
- address: k8s://
221237
defaultConfig:
222238
disableAlpnH2: true
223239
discoveryAddress: pilot:15012
@@ -310,7 +326,82 @@ EOF
310326
fi
311327
}
312328

329+
checkGatewayApi() {
330+
echo "Checking Gateway API configurations..."
331+
332+
checkConfigExists "higress-system" "v1" "services" "higress-gateway"
333+
if [ $? -ne 0 ]; then
334+
echo " The Service resource \"higress-gateway\" doesn't exist. Create it now..."
335+
read -r -d '' content <<EOF
336+
apiVersion: v1
337+
kind: Service
338+
metadata:
339+
labels:
340+
higress: higress-system-higress-gateway
341+
name: higress-gateway
342+
namespace: higress-system
343+
spec:
344+
ports:
345+
- name: http2
346+
port: 80
347+
protocol: TCP
348+
targetPort: 80
349+
- name: https
350+
port: 443
351+
protocol: TCP
352+
targetPort: 443
353+
selector:
354+
higress: higress-system-higress-gateway
355+
type: LoadBalancer
356+
EOF
357+
publishConfig "higress-system" "v1" "services" "higress-gateway" "$content"
358+
fi
359+
360+
checkConfigExists "" "gateway.networking.k8s.io/v1beta1" "gatewayclasses" "higress-gateway"
361+
if [ $? -ne 0 ]; then
362+
echo " The GatewayClass resource \"higress-gateway\" doesn't exist. Create it now..."
363+
read -r -d '' content <<EOF
364+
apiVersion: gateway.networking.k8s.io/v1beta1
365+
kind: GatewayClass
366+
metadata:
367+
name: higress-gateway
368+
spec:
369+
controllerName: "higress.io/gateway-controller"
370+
EOF
371+
publishConfig "" "gateway.networking.k8s.io/v1beta1" "gatewayclasses" "higress-gateway" "$content"
372+
fi
373+
374+
checkConfigExists "higress-system" "gateway.networking.k8s.io/v1beta1" "gateways" "higress-gateway"
375+
if [ $? -ne 0 ]; then
376+
echo " The Gateway resource \"higress-gateway\" doesn't exist. Create it now..."
377+
read -r -d '' content <<EOF
378+
apiVersion: gateway.networking.k8s.io/v1beta1
379+
kind: Gateway
380+
metadata:
381+
name: higress-gateway
382+
namespace: higress-system
383+
spec:
384+
gatewayClassName: higress-gateway
385+
listeners:
386+
- name: http
387+
port: 80
388+
protocol: HTTP
389+
allowedRoutes:
390+
namespaces:
391+
from: All
392+
- name: https
393+
port: 443
394+
protocol: HTTPS
395+
allowedRoutes:
396+
namespaces:
397+
from: All
398+
EOF
399+
publishConfig "higress-system" "gateway.networking.k8s.io/v1beta1" "gateways" "higress-gateway" "$content"
400+
fi
401+
}
402+
313403
checkStorage
314404
checkPilot
315405
checkGateway
316406
checkConsole
407+
checkGatewayApi

src/apiserver/pkg/apiserver/apiserver.go

+1-18
Original file line numberDiff line numberDiff line change
@@ -381,24 +381,7 @@ func (c completedConfig) New() (*HigressServer, error) {
381381
func() runtime.Object { return &gwapiv1beta1.ReferenceGrantList{} },
382382
nil, false)
383383
gwapiApiGroupInfo.VersionedResourcesStorageMap[gwapiv1beta1.SchemeGroupVersion.Version] = gwapiv1beta1Storages
384-
gwapiv1alpha2Storages := map[string]rest.Storage{}
385-
appendStorage(gwapiv1alpha2Storages, storageCreateFunc, gwapiv1alpha2.SchemeGroupVersion, false, "gatewayclass", "gatewayclasses",
386-
func() runtime.Object { return &gwapiv1alpha2.GatewayClass{} },
387-
func() runtime.Object { return &gwapiv1alpha2.GatewayClassList{} },
388-
nil, false)
389-
appendStorage(gwapiv1alpha2Storages, storageCreateFunc, gwapiv1alpha2.SchemeGroupVersion, true, "gateway", "gateways",
390-
func() runtime.Object { return &gwapiv1alpha2.Gateway{} },
391-
func() runtime.Object { return &gwapiv1alpha2.GatewayList{} },
392-
nil, false)
393-
appendStorage(gwapiv1alpha2Storages, storageCreateFunc, gwapiv1alpha2.SchemeGroupVersion, true, "httproute", "httproutes",
394-
func() runtime.Object { return &gwapiv1alpha2.HTTPRoute{} },
395-
func() runtime.Object { return &gwapiv1alpha2.HTTPRouteList{} },
396-
nil, false)
397-
appendStorage(gwapiv1alpha2Storages, storageCreateFunc, gwapiv1alpha2.SchemeGroupVersion, true, "referencegrant", "referencegrants",
398-
func() runtime.Object { return &gwapiv1alpha2.ReferenceGrant{} },
399-
func() runtime.Object { return &gwapiv1alpha2.ReferenceGrantList{} },
400-
nil, false)
401-
gwapiApiGroupInfo.VersionedResourcesStorageMap[gwapiv1alpha2.SchemeGroupVersion.Version] = gwapiv1alpha2Storages
384+
gwapiApiGroupInfo.VersionedResourcesStorageMap[gwapiv1alpha2.SchemeGroupVersion.Version] = gwapiv1beta1Storages
402385
if err := s.GenericAPIServer.InstallAPIGroup(&gwapiApiGroupInfo); err != nil {
403386
return nil, err
404387
}

src/apiserver/pkg/converter/gatewayapi.go

+104
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,32 @@ import (
88
)
99

1010
func registerGatewayApiConverters(scheme *runtime.Scheme) {
11+
_ = scheme.Converter().RegisterUntypedConversionFunc(&gwapiv1alpha2.GatewayClassList{}, &gwapiv1beta1.GatewayClassList{},
12+
func(a, b interface{}, scope conversion.Scope) error {
13+
lb := b.(*gwapiv1beta1.GatewayClassList)
14+
la := a.(*gwapiv1alpha2.GatewayClassList)
15+
lb.Items = make([]gwapiv1beta1.GatewayClass, len(la.Items))
16+
for i := range la.Items {
17+
if err := scheme.Convert(&la.Items[i], &lb.Items[i], scope); err != nil {
18+
return err
19+
}
20+
}
21+
setApiVersion(b, gwapiv1beta1.GroupVersion)
22+
return nil
23+
})
24+
_ = scheme.Converter().RegisterUntypedConversionFunc(&gwapiv1beta1.GatewayClassList{}, &gwapiv1alpha2.GatewayClassList{},
25+
func(a, b interface{}, scope conversion.Scope) error {
26+
lb := b.(*gwapiv1alpha2.GatewayClassList)
27+
la := a.(*gwapiv1beta1.GatewayClassList)
28+
lb.Items = make([]gwapiv1alpha2.GatewayClass, len(la.Items))
29+
for i := range la.Items {
30+
if err := scheme.Convert(&la.Items[i], &lb.Items[i], scope); err != nil {
31+
return err
32+
}
33+
}
34+
setApiVersion(b, gwapiv1alpha2.GroupVersion)
35+
return nil
36+
})
1137
_ = scheme.Converter().RegisterUntypedConversionFunc(&gwapiv1alpha2.GatewayClass{}, &gwapiv1beta1.GatewayClass{},
1238
func(a, b interface{}, scope conversion.Scope) error {
1339
*(b.(*gwapiv1beta1.GatewayClass)) = gwapiv1beta1.GatewayClass(*a.(*gwapiv1alpha2.GatewayClass))
@@ -21,6 +47,32 @@ func registerGatewayApiConverters(scheme *runtime.Scheme) {
2147
return nil
2248
})
2349

50+
_ = scheme.Converter().RegisterUntypedConversionFunc(&gwapiv1alpha2.GatewayList{}, &gwapiv1beta1.GatewayList{},
51+
func(a, b interface{}, scope conversion.Scope) error {
52+
lb := b.(*gwapiv1beta1.GatewayList)
53+
la := a.(*gwapiv1alpha2.GatewayList)
54+
lb.Items = make([]gwapiv1beta1.Gateway, len(la.Items))
55+
for i := range la.Items {
56+
if err := scheme.Convert(&la.Items[i], &lb.Items[i], scope); err != nil {
57+
return err
58+
}
59+
}
60+
setApiVersion(b, gwapiv1beta1.GroupVersion)
61+
return nil
62+
})
63+
_ = scheme.Converter().RegisterUntypedConversionFunc(&gwapiv1beta1.GatewayList{}, &gwapiv1alpha2.GatewayList{},
64+
func(a, b interface{}, scope conversion.Scope) error {
65+
lb := b.(*gwapiv1alpha2.GatewayList)
66+
la := a.(*gwapiv1beta1.GatewayList)
67+
lb.Items = make([]gwapiv1alpha2.Gateway, len(la.Items))
68+
for i := range la.Items {
69+
if err := scheme.Convert(&la.Items[i], &lb.Items[i], scope); err != nil {
70+
return err
71+
}
72+
}
73+
setApiVersion(b, gwapiv1alpha2.GroupVersion)
74+
return nil
75+
})
2476
_ = scheme.Converter().RegisterUntypedConversionFunc(&gwapiv1alpha2.Gateway{}, &gwapiv1beta1.Gateway{},
2577
func(a, b interface{}, scope conversion.Scope) error {
2678
*(b.(*gwapiv1beta1.Gateway)) = gwapiv1beta1.Gateway(*a.(*gwapiv1alpha2.Gateway))
@@ -34,6 +86,32 @@ func registerGatewayApiConverters(scheme *runtime.Scheme) {
3486
return nil
3587
})
3688

89+
_ = scheme.Converter().RegisterUntypedConversionFunc(&gwapiv1alpha2.HTTPRouteList{}, &gwapiv1beta1.HTTPRouteList{},
90+
func(a, b interface{}, scope conversion.Scope) error {
91+
lb := b.(*gwapiv1beta1.HTTPRouteList)
92+
la := a.(*gwapiv1alpha2.HTTPRouteList)
93+
lb.Items = make([]gwapiv1beta1.HTTPRoute, len(la.Items))
94+
for i := range la.Items {
95+
if err := scheme.Convert(&la.Items[i], &lb.Items[i], scope); err != nil {
96+
return err
97+
}
98+
}
99+
setApiVersion(b, gwapiv1beta1.GroupVersion)
100+
return nil
101+
})
102+
_ = scheme.Converter().RegisterUntypedConversionFunc(&gwapiv1beta1.HTTPRouteList{}, &gwapiv1alpha2.HTTPRouteList{},
103+
func(a, b interface{}, scope conversion.Scope) error {
104+
lb := b.(*gwapiv1alpha2.HTTPRouteList)
105+
la := a.(*gwapiv1beta1.HTTPRouteList)
106+
lb.Items = make([]gwapiv1alpha2.HTTPRoute, len(la.Items))
107+
for i := range la.Items {
108+
if err := scheme.Convert(&la.Items[i], &lb.Items[i], scope); err != nil {
109+
return err
110+
}
111+
}
112+
setApiVersion(b, gwapiv1alpha2.GroupVersion)
113+
return nil
114+
})
37115
_ = scheme.Converter().RegisterUntypedConversionFunc(&gwapiv1alpha2.HTTPRoute{}, &gwapiv1beta1.HTTPRoute{},
38116
func(a, b interface{}, scope conversion.Scope) error {
39117
*(b.(*gwapiv1beta1.HTTPRoute)) = gwapiv1beta1.HTTPRoute(*a.(*gwapiv1alpha2.HTTPRoute))
@@ -47,6 +125,32 @@ func registerGatewayApiConverters(scheme *runtime.Scheme) {
47125
return nil
48126
})
49127

128+
_ = scheme.Converter().RegisterUntypedConversionFunc(&gwapiv1alpha2.ReferenceGrantList{}, &gwapiv1beta1.ReferenceGrantList{},
129+
func(a, b interface{}, scope conversion.Scope) error {
130+
lb := b.(*gwapiv1beta1.ReferenceGrantList)
131+
la := a.(*gwapiv1alpha2.ReferenceGrantList)
132+
lb.Items = make([]gwapiv1beta1.ReferenceGrant, len(la.Items))
133+
for i := range la.Items {
134+
if err := scheme.Convert(&la.Items[i], &lb.Items[i], scope); err != nil {
135+
return err
136+
}
137+
}
138+
setApiVersion(b, gwapiv1beta1.GroupVersion)
139+
return nil
140+
})
141+
_ = scheme.Converter().RegisterUntypedConversionFunc(&gwapiv1beta1.ReferenceGrantList{}, &gwapiv1alpha2.ReferenceGrantList{},
142+
func(a, b interface{}, scope conversion.Scope) error {
143+
lb := b.(*gwapiv1alpha2.ReferenceGrantList)
144+
la := a.(*gwapiv1beta1.ReferenceGrantList)
145+
lb.Items = make([]gwapiv1alpha2.ReferenceGrant, len(la.Items))
146+
for i := range la.Items {
147+
if err := scheme.Convert(&la.Items[i], &lb.Items[i], scope); err != nil {
148+
return err
149+
}
150+
}
151+
setApiVersion(b, gwapiv1alpha2.GroupVersion)
152+
return nil
153+
})
50154
_ = scheme.Converter().RegisterUntypedConversionFunc(&gwapiv1alpha2.ReferenceGrant{}, &gwapiv1beta1.ReferenceGrant{},
51155
func(a, b interface{}, scope conversion.Scope) error {
52156
*(b.(*gwapiv1beta1.ReferenceGrant)) = gwapiv1beta1.ReferenceGrant(*a.(*gwapiv1alpha2.ReferenceGrant))

0 commit comments

Comments
 (0)