Skip to content

Commit

Permalink
feat(backendtlspolicy): enqueue for ConfigMaps (#6837)
Browse files Browse the repository at this point in the history
  • Loading branch information
pmalek authored Dec 13, 2024
1 parent cd23363 commit ae372cd
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ Adding a new version? You'll need three changes:
is applied to the service section of the Kong configuration.
[#6712](https://github.com/Kong/kubernetes-ingress-controller/pull/6712)
[#6753](https://github.com/Kong/kubernetes-ingress-controller/pull/6753)
[#6837](https://github.com/Kong/kubernetes-ingress-controller/pull/6837)
- Added the flag `--configmap-label-selector` to set the label selector for `ConfigMap`s
to ingest. By setting this flag, the `ConfigMap`s that are ingested will be limited
to those having this label set to "true". This limits the amount of resources that are kept in memory.
Expand Down
54 changes: 54 additions & 0 deletions internal/controllers/gateway/backendtlspolicy_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ func (r *BackendTLSPolicyReconciler) SetupWithManager(mgr ctrl.Manager) error {
CacheSyncTimeout: r.CacheSyncTimeout,
}).
For(&gatewayapi.BackendTLSPolicy{}).
Watches(&corev1.ConfigMap{}, handler.EnqueueRequestsFromMapFunc(r.listBackendTLSPoliciesForConfigMaps)).
Watches(&corev1.Service{}, handler.EnqueueRequestsFromMapFunc(r.listBackendTLSPoliciesForServices)).
Watches(&gatewayapi.HTTPRoute{}, handler.EnqueueRequestsFromMapFunc(r.listBackendTLSPoliciesForHTTPRoutes)).
Watches(&gatewayapi.Gateway{}, handler.EnqueueRequestsFromMapFunc(r.listBackendTLSPoliciesForGateways)).
Expand All @@ -65,6 +66,9 @@ func (r *BackendTLSPolicyReconciler) SetupWithManager(mgr ctrl.Manager) error {
// -----------------------------------------------------------------------------

const (
// backendTLSPolicyValidationCARefIndexKey is the index key for BackendTLSPolicy objects by their validation CA configmap reference.
// The value is the name of the configmap.
backendTLSPolicyValidationCARefIndexKey = "backendtlspolicy-validation-cacertificateref"
// backendTLSPolicyTargetRefIndexKey is the index key for BackendTLSPolicy objects by their target service reference.
// The value is the name of the service.
backendTLSPolicyTargetRefIndexKey = "backendtlspolicy-targetref"
Expand Down Expand Up @@ -92,6 +96,23 @@ func indexBackendTLSPolicyOnTargetRef(obj client.Object) []string {
return services
}

// indexBackendTLSPolicyOnValidationCACertificateRef indexes BackendTLSPolicy objects
// by their validation CA Certificate configmap reference.
func indexBackendTLSPolicyOnValidationCACertificateRef(obj client.Object) []string {
policy, ok := obj.(*gatewayapi.BackendTLSPolicy)
if !ok {
return []string{}
}

configmaps := []string{}
for _, cacertref := range policy.Spec.Validation.CACertificateRefs {
if (cacertref.Group == "" || cacertref.Group == "core") && cacertref.Kind == "ConfigMap" {
configmaps = append(configmaps, string(cacertref.Name))
}
}
return configmaps
}

// indexHTTPRouteOnParentRef indexes HTTPRoute objects by their parent Gateway references.
func indexHTTPRouteOnParentRef(obj client.Object) []string {
httpRoute, ok := obj.(*gatewayapi.HTTPRoute)
Expand Down Expand Up @@ -148,6 +169,15 @@ func setupBackendTLSPolicyIndices(mgr ctrl.Manager) error {
return fmt.Errorf("failed to index backendTLSPolicies on service reference: %w", err)
}

if err := mgr.GetCache().IndexField(
context.Background(),
&gatewayapi.BackendTLSPolicy{},
backendTLSPolicyValidationCARefIndexKey,
indexBackendTLSPolicyOnValidationCACertificateRef,
); err != nil {
return fmt.Errorf("failed to index backendTLSPolicies on validation CA configmap reference: %w", err)
}

if err := mgr.GetCache().IndexField(
context.Background(),
&gatewayapi.HTTPRoute{},
Expand All @@ -173,6 +203,30 @@ func setupBackendTLSPolicyIndices(mgr ctrl.Manager) error {
// BackendTLSPolicy Controller - Event Handlers
// -----------------------------------------------------------------------------

// listBackendTLSPoliciesForConfigMaps returns the list of BackendTLSPolicies that targets the given ConfigMap.
func (r *BackendTLSPolicyReconciler) listBackendTLSPoliciesForConfigMaps(ctx context.Context, obj client.Object) []reconcile.Request {
cm, ok := obj.(*corev1.ConfigMap)
if !ok {
r.Log.Error(fmt.Errorf("invalid type"), "Found invalid type in event handlers", "expected", "ConfigMap", "found", reflect.TypeOf(obj))
return nil
}
policies := &gatewayapi.BackendTLSPolicyList{}
if err := r.List(ctx, policies,
client.InNamespace(cm.Namespace),
client.MatchingFields{backendTLSPolicyValidationCARefIndexKey: cm.Name},
); err != nil {
r.Log.Error(err, "Failed to list BackendTLSPolicies for ConfigMap", "configmap", cm)
return nil
}
requests := make([]reconcile.Request, 0, len(policies.Items))
for _, policy := range policies.Items {
requests = append(requests, reconcile.Request{
NamespacedName: client.ObjectKeyFromObject(&policy),
})
}
return requests
}

// listBackendTLSPoliciesForServices returns the list of BackendTLSPolicies that targets the given Service.
func (r *BackendTLSPolicyReconciler) listBackendTLSPoliciesForServices(ctx context.Context, obj client.Object) []reconcile.Request {
service, ok := obj.(*corev1.Service)
Expand Down
16 changes: 16 additions & 0 deletions internal/controllers/gateway/backendtlspolicy_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package gateway

import (
"context"
"fmt"
"sort"
"strings"

"github.com/samber/lo"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8stypes "k8s.io/apimachinery/pkg/types"
Expand Down Expand Up @@ -240,6 +242,20 @@ func (r *BackendTLSPolicyReconciler) validateBackendTLSPolicy(ctx context.Contex
invalidMessages = append(invalidMessages, "CACertificateRefs must reference ConfigMaps in the core group")
break
}

var (
cm corev1.ConfigMap
configMapNN = k8stypes.NamespacedName{
Namespace: policy.Namespace,
Name: string(caCert.Name),
}
)
if err := r.Get(ctx, configMapNN, &cm); err != nil {
invalidMessages = append(invalidMessages,
fmt.Sprintf("failed getting ConfigMap %s set as CACertificateRef: %s", configMapNN, err),
)
break
}
}
if len(policy.Spec.Validation.SubjectAltNames) > 0 {
invalidMessages = append(invalidMessages, "SubjectAltNames feature is not currently supported")
Expand Down
77 changes: 77 additions & 0 deletions internal/controllers/gateway/backendtlspolicy_utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
k8stypes "k8s.io/apimachinery/pkg/types"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"

Expand Down Expand Up @@ -764,9 +765,80 @@ func TestValidateBackendTLSPolicy(t *testing.T) {
Message: "CACertificateRefs must reference ConfigMaps in the core group - SubjectAltNames feature is not currently supported - WellKnownCACertificates feature is not currently supported",
},
},
{
name: "valid policy referencing not existing CACert (ConfigMap)",
policy: &gatewayapi.BackendTLSPolicy{
ObjectMeta: metav1.ObjectMeta{
Name: "test-policy",
Namespace: "default",
},
Spec: gatewayapi.BackendTLSPolicySpec{
TargetRefs: []gatewayapi.LocalPolicyTargetReferenceWithSectionName{
{
LocalPolicyTargetReference: gatewayapi.LocalPolicyTargetReference{
Group: "core",
Kind: "Service",
Name: "example-service",
},
},
},
Validation: gatewayapi.BackendTLSPolicyValidation{
CACertificateRefs: []gatewayapi.LocalObjectReference{
{
Group: "",
Kind: "ConfigMap",
Name: gatewayapi.ObjectName("example-configmap"),
},
},
},
},
},
expected: &metav1.Condition{
Type: string(gatewayapi.PolicyConditionAccepted),
Status: metav1.ConditionFalse,
Reason: string(gatewayapi.PolicyReasonInvalid),
Message: "failed getting ConfigMap default/example-configmap set as CACertificateRef: configmaps \"example-configmap\" not found",
},
},
{
name: "valid policy referencing not existing CACert (ConfigMap, group core)",
policy: &gatewayapi.BackendTLSPolicy{
ObjectMeta: metav1.ObjectMeta{
Name: "test-policy",
Namespace: "default",
},
Spec: gatewayapi.BackendTLSPolicySpec{
TargetRefs: []gatewayapi.LocalPolicyTargetReferenceWithSectionName{
{
LocalPolicyTargetReference: gatewayapi.LocalPolicyTargetReference{
Group: "core",
Kind: "Service",
Name: "example-service",
},
},
},
Validation: gatewayapi.BackendTLSPolicyValidation{
CACertificateRefs: []gatewayapi.LocalObjectReference{
{
Group: "core",
Kind: "ConfigMap",
Name: gatewayapi.ObjectName("example-configmap"),
},
},
},
},
},
expected: &metav1.Condition{
Type: string(gatewayapi.PolicyConditionAccepted),
Status: metav1.ConditionFalse,
Reason: string(gatewayapi.PolicyReasonInvalid),
Message: "failed getting ConfigMap default/example-configmap set as CACertificateRef: configmaps \"example-configmap\" not found",
},
},
}

scheme := runtime.NewScheme()
require.NoError(t, clientgoscheme.AddToScheme(scheme))
require.NoError(t, gatewayapi.InstallV1(scheme))
require.NoError(t, gatewayapi.InstallV1alpha3(scheme))

Expand All @@ -784,6 +856,11 @@ func TestValidateBackendTLSPolicy(t *testing.T) {
backendTLSPolicyTargetRefIndexKey,
indexBackendTLSPolicyOnTargetRef,
).
WithIndex(
&gatewayapi.BackendTLSPolicy{},
backendTLSPolicyValidationCARefIndexKey,
indexBackendTLSPolicyOnValidationCACertificateRef,
).
Build()

r := &BackendTLSPolicyReconciler{
Expand Down

0 comments on commit ae372cd

Please sign in to comment.