diff --git a/controllers/dns_workflow.go b/controllers/dns_workflow.go index 99787a34c..fee9f75d3 100644 --- a/controllers/dns_workflow.go +++ b/controllers/dns_workflow.go @@ -1,7 +1,59 @@ package controllers -import "github.com/kuadrant/policy-machinery/controller" +import ( + "github.com/samber/lo" -func NewDNSWorkflow() *controller.Workflow { - return &controller.Workflow{} + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/dynamic" + gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" + + kuadrantdnsv1alpha1 "github.com/kuadrant/dns-operator/api/v1alpha1" + "github.com/kuadrant/policy-machinery/controller" + "github.com/kuadrant/policy-machinery/machinery" + + kuadrantv1alpha1 "github.com/kuadrant/kuadrant-operator/api/v1alpha1" +) + +var ( + DNSRecordResource = kuadrantdnsv1alpha1.GroupVersion.WithResource("dnsrecords") + DNSRecordGroupKind = schema.GroupKind{Group: kuadrantdnsv1alpha1.GroupVersion.Group, Kind: "DNSRecord"} +) + +//+kubebuilder:rbac:groups=kuadrant.io,resources=dnspolicies,verbs=get;list;watch;update;patch;delete +//+kubebuilder:rbac:groups=kuadrant.io,resources=dnspolicies/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=kuadrant.io,resources=dnspolicies/finalizers,verbs=update + +//+kubebuilder:rbac:groups=kuadrant.io,resources=dnsrecords,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=kuadrant.io,resources=dnsrecords/status,verbs=get + +func NewDNSWorkflow(client *dynamic.DynamicClient) *controller.Workflow { + return &controller.Workflow{ + Precondition: NewDNSPoliciesValidator().Subscription().Reconcile, + Tasks: []controller.ReconcileFunc{(&controller.Workflow{ + Tasks: []controller.ReconcileFunc{ + NewEffectiveDNSPoliciesReconciler(client).Subscription().Reconcile, + }, + }).Run}, + Postcondition: NewDNSPolicyStatusUpdater(client).Subscription().Reconcile, + } +} + +func LinkListenerToDNSRecord(objs controller.Store) machinery.LinkFunc { + gateways := lo.Map(objs.FilterByGroupKind(machinery.GatewayGroupKind), controller.ObjectAs[*gwapiv1.Gateway]) + listeners := lo.FlatMap(lo.Map(gateways, func(g *gwapiv1.Gateway, _ int) *machinery.Gateway { + return &machinery.Gateway{Gateway: g} + }), machinery.ListenersFromGatewayFunc) + + return machinery.LinkFunc{ + From: machinery.ListenerGroupKind, + To: DNSRecordGroupKind, + Func: func(child machinery.Object) []machinery.Object { + return lo.FilterMap(listeners, func(l *machinery.Listener, _ int) (machinery.Object, bool) { + o := child.(*controller.RuntimeObject) + return l, isObjectOwnedByGroupKind(o, kuadrantv1alpha1.DNSPolicyGroupKind) && + l.GetNamespace() == child.GetNamespace() && + child.GetName() == dnsRecordName(l.Gateway.Name, string(l.Name)) + }) + }, + } } diff --git a/controllers/dnspolicies_validator.go b/controllers/dnspolicies_validator.go new file mode 100644 index 000000000..a991bb50a --- /dev/null +++ b/controllers/dnspolicies_validator.go @@ -0,0 +1,44 @@ +package controllers + +import ( + "context" + "sync" + + "github.com/kuadrant/policy-machinery/controller" + "github.com/kuadrant/policy-machinery/machinery" + "github.com/samber/lo" + + kuadrantv1alpha1 "github.com/kuadrant/kuadrant-operator/api/v1alpha1" +) + +var ( + StateDNSPolicyValid = struct{}{} +) + +func NewDNSPoliciesValidator() *DNSPoliciesValidator { + return &DNSPoliciesValidator{} +} + +type DNSPoliciesValidator struct{} + +func (r *DNSPoliciesValidator) Subscription() controller.Subscription { + return controller.Subscription{ + ReconcileFunc: r.validate, + Events: []controller.ResourceEventMatcher{ + {Kind: &machinery.GatewayGroupKind}, + {Kind: &kuadrantv1alpha1.DNSPolicyGroupKind}, + }, + } +} + +func (r *DNSPoliciesValidator) validate(_ context.Context, _ []controller.ResourceEvent, topology *machinery.Topology, _ error, state *sync.Map) error { + policies := topology.Policies().Items(func(o machinery.Object) bool { + return o.GroupVersionKind().GroupKind() == kuadrantv1alpha1.DNSPolicyGroupKind + }) + + state.Store(StateDNSPolicyValid, lo.SliceToMap(policies, func(policy machinery.Policy) (string, bool) { + return policy.GetLocator(), len(policy.GetTargetRefs()) == 0 || len(topology.Targetables().Parents(policy)) > 0 + })) + + return nil +} diff --git a/controllers/dnspolicy_controller.go b/controllers/dnspolicy_controller.go index 749c6efc6..a7d33cf37 100644 --- a/controllers/dnspolicy_controller.go +++ b/controllers/dnspolicy_controller.go @@ -51,14 +51,6 @@ type DNSPolicyReconciler struct { dnsHelper dnsHelper } -//+kubebuilder:rbac:groups=core,resources=namespaces,verbs=get;list;watch -//+kubebuilder:rbac:groups=kuadrant.io,resources=dnspolicies,verbs=get;list;watch;update;patch;delete -//+kubebuilder:rbac:groups=kuadrant.io,resources=dnspolicies/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=kuadrant.io,resources=dnspolicies/finalizers,verbs=update - -//+kubebuilder:rbac:groups=kuadrant.io,resources=dnsrecords,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=kuadrant.io,resources=dnsrecords/status,verbs=get - func (r *DNSPolicyReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { log := r.Logger().WithValues("DNSPolicy", req.NamespacedName) log.Info("Reconciling DNSPolicy") diff --git a/controllers/dnspolicy_status_updater.go b/controllers/dnspolicy_status_updater.go new file mode 100644 index 000000000..824c9e8e1 --- /dev/null +++ b/controllers/dnspolicy_status_updater.go @@ -0,0 +1,36 @@ +package controllers + +import ( + "context" + "sync" + + "github.com/kuadrant/policy-machinery/controller" + "github.com/kuadrant/policy-machinery/machinery" + "k8s.io/client-go/dynamic" + + kuadrantv1alpha1 "github.com/kuadrant/kuadrant-operator/api/v1alpha1" +) + +func NewDNSPolicyStatusUpdater(client *dynamic.DynamicClient) *DNSPolicyStatusUpdater { + return &DNSPolicyStatusUpdater{client: client} +} + +type DNSPolicyStatusUpdater struct { + client *dynamic.DynamicClient +} + +func (r *DNSPolicyStatusUpdater) Subscription() controller.Subscription { + return controller.Subscription{ + ReconcileFunc: r.update, + Events: []controller.ResourceEventMatcher{ + {Kind: &machinery.GatewayGroupKind}, + {Kind: &kuadrantv1alpha1.DNSPolicyGroupKind}, + {Kind: &DNSRecordGroupKind}, + }, + } +} + +func (r *DNSPolicyStatusUpdater) update(_ context.Context, _ []controller.ResourceEvent, _ *machinery.Topology, _ error, _ *sync.Map) error { + //ToDo Implement implement me !!! + return nil +} diff --git a/controllers/effective_dnspolicies_reconciler.go b/controllers/effective_dnspolicies_reconciler.go new file mode 100644 index 000000000..cfc7e0300 --- /dev/null +++ b/controllers/effective_dnspolicies_reconciler.go @@ -0,0 +1,35 @@ +package controllers + +import ( + "context" + "sync" + + "github.com/kuadrant/policy-machinery/controller" + "github.com/kuadrant/policy-machinery/machinery" + "k8s.io/client-go/dynamic" + + kuadrantv1alpha1 "github.com/kuadrant/kuadrant-operator/api/v1alpha1" +) + +func NewEffectiveDNSPoliciesReconciler(client *dynamic.DynamicClient) *EffectiveDNSPoliciesReconciler { + return &EffectiveDNSPoliciesReconciler{client: client} +} + +type EffectiveDNSPoliciesReconciler struct { + client *dynamic.DynamicClient +} + +func (r *EffectiveDNSPoliciesReconciler) Subscription() controller.Subscription { + return controller.Subscription{ + ReconcileFunc: r.reconcile, + Events: []controller.ResourceEventMatcher{ + {Kind: &machinery.GatewayGroupKind}, + {Kind: &kuadrantv1alpha1.DNSPolicyGroupKind}, + {Kind: &DNSRecordGroupKind}, + }, + } +} + +func (r *EffectiveDNSPoliciesReconciler) reconcile(ctx context.Context, _ []controller.ResourceEvent, topology *machinery.Topology, _ error, state *sync.Map) error { + return nil +} diff --git a/controllers/state_of_the_world.go b/controllers/state_of_the_world.go index 3a6a31d7d..7345df828 100644 --- a/controllers/state_of_the_world.go +++ b/controllers/state_of_the_world.go @@ -8,6 +8,7 @@ import ( egv1alpha1 "github.com/envoyproxy/gateway/api/v1alpha1" "github.com/go-logr/logr" authorinov1beta1 "github.com/kuadrant/authorino-operator/api/v1beta1" + kuadrantdnsv1alpha1 "github.com/kuadrant/dns-operator/api/v1alpha1" limitadorv1alpha1 "github.com/kuadrant/limitador-operator/api/v1alpha1" "github.com/kuadrant/policy-machinery/controller" consolev1 "github.com/openshift/api/console/v1" @@ -155,6 +156,7 @@ func (b *BootOptionsBuilder) getOptions() []controller.ControllerOption { opts = append(opts, b.getEnvoyGatewayOptions()...) opts = append(opts, b.getCertManagerOptions()...) opts = append(opts, b.getConsolePluginOptions()...) + opts = append(opts, b.getDNSOperatorOptions()...) return opts } @@ -291,13 +293,28 @@ func (b *BootOptionsBuilder) getConsolePluginOptions() []controller.ControllerOp return opts } +func (b *BootOptionsBuilder) getDNSOperatorOptions() []controller.ControllerOption { + var opts []controller.ControllerOption + opts = append(opts, + controller.WithRunnable("dnsrecord watcher", controller.Watch(&kuadrantdnsv1alpha1.DNSRecord{}, DNSRecordResource, metav1.NamespaceAll)), + controller.WithObjectKinds( + DNSRecordGroupKind, + ), + controller.WithObjectLinks( + LinkListenerToDNSRecord, + ), + ) + + return opts +} + func (b *BootOptionsBuilder) Reconciler() controller.ReconcileFunc { mainWorkflow := &controller.Workflow{ Precondition: initWorkflow(b.client).Run, Tasks: []controller.ReconcileFunc{ NewAuthorinoReconciler(b.client).Subscription().Reconcile, NewLimitadorReconciler(b.client).Subscription().Reconcile, - NewDNSWorkflow().Run, + NewDNSWorkflow(b.client).Run, NewTLSWorkflow(b.client, b.isCertManagerInstalled).Run, NewAuthWorkflow().Run, NewRateLimitWorkflow().Run,