Skip to content

Commit 4f9cd00

Browse files
authored
feat: support disable gateway-api (#2672)
1 parent 2bab77a commit 4f9cd00

File tree

16 files changed

+500
-161
lines changed

16 files changed

+500
-161
lines changed

.github/workflows/apisix-e2e-test.yml

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,67 @@ jobs:
116116
else
117117
make ginkgo-e2e-test
118118
fi
119+
120+
disable-gateway-api:
121+
runs-on: ubuntu-latest
122+
steps:
123+
- name: Checkout
124+
uses: actions/checkout@v4
125+
with:
126+
submodules: recursive
127+
128+
- name: Setup Go Env
129+
uses: actions/setup-go@v4
130+
with:
131+
go-version: "1.24"
132+
133+
- name: Setup Node.js
134+
uses: actions/setup-node@v3
135+
with:
136+
node-version: "*"
137+
138+
- name: Install kind
139+
run: |
140+
go install sigs.k8s.io/[email protected]
141+
142+
- name: Install ginkgo
143+
run: |
144+
make install-ginkgo
145+
146+
- name: Build images
147+
env:
148+
TAG: dev
149+
ARCH: amd64
150+
ENABLE_PROXY: "false"
151+
BASE_IMAGE_TAG: "debug"
152+
run: |
153+
echo "building images..."
154+
make build-image
155+
156+
- name: Launch Kind Cluster
157+
run: |
158+
make kind-up
159+
160+
- name: Loading Docker Image to Kind Cluster
161+
run: |
162+
make kind-load-images
163+
164+
- name: Extract adc binary
165+
if: ${{ env.ADC_VERSION == 'dev' }}
166+
run: |
167+
docker create --name adc-temp ghcr.io/api7/adc:dev
168+
docker cp adc-temp:main.js adc.js
169+
docker rm adc-temp
170+
node $(pwd)/adc.js -v
171+
echo "ADC_BIN=node $(pwd)/adc.js" >> $GITHUB_ENV
172+
173+
- name: Install CRDs
174+
run: make install-crds
175+
176+
- name: Run E2E test suite
177+
shell: bash
178+
env:
179+
TEST_DIR: "./test/e2e/apisix/"
180+
TEST_ENV: CI
181+
TEST_FOCUS: "Test ApisixRoute Basic tests"
182+
run: make e2e-test

Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,10 @@ uninstall-gateway-api: ## Uninstall Gateway API CRDs from the K8s cluster specif
290290
kubectl delete -f https://github.com/kubernetes-sigs/gateway-api/releases/download/$(GATEAY_API_VERSION)/experimental-install.yaml
291291

292292
.PHONY: install
293-
install: manifests kustomize install-gateway-api ## Install CRDs into the K8s cluster specified in ~/.kube/config.
293+
install: manifests kustomize install-gateway-api install-crds ## Install CRDs and Gateway API into the K8s cluster specified in ~/.kube/config.
294+
295+
.PHONY: install-crds
296+
install-crds: manifests kustomize ## Install CRDs into the K8s cluster specified
294297
$(KUSTOMIZE) build config/crd | $(KUBECTL) apply -f -
295298

296299
.PHONY: uninstall

config/samples/config.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ secure_metrics: false # The secure metrics configuration.
3232

3333
exec_adc_timeout: 15s # The timeout for the ADC to execute.
3434
# The default value is 15 seconds.
35+
disable_gateway_api: false # Whether to disable the Gateway API support.
36+
# The default value is false.
3537

3638
provider:
3739
type: "apisix" # Provider type.

internal/controller/config/types.go

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -55,19 +55,20 @@ const (
5555
// Config contains all config items which are necessary for
5656
// apisix-ingress-controller's running.
5757
type Config struct {
58-
LogLevel string `json:"log_level" yaml:"log_level"`
59-
ControllerName string `json:"controller_name" yaml:"controller_name"`
60-
LeaderElectionID string `json:"leader_election_id" yaml:"leader_election_id"`
61-
MetricsAddr string `json:"metrics_addr" yaml:"metrics_addr"`
62-
ServerAddr string `json:"server_addr" yaml:"server_addr"`
63-
EnableServer bool `json:"enable_server" yaml:"enable_server"`
64-
EnableHTTP2 bool `json:"enable_http2" yaml:"enable_http2"`
65-
ProbeAddr string `json:"probe_addr" yaml:"probe_addr"`
66-
SecureMetrics bool `json:"secure_metrics" yaml:"secure_metrics"`
67-
LeaderElection *LeaderElection `json:"leader_election" yaml:"leader_election"`
68-
ExecADCTimeout types.TimeDuration `json:"exec_adc_timeout" yaml:"exec_adc_timeout"`
69-
ProviderConfig ProviderConfig `json:"provider" yaml:"provider"`
70-
Webhook *WebhookConfig `json:"webhook" yaml:"webhook"`
58+
LogLevel string `json:"log_level" yaml:"log_level"`
59+
ControllerName string `json:"controller_name" yaml:"controller_name"`
60+
LeaderElectionID string `json:"leader_election_id" yaml:"leader_election_id"`
61+
MetricsAddr string `json:"metrics_addr" yaml:"metrics_addr"`
62+
ServerAddr string `json:"server_addr" yaml:"server_addr"`
63+
EnableServer bool `json:"enable_server" yaml:"enable_server"`
64+
EnableHTTP2 bool `json:"enable_http2" yaml:"enable_http2"`
65+
ProbeAddr string `json:"probe_addr" yaml:"probe_addr"`
66+
SecureMetrics bool `json:"secure_metrics" yaml:"secure_metrics"`
67+
LeaderElection *LeaderElection `json:"leader_election" yaml:"leader_election"`
68+
ExecADCTimeout types.TimeDuration `json:"exec_adc_timeout" yaml:"exec_adc_timeout"`
69+
ProviderConfig ProviderConfig `json:"provider" yaml:"provider"`
70+
Webhook *WebhookConfig `json:"webhook" yaml:"webhook"`
71+
DisableGatewayAPI bool `json:"disable_gateway_api" yaml:"disable_gateway_api"`
7172
}
7273

7374
type GatewayConfig struct {

internal/controller/consumer_controller.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import (
4444
"github.com/apache/apisix-ingress-controller/internal/provider"
4545
internaltypes "github.com/apache/apisix-ingress-controller/internal/types"
4646
"github.com/apache/apisix-ingress-controller/internal/utils"
47+
pkgutils "github.com/apache/apisix-ingress-controller/pkg/utils"
4748
)
4849

4950
// ConsumerReconciler reconciles a Gateway object.
@@ -60,6 +61,10 @@ type ConsumerReconciler struct { //nolint:revive
6061

6162
// SetupWithManager sets up the controller with the Manager.
6263
func (r *ConsumerReconciler) SetupWithManager(mgr ctrl.Manager) error {
64+
if config.ControllerConfig.DisableGatewayAPI || !pkgutils.HasAPIResource(mgr, &gatewayv1.Gateway{}) {
65+
r.Log.Info("skipping Consumer controller setup as Gateway API is not available")
66+
return nil
67+
}
6368
return ctrl.NewControllerManagedBy(mgr).
6469
For(&v1alpha1.Consumer{},
6570
builder.WithPredicates(

internal/controller/gateway_controller.go

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import (
4343
"github.com/apache/apisix-ingress-controller/internal/provider"
4444
internaltypes "github.com/apache/apisix-ingress-controller/internal/types"
4545
"github.com/apache/apisix-ingress-controller/internal/utils"
46+
pkgutils "github.com/apache/apisix-ingress-controller/pkg/utils"
4647
)
4748

4849
// GatewayReconciler reconciles a Gateway object.
@@ -83,18 +84,6 @@ func (r *GatewayReconciler) SetupWithManager(mgr ctrl.Manager) error {
8384
&gatewayv1.GRPCRoute{},
8485
handler.EnqueueRequestsFromMapFunc(r.listGatewaysForStatusParentRefs),
8586
).
86-
Watches(
87-
&gatewayv1alpha2.TCPRoute{},
88-
handler.EnqueueRequestsFromMapFunc(r.listGatewaysForStatusParentRefs),
89-
).
90-
Watches(
91-
&gatewayv1alpha2.TLSRoute{},
92-
handler.EnqueueRequestsFromMapFunc(r.listGatewaysForStatusParentRefs),
93-
).
94-
Watches(
95-
&gatewayv1alpha2.UDPRoute{},
96-
handler.EnqueueRequestsFromMapFunc(r.listGatewaysForStatusParentRefs),
97-
).
9887
Watches(
9988
&v1alpha1.GatewayProxy{},
10089
handler.EnqueueRequestsFromMapFunc(r.listGatewaysForGatewayProxy),
@@ -110,6 +99,24 @@ func (r *GatewayReconciler) SetupWithManager(mgr ctrl.Manager) error {
11099
builder.WithPredicates(referenceGrantPredicates(KindGateway)),
111100
)
112101
}
102+
if pkgutils.HasAPIResource(mgr, &gatewayv1alpha2.TCPRoute{}) {
103+
bdr.Watches(
104+
&gatewayv1alpha2.TCPRoute{},
105+
handler.EnqueueRequestsFromMapFunc(r.listGatewaysForStatusParentRefs),
106+
)
107+
}
108+
if pkgutils.HasAPIResource(mgr, &gatewayv1alpha2.TLSRoute{}) {
109+
bdr.Watches(
110+
&gatewayv1alpha2.TLSRoute{},
111+
handler.EnqueueRequestsFromMapFunc(r.listGatewaysForStatusParentRefs),
112+
)
113+
}
114+
if pkgutils.HasAPIResource(mgr, &gatewayv1alpha2.UDPRoute{}) {
115+
bdr.Watches(
116+
&gatewayv1alpha2.UDPRoute{},
117+
handler.EnqueueRequestsFromMapFunc(r.listGatewaysForStatusParentRefs),
118+
)
119+
}
113120

114121
return bdr.Complete(r)
115122
}

internal/controller/gatewayproxy_controller.go

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import (
3939
"github.com/apache/apisix-ingress-controller/internal/controller/indexer"
4040
"github.com/apache/apisix-ingress-controller/internal/provider"
4141
"github.com/apache/apisix-ingress-controller/internal/utils"
42+
pkgutils "github.com/apache/apisix-ingress-controller/pkg/utils"
4243
)
4344

4445
// GatewayProxyController reconciles a GatewayProxy object.
@@ -48,10 +49,15 @@ type GatewayProxyController struct {
4849
Scheme *runtime.Scheme
4950
Log logr.Logger
5051
Provider provider.Provider
52+
53+
disableGatewayAPI bool
5154
}
5255

5356
func (r *GatewayProxyController) SetupWithManager(mrg ctrl.Manager) error {
54-
return ctrl.NewControllerManagedBy(mrg).
57+
if config.ControllerConfig.DisableGatewayAPI || !pkgutils.HasAPIResource(mrg, &gatewayv1.Gateway{}) {
58+
r.disableGatewayAPI = true
59+
}
60+
builder := ctrl.NewControllerManagedBy(mrg).
5561
For(&v1alpha1.GatewayProxy{}).
5662
WithEventFilter(
5763
predicate.Or(
@@ -68,13 +74,15 @@ func (r *GatewayProxyController) SetupWithManager(mrg ctrl.Manager) error {
6874
Watches(&corev1.Secret{},
6975
handler.EnqueueRequestsFromMapFunc(r.listGatewayProxiesForSecret),
7076
).
71-
Watches(&gatewayv1.Gateway{},
72-
handler.EnqueueRequestsFromMapFunc(r.listGatewayProxiesByGateway),
73-
).
7477
Watches(&networkingv1.IngressClass{},
7578
handler.EnqueueRequestsFromMapFunc(r.listGatewayProxiesForIngressClass),
76-
).
77-
Complete(r)
79+
)
80+
if !r.disableGatewayAPI {
81+
builder.Watches(&gatewayv1.Gateway{},
82+
handler.EnqueueRequestsFromMapFunc(r.listGatewayProxiesByGateway),
83+
)
84+
}
85+
return builder.Complete(r)
7886
}
7987

8088
func (r *GatewayProxyController) Reconcile(ctx context.Context, req ctrl.Request) (reconcile.Result, error) {
@@ -131,19 +139,32 @@ func (r *GatewayProxyController) Reconcile(ctx context.Context, req ctrl.Request
131139
ingressClassList networkingv1.IngressClassList
132140
indexKey = indexer.GenIndexKey(gp.GetNamespace(), gp.GetName())
133141
)
134-
if err := r.List(ctx, &gatewayList, client.MatchingFields{indexer.ParametersRef: indexKey}); err != nil {
135-
r.Log.Error(err, "failed to list GatewayList")
136-
return ctrl.Result{}, nil
137-
}
138142

139-
var gatewayclassList gatewayv1.GatewayClassList
140-
if err := r.List(ctx, &gatewayclassList, client.MatchingFields{indexer.ControllerName: config.GetControllerName()}); err != nil {
141-
r.Log.Error(err, "failed to list GatewayClassList")
142-
return ctrl.Result{}, nil
143-
}
144-
gcMatched := make(map[string]*gatewayv1.GatewayClass)
145-
for _, item := range gatewayclassList.Items {
146-
gcMatched[item.Name] = &item
143+
if !r.disableGatewayAPI {
144+
if err := r.List(ctx, &gatewayList, client.MatchingFields{indexer.ParametersRef: indexKey}); err != nil {
145+
r.Log.Error(err, "failed to list GatewayList")
146+
return ctrl.Result{}, nil
147+
}
148+
var gatewayclassList gatewayv1.GatewayClassList
149+
if err := r.List(ctx, &gatewayclassList, client.MatchingFields{indexer.ControllerName: config.GetControllerName()}); err != nil {
150+
r.Log.Error(err, "failed to list GatewayClassList")
151+
return ctrl.Result{}, nil
152+
}
153+
gcMatched := make(map[string]*gatewayv1.GatewayClass)
154+
for _, item := range gatewayclassList.Items {
155+
gcMatched[item.Name] = &item
156+
}
157+
// append referrers to translate context
158+
for _, item := range gatewayList.Items {
159+
gcName := string(item.Spec.GatewayClassName)
160+
if gcName == "" {
161+
continue
162+
}
163+
if _, ok := gcMatched[gcName]; ok {
164+
tctx.GatewayProxyReferrers[req.NamespacedName] = append(tctx.GatewayProxyReferrers[req.NamespacedName], utils.NamespacedNameKind(&item))
165+
}
166+
}
167+
r.Log.V(1).Info("found Gateways for GatewayProxy", "gatewayproxy", req.String(), "gateways", len(gatewayList.Items), "gatewayclasses", len(gatewayclassList.Items), "ingressclasses", len(ingressClassList.Items))
147168
}
148169

149170
// list IngressClasses that reference the GatewayProxy
@@ -152,23 +173,12 @@ func (r *GatewayProxyController) Reconcile(ctx context.Context, req ctrl.Request
152173
return reconcile.Result{}, err
153174
}
154175

155-
// append referrers to translate context
156-
for _, item := range gatewayList.Items {
157-
gcName := string(item.Spec.GatewayClassName)
158-
if gcName == "" {
159-
continue
160-
}
161-
if _, ok := gcMatched[gcName]; ok {
162-
tctx.GatewayProxyReferrers[req.NamespacedName] = append(tctx.GatewayProxyReferrers[req.NamespacedName], utils.NamespacedNameKind(&item))
163-
}
164-
}
165176
for _, item := range ingressClassList.Items {
166177
if item.Spec.Controller != config.GetControllerName() {
167178
continue
168179
}
169180
tctx.GatewayProxyReferrers[req.NamespacedName] = append(tctx.GatewayProxyReferrers[req.NamespacedName], utils.NamespacedNameKind(&item))
170181
}
171-
r.Log.V(1).Info("found Gateways for GatewayProxy", "gatewayproxy", req.String(), "gateways", len(gatewayList.Items), "gatewayclasses", len(gatewayclassList.Items), "ingressclasses", len(ingressClassList.Items))
172182

173183
if len(tctx.GatewayProxyReferrers[req.NamespacedName]) == 0 {
174184
return ctrl.Result{}, nil

0 commit comments

Comments
 (0)