Skip to content

Commit

Permalink
Fix the out-of-order creation issue for authPolices.
Browse files Browse the repository at this point in the history
  • Loading branch information
Boomatang committed May 30, 2024
1 parent faa4a60 commit 805f896
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 18 deletions.
4 changes: 2 additions & 2 deletions controllers/authpolicy_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ func (r *AuthPolicyReconciler) reconcileRouteParentGatewayPolicies(ctx context.C

// SetupWithManager sets up the controller with the Manager.
func (r *AuthPolicyReconciler) SetupWithManager(mgr ctrl.Manager) error {
httpRouteEventMapper := mappers.NewHTTPRouteEventMapper(mappers.WithLogger(r.Logger().WithName("httpRouteEventMapper")))
httpRouteEventMapper := mappers.NewHTTPRouteEventMapper(mappers.WithLogger(r.Logger().WithName("httpRouteEventMapper")), mappers.WithClient(mgr.GetClient()))
gatewayEventMapper := mappers.NewGatewayEventMapper(mappers.WithLogger(r.Logger().WithName("gatewayEventMapper")), mappers.WithClient(mgr.GetClient()))

return ctrl.NewControllerManagedBy(mgr).
Expand All @@ -271,7 +271,7 @@ func (r *AuthPolicyReconciler) SetupWithManager(mgr ctrl.Manager) error {
Watches(
&gatewayapiv1.HTTPRoute{},
handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, object client.Object) []reconcile.Request {
return httpRouteEventMapper.MapToPolicy(object, &api.AuthPolicy{})
return httpRouteEventMapper.MapToPolicy(object, schema.GroupVersionKind{Group: "kuadrant.io", Version: "kuadrant.io/v1beta2", Kind: "AuthPolicy"})
}),
).
Watches(&gatewayapiv1.Gateway{},
Expand Down
4 changes: 2 additions & 2 deletions controllers/ratelimitpolicy_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,15 +226,15 @@ func (r *RateLimitPolicyReconciler) deleteNetworkResourceDirectBackReference(ctx

// SetupWithManager sets up the controller with the Manager.
func (r *RateLimitPolicyReconciler) SetupWithManager(mgr ctrl.Manager) error {
httpRouteEventMapper := mappers.NewHTTPRouteEventMapper(mappers.WithLogger(r.Logger().WithName("httpRouteEventMapper")))
httpRouteEventMapper := mappers.NewHTTPRouteEventMapper(mappers.WithLogger(r.Logger().WithName("httpRouteEventMapper")), mappers.WithClient(mgr.GetClient()))
gatewayEventMapper := mappers.NewGatewayEventMapper(mappers.WithLogger(r.Logger().WithName("gatewayEventMapper")), mappers.WithClient(mgr.GetClient()))

return ctrl.NewControllerManagedBy(mgr).
For(&kuadrantv1beta2.RateLimitPolicy{}).
Watches(
&gatewayapiv1.HTTPRoute{},
handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, object client.Object) []reconcile.Request {
return httpRouteEventMapper.MapToPolicy(object, &kuadrantv1beta2.RateLimitPolicy{})
return httpRouteEventMapper.MapToPolicy(object, schema.GroupVersionKind{Group: "kuadrant.io", Version: "kuadrant.io/v1beta2", Kind: "RateLimitPolicy"})
}),
).
// Currently the purpose is to generate events when rlp references change in gateways
Expand Down
15 changes: 15 additions & 0 deletions pkg/library/kuadrant/referrer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package kuadrant

import (
"encoding/json"
"strings"

"sigs.k8s.io/controller-runtime/pkg/client"

Expand Down Expand Up @@ -33,3 +34,17 @@ func BackReferencesFromObject(obj client.Object, referrer Referrer) []client.Obj

return refs
}

func DirectReferencesFromObject(obj client.Object, referrer Referrer) client.ObjectKey {
annotations := utils.ReadAnnotationsFromObject(obj)
key := referrer.DirectReferenceAnnotationName()
directRefs, found := annotations[key]
if !found {
return client.ObjectKey{}
}

parts := strings.Split(directRefs, "/")
ref := client.ObjectKey{Namespace: parts[0], Name: parts[1]}

return ref
}
2 changes: 1 addition & 1 deletion pkg/library/mappers/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func (m *gatewayEventMapper) MapToPolicy(obj client.Object, policyGVK schema.Gro
policyList.SetAPIVersion(policyGVK.Version)
policyList.SetKind(policyGVK.Kind)
if err := m.opts.Client.List(ctx, policyList, client.InNamespace(obj.GetNamespace())); err != nil {
logger.V(1).Error(err, fmt.Sprintf("unable to list UnstructuredList of policies, %T", policyGVK))
logger.V(1).Info("unable to list UnstructuredList of policies, %T", policyGVK)
return []reconcile.Request{}
}

Expand Down
135 changes: 122 additions & 13 deletions pkg/library/mappers/httproute.go
Original file line number Diff line number Diff line change
@@ -1,44 +1,153 @@
package mappers

Check failure on line 1 in pkg/library/mappers/httproute.go

View workflow job for this annotation

GitHub Actions / Auto-format and Check (goimports)

Please run goimports . diff --git a/pkg/library/mappers/httproute.go b/pkg/library/mappers/httproute.go index 4baf30f..9123217 100644 --- a/pkg/library/mappers/httproute.go +++ b/pkg/library/mappers/httproute.go @@ -3,6 +3,7 @@ package mappers import ( "context" "fmt" + "github.com/kuadrant/kuadrant-operator/api/v1alpha1" api "github.com/kuadrant/kuadrant-operator/api/v1beta2" kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/library/gatewayapi"

import (
"context"
"fmt"

"github.com/kuadrant/kuadrant-operator/api/v1alpha1"
api "github.com/kuadrant/kuadrant-operator/api/v1beta2"
kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/library/gatewayapi"
"github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant"
"github.com/kuadrant/kuadrant-operator/pkg/library/utils"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/json"
"k8s.io/utils/ptr"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1"

"github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant"
)

func NewHTTPRouteEventMapper(o ...MapperOption) EventMapper {
func NewHTTPRouteEventMapper(o ...MapperOption) EventMapperTwo {
return &httpRouteEventMapper{opts: Apply(o...)}
}

var _ EventMapper = &httpRouteEventMapper{}
var _ EventMapperTwo = &httpRouteEventMapper{}

type httpRouteEventMapper struct {
opts MapperOptions
}

func (m *httpRouteEventMapper) MapToPolicy(obj client.Object, policyKind kuadrant.Referrer) []reconcile.Request {
func (m *httpRouteEventMapper) MapToPolicy(obj client.Object, policyGVK schema.GroupVersionKind) []reconcile.Request {
logger := m.opts.Logger.WithValues("httproute", client.ObjectKeyFromObject(obj))

ctx := context.Background()
requests := make([]reconcile.Request, 0)
httpRoute, ok := obj.(*gatewayapiv1.HTTPRoute)
if !ok {
logger.Info("cannot map httproute event to kuadrant policy", "error", fmt.Sprintf("%T is not a *gatewayapiv1beta1.HTTPRoute", obj))
return []reconcile.Request{}
}

requests := make([]reconcile.Request, 0)
gatewayKeys := kuadrantgatewayapi.GetRouteAcceptedGatewayParentKeys(httpRoute)

for _, gatewayKey := range gatewayKeys {
gateway := &gatewayapiv1.Gateway{}
err := m.opts.Client.Get(ctx, gatewayKey, gateway)
if err != nil {
logger.Info("cannot get gateway", "error", err)
continue
}

routeList := &gatewayapiv1.HTTPRouteList{}
fields := client.MatchingFields{kuadrantgatewayapi.HTTPRouteGatewayParentField: client.ObjectKeyFromObject(gateway).String()}
if err = m.opts.Client.List(ctx, routeList, fields); err != nil {
logger.Info("cannot list httproutes", "error", err)
continue
}
policyList := &unstructured.UnstructuredList{}
policyList.SetAPIVersion(policyGVK.Version)
policyList.SetKind(policyGVK.Kind)
if err = m.opts.Client.List(ctx, policyList, client.InNamespace(obj.GetNamespace())); err != nil {
logger.V(1).Info("unable to list UnstructuredList of policies, %T", policyGVK)
continue
}

for _, policyKey := range kuadrant.BackReferencesFromObject(httpRoute, policyKind) {
logger.V(1).Info("kuadrant policy possibly affected by the httproute related event found", policyKind.Kind(), policyKey)
requests = append(requests, reconcile.Request{NamespacedName: policyKey})
var policies []kuadrantgatewayapi.Policy
if err = policyList.EachListItem(func(obj runtime.Object) error {
objBytes, err := json.Marshal(obj)
if err != nil {
return err
}

switch obj.GetObjectKind().GroupVersionKind().Kind {
case "AuthPolicy":
policy := &api.AuthPolicy{}
err = json.Unmarshal(objBytes, policy)
if err != nil {
return err
}
policies = append(policies, policy)
case "DNSPolicy":
policy := &v1alpha1.DNSPolicy{}
err = json.Unmarshal(objBytes, policy)
if err != nil {
return err
}
policies = append(policies, policy)
case "TLSPolicy":
policy := &v1alpha1.TLSPolicy{}
err = json.Unmarshal(objBytes, policy)
if err != nil {
return err
}
policies = append(policies, policy)
case "RateLimitPolicy":
policy := &api.RateLimitPolicy{}
err = json.Unmarshal(objBytes, policy)
if err != nil {
return err
}
policies = append(policies, policy)
default:
return fmt.Errorf("unknown policy kind: %s", obj.GetObjectKind().GroupVersionKind().Kind)
}
return nil
}); err != nil {
logger.Info("unable to list UnstructuredList of policies, %T", policyGVK)
continue
}
if len(policies) == 0 {
logger.Info("no kuadrant policy possibly affected by the gateway related event")
continue
}
topology, err := kuadrantgatewayapi.NewTopology(
kuadrantgatewayapi.WithGateways([]*gatewayapiv1.Gateway{gateway}),
kuadrantgatewayapi.WithRoutes(utils.Map(routeList.Items, ptr.To[gatewayapiv1.HTTPRoute])),
kuadrantgatewayapi.WithPolicies(policies),
kuadrantgatewayapi.WithLogger(logger),
)
if err != nil {
logger.Info("unable to build topology for gateway", "error", err)
continue
}
index := kuadrantgatewayapi.NewTopologyIndexes(topology)
data := utils.Map(index.PoliciesFromGateway(gateway), func(p kuadrantgatewayapi.Policy) reconcile.Request {
policyKey := client.ObjectKeyFromObject(p)
logger.V(1).Info("kuadrant policy possibly affected by the gateway related event found", policyGVK.Kind, policyKey)
return reconcile.Request{NamespacedName: policyKey}
})
requests = append(requests, data...)
}

if len(requests) == 0 {
logger.V(1).Info("no kuadrant policy possibly affected by the httproute related event")
if len(requests) != 0 {
return requests
}

// This block is required when a HTTProute has being deleted
var policy kuadrant.Referrer
switch policyGVK.Kind {
case "AuthPolicy":
policy = &api.AuthPolicy{}
case "DNSPolicy":
policy = &v1alpha1.DNSPolicy{}
case "TLSPolicy":
policy = &v1alpha1.TLSPolicy{}
case "RateLimitPolicy":
policy = &api.RateLimitPolicy{}
default:
return requests
}
policyKey := kuadrant.DirectReferencesFromObject(httpRoute, policy)
requests = append(requests, reconcile.Request{NamespacedName: policyKey})
return requests
}

0 comments on commit 805f896

Please sign in to comment.