Skip to content

Commit 9af1396

Browse files
czeslavorandmonkey
andauthored
[backport release/3.1.x] fix: add check for existence of HTTPRoute in KongUpstreamPolicy controller (#5806)
* fix: add check for existence of HTTPRoute in KongUpstreamPolicy controller (#5780) * add HTTPRoute controller for watching HTTPRoute to enqueue KongUpstreamPolicy needing to update ancestor status * add CHANGELOG * do not use dynamic CRD controller and and envtest cases * Apply suggestions from code review --------- Co-authored-by: Grzegorz Burzyński <czeslavo@gmail.com> (cherry picked from commit 30a2991) * Update CHANGELOG.md --------- Co-authored-by: Tao Yi <tao.yi@konghq.com>
1 parent cb6e7ab commit 9af1396

9 files changed

Lines changed: 503 additions & 44 deletions

CHANGELOG.md

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ Adding a new version? You'll need three changes:
9292
[#5658](https://github.com/Kong/kubernetes-ingress-controller/issues/5658)
9393
- Do not require `rsa_public_key` field in credential `Secret`s when working with jwt HMAC credentials.
9494
[#5737](https://github.com/Kong/kubernetes-ingress-controller/issues/5737)
95+
- `KongUpstreamPolicy` controller no longer requires existence of `HTTPRoute` CRD
96+
to start.
97+
[#5780](https://github.com/Kong/kubernetes-ingress-controller/pull/5780)
9598

9699
## [3.1.2]
97100

@@ -126,14 +129,21 @@ Adding a new version? You'll need three changes:
126129
127130
### Highlights
128131

129-
- 🔒 Kong Gateway's [secret vaults](kong-vault) now become a first-class citizen for Kubernetes users
130-
thanks to the new `KongVault` CRD.
131-
- 🔒 Providing an Enterprise license to KIC-managed Kong Gateways becomes much easier thanks to the new `KongLicense` CRD
132-
which is used to dynamically provision all the replicas with the latest license found in the cluster.
133-
- ✨ Populating a single field of `KongPlugin`'s configuration with use of a Kubernetes Secret becomes possible thanks
134-
to the new `KongPlugin`'s `configPatches` field.
132+
- 🔒 Kong Gateway's [secret vaults][kong-vault] now become a first-class citizen for Kubernetes users thanks to the new
133+
`KongVault` CRD. _See [Kong Vault guide][vault-guide] and [CRDs reference][crds-ref] for more details._
134+
- 🔒 Providing an Enterprise license to KIC-managed Kong Gateways becomes much easier thanks to the new `KongLicense`
135+
CRD which is used to dynamically provision all the replicas with the latest license found in the cluster. _See
136+
[Enterprise License][license-guide] and [CRDs reference][crds-ref] for more details._
137+
- ✨ Populating a single field of `KongPlugin`'s configuration with use of a Kubernetes Secret becomes possible thanks
138+
to the new `KongPlugin`'s `configPatches` field. _See [Using Kubernetes Secrets in Plugins][secrets-in-plugins-guide]
139+
and [CRDs reference][crds-ref] for more details._
135140
- 🔒 All sensitive information stored in the cluster is now sanitized while sending configuration to Konnect.
136141

142+
[crds-ref]: https://docs.konghq.com/kubernetes-ingress-controller/latest/reference/custom-resources/
143+
[vault-guide]: https://docs.konghq.com/kubernetes-ingress-controller/latest/guides/security/kong-vault/
144+
[license-guide]: https://docs.konghq.com/kubernetes-ingress-controller/latest/license/
145+
[secrets-in-plugins-guide]: https://docs.konghq.com/kubernetes-ingress-controller/latest/guides/security/plugin-secrets/
146+
137147
### Added
138148

139149
- New CRD `KongVault` to represent a custom Kong vault for storing sensitive

internal/controllers/configuration/konglicense_controller.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ func WrapKongLicenseReconcilerToDynamicCRDController(
366366
) *crds.DynamicCRDController {
367367
return &crds.DynamicCRDController{
368368
Manager: mgr,
369-
Log: ctrl.LoggerFrom(ctx).WithName("controllers").WithName("Dynamic/KongUpstreamPolicy"),
369+
Log: ctrl.LoggerFrom(ctx).WithName("controllers").WithName("Dynamic/KongLicense"),
370370
CacheSyncTimeout: r.CacheSyncTimeout,
371371
RequiredCRDs: []schema.GroupVersionResource{
372372
{

internal/controllers/configuration/kongupstreampolicy_controller.go

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ type KongUpstreamPolicyReconciler struct {
4444
// KongServiceFacadeEnabled determines whether the controller should populate the KongUpstreamPolicy's ancestor
4545
// status for KongServiceFacades.
4646
KongServiceFacadeEnabled bool
47+
// HTTPRouteEnabled determines whether the controller should populate the KongUpstreamPolicy's
48+
// ancestor status for Services used in HTTPRoutes.
49+
HTTPRouteEnabled bool
4750
}
4851

4952
// SetupWithManager sets up the controller with the Manager.
@@ -71,13 +74,15 @@ func (r *KongUpstreamPolicyReconciler) SetupWithManager(mgr ctrl.Manager) error
7174
return err
7275
}
7376

74-
// Watch for HTTPRoute changes to trigger reconciliation for the KongUpstreamPolicies referenced by the Services
75-
// of the HTTPRoute.
76-
if err := c.Watch(
77-
source.Kind(mgr.GetCache(), &gatewayapi.HTTPRoute{}),
78-
handler.EnqueueRequestsFromMapFunc(r.getUpstreamPoliciesForHTTPRouteServices),
79-
); err != nil {
80-
return err
77+
if r.HTTPRouteEnabled {
78+
// Watch for HTTPRoute changes to trigger reconciliation for the KongUpstreamPolicies referenced by the Services
79+
// of the HTTPRoute.
80+
if err := c.Watch(
81+
source.Kind(mgr.GetCache(), &gatewayapi.HTTPRoute{}),
82+
handler.EnqueueRequestsFromMapFunc(r.getUpstreamPoliciesForHTTPRouteServices),
83+
); err != nil {
84+
return err
85+
}
8186
}
8287

8388
if r.KongServiceFacadeEnabled {
@@ -136,13 +141,15 @@ func (r *KongUpstreamPolicyReconciler) setupIndices(mgr ctrl.Manager) error {
136141
return fmt.Errorf("failed to index services on annotation %s: %w", kongv1beta1.KongUpstreamPolicyAnnotationKey, err)
137142
}
138143

139-
if err := mgr.GetCache().IndexField(
140-
context.Background(),
141-
&gatewayapi.HTTPRoute{},
142-
routeBackendRefServiceNameIndexKey,
143-
indexRoutesOnBackendRefServiceName,
144-
); err != nil {
145-
return fmt.Errorf("failed to index HTTPRoutes on backendReferences: %w", err)
144+
if r.HTTPRouteEnabled {
145+
if err := mgr.GetCache().IndexField(
146+
context.Background(),
147+
&gatewayapi.HTTPRoute{},
148+
routeBackendRefServiceNameIndexKey,
149+
indexRoutesOnBackendRefServiceName,
150+
); err != nil {
151+
return fmt.Errorf("failed to index HTTPRoutes on backendReferences: %w", err)
152+
}
146153
}
147154

148155
if r.KongServiceFacadeEnabled {
@@ -261,7 +268,6 @@ func (r *KongUpstreamPolicyReconciler) getUpstreamPoliciesForHTTPRouteServices(c
261268
if !ok {
262269
return nil
263270
}
264-
265271
var requests []reconcile.Request
266272
for _, rule := range httpRoute.Spec.Rules {
267273
for _, br := range rule.BackendRefs {

internal/controllers/configuration/kongupstreampolicy_utils.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,10 @@ func (r *KongUpstreamPolicyReconciler) buildAncestorsStatus(
212212

213213
// getConflictedServices returns a set of services that have conflicts.
214214
func (r *KongUpstreamPolicyReconciler) getConflictedServices(ctx context.Context, services []corev1.Service) (servicesSet, error) {
215+
// return directly when HTTPRoute is not enabled, as it only check conflicted services in HTTPRoute backends only.
216+
if !r.HTTPRouteEnabled {
217+
return make(servicesSet), nil
218+
}
215219
// Prepare a mapping for efficient lookups if a Service uses this KongUpstreamPolicy.
216220
upstreamPolicyServices := make(servicesSet)
217221
for _, service := range services {

internal/controllers/configuration/kongupstreampolicy_utils_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,7 @@ func TestEnforceKongUpstreamPolicyStatus(t *testing.T) {
698698
Client: fakeClient,
699699
DataplaneClient: DataPlaneStatusClientMock{ObjectsConfigured: tc.objectsConfiguredInDataPlane},
700700
KongServiceFacadeEnabled: true,
701+
HTTPRouteEnabled: true,
701702
}
702703

703704
updated, err := reconciler.enforceKongUpstreamPolicyStatus(context.TODO(), &tc.kongUpstreamPolicy)

internal/manager/controllerdef.go

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"github.com/kong/kubernetes-ingress-controller/v3/internal/controllers/crds"
1717
"github.com/kong/kubernetes-ingress-controller/v3/internal/controllers/gateway"
1818
ctrlref "github.com/kong/kubernetes-ingress-controller/v3/internal/controllers/reference"
19+
"github.com/kong/kubernetes-ingress-controller/v3/internal/controllers/utils"
1920
"github.com/kong/kubernetes-ingress-controller/v3/internal/dataplane"
2021
"github.com/kong/kubernetes-ingress-controller/v3/internal/manager/featuregates"
2122
"github.com/kong/kubernetes-ingress-controller/v3/internal/util/kubernetes/object/status"
@@ -250,28 +251,23 @@ func setupControllers(
250251
// StatusQueue: kubernetesStatusQueue,
251252
},
252253
},
254+
// KongUpstreamPolicy controller.
255+
// When HTTPRoute exists, the controller is enabled to watch HTTPRoutes to set ancestor status of KongUpstreamPolicies.
253256
{
254257
Enabled: c.KongUpstreamPolicyEnabled,
255-
Controller: &crds.DynamicCRDController{
256-
Manager: mgr,
257-
Log: ctrl.LoggerFrom(ctx).WithName("controllers").WithName("Dynamic/KongUpstreamPolicy"),
258-
CacheSyncTimeout: c.CacheSyncTimeout,
259-
RequiredCRDs: []schema.GroupVersionResource{
260-
{
261-
Group: gatewayv1.GroupVersion.Group,
262-
Version: gatewayv1.GroupVersion.Version,
263-
Resource: "httproutes",
264-
},
265-
},
266-
Controller: &configuration.KongUpstreamPolicyReconciler{
267-
Client: mgr.GetClient(),
268-
Log: ctrl.LoggerFrom(ctx).WithName("controllers").WithName("KongUpstreamPolicy"),
269-
Scheme: mgr.GetScheme(),
270-
DataplaneClient: dataplaneClient,
271-
CacheSyncTimeout: c.CacheSyncTimeout,
272-
KongServiceFacadeEnabled: featureGates.Enabled(featuregates.KongServiceFacade) && c.KongServiceFacadeEnabled,
273-
StatusQueue: kubernetesStatusQueue,
274-
},
258+
Controller: &configuration.KongUpstreamPolicyReconciler{
259+
Client: mgr.GetClient(),
260+
Log: ctrl.LoggerFrom(ctx).WithName("controllers").WithName("KongUpstreamPolicy"),
261+
Scheme: mgr.GetScheme(),
262+
DataplaneClient: dataplaneClient,
263+
CacheSyncTimeout: c.CacheSyncTimeout,
264+
KongServiceFacadeEnabled: featureGates.Enabled(featuregates.KongServiceFacade) && c.KongServiceFacadeEnabled,
265+
StatusQueue: kubernetesStatusQueue,
266+
HTTPRouteEnabled: utils.CRDExists(mgr.GetRESTMapper(), schema.GroupVersionResource{
267+
Group: gatewayv1.GroupVersion.Group,
268+
Version: gatewayv1.GroupVersion.Version,
269+
Resource: "httproutes",
270+
}),
275271
},
276272
},
277273
{

test/envtest/adminapi_discoverer_envtest_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ func TestDiscoverer_GetAdminAPIsForServiceReturnsAllAddressesCorrectlyPagingThro
9696
}
9797
}
9898

99-
func testPodReference(name, ns string) *corev1.ObjectReference {
99+
func testPodReference(name, ns string) *corev1.ObjectReference { //nolint:unparam
100100
return &corev1.ObjectReference{
101101
Kind: "Pod",
102102
Namespace: ns,

0 commit comments

Comments
 (0)