-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sotw: dnspolicy #937
base: main
Are you sure you want to change the base?
sotw: dnspolicy #937
Conversation
d558ea1
to
18f3056
Compare
//+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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved all these to here for now, but will need to review these permissions again. I'm not sure why we need the namespace permissions for instance.
type PolicyOwnerReference struct { | ||
metav1.OwnerReference | ||
PolicyNamespace string | ||
GVK schema.GroupVersionKind | ||
} | ||
|
||
func (o *PolicyOwnerReference) SetGroupVersionKind(gvk schema.GroupVersionKind) { | ||
o.GVK = gvk | ||
} | ||
|
||
func (o *PolicyOwnerReference) GroupVersionKind() schema.GroupVersionKind { | ||
return o.GVK | ||
} | ||
|
||
func (o *PolicyOwnerReference) GetNamespace() string { | ||
return o.PolicyNamespace | ||
} | ||
|
||
func (o *PolicyOwnerReference) GetName() string { | ||
return o.OwnerReference.Name | ||
} | ||
|
||
func (o *PolicyOwnerReference) GetLocator() string { | ||
return machinery.LocatorFromObject(o) | ||
} | ||
|
||
var _ machinery.PolicyTargetReference = &PolicyOwnerReference{} | ||
|
||
func getObjectPolicyOwnerReference(item machinery.Object, gk schema.GroupKind) *PolicyOwnerReference { | ||
var ownerRef *PolicyOwnerReference | ||
for _, o := range item.(*controller.RuntimeObject).GetOwnerReferences() { | ||
oGV, err := schema.ParseGroupVersion(o.APIVersion) | ||
if err != nil { | ||
continue | ||
} | ||
|
||
if oGV.Group == gk.Group && o.Kind == gk.Kind { | ||
ownerRef = &PolicyOwnerReference{ | ||
OwnerReference: o, | ||
PolicyNamespace: item.GetNamespace(), | ||
GVK: schema.GroupVersionKind{ | ||
Group: gk.Group, | ||
Kind: gk.Kind, | ||
}, | ||
} | ||
break | ||
} | ||
} | ||
return ownerRef | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should all go somewhere else, state_of_the_world.go maybe? This also, if we agree it seems like a reasonable way to link an OwnerReference to a Policy could be reused by at least the TLSPolicy.
controllers/dnspolicies_validator.go
Outdated
} | ||
|
||
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 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
night be a nice option in the future to have a topology.Policies().ForGVK(...)
?
return nil, false | ||
}) | ||
|
||
for i := range orphanRecords { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
open question. If we are using lo
should we not end up using it for slices also? https://github.com/samber/lo?tab=readme-ov-file#foreach
@guicassolato ?
var ownerRef *PolicyOwnerReference | ||
for _, o := range item.(*controller.RuntimeObject).GetOwnerReferences() { | ||
oGV, err := schema.ParseGroupVersion(o.APIVersion) | ||
if err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
guessing we skip the error here as it would be none kuadrant owner ref that would cause this error?
|
||
return opts | ||
} | ||
|
||
func (b *BootOptionsBuilder) Reconciler() controller.ReconcileFunc { | ||
mainWorkflow := &controller.Workflow{ | ||
Precondition: initWorkflow(b.client).Run, | ||
Tasks: []controller.ReconcileFunc{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are each of these dispatched in their own routine?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These changes all look pretty good to me. Couple of minor comments but nothing major.
18f3056
to
4c58b9a
Compare
Add basic setup for DNSPolicy state of the world tasks, dnsrecord types, watcher and linker function (Listener -> DNSRecord) Signed-off-by: Michael Nairn <mnairn@redhat.com>
Move all logic to delete orphan dnsrecord resources for a DNSPolicy to the sotw reconciler and based all decisions on the current topology. Orphan record is one that no longer has a valid path between it's owner DNSPolicy and itself in the topology. This covers the following scenarios: * Listener is deleted from the Gateway * Gateway is deleted * Policy is deleted(K8s will also deal with this due to the owner relationship) * Policy ref is changed Does not deal with the removal of records based on the state of the gateway. Signed-off-by: Michael Nairn <mnairn@redhat.com>
4c58b9a
to
76839c3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have removed so of my previous comments. After looking at this a second time last night, I had a misunderstanding of what was going on here. There is something going on here that seems out of place I have quite point my finger on it yet.
controllers/state_of_the_world.go
Outdated
func (b *BootOptionsBuilder) getDNSOperatorOptions() []controller.ControllerOption { | ||
var opts []controller.ControllerOption | ||
opts = append(opts, | ||
controller.WithRunnable("dnsrecord watcher", controller.Watch(&kuadrantdnsv1alpha1.DNSRecord{}, DNSRecordResource, metav1.NamespaceAll)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this needs address as it brings in results that are not created by kuadrant and kuadrant has no right to know about.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, so i actually wasn't aware until you commented and i looked more closely at the controller code that there was a way to filter out the objects that get added to the topology. This is definitely something i think we should do as we don't want to interfere with resources that weren't created by a policy as you correctly pointed out.
The only way i see to do that with the current implementation of the controller is by using a label filter, and ensuring that all resources we create on behalf of the kuadrant operator are consistently labelled. I had a go at that here 8e1afd2.
If this is the approach we want to take, i think we should do it for all resources that we create on behalf of any policy. I noticed for instance TLS Certificates and Issuers that are not created by a TLSPolicy are also added to the topoloy.
@guicassolato @KevFan @Boomatang wdyt about common labelling for all created resources?
45d301e
to
76839c3
Compare
* Update dns policy validator in prepration for status updates, adds correct errors for acceptance. * Add common labels that get applied to all dnsrecord resources created by the kuadrant operator * Add filter to topology for dnsrecords to only add records that contain the correct label. * Adds predicates to only trigger on events to owned policies (might be pointless) Signed-off-by: Michael Nairn <mnairn@redhat.com>
* go mod updaate (main) Signed-off-by: Michael Nairn <mnairn@redhat.com>
"app.kubernetes.io/name": KuadrantAppName, | ||
"app.kubernetes.io/part-of": KuadrantAppName, | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copied the layout and labels from https://github.com/Kuadrant/kuadrant-operator/blob/main/pkg/openshift/consoleplugin/common.go
controller.WithRunnable("dnsrecord watcher", controller.Watch( | ||
&kuadrantdnsv1alpha1.DNSRecord{}, DNSRecordResource, metav1.NamespaceAll, | ||
controller.FilterResourcesByLabel[*kuadrantdnsv1alpha1.DNSRecord](fmt.Sprintf("%s=%s", AppLabelKey, AppLabelValue)), | ||
controller.WithPredicates(ctrlruntimepredicate.NewTypedPredicateFuncs(isDNSRecordOwnedByDNSPolicy)))), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added this predicate based on what had been added for TLS but I'm unsure of its usefulness when we are using a label filter. The label filter gets added as a predicate internally anyway. I'm thinking we can probably just drop it entirely and rely solely on the label filter.
sotw: dnspolicy init
Add basic setup for DNSPolicy state of the world tasks, dnsrecord types, watcher and linker function (Listener -> DNSRecord)
sotw: dnspolicy delete orphan records
Move all logic to delete orphan dnsrecord resources for a DNSPolicy to the sotw reconciler and based all decisions on the current topology.
Orphan record is one that no longer has a valid path between it's owner DNSPolicy and itself in the topology. This covers the following scenarios:
Does not deal with the removal of records based on the state of the gateway, these aren't considered "orphans" and will be dealt with separately.
Requires: Kuadrant/policy-machinery#42