Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add new flag to reconcile one specific Gateway only #5405

Merged
merged 1 commit into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,9 @@ Adding a new version? You'll need three changes:
[#5384](https://github.com/Kong/kubernetes-ingress-controller/pull/5384)
[#5435](https://github.com/Kong/kubernetes-ingress-controller/pull/5435)
[#5412](https://github.com/Kong/kubernetes-ingress-controller/pull/5412)

- Added flag `--gateway-to-reconcile` to set KIC to only reconcile
the specified Gateway resource in Kubernetes.
[#5405](https://github.com/Kong/kubernetes-ingress-controller/pull/5405)

### Fixed

Expand Down
1 change: 1 addition & 0 deletions docs/cli-arguments.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
| `--feature-gates` | `list of string=bool` | A set of comma separated key=value pairs that describe feature gates for alpha/beta/experimental features. See the Feature Gates documentation for information and available options: https://github.com/Kong/kubernetes-ingress-controller/blob/main/FEATURE_GATES.md. | |
| `--gateway-api-controller-name` | `string` | The controller name to match on Gateway API resources. | `konghq.com/kic-gateway-controller` |
| `--gateway-discovery-dns-strategy` | `dns-strategy` | DNS strategy to use when creating Gateway's Admin API addresses. One of: ip, service, pod. | `"ip"` |
| `--gateway-to-reconcile` | `namespaced-name` | Gateway namespaced name in "namespace/name" format. Makes KIC reconcile only the specified Gateway. | |
| `--health-probe-bind-address` | `string` | The address the probe endpoint binds to. | `:10254` |
| `--ingress-class` | `string` | Name of the ingress class to route through this controller. | `kong` |
| `--init-cache-sync-duration` | `duration` | The initial delay to wait for Kubernetes object caches to be synced before the initial configuration. | `5s` |
Expand Down
4 changes: 4 additions & 0 deletions internal/controllers/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@ package controllers

import (
"github.com/go-logr/logr"
"github.com/samber/mo"
k8stypes "k8s.io/apimachinery/pkg/types"
ctrl "sigs.k8s.io/controller-runtime"
)

type Reconciler interface {
SetupWithManager(ctrl.Manager) error
SetLogger(logr.Logger)
}

type OptionalNamespacedName = mo.Option[k8stypes.NamespacedName]
20 changes: 20 additions & 0 deletions internal/controllers/gateway/gateway_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ type GatewayReconciler struct { //nolint:revive
// to invalidate or allow cross-namespace TLSConfigs in gateways.
// It's resolved on SetupWithManager call.
enableReferenceGrant bool

// If GatewayNN is set,
// only resources managed by the specified Gateway are reconciled.
GatewayNN controllers.OptionalNamespacedName
}

// SetupWithManager sets up the controller with the Manager.
Expand Down Expand Up @@ -173,6 +177,15 @@ func (r *GatewayReconciler) gatewayHasMatchingGatewayClass(obj client.Object) bo
)
return false
}

// If the flag `--gateway-to-reconcile` is set, KIC will only reconcile the specified gateway.
// https://github.com/Kong/kubernetes-ingress-controller/issues/5322
if gatewayToReconcile, ok := r.GatewayNN.Get(); ok {
if gatewayToReconcile.Namespace != gateway.Namespace || gatewayToReconcile.Name != gateway.Name {
return false
}
}

gatewayClass := &gatewayapi.GatewayClass{}
if err := r.Client.Get(context.Background(), client.ObjectKey{Name: string(gateway.Spec.GatewayClassName)}, gatewayClass); err != nil {
r.Log.Error(err, "Could not retrieve gatewayclass", "gatewayclass", gateway.Spec.GatewayClassName)
Expand Down Expand Up @@ -327,6 +340,13 @@ func referenceGrantHasGatewayFrom(obj client.Object) bool {
func (r *GatewayReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
log := r.Log.WithValues("GatewayV1Gateway", req.NamespacedName)

if gatewayToReconcile, ok := r.GatewayNN.Get(); ok {
if req.Namespace != gatewayToReconcile.Namespace || req.Name != gatewayToReconcile.Name {
r.Log.V(util.DebugLevel).Info("The request does not match the specified Gateway and will be skipped.", "gateway", gatewayToReconcile.String())
return ctrl.Result{}, nil
}
}

// gather the gateway object based on the reconciliation trigger. It's possible for the object
// to be gone at this point in which case it will be ignored.
gateway := new(gatewayapi.Gateway)
Expand Down
22 changes: 21 additions & 1 deletion internal/controllers/gateway/grpcroute_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ type GRPCRouteReconciler struct {
// If it is false, referencing backend in different namespace will be rejected.
EnableReferenceGrant bool
CacheSyncTimeout time.Duration

// If GatewayNN is set,
// only resources managed by the specified Gateway are reconciled.
GatewayNN controllers.OptionalNamespacedName
}

// SetupWithManager sets up the controller with the Manager.
Expand Down Expand Up @@ -143,6 +147,14 @@ func (r *GRPCRouteReconciler) listGRPCRoutesForGatewayClass(ctx context.Context,
gateways := make(map[string]map[string]struct{})
for _, gateway := range gatewayList.Items {
if string(gateway.Spec.GatewayClassName) == gwc.Name {
// If the flag `--gateway-to-reconcile` is set, KIC will only reconcile the specified gateway.
// https://github.com/Kong/kubernetes-ingress-controller/issues/5322
if gatewayToReconcile, ok := r.GatewayNN.Get(); ok {
if gatewayToReconcile.Namespace != gateway.Namespace || gatewayToReconcile.Name != gateway.Name {
continue
}
}

_, ok := gateways[gateway.Namespace]
if !ok {
gateways[gateway.Namespace] = make(map[string]struct{})
Expand Down Expand Up @@ -217,6 +229,14 @@ func (r *GRPCRouteReconciler) listGRPCRoutesForGateway(ctx context.Context, obj
return nil
}

// If the flag `--gateway-to-reconcile` is set, KIC will only reconcile the specified gateway.
// https://github.com/Kong/kubernetes-ingress-controller/issues/5322
if gatewayToReconcile, ok := r.GatewayNN.Get(); ok {
if gatewayToReconcile.Namespace != gw.Namespace || gatewayToReconcile.Name != gw.Name {
return nil
}
}

// map all GRPCRoute objects
grpcrouteList := gatewayapi.GRPCRouteList{}
if err := r.Client.List(ctx, &grpcrouteList); err != nil {
Expand Down Expand Up @@ -293,7 +313,7 @@ func (r *GRPCRouteReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
// we need to pull the Gateway parent objects for the grpcroute to verify
// routing behavior and ensure compatibility with Gateway configurations.
debug(log, grpcroute, "Retrieving GatewayClass and Gateway for route")
gateways, err := getSupportedGatewayForRoute(ctx, log, r.Client, grpcroute)
gateways, err := getSupportedGatewayForRoute(ctx, log, r.Client, grpcroute, r.GatewayNN)
if err != nil {
if err.Error() == unsupportedGW {
debug(log, grpcroute, "Unsupported route found, processing to verify whether it was ever supported")
Expand Down
22 changes: 21 additions & 1 deletion internal/controllers/gateway/httproute_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ type HTTPRouteReconciler struct {
// If it is false, referencing backend in different namespace will be rejected.
// It's resolved on SetupWithManager call.
enableReferenceGrant bool

// If GatewayNN is set,
// only resources managed by the specified Gateway are reconciled.
GatewayNN controllers.OptionalNamespacedName
}

// SetupWithManager sets up the controller with the Manager.
Expand Down Expand Up @@ -217,6 +221,14 @@ func (r *HTTPRouteReconciler) listHTTPRoutesForGatewayClass(ctx context.Context,
gateways := make(map[string]map[string]struct{})
for _, gateway := range gatewayList.Items {
if string(gateway.Spec.GatewayClassName) == gwc.Name {
// If the flag `--gateway-to-reconcile` is set, KIC will only reconcile the specified gateway.
// https://github.com/Kong/kubernetes-ingress-controller/issues/5322
if gatewayToReconcile, ok := r.GatewayNN.Get(); ok {
if gatewayToReconcile.Namespace != gateway.Namespace || gatewayToReconcile.Name != gateway.Name {
continue
}
}

_, ok := gateways[gateway.Namespace]
if !ok {
gateways[gateway.Namespace] = make(map[string]struct{})
Expand Down Expand Up @@ -291,6 +303,14 @@ func (r *HTTPRouteReconciler) listHTTPRoutesForGateway(ctx context.Context, obj
return nil
}

// If the flag `--gateway-to-reconcile` is set, KIC will only reconcile the specified gateway.
// https://github.com/Kong/kubernetes-ingress-controller/issues/5322
if gatewayToReconcile, ok := r.GatewayNN.Get(); ok {
if gatewayToReconcile.Namespace != gw.Namespace || gatewayToReconcile.Name != gw.Name {
return nil
}
}

// map all HTTPRoute objects
httprouteList := gatewayapi.HTTPRouteList{}
if err := r.Client.List(ctx, &httprouteList); err != nil {
Expand Down Expand Up @@ -368,7 +388,7 @@ func (r *HTTPRouteReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
// we need to pull the Gateway parent objects for the HTTPRoute to verify
// routing behavior and ensure compatibility with Gateway configurations.
debug(log, httproute, "Retrieving GatewayClass and Gateway for route")
gateways, err := getSupportedGatewayForRoute(ctx, log, r.Client, httproute)
gateways, err := getSupportedGatewayForRoute(ctx, log, r.Client, httproute, r.GatewayNN)
if err != nil {
if err.Error() == unsupportedGW {
debug(log, httproute, "Unsupported route found, processing to verify whether it was ever supported")
Expand Down
13 changes: 12 additions & 1 deletion internal/controllers/gateway/route_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"

"github.com/kong/kubernetes-ingress-controller/v3/internal/controllers"
"github.com/kong/kubernetes-ingress-controller/v3/internal/gatewayapi"
"github.com/kong/kubernetes-ingress-controller/v3/internal/util"
)
Expand Down Expand Up @@ -125,7 +126,9 @@ func parentRefsForRoute[T gatewayapi.RouteT](route T) ([]gatewayapi.ParentRefere
// Gateway APIs route object (e.g. HTTPRoute, TCPRoute, e.t.c.) from the provided cached
// client if they match this controller. If there are no gateways present for this route
// OR the present gateways are references to missing objects, this will return a unsupportedGW error.
func getSupportedGatewayForRoute[T gatewayapi.RouteT](ctx context.Context, logger logr.Logger, mgrc client.Client, route T) ([]supportedGatewayWithCondition, error) {
//
// There is a parameter `specifiedGW` here, which is used to specific the gateway.
func getSupportedGatewayForRoute[T gatewayapi.RouteT](ctx context.Context, logger logr.Logger, mgrc client.Client, route T, specifiedGW controllers.OptionalNamespacedName) ([]supportedGatewayWithCondition, error) {
// gather the parentrefs for this route object
parentRefs, err := parentRefsForRoute(route)
if err != nil {
Expand All @@ -145,6 +148,14 @@ func getSupportedGatewayForRoute[T gatewayapi.RouteT](ctx context.Context, logge
}
name := string(parentRef.Name)

// If the flag `--gateway-to-reconcile` is set, KIC will only reconcile the specified gateway.
// https://github.com/Kong/kubernetes-ingress-controller/issues/5322
if gatewayToReconcile, ok := specifiedGW.Get(); ok {
namespace = gatewayToReconcile.Namespace
name = gatewayToReconcile.Name

}

// pull the Gateway object from the cached client
gateway := gatewayapi.Gateway{}
if err := mgrc.Get(ctx, client.ObjectKey{
Expand Down
11 changes: 6 additions & 5 deletions internal/controllers/gateway/route_utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
fakeclient "sigs.k8s.io/controller-runtime/pkg/client/fake"
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"

"github.com/kong/kubernetes-ingress-controller/v3/internal/controllers"
"github.com/kong/kubernetes-ingress-controller/v3/internal/gatewayapi"
"github.com/kong/kubernetes-ingress-controller/v3/internal/util"
"github.com/kong/kubernetes-ingress-controller/v3/internal/util/builder"
Expand Down Expand Up @@ -542,7 +543,7 @@ func TestGetSupportedGatewayForRoute(t *testing.T) {
WithObjects(tt.objects...).
Build()

got, err := getSupportedGatewayForRoute(context.Background(), logr.Discard(), fakeClient, tt.route)
got, err := getSupportedGatewayForRoute(context.Background(), logr.Discard(), fakeClient, tt.route, controllers.OptionalNamespacedName{})
require.NoError(t, err)
require.Len(t, got, len(tt.expected))

Expand Down Expand Up @@ -813,7 +814,7 @@ func TestGetSupportedGatewayForRoute(t *testing.T) {
WithObjects(tt.objects...).
Build()

got, err := getSupportedGatewayForRoute(context.Background(), logr.Discard(), fakeClient, tt.route)
got, err := getSupportedGatewayForRoute(context.Background(), logr.Discard(), fakeClient, tt.route, controllers.OptionalNamespacedName{})
require.NoError(t, err)
require.Len(t, got, 1)
match := got[0]
Expand Down Expand Up @@ -1048,7 +1049,7 @@ func TestGetSupportedGatewayForRoute(t *testing.T) {
WithObjects(tt.objects...).
Build()

got, err := getSupportedGatewayForRoute(context.Background(), logr.Discard(), fakeClient, tt.route)
got, err := getSupportedGatewayForRoute(context.Background(), logr.Discard(), fakeClient, tt.route, controllers.OptionalNamespacedName{})
require.NoError(t, err)
require.Len(t, got, 1)
match := got[0]
Expand Down Expand Up @@ -1270,7 +1271,7 @@ func TestGetSupportedGatewayForRoute(t *testing.T) {
WithObjects(tt.objects...).
Build()

got, err := getSupportedGatewayForRoute(context.Background(), logr.Discard(), fakeClient, tt.route)
got, err := getSupportedGatewayForRoute(context.Background(), logr.Discard(), fakeClient, tt.route, controllers.OptionalNamespacedName{})
require.NoError(t, err)
require.Len(t, got, len(tt.expected))

Expand Down Expand Up @@ -1300,7 +1301,7 @@ func TestGetSupportedGatewayForRoute(t *testing.T) {
WithScheme(scheme.Scheme).
Build()

_, err := getSupportedGatewayForRoute(context.Background(), logr.Discard(), fakeClient, bustedParentHTTPRoute)
_, err := getSupportedGatewayForRoute(context.Background(), logr.Discard(), fakeClient, bustedParentHTTPRoute, controllers.OptionalNamespacedName{})
require.Equal(t, fmt.Errorf("unsupported parent kind %s/%s", string(badGroup), string(badKind)), err)
})
}
Expand Down
22 changes: 21 additions & 1 deletion internal/controllers/gateway/tcproute_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ type TCPRouteReconciler struct {
DataplaneClient controllers.DataPlane
CacheSyncTimeout time.Duration
StatusQueue *status.Queue

// If GatewayNN is set,
// only resources managed by the specified Gateway are reconciled.
GatewayNN controllers.OptionalNamespacedName
}

// SetupWithManager sets up the controller with the Manager.
Expand Down Expand Up @@ -140,6 +144,14 @@ func (r *TCPRouteReconciler) listTCPRoutesForGatewayClass(ctx context.Context, o
gateways := make(map[string]map[string]struct{})
for _, gateway := range gatewayList.Items {
if string(gateway.Spec.GatewayClassName) == gwc.Name {
// If the flag `--gateway-to-reconcile` is set, KIC will only reconcile the specified gateway.
// https://github.com/Kong/kubernetes-ingress-controller/issues/5322
if gatewayToReconcile, ok := r.GatewayNN.Get(); ok {
if gatewayToReconcile.Namespace != gateway.Namespace || gatewayToReconcile.Name != gateway.Name {
continue
}
}

_, ok := gateways[gateway.Namespace]
if !ok {
gateways[gateway.Namespace] = make(map[string]struct{})
Expand Down Expand Up @@ -214,6 +226,14 @@ func (r *TCPRouteReconciler) listTCPRoutesForGateway(ctx context.Context, obj cl
return nil
}

// If the flag `--gateway-to-reconcile` is set, KIC will only reconcile the specified gateway.
// https://github.com/Kong/kubernetes-ingress-controller/issues/5322
if gatewayToReconcile, ok := r.GatewayNN.Get(); ok {
if gatewayToReconcile.Namespace != gw.Namespace || gatewayToReconcile.Name != gw.Name {
return nil
}
}

// map all TCPRoute objects
tcprouteList := gatewayapi.TCPRouteList{}
if err := r.Client.List(ctx, &tcprouteList); err != nil {
Expand Down Expand Up @@ -290,7 +310,7 @@ func (r *TCPRouteReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
// we need to pull the Gateway parent objects for the TCPRoute to verify
// routing behavior and ensure compatibility with Gateway configurations.
debug(log, tcproute, "Retrieving GatewayClass and Gateway for route")
gateways, err := getSupportedGatewayForRoute(ctx, log, r.Client, tcproute)
gateways, err := getSupportedGatewayForRoute(ctx, log, r.Client, tcproute, r.GatewayNN)
if err != nil {
if err.Error() == unsupportedGW {
debug(log, tcproute, "Unsupported route found, processing to verify whether it was ever supported")
Expand Down
22 changes: 21 additions & 1 deletion internal/controllers/gateway/tlsroute_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ type TLSRouteReconciler struct {
DataplaneClient controllers.DataPlane
CacheSyncTimeout time.Duration
StatusQueue *status.Queue

// If GatewayNN is set,
// only resources managed by the specified Gateway are reconciled.
GatewayNN controllers.OptionalNamespacedName
}

// SetupWithManager sets up the controller with the Manager.
Expand Down Expand Up @@ -139,6 +143,14 @@ func (r *TLSRouteReconciler) listTLSRoutesForGatewayClass(ctx context.Context, o
gateways := make(map[string]map[string]struct{})
for _, gateway := range gatewayList.Items {
if string(gateway.Spec.GatewayClassName) == gwc.Name {
// If the flag `--gateway-to-reconcile` is set, KIC will only reconcile the specified gateway.
// https://github.com/Kong/kubernetes-ingress-controller/issues/5322
if gatewayToReconcile, ok := r.GatewayNN.Get(); ok {
if gatewayToReconcile.Namespace != gateway.Namespace || gatewayToReconcile.Name != gateway.Name {
continue
}
}

_, ok := gateways[gateway.Namespace]
if !ok {
gateways[gateway.Namespace] = make(map[string]struct{})
Expand Down Expand Up @@ -213,6 +225,14 @@ func (r *TLSRouteReconciler) listTLSRoutesForGateway(ctx context.Context, obj cl
return nil
}

// If the flag `--gateway-to-reconcile` is set, KIC will only reconcile the specified gateway.
// https://github.com/Kong/kubernetes-ingress-controller/issues/5322
if gatewayToReconcile, ok := r.GatewayNN.Get(); ok {
if gatewayToReconcile.Namespace != gw.Namespace || gatewayToReconcile.Name != gw.Name {
return nil
}
}

// map all TLSRoute objects
tlsrouteList := gatewayapi.TLSRouteList{}
if err := r.Client.List(ctx, &tlsrouteList); err != nil {
Expand Down Expand Up @@ -289,7 +309,7 @@ func (r *TLSRouteReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
// we need to pull the Gateway parent objects for the TLSRoute to verify
// routing behavior and ensure compatibility with Gateway configurations.
debug(log, tlsroute, "Retrieving GatewayClass and Gateway for route")
gateways, err := getSupportedGatewayForRoute(ctx, log, r.Client, tlsroute)
gateways, err := getSupportedGatewayForRoute(ctx, log, r.Client, tlsroute, r.GatewayNN)
if err != nil {
if err.Error() == unsupportedGW {
debug(log, tlsroute, "Unsupported route found, processing to verify whether it was ever supported")
Expand Down
Loading
Loading