-
Notifications
You must be signed in to change notification settings - Fork 150
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
Update reference resolution interface types #121
Update reference resolution interface types #121
Conversation
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 understand the need for those changes for now and overall it makes sense!
Kinda a low level review from my end. I mostly have questions but most importantly i want to bring this:
One think that is crossing my mind now: Should we NOT allow users to have a mix between referenced and non-referenced data for the same field?
// ResolveReferences finds if there are any Reference field(s) present | ||
// inside AWSResource passed in the parameter and attempts to resolve those | ||
// reference field(s) into their respective target field(s). It returns a | ||
// copy of the input AWSResource with resolved reference(s), a boolean which | ||
// is set to true if the resource contains any references (regardless of if | ||
// they are resolved successfully) and an error if the passed AWSResource's | ||
// reference field(s) could not be resolved. | ||
ResolveReferences(context.Context, client.Reader, AWSResource) (AWSResource, bool, error) |
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.
Why is it important to know whether a resource has references or not? Couldn't we just rely on err == nil || 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.
There are 3 cases:
- References exist, and resolution was successful
- References exist, but resolution was not successful
- References don't exist
err
only covers cases 1 and 2. Case 3 doesn't execute anything, so it'll never return an err
. The only way we know if references exist, then, is to return a bool
to say we at least attempted to resolve them.
@@ -811,6 +808,7 @@ func (r *resourceReconciler) setResourceManaged( | |||
// allows the CR to be deleted by the Kubernetes API server. | |||
func (r *resourceReconciler) setResourceUnmanaged( | |||
ctx context.Context, | |||
rm acktypes.AWSResourceManager, |
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.
Shall we just make rm
part of resourceReconciler
instead of passing it around between functions?
// is set to true if the resource contains any references (regardless of if | ||
// they are resolved successfully) and an error if the passed AWSResource's | ||
// reference field(s) could not be resolved. | ||
ResolveReferences(context.Context, client.Reader, AWSResource) (AWSResource, bool, error) |
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.
Same here maybe make client.Reader
part of the implementation?
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.
Still thinking this through but I think these changes make sense. :+1
// NOTE(redbackthomson): This method returns an updated version of the latest | ||
// parameter. This version has an updated metadata.resourceVersion, which is | ||
// incremented in the process of calling Patch. This is intentional, because | ||
// without updating the resource's metadata.resourceVersion, the resource cannot | ||
// be passed to Patch again later in the reconciliation if Patch is called with | ||
// the Optimistic Locking option. |
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.
Perhaps update this note to say that the returned resource has its resource references removed?
patch := client.MergeFrom(dobj) | ||
err = r.kc.Patch(ctx, latest.RuntimeObject(), patch) | ||
lorig := latestCleaned.DeepCopy() | ||
patch := client.MergeFrom(desiredCleaned.RuntimeObject()) |
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.
noting that this is now effectively
client.MergeFrom(rm.ClearResolvedReferences(desired).RuntimeObject())
vs previously
client.MergeFrom(desired.DeepCopy().RuntimeObject())
I'm not 100% positive from reading the corresponding code-generator
change -- but I think that ClearResolvedReferences
does not return a deep copy of the resource, so you're effectively doing away with the deep copy part here. Does that matter? Is it intentional?
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 made sure that all of the reference resolution-related methods returned copies. You can see this in the ClearResolvedReferences
method - https://gist.github.com/RedbackThomson/8e11cbbe96065a4eb812c387665c747d#file-references-go-L34
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.
👍
/lgtm |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: A-Hilaly, jaypipes, jljaco, RedbackThomson The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
#435) Implements aws-controllers-k8s/runtime#121 Description of changes: This PR abstracts out the process of iterating through all references into a separate method called `iterReferenceValues`. `iterReferenceValues` produces Go code that drills down into the spec for every ref, iterating through any slices as necessary. Once it reaches the ref object, it calls a callback which can be used by other methods for logic pertaining to accessing the refs. This change allows `ResolveReferencesForField` to access all refs within lists of structs (or even within lists of lists of structs, etc.). `iterReferenceValues` is also used to implement `ClearResolvedReferencesForField`, which simply sets the concrete value to `nil` if it detects a non-nil value in the ref field (or `len > 0` for lists of refs). This PR also removes `hasNonNilReferences`. `hasNonNilReferences` was being used to indicate whether there were any references inside the resource, which required another set of iterating through all ref fields. Instead, each `resolveReferencesFor*` returns a boolean which indicates whether it found a reference during its iteration. Below is a Gist that shows the output of running the code-generator on the current EC2 `generator.yaml`: https://gist.github.com/RedbackThomson/8e11cbbe96065a4eb812c387665c747d For testing: `ec2` and `lambda` already have a series of tests for references. Both of these tests are passing, but they were also passing before this PR. I have a branch of the `ec2-controller` with additional tests using `RouteTables`, which have lists of structs containing refs, and all of those are passing as well. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
Description of changes:
Creates a new
ReferenceManager
type that re-definesResolveReferences
and adds a newClearResolvedReferences
methods toResourceManager
.ResolveReferences
now returns a copy of the originalAWSResource
.ClearResolvedReferences
also returns a copy of the originalAWSResource
.The reconciler now resolves the references once at the beginning and passes around the resolved versions of the resource. Right before the resource is patched, in
patchMetadataAndSpec
, the resource is cleaned of references so that they are not persisted toetcd
.By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.