Skip to content

Commit

Permalink
feat: add new flag to specific Gateway
Browse files Browse the repository at this point in the history
Signed-off-by: Jintao Zhang <zhangjintao9020@gmail.com>
  • Loading branch information
tao12345666333 committed Jan 15, 2024
1 parent c9e95e9 commit 8712177
Show file tree
Hide file tree
Showing 15 changed files with 298 additions and 32 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,8 @@ Adding a new version? You'll need three changes:
plugins. Reference of using Kong vaults: [Kong vault]
[#5354](https://github.com/Kong/kubernetes-ingress-controller/pull/5354)
[#5384](https://github.com/Kong/kubernetes-ingress-controller/pull/5384)

- Add new flag `--gateway-namespaced-name` KIC can only reconciling the specified Gateway.
[#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-namespaced-name` | `namespaced-name` | Gateway namespaced name in "namespace/name" format, to use for KIC can only reconciling 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
21 changes: 21 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 k8stypes.NamespacedName
}

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

// KIC introduced a new flag called `--gateway-namespaced-name`.
// If this flag is set, KIC will only reconcile the specified gateway.
// https://github.com/Kong/kubernetes-ingress-controller/issues/5322
if r.GatewayNN.Namespace != "" && r.GatewayNN.Name != "" {
if gateway.Namespace != r.GatewayNN.Namespace || gateway.Name != r.GatewayNN.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 +341,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 r.GatewayNN.Namespace != "" && r.GatewayNN.Name != "" {
if req.Namespace != r.GatewayNN.Namespace || req.Name != r.GatewayNN.Name {
r.Log.V(util.DebugLevel).Info("The request does not match the specified Gateway and will be skipped.", "gateway", r.GatewayNN.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
34 changes: 29 additions & 5 deletions 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 k8stypes.NamespacedName
}

// SetupWithManager sets up the controller with the Manager.
Expand Down Expand Up @@ -143,11 +147,22 @@ 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 {
_, ok := gateways[gateway.Namespace]
if !ok {
gateways[gateway.Namespace] = make(map[string]struct{})
// KIC introduced a new flag called `--gateway-namespaced-name`.
// If this flag is set, KIC will only reconcile the specified gateway.
// https://github.com/Kong/kubernetes-ingress-controller/issues/5322
if r.GatewayNN.Namespace != "" && r.GatewayNN.Name != "" {
_, ok := gateways[r.GatewayNN.Namespace]
if !ok {
gateways[r.GatewayNN.Namespace] = make(map[string]struct{})
}
gateways[r.GatewayNN.Namespace][r.GatewayNN.Name] = struct{}{}
} else {
_, ok := gateways[gateway.Namespace]
if !ok {
gateways[gateway.Namespace] = make(map[string]struct{})
}
gateways[gateway.Namespace][gateway.Name] = struct{}{}
}
gateways[gateway.Namespace][gateway.Name] = struct{}{}
}
}

Expand Down Expand Up @@ -217,6 +232,15 @@ func (r *GRPCRouteReconciler) listGRPCRoutesForGateway(ctx context.Context, obj
return nil
}

// KIC introduced a new flag called `--gateway-namespaced-name`.
// If this flag is set, KIC will only reconcile the specified gateway.
// https://github.com/Kong/kubernetes-ingress-controller/issues/5322
if r.GatewayNN.Namespace != "" && r.GatewayNN.Name != "" {
if gw.Namespace != r.GatewayNN.Namespace || gw.Name != r.GatewayNN.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 +317,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
34 changes: 29 additions & 5 deletions 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 k8stypes.NamespacedName
}

// SetupWithManager sets up the controller with the Manager.
Expand Down Expand Up @@ -217,11 +221,22 @@ 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 {
_, ok := gateways[gateway.Namespace]
if !ok {
gateways[gateway.Namespace] = make(map[string]struct{})
// KIC introduced a new flag called `--gateway-namespaced-name`.
// If this flag is set, KIC will only reconcile the specified gateway.
// https://github.com/Kong/kubernetes-ingress-controller/issues/5322
if r.GatewayNN.Namespace != "" && r.GatewayNN.Name != "" {
_, ok := gateways[r.GatewayNN.Namespace]
if !ok {
gateways[r.GatewayNN.Namespace] = make(map[string]struct{})
}
gateways[r.GatewayNN.Namespace][r.GatewayNN.Name] = struct{}{}
} else {
_, ok := gateways[gateway.Namespace]
if !ok {
gateways[gateway.Namespace] = make(map[string]struct{})
}
gateways[gateway.Namespace][gateway.Name] = struct{}{}
}
gateways[gateway.Namespace][gateway.Name] = struct{}{}
}
}

Expand Down Expand Up @@ -291,6 +306,15 @@ func (r *HTTPRouteReconciler) listHTTPRoutesForGateway(ctx context.Context, obj
return nil
}

// KIC introduced a new flag called `--gateway-namespaced-name`.
// If this flag is set, KIC will only reconcile the specified gateway.
// https://github.com/Kong/kubernetes-ingress-controller/issues/5322
if r.GatewayNN.Namespace != "" && r.GatewayNN.Name != "" {
if gw.Namespace != r.GatewayNN.Namespace || gw.Name != r.GatewayNN.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 +392,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 @@ -14,6 +14,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime/schema"
k8stypes "k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"

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 k8stypes.NamespacedName) ([]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)

// KIC introduced a new flag called `--gateway-namespaced-name`.
// If this flag is set, KIC will only reconcile the specified gateway.
// https://github.com/Kong/kubernetes-ingress-controller/issues/5322
if specifiedGW.Namespace != "" && specifiedGW.Name != "" {
namespace = specifiedGW.Namespace
name = specifiedGW.Name
}

// pull the Gateway object from the cached client
gateway := gatewayapi.Gateway{}
if err := mgrc.Get(ctx, client.ObjectKey{
Expand Down
10 changes: 5 additions & 5 deletions internal/controllers/gateway/route_utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,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, k8stypes.NamespacedName{})
require.NoError(t, err)
require.Len(t, got, len(tt.expected))

Expand Down Expand Up @@ -813,7 +813,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, k8stypes.NamespacedName{})
require.NoError(t, err)
require.Len(t, got, 1)
match := got[0]
Expand Down Expand Up @@ -1048,7 +1048,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, k8stypes.NamespacedName{})
require.NoError(t, err)
require.Len(t, got, 1)
match := got[0]
Expand Down Expand Up @@ -1270,7 +1270,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, k8stypes.NamespacedName{})
require.NoError(t, err)
require.Len(t, got, len(tt.expected))

Expand Down Expand Up @@ -1300,7 +1300,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, k8stypes.NamespacedName{})
require.Equal(t, fmt.Errorf("unsupported parent kind %s/%s", string(badGroup), string(badKind)), err)
})
}
Expand Down
34 changes: 29 additions & 5 deletions 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 k8stypes.NamespacedName
}

// SetupWithManager sets up the controller with the Manager.
Expand Down Expand Up @@ -140,11 +144,22 @@ 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 {
_, ok := gateways[gateway.Namespace]
if !ok {
gateways[gateway.Namespace] = make(map[string]struct{})
// KIC introduced a new flag called `--gateway-namespaced-name`.
// If this flag is set, KIC will only reconcile the specified gateway.
// https://github.com/Kong/kubernetes-ingress-controller/issues/5322
if r.GatewayNN.Namespace != "" && r.GatewayNN.Name != "" {
_, ok := gateways[r.GatewayNN.Namespace]
if !ok {
gateways[r.GatewayNN.Namespace] = make(map[string]struct{})
}
gateways[r.GatewayNN.Namespace][r.GatewayNN.Name] = struct{}{}
} else {
_, ok := gateways[gateway.Namespace]
if !ok {
gateways[gateway.Namespace] = make(map[string]struct{})
}
gateways[gateway.Namespace][gateway.Name] = struct{}{}
}
gateways[gateway.Namespace][gateway.Name] = struct{}{}
}
}

Expand Down Expand Up @@ -214,6 +229,15 @@ func (r *TCPRouteReconciler) listTCPRoutesForGateway(ctx context.Context, obj cl
return nil
}

// KIC introduced a new flag called `--gateway-namespaced-name`.
// If this flag is set, KIC will only reconcile the specified gateway.
// https://github.com/Kong/kubernetes-ingress-controller/issues/5322
if r.GatewayNN.Namespace != "" && r.GatewayNN.Name != "" {
if gw.Namespace != r.GatewayNN.Namespace || gw.Name != r.GatewayNN.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 +314,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
34 changes: 29 additions & 5 deletions 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 k8stypes.NamespacedName
}

// SetupWithManager sets up the controller with the Manager.
Expand Down Expand Up @@ -139,11 +143,22 @@ 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 {
_, ok := gateways[gateway.Namespace]
if !ok {
gateways[gateway.Namespace] = make(map[string]struct{})
// KIC introduced a new flag called `--gateway-namespaced-name`.
// If this flag is set, KIC will only reconcile the specified gateway.
// https://github.com/Kong/kubernetes-ingress-controller/issues/5322
if r.GatewayNN.Namespace != "" && r.GatewayNN.Name != "" {
_, ok := gateways[r.GatewayNN.Namespace]
if !ok {
gateways[r.GatewayNN.Namespace] = make(map[string]struct{})
}
gateways[r.GatewayNN.Namespace][r.GatewayNN.Name] = struct{}{}
} else {
_, ok := gateways[gateway.Namespace]
if !ok {
gateways[gateway.Namespace] = make(map[string]struct{})
}
gateways[gateway.Namespace][gateway.Name] = struct{}{}
}
gateways[gateway.Namespace][gateway.Name] = struct{}{}
}
}

Expand Down Expand Up @@ -213,6 +228,15 @@ func (r *TLSRouteReconciler) listTLSRoutesForGateway(ctx context.Context, obj cl
return nil
}

// KIC introduced a new flag called `--gateway-namespaced-name`.
// If this flag is set, KIC will only reconcile the specified gateway.
// https://github.com/Kong/kubernetes-ingress-controller/issues/5322
if r.GatewayNN.Namespace != "" && r.GatewayNN.Name != "" {
if gw.Namespace != r.GatewayNN.Namespace || gw.Name != r.GatewayNN.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 +313,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

0 comments on commit 8712177

Please sign in to comment.