diff --git a/controllers/state_of_the_world.go b/controllers/state_of_the_world.go index 404a57342..d9bb62fa2 100644 --- a/controllers/state_of_the_world.go +++ b/controllers/state_of_the_world.go @@ -22,6 +22,7 @@ import ( "k8s.io/client-go/dynamic" "k8s.io/utils/env" ctrlruntime "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/event" ctrlruntimepredicate "sigs.k8s.io/controller-runtime/pkg/predicate" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" @@ -193,47 +194,7 @@ func NewPolicyMachineryController(manager ctrlruntime.Manager, client *dynamic.D if err != nil || !ok { logger.Info("cert manager is not installed, skipping related watches and reconcilers", "err", err) } else { - controllerOpts = append(controllerOpts, - controller.WithRunnable("certificate watcher", controller.Watch( - &certmanagerv1.Certificate{}, - CertManagerCertificatesResource, - metav1.NamespaceAll), - ), - controller.WithRunnable("issuers watcher", controller.Watch( - &certmanagerv1.Issuer{}, - CertManagerIssuersResource, - metav1.NamespaceAll, - controller.WithPredicates(ctrlruntimepredicate.TypedFuncs[*certmanagerv1.Issuer]{ - UpdateFunc: func(e event.TypedUpdateEvent[*certmanagerv1.Issuer]) bool { - oldStatus := e.ObjectOld.GetStatus() - newStatus := e.ObjectOld.GetStatus() - return !reflect.DeepEqual(oldStatus, newStatus) - }, - })), - ), - controller.WithRunnable("clusterissuers watcher", controller.Watch( - &certmanagerv1.ClusterIssuer{}, - CertMangerClusterIssuersResource, - metav1.NamespaceAll, - controller.WithPredicates(ctrlruntimepredicate.TypedFuncs[*certmanagerv1.ClusterIssuer]{ - UpdateFunc: func(e event.TypedUpdateEvent[*certmanagerv1.ClusterIssuer]) bool { - oldStatus := e.ObjectOld.GetStatus() - newStatus := e.ObjectOld.GetStatus() - return !reflect.DeepEqual(oldStatus, newStatus) - }, - })), - ), - controller.WithObjectKinds( - CertManagerCertificateKind, - CertManagerIssuerKind, - CertManagerClusterIssuerKind, - ), - controller.WithObjectLinks( - LinkGatewayToCertificateFunc, - LinkGatewayToIssuerFunc, - LinkGatewayToClusterIssuerFunc, - ), - ) + controllerOpts = append(controllerOpts, certManagerControllerOpts()...) // TODO: add tls policy specific tasks to workflow } @@ -255,6 +216,68 @@ func buildReconciler(client *dynamic.DynamicClient) controller.ReconcileFunc { return reconciler.Run } +func certManagerControllerOpts() []controller.ControllerOption { + isCertificateOwnedByTLSPolicy := func(c *certmanagerv1.Certificate) bool { + return isObjectOwnedByKind(c, kuadrantv1alpha1.TLSPolicyKind.Group, kuadrantv1alpha1.TLSPolicyKind.Kind) + } + + return []controller.ControllerOption{ + controller.WithRunnable("certificate watcher", controller.Watch( + &certmanagerv1.Certificate{}, + CertManagerCertificatesResource, + metav1.NamespaceAll, + controller.WithPredicates(ctrlruntimepredicate.TypedFuncs[*certmanagerv1.Certificate]{ + CreateFunc: func(e event.TypedCreateEvent[*certmanagerv1.Certificate]) bool { + return isCertificateOwnedByTLSPolicy(e.Object) + }, + UpdateFunc: func(e event.TypedUpdateEvent[*certmanagerv1.Certificate]) bool { + return isCertificateOwnedByTLSPolicy(e.ObjectNew) + }, + DeleteFunc: func(e event.TypedDeleteEvent[*certmanagerv1.Certificate]) bool { + return isCertificateOwnedByTLSPolicy(e.Object) + }, + GenericFunc: func(e event.TypedGenericEvent[*certmanagerv1.Certificate]) bool { + return isCertificateOwnedByTLSPolicy(e.Object) + }, + })), + ), + controller.WithRunnable("issuers watcher", controller.Watch( + &certmanagerv1.Issuer{}, + CertManagerIssuersResource, + metav1.NamespaceAll, + controller.WithPredicates(ctrlruntimepredicate.TypedFuncs[*certmanagerv1.Issuer]{ + UpdateFunc: func(e event.TypedUpdateEvent[*certmanagerv1.Issuer]) bool { + oldStatus := e.ObjectOld.GetStatus() + newStatus := e.ObjectOld.GetStatus() + return !reflect.DeepEqual(oldStatus, newStatus) + }, + })), + ), + controller.WithRunnable("clusterissuers watcher", controller.Watch( + &certmanagerv1.ClusterIssuer{}, + CertMangerClusterIssuersResource, + metav1.NamespaceAll, + controller.WithPredicates(ctrlruntimepredicate.TypedFuncs[*certmanagerv1.ClusterIssuer]{ + UpdateFunc: func(e event.TypedUpdateEvent[*certmanagerv1.ClusterIssuer]) bool { + oldStatus := e.ObjectOld.GetStatus() + newStatus := e.ObjectOld.GetStatus() + return !reflect.DeepEqual(oldStatus, newStatus) + }, + })), + ), + controller.WithObjectKinds( + CertManagerCertificateKind, + CertManagerIssuerKind, + CertManagerClusterIssuerKind, + ), + controller.WithObjectLinks( + LinkGatewayToCertificateFunc, + LinkGatewayToIssuerFunc, + LinkGatewayToClusterIssuerFunc, + ), + } +} + type TopologyFileReconciler struct { Client *dynamic.DynamicClient Namespace string @@ -353,3 +376,18 @@ func NewTLSPolicyWorkflow(client *dynamic.DynamicClient) *controller.Workflow { Postcondition: NewTLSPolicyStatusTask(client).Reconcile, } } + +func isObjectOwnedByKind(o client.Object, ownerGroup, ownerKind string) bool { + for _, o := range o.GetOwnerReferences() { + oGV, err := schema.ParseGroupVersion(o.APIVersion) + if err != nil { + return false + } + + if oGV.Group == ownerGroup && o.Kind == ownerKind { + return true + } + } + + return false +} diff --git a/controllers/tlspolicy_tasks.go b/controllers/tlspolicy_tasks.go index 8419e5f92..d9f7fb050 100644 --- a/controllers/tlspolicy_tasks.go +++ b/controllers/tlspolicy_tasks.go @@ -216,13 +216,17 @@ func (t *TLSPolicyStatusTask) isIssuerReady(ctx context.Context, tlsPolicy *kuad }) // Find gateway defined by target ref - gw, _ := lo.Find(gws, func(item *machinery.Gateway) bool { + gw, ok := lo.Find(gws, func(item *machinery.Gateway) bool { if item.GetName() == string(tlsPolicy.GetTargetRef().Name) && item.GetNamespace() == tlsPolicy.GetNamespace() { return true } return false }) + if !ok { + return fmt.Errorf("unable to find target ref %s for policy %s in ns %s in topology", tlsPolicy.GetTargetRef(), tlsPolicy.Name, tlsPolicy.Namespace) + } + var conditions []certmanagerv1.IssuerCondition switch tlsPolicy.Spec.IssuerRef.Kind {