Skip to content
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

Resolve references on every reconcile #66

Merged
merged 7 commits into from
Nov 1, 2019
Merged

Conversation

negz
Copy link
Member

@negz negz commented Oct 31, 2019

Description of your changes

Fixes #53

This PR updates the managed resource reconciler to resolve references on every reconcile, not just the first one. The default reference resolver implementation is updated to avoid updating the managed resource if it doesn't change during the reference resolution process.

Note that this subtly changes the behaviour stacks will see when using crossplane-runtime if this change is merged; they will need to ensure their reference value assignment functions are idempotent. Currently the assignment functions that handle a slice of values append the resolved value, even if it's already set, thus growing the slice of values with every reconcile.

The PR also updates the attribute referencer finder to avoid checking struct tags. Previously errors were returned when:

  1. A struct field tagged as a referencer did not satisfy AttributeReferencer
  2. A struct field not tagged as a referencer satisfied AttributeReferencer

If either of these scenarios occurred, ResolveReferences would panic with the returned error the first time it encountered an incorrectly written API type. I can see the value in using struct tags to document the intent that a type satisfies the AttributeReferencer interface, but my feeling is that both of these conditions are testing for programmer errors that would be better caught at build time than at runtime.

Checklist

I have:

  • Run make reviewable to ensure this PR is ready for review.
  • Ensured this PR contains a neat, self documenting set of commits.
  • Updated any relevant documentation, examples, or release notes.
  • Updated the RBAC permissions in clusterrole.yaml to include any new types.

@negz negz requested review from muvaf and hasheddan October 31, 2019 19:30
@upbound-bot
Copy link
Collaborator

91% (-0.15%) vs master 91%

@upbound-bot
Copy link
Collaborator

91% (-0.15%) vs master 91%

This commit refactors ResolveReferencers to allow the code that finds types
within a struct that satisfy AttributeReferencer to be swapped out. It also
updates the default AttributeReferencerFinder to avoid checking struct tags.

Previously errors were returned when:

1. A struct field tagged as a referencer did not satisfy AttributeReferencer
2. A struct field not tagged as a referencer satisfied AttributeReferencer

If either of these scenarios occurred, ResolveReferences would panic with the
returned error the first time it encountered an incorrectly written API type.
My feeling is that both of these conditions are testing for programmer errors
that would be better caught at build time than at runtime.

Signed-off-by: Nic Cope <negz@rk0n.org>
Signed-off-by: Nic Cope <negz@rk0n.org>
the established convention is for the managed resource reconciler to requeue
after a short wait (typically 30 seconds) when it knows it is waiting for an
operation.

Signed-off-by: Nic Cope <negz@rk0n.org>
The mock binding status was identical to the real one, while the mock
conditioned status set only the most recent condition, leading to a few
slightly broken managed resource reconciler tests.

Signed-off-by: Nic Cope <negz@rk0n.org>
@negz negz changed the title Don't update managed resource if resource resolution was a no-op Resolve references on every reconcile Oct 31, 2019
@upbound-bot
Copy link
Collaborator

92% (-0.54%) vs master 92%

Reference resolution is now a no-op if nothing changes, so we run it on every
reconcile. We also run it after delete has been handled, so unresolved
references will only block creates and updates.

This commit means we'll make more get calls to the cache (or API) in order to
resolve our references each reconcile, and also risk potentially changing the
values of 'immutable' fields automatically if and when our references resources
change. I believe we should address this by having referencers be no-ops when
the field value they would set is already set.

I attempted to move reference resolution to right before we call create or
update (i.e. after observe and delete), but it turns out certain resources
(specifically GCP Connections) could need references to be resolved in order to
observe the external resource.

Signed-off-by: Nic Cope <negz@rk0n.org>
We no longer need CanReference types to satisfy the metav1.Object interface. It
was used only to determine the namespace of the referencing object before all
such objects became cluster scoped.

Signed-off-by: Nic Cope <negz@rk0n.org>
@upbound-bot
Copy link
Collaborator

92% (-0.15%) vs master 92%

Copy link
Member

@hasheddan hasheddan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This LGTM and it appears that though the controllers will not have to change for existing managed reconcilers unless they want to implement a custom Finder! That's pretty cool! We should think about how we want to notify stack owners on the next release of crossplane-runtime that their Assign() methods may need updating.

@negz
Copy link
Member Author

negz commented Oct 31, 2019

We should think about how we want to notify stack owners on the next release of crossplane-runtime that their Assign() methods may need updating.

Agreed. Now that we have semantic versioning for crossplane-runtime I think we could introduce this as 0.1.1 but we'll want to include this detail in the release notes. I'll add a label to this PR in the hopes that will help us remember it at release time.

@negz negz added the release/behaviour-change This PR will change controller behaviour when released. label Oct 31, 2019
@negz negz merged commit 3ad494e into crossplane:master Nov 1, 2019
@negz negz deleted the nooprefs branch November 1, 2019 00:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release/behaviour-change This PR will change controller behaviour when released.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ReferenceResolver: Remove the condition on ReferenceResolutionSuccess to resolve references
3 participants