Skip to content

Commit edbb688

Browse files
authored
Engnode 568 (#3997)
* feat: use latest gateway api versions only Pin ReferenceGrant, TLSRoute, and BackendTLSPolicy syncing to the v1 Gateway API versions instead of negotiating older served versions against the host. Hosts whose Gateway API CRDs do not serve v1 fail fast at startup with an actionable error. Signed-off-by: Ryan Swanson <ryan.swanson@loft.sh> * fix: install tenant referencegrant crd whenever route sync is enabled - route controllers watch virtual ReferenceGrants regardless of sync.toHost.gatewayApi.referenceGrants.enabled; with the flag "false" the CRD was never installed and the watch failed forever, silently blocking all HTTPRoute/TLSRoute sync - extract EnsureReferenceGrantCRD and call it from the HTTPRoute and TLSRoute mappers, keeping "false" semantics: grants never sync to the host and virtual grants stay authoritative for cross-namespace refs - add gatewayapi-grants-disabled e2e suite plus a unit test asserting route mappers ensure the grant CRD when grant sync is disabled Signed-off-by: Ryan Swanson <ryan.swanson@loft.sh> * fix: install tenant referencegrant crd whenever route sync is enabled - route controllers watch virtual ReferenceGrants for cross-namespace authorization regardless of sync.toHost.gatewayApi.referenceGrants.enabled; with the flag "false" the CRD was never installed and the watch failed forever (no matches for kind "ReferenceGrant"), silently blocking all HTTPRoute/TLSRoute sync - extract EnsureReferenceGrantCRD and call it from the HTTPRoute and TLSRoute mappers, independent of grant sync - keep "false" semantics: no host discovery check, no mapper, no syncer, grants never sync to the host; virtual grants stay authoritative for cross-namespace refs in single-namespace mode - add gatewayapi-grants-disabled e2e suite: same-namespace route syncs, cross-namespace backendRef denied until a virtual ReferenceGrant permits it, grant itself never syncs to the host - add unit test asserting route mappers ensure the grant CRD when grant sync is disabled Signed-off-by: Ryan Swanson <ryan.swanson@loft.sh> # Conflicts: # e2e-next/test_gatewayapi/test_gatewayapi_grants_disabled.go # pkg/mappings/resources/register_gateway_test.go # pkg/mappings/resources/tlsroutes.go * fix: enable tenant gateway sync via the gatewayapi umbrella switch The umbrella sync.toHost.gatewayApi.enabled only enabled HTTPRoute sync: the tenant gateways CRD was never installed, host RBAC for gateways was never granted, and route controllers logged watch errors for the missing Gateway kind. - honor the umbrella in GatewaysEnabled and the chart gateways RBAC rule - install the tenant Gateway CRD whenever route sync is enabled - sync ReferenceGrants to the host only with namespace sync or an explicit referenceGrants toggle, matching the read-only RBAC the chart grants in single-namespace mode; tenant-side validation is unchanged - document umbrella and referenceGrants auto semantics in the schema - add umbrella-only e2e suite plus unit and chart test coverage Closes ENGNODE-568 Signed-off-by: Ryan Swanson <ryan.swanson@loft.sh> --------- Signed-off-by: Ryan Swanson <ryan.swanson@loft.sh>
1 parent 7f4d24d commit edbb688

21 files changed

Lines changed: 515 additions & 54 deletions

chart/templates/clusterrole.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ rules:
8383
resources: ["ingressclasses"]
8484
verbs: ["get", "watch", "list"]
8585
{{- end }}
86-
{{- if or .Values.sync.fromHost.gatewayClasses.enabled .Values.sync.fromHost.gateways.enabled }}
86+
{{- if or .Values.sync.fromHost.gatewayClasses.enabled .Values.sync.fromHost.gateways.enabled .Values.sync.toHost.gatewayApi.enabled }}
8787
- apiGroups: ["gateway.networking.k8s.io"]
8888
resources: ["gatewayclasses"]
8989
verbs: ["get", "watch", "list"]

chart/templates/role.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ rules:
8686
# Gateway API /status subresources are intentionally omitted for this block:
8787
# vCluster only mirrors host status to virtual resources.
8888
{{- end }}
89-
{{- if .Values.sync.toHost.gatewayApi.gateways.enabled }}
89+
{{- if or .Values.sync.toHost.gatewayApi.enabled .Values.sync.toHost.gatewayApi.gateways.enabled }}
9090
- apiGroups: ["gateway.networking.k8s.io"]
9191
resources: ["gateways"]
9292
verbs: ["create", "delete", "patch", "update", "get", "list", "watch"]

chart/tests/clusterrole_test.yaml

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -922,3 +922,67 @@ tests:
922922
apiGroups: ["resource.k8s.io"]
923923
resources: ["deviceclasses"]
924924
verbs: ["get", "watch", "list"]
925+
926+
- it: gateway api umbrella enables gatewayclasses rule
927+
set:
928+
sync:
929+
toHost:
930+
gatewayApi:
931+
enabled: true
932+
release:
933+
name: my-release
934+
namespace: my-namespace
935+
asserts:
936+
- hasDocuments:
937+
count: 1
938+
- equal:
939+
path: kind
940+
value: ClusterRole
941+
- contains:
942+
path: rules
943+
content:
944+
apiGroups: ["gateway.networking.k8s.io"]
945+
resources: ["gatewayclasses"]
946+
verbs: ["get", "watch", "list"]
947+
948+
- it: gateway api explicit gateways toggle does not enable gatewayclasses rule
949+
set:
950+
sync:
951+
toHost:
952+
gatewayApi:
953+
gateways:
954+
enabled: true
955+
release:
956+
name: my-release
957+
namespace: my-namespace
958+
asserts:
959+
- hasDocuments:
960+
count: 1
961+
- notContains:
962+
path: rules
963+
content:
964+
apiGroups: ["gateway.networking.k8s.io"]
965+
resources: ["gatewayclasses"]
966+
verbs: ["get", "watch", "list"]
967+
968+
- it: fromHost gateways enables gatewayclasses rule
969+
set:
970+
sync:
971+
fromHost:
972+
gateways:
973+
enabled: true
974+
mappings:
975+
byName:
976+
"default/my-gateway": "default/my-gateway"
977+
release:
978+
name: my-release
979+
namespace: my-namespace
980+
asserts:
981+
- hasDocuments:
982+
count: 1
983+
- contains:
984+
path: rules
985+
content:
986+
apiGroups: ["gateway.networking.k8s.io"]
987+
resources: ["gatewayclasses"]
988+
verbs: ["get", "watch", "list"]

chart/tests/role_test.yaml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,57 @@ tests:
397397
verbs:
398398
["create", "delete", "patch", "update", "get", "list", "watch"]
399399

400+
- it: gateway api umbrella enables gateways and httproutes rules
401+
set:
402+
sync:
403+
toHost:
404+
gatewayApi:
405+
enabled: true
406+
release:
407+
name: my-release
408+
namespace: my-namespace
409+
asserts:
410+
- hasDocuments:
411+
count: 1
412+
- equal:
413+
path: kind
414+
value: Role
415+
- contains:
416+
path: rules
417+
content:
418+
apiGroups: ["gateway.networking.k8s.io"]
419+
resources: ["gateways"]
420+
verbs:
421+
["create", "delete", "patch", "update", "get", "list", "watch"]
422+
- contains:
423+
path: rules
424+
content:
425+
apiGroups: ["gateway.networking.k8s.io"]
426+
resources: ["httproutes"]
427+
verbs:
428+
["create", "delete", "patch", "update", "get", "list", "watch"]
429+
430+
- it: gateway api explicit gateways toggle enables gateways rule
431+
set:
432+
sync:
433+
toHost:
434+
gatewayApi:
435+
gateways:
436+
enabled: true
437+
release:
438+
name: my-release
439+
namespace: my-namespace
440+
asserts:
441+
- hasDocuments:
442+
count: 1
443+
- contains:
444+
path: rules
445+
content:
446+
apiGroups: ["gateway.networking.k8s.io"]
447+
resources: ["gateways"]
448+
verbs:
449+
["create", "delete", "patch", "update", "get", "list", "watch"]
450+
400451
- it: private nodes
401452
set:
402453
privateNodes:

chart/values.schema.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2598,7 +2598,7 @@
25982598
},
25992599
"referenceGrants": {
26002600
"$ref": "#/$defs/EnableAutoSwitchWithPatches",
2601-
"description": "ReferenceGrants configures ReferenceGrant sync to the control plane cluster. Enabled may be \"auto\", \"true\", or \"false\"."
2601+
"description": "ReferenceGrants configures ReferenceGrant sync to the control plane cluster. Enabled may be \"auto\", \"true\", or \"false\".\nIn auto mode grants follow route sync and are validated within the tenant cluster; they sync to the control plane cluster only when namespace sync is also enabled."
26022602
}
26032603
},
26042604
"additionalProperties": false,
@@ -5306,7 +5306,7 @@
53065306
},
53075307
"gatewayApi": {
53085308
"$ref": "#/$defs/GatewayAPIEnableSwitchWithPatches",
5309-
"description": "GatewayAPI defines Gateway API resources created within the tenant cluster that should get synced to the control plane cluster."
5309+
"description": "GatewayAPI defines Gateway API resources created within the tenant cluster that should get synced to the control plane cluster.\nSetting enabled: true turns on Gateway and HTTPRoute sync, imports control plane cluster GatewayClasses so tenant Gateways can resolve them, and serves tenant ReferenceGrants for validation; TLSRoutes and BackendTLSPolicies must be enabled individually."
53105310
},
53115311
"services": {
53125312
"$ref": "#/$defs/EnableSwitchWithPatches",

chart/values.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ sync:
8282
# Enabled defines if this option should be enabled.
8383
enabled: false
8484
# GatewayAPI defines Gateway API resources created within the tenant cluster that should get synced to the control plane cluster.
85+
# Setting enabled: true turns on Gateway and HTTPRoute sync, imports control plane cluster GatewayClasses so tenant Gateways can resolve them, and serves tenant ReferenceGrants for validation; TLSRoutes and BackendTLSPolicies must be enabled individually.
8586
gatewayApi:
8687
# Enabled defines if this option should be enabled.
8788
enabled: false
@@ -102,6 +103,7 @@ sync:
102103
# Enabled defines if this option should be enabled.
103104
enabled: false
104105
# ReferenceGrants configures ReferenceGrant sync to the control plane cluster. Enabled may be "auto", "true", or "false".
106+
# In auto mode grants follow route sync and are validated within the tenant cluster; they sync to the control plane cluster only when namespace sync is also enabled.
105107
referenceGrants:
106108
# Enabled defines if this option should be enabled.
107109
enabled: auto

config/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1234,6 +1234,7 @@ type SyncToHost struct {
12341234
Ingresses EnableSwitchWithPatches `json:"ingresses,omitempty"`
12351235

12361236
// GatewayAPI defines Gateway API resources created within the tenant cluster that should get synced to the control plane cluster.
1237+
// Setting enabled: true turns on Gateway and HTTPRoute sync, imports control plane cluster GatewayClasses so tenant Gateways can resolve them, and serves tenant ReferenceGrants for validation; TLSRoutes and BackendTLSPolicies must be enabled individually.
12371238
GatewayAPI GatewayAPIEnableSwitchWithPatches `json:"gatewayApi,omitempty"`
12381239

12391240
// Services defines if services created within the virtual cluster should get synced to the host cluster.
@@ -1310,6 +1311,7 @@ type GatewayAPIEnableSwitchWithPatches struct {
13101311
BackendTLSPolicies EnableSwitchWithPatches `json:"backendTLSPolicies,omitempty"`
13111312

13121313
// ReferenceGrants configures ReferenceGrant sync to the control plane cluster. Enabled may be "auto", "true", or "false".
1314+
// In auto mode grants follow route sync and are validated within the tenant cluster; they sync to the control plane cluster only when namespace sync is also enabled.
13131315
ReferenceGrants EnableAutoSwitchWithPatches `json:"referenceGrants,omitempty"`
13141316
}
13151317

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Suite: gatewayapi-umbrella-vcluster
2+
// vCluster: Gateway API enabled via the sync.toHost.gatewayApi umbrella switch
3+
// only, covering Gateway + HTTPRoute + ReferenceGrant CRD installation and sync.
4+
// Run: just run-e2e 'pr && gatewayapi'
5+
package e2e_next
6+
7+
import (
8+
"context"
9+
_ "embed"
10+
11+
"github.com/loft-sh/e2e-framework/pkg/setup/cluster"
12+
"github.com/loft-sh/vcluster/e2e-next/clusters"
13+
"github.com/loft-sh/vcluster/e2e-next/labels"
14+
"github.com/loft-sh/vcluster/e2e-next/setup"
15+
"github.com/loft-sh/vcluster/e2e-next/setup/lazyvcluster"
16+
"github.com/loft-sh/vcluster/e2e-next/test_gatewayapi"
17+
. "github.com/onsi/ginkgo/v2"
18+
)
19+
20+
//go:embed vcluster-gatewayapi-umbrella.yaml
21+
var gatewayAPIUmbrellaVClusterYAML string
22+
23+
const gatewayAPIUmbrellaVClusterName = "gatewayapi-umbrella-vcluster"
24+
25+
func init() { suiteGatewayAPIUmbrellaVCluster() }
26+
27+
func suiteGatewayAPIUmbrellaVCluster() {
28+
// Ordered so all specs share one lazyvcluster bring-up; specs are independent.
29+
Describe("gatewayapi-umbrella-vcluster", labels.PR, labels.GatewayAPI, labels.GatewayClasses, Ordered,
30+
cluster.Use(clusters.HostCluster),
31+
func() {
32+
BeforeAll(func(ctx context.Context) context.Context {
33+
return lazyvcluster.LazyVCluster(ctx,
34+
gatewayAPIUmbrellaVClusterName,
35+
gatewayAPIUmbrellaVClusterYAML,
36+
lazyvcluster.WithPreSetup(setup.GatewayAPIPreSetup()),
37+
)
38+
})
39+
40+
test_gatewayapi.GatewayAPIUmbrellaSpec()
41+
},
42+
)
43+
}

0 commit comments

Comments
 (0)