Skip to content

Commit 8d04f8b

Browse files
committed
[kube-mirror] skip unavailable gateway route CRDs
1 parent 37a6715 commit 8d04f8b

File tree

2 files changed

+84
-25
lines changed

2 files changed

+84
-25
lines changed

pkg/kube-controller/controllers/mirror.go

Lines changed: 47 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@ import (
66
"encoding/hex"
77
"fmt"
88

9-
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
109
apierrors "k8s.io/apimachinery/pkg/api/errors"
10+
"k8s.io/apimachinery/pkg/api/meta"
11+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
12+
"k8s.io/apimachinery/pkg/runtime"
1113
ctrl "sigs.k8s.io/controller-runtime"
1214
"sigs.k8s.io/controller-runtime/pkg/client"
15+
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
1316
"sigs.k8s.io/controller-runtime/pkg/reconcile"
1417
gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
1518
gwapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
@@ -142,42 +145,61 @@ func (r *MirrorReconciler) isRouteForApoxyGatewayV1Alpha2(ctx context.Context, n
142145
return false, nil
143146
}
144147

148+
func resourceIsAvailable(scheme *runtime.Scheme, mapper meta.RESTMapper, obj client.Object) (bool, string, error) {
149+
gvk, err := apiutil.GVKForObject(obj, scheme)
150+
if err != nil {
151+
return false, "", err
152+
}
153+
if _, err := mapper.RESTMapping(gvk.GroupKind(), gvk.Version); err != nil {
154+
if meta.IsNoMatchError(err) {
155+
return false, gvk.String(), nil
156+
}
157+
return false, gvk.String(), err
158+
}
159+
return true, gvk.String(), nil
160+
}
161+
162+
func setupControllerIfAvailable(mgr ctrl.Manager, name string, obj client.Object, fn reconcile.Func) error {
163+
ok, gvk, err := resourceIsAvailable(mgr.GetScheme(), mgr.GetRESTMapper(), obj)
164+
if err != nil {
165+
return fmt.Errorf("checking %s availability: %w", name, err)
166+
}
167+
if !ok {
168+
log.Infof("Mirror: skipping %s controller; resource %s is not installed", name, gvk)
169+
return nil
170+
}
171+
if err := ctrl.NewControllerManagedBy(mgr).
172+
For(obj).
173+
Complete(fn); err != nil {
174+
return fmt.Errorf("setting up %s controller: %w", name, err)
175+
}
176+
return nil
177+
}
178+
145179
// SetupWithManager registers controllers for each Gateway API resource type.
146180
func (r *MirrorReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Manager) error {
147-
if err := ctrl.NewControllerManagedBy(mgr).
148-
For(&gwapiv1.Gateway{}).
149-
Complete(reconcile.Func(r.reconcileGateway)); err != nil {
150-
return fmt.Errorf("setting up Gateway controller: %w", err)
181+
if err := setupControllerIfAvailable(mgr, "Gateway", &gwapiv1.Gateway{}, reconcile.Func(r.reconcileGateway)); err != nil {
182+
return err
151183
}
152184

153-
if err := ctrl.NewControllerManagedBy(mgr).
154-
For(&gwapiv1.HTTPRoute{}).
155-
Complete(reconcile.Func(r.reconcileHTTPRoute)); err != nil {
156-
return fmt.Errorf("setting up HTTPRoute controller: %w", err)
185+
if err := setupControllerIfAvailable(mgr, "HTTPRoute", &gwapiv1.HTTPRoute{}, reconcile.Func(r.reconcileHTTPRoute)); err != nil {
186+
return err
157187
}
158188

159-
if err := ctrl.NewControllerManagedBy(mgr).
160-
For(&gwapiv1.GRPCRoute{}).
161-
Complete(reconcile.Func(r.reconcileGRPCRoute)); err != nil {
162-
return fmt.Errorf("setting up GRPCRoute controller: %w", err)
189+
if err := setupControllerIfAvailable(mgr, "GRPCRoute", &gwapiv1.GRPCRoute{}, reconcile.Func(r.reconcileGRPCRoute)); err != nil {
190+
return err
163191
}
164192

165-
if err := ctrl.NewControllerManagedBy(mgr).
166-
For(&gwapiv1alpha2.TCPRoute{}).
167-
Complete(reconcile.Func(r.reconcileTCPRoute)); err != nil {
168-
return fmt.Errorf("setting up TCPRoute controller: %w", err)
193+
if err := setupControllerIfAvailable(mgr, "TCPRoute", &gwapiv1alpha2.TCPRoute{}, reconcile.Func(r.reconcileTCPRoute)); err != nil {
194+
return err
169195
}
170196

171-
if err := ctrl.NewControllerManagedBy(mgr).
172-
For(&gwapiv1alpha2.TLSRoute{}).
173-
Complete(reconcile.Func(r.reconcileTLSRoute)); err != nil {
174-
return fmt.Errorf("setting up TLSRoute controller: %w", err)
197+
if err := setupControllerIfAvailable(mgr, "TLSRoute", &gwapiv1alpha2.TLSRoute{}, reconcile.Func(r.reconcileTLSRoute)); err != nil {
198+
return err
175199
}
176200

177-
if err := ctrl.NewControllerManagedBy(mgr).
178-
For(&gwapiv1alpha2.UDPRoute{}).
179-
Complete(reconcile.Func(r.reconcileUDPRoute)); err != nil {
180-
return fmt.Errorf("setting up UDPRoute controller: %w", err)
201+
if err := setupControllerIfAvailable(mgr, "UDPRoute", &gwapiv1alpha2.UDPRoute{}, reconcile.Func(r.reconcileUDPRoute)); err != nil {
202+
return err
181203
}
182204

183205
return nil
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package controllers
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/require"
7+
"k8s.io/apimachinery/pkg/api/meta"
8+
"k8s.io/apimachinery/pkg/runtime"
9+
"k8s.io/apimachinery/pkg/runtime/schema"
10+
gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
11+
gwapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
12+
)
13+
14+
func TestResourceIsAvailable(t *testing.T) {
15+
t.Parallel()
16+
17+
scheme := runtime.NewScheme()
18+
require.NoError(t, gwapiv1.Install(scheme))
19+
require.NoError(t, gwapiv1alpha2.Install(scheme))
20+
21+
mapper := meta.NewDefaultRESTMapper([]schema.GroupVersion{
22+
gwapiv1.SchemeGroupVersion,
23+
gwapiv1alpha2.SchemeGroupVersion,
24+
})
25+
mapper.Add(gwapiv1.SchemeGroupVersion.WithKind("Gateway"), meta.RESTScopeNamespace)
26+
mapper.Add(gwapiv1.SchemeGroupVersion.WithKind("HTTPRoute"), meta.RESTScopeNamespace)
27+
28+
ok, gvk, err := resourceIsAvailable(scheme, mapper, &gwapiv1.Gateway{})
29+
require.NoError(t, err)
30+
require.True(t, ok)
31+
require.Equal(t, "gateway.networking.k8s.io/v1, Kind=Gateway", gvk)
32+
33+
ok, gvk, err = resourceIsAvailable(scheme, mapper, &gwapiv1alpha2.TLSRoute{})
34+
require.NoError(t, err)
35+
require.False(t, ok)
36+
require.Equal(t, "gateway.networking.k8s.io/v1alpha2, Kind=TLSRoute", gvk)
37+
}

0 commit comments

Comments
 (0)