-
Notifications
You must be signed in to change notification settings - Fork 218
OCPBUGS-31521: Don't publish duplicate DNS records #1229
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
base: master
Are you sure you want to change the base?
Conversation
|
Skipping CI for Draft Pull Request. |
| for _, existingRecord := range records.Items { | ||
| // we only care if the domain name is published by a different record, so ignore the matching record if it | ||
| // already exists. | ||
| // TODO: There's got to be a better way to match the same object |
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.
Compare by UID instead of name.
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 is still a relevant comment, but I moved the function, which made github think it's outdated. I'll make this change in my next update
| } | ||
| } else if isRecordPublished { | ||
| condition, err = r.replacePublishedRecord(zones[i], record) | ||
| } else if isDomainPublished, err = domainIsAlreadyPublishedInZone(context.Background(), r.cache, record, &zones[i]); 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.
You don't need to declare isDomainPublished outside the else if clause. Better to keep isDomainPublished and err scoped to the else if clauses.
| } else if isDomainPublished, err = domainIsAlreadyPublishedInZone(context.Background(), r.cache, record, &zones[i]); err != nil { | |
| } else if isDomainPublished, err := domainIsAlreadyPublishedInZone(context.Background(), r.cache, record, &zones[i]); err != nil { |
Edit: Discussed on a call. Line 388 uses the err value. This logic is a bit subtle and could use some refactoring.
9fece4b to
d38f7bf
Compare
| func (r *reconciler) MapOnRecordDelete(ctx context.Context, o client.Object) []reconcile.Request { | ||
| deletedRecord, ok := o.(*iov1.DNSRecord) | ||
| if !ok { | ||
| log.Info("failed to read DNS record") |
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.
| log.Info("failed to read DNS record") | |
| log.Infof("Got unexpected object; expected type DNSRecord, got type %T", o) |
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.
Or something more like this:
| log.Info("failed to read DNS record") | |
| log.Error(nil, "Got unexpected type of object", "expected", "DNSRecord", "actual", fmt.Sprintf("%T", o)) |
| // When a DNS record is deleted, there may be a conflicting record that should be published. Watch exclusively for | ||
| // deletes, and queue a reconcile request for the appropriate conflicting record, if applicable. | ||
| if err := c.Watch(source.Kind[client.Object](operatorCache, &iov1.DNSRecord{}, handler.EnqueueRequestsFromMapFunc(reconciler.MapOnRecordDelete), predicate.Funcs{ |
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.
Make the comment a little more explicit that, yes, we have two watches on the same resource (dnsrecords), and the reason is so that we can have a predicate and mapfunc to do something special for deletes.
| // When a DNS record is deleted, there may be a conflicting record that should be published. Watch exclusively for | ||
| // deletes, and queue a reconcile request for the appropriate conflicting record, if applicable. | ||
| if err := c.Watch(source.Kind[client.Object](operatorCache, &iov1.DNSRecord{}, handler.EnqueueRequestsFromMapFunc(reconciler.MapOnRecordDelete), predicate.Funcs{ | ||
| CreateFunc: func(e event.CreateEvent) bool { return false }, | ||
| DeleteFunc: func(e event.DeleteEvent) bool { return true }, |
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.
Add a comment with your findings that the delete event happens when the object is actually deleted, not when it is merely marked for deletion (that is, when deletionTimestamp is set).
| // Test_publishRecordToZonesMergesStatus verifies that publishRecordToZones | ||
| // correctly merges status updates. | ||
| func TestPublishRecordToZonesMergesStatus(t *testing.T) { | ||
| func Test_publishRecordToZonesMergesStatus(t *testing.T) { |
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.
TestPublishRecordToZonesMergesStatus is an appropriate name for the test as there is no publishRecordToZonesMergesStatus function.
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.
Probably I am also missing something here, but is there a new test case that will check if the condition is set?
|
@rfredette: This pull request references Jira Issue OCPBUGS-31521, which is invalid:
Comment The bug has been updated to refer to the pull request using the external bug tracker. In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository. |
| iov1.AddToScheme(scheme) | ||
| fakeClient := fake.NewClientBuilder(). | ||
| WithScheme(scheme). | ||
| WithIndex(&iov1.DNSRecord{}, dnsRecordIndexFieldName, func(o client.Object) []string { |
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.
nit (no need to fix now!): do we care about making this indexer function some sort of utils/specific function that can be used both on the operatorCache.IndexField and on fakeCache to keep consistency?
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.
Do you mean a util function that the controller logic and test logic would share? That does make sense, though I do caution against re-using controller logic in tests if doing so could mask a defect in the controller logic.
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, the idea was to make some util/shared function, but also I see your concerns here, so makes sense also to not share and in case something changes on the main reconciliation logic, the test that has a different cache logic will catch the regression.
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.
The intent here is to use the same index function that was added in lines 117-122. Since the fake cache doesn't go through all the setup steps that the actual one does, it needed to be added manually. In this case, having the logic match what's used in the actual controller probably is the way to go.
|
/assign @rikatz |
d38f7bf to
e48bfe1
Compare
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Before attempting to publish a domain to a zone, check if that domain is already being published to the same zone.
e48bfe1 to
4822baa
Compare
|
/cc |
| oldestExistingRecord := iov1.DNSRecord{} | ||
| for _, existingRecord := range otherRecords.Items { | ||
| // Exclude records that are marked for deletion. | ||
| if !existingRecord.DeletionTimestamp.IsZero() { |
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.
just for safety (sorry for realizing this just now): DeletionTimestamp is a nullable field / a pointer (https://github.com/kubernetes/apimachinery/blob/d74026bbe3beeff64c3dc7259a29be7708aa834f/pkg/apis/meta/v1/types.go#L209) and as so, I would recommend checking if it is null, and then checking if it is zero.
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.
The IsZero method has an nil check on its receiver, so I think the caller can omit the nil check?
cluster-ingress-operator/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/time.go
Lines 60 to 63 in 4822baa
| // IsZero returns true if the value is nil or time is zero. | |
| func (t *Time) IsZero() bool { | |
| if t == nil { | |
| return true |
I would be happy with a unit test case in lieu of a nil check.
|
/jira refresh |
|
@Miciah: This pull request references Jira Issue OCPBUGS-31521, which is valid. 3 validation(s) were run on this bug
No GitHub users were found matching the public email listed for the QA contact in Jira ([email protected]), skipping review request. In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository. |
|
marking bug as verified, since it is fixed through pre-merge testing
/verified by rhamini3 |
|
@rhamini3: This PR has been marked as verified by In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository. |
|
@rfredette: The following tests failed, say
Full PR test history. Your PR dashboard. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here. |
|
E2E test failure seen on this, reported by @rikatz in https://issues.redhat.com/browse/OCPBUGS-64675.
|
Before attempting to publish a domain to a zone, check if that domain is already being published to the same zone.