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

internal/provisioner: set GatewayClass conditions correctly based on parametersRef #4440

Merged
merged 4 commits into from
Apr 4, 2022

Conversation

skriss
Copy link
Member

@skriss skriss commented Mar 31, 2022

Sets the GatewayClass's "Accepted" condition to true or
false based on whether the GatewayClass has a parametersRef
and if it is valid. Also wires up all of the reconciles
based on changes in related objects.

Signed-off-by: Steve Kriss krisss@vmware.com

(This doesn't actually do anything with the parameters yet, that'll come later, this was big enough as-is just to get the conditions and reconcile loops right).

I don't love only testing this controller logic via E2E's, but it does work pretty well and the alternatives are either a bunch of fakes/mocks for the Client which can get messy, or using envtest (which ends up looking a lot like E2E's, but runs locally so faster, but also doesn't always work like a real cluster which can cause some weirdness). Any thoughts?

skriss added 2 commits March 31, 2022 22:57
Sets the GatewayClass's "Accepted" condition to true or
false based on whether the GatewayClass has a parametersRef
and if it is valid. Also wires up all of the reconciles
based on changes in related objects.

Signed-off-by: Steve Kriss <krisss@vmware.com>
Signed-off-by: Steve Kriss <krisss@vmware.com>
@skriss skriss requested a review from a team as a code owner March 31, 2022 23:02
@skriss skriss requested review from tsaarni, stevesloka, sunjayBhatia and youngnick and removed request for a team, tsaarni and stevesloka March 31, 2022 23:02
@codecov
Copy link

codecov bot commented Mar 31, 2022

Codecov Report

Merging #4440 (79df8ab) into main (105f6e5) will decrease coverage by 0.45%.
The diff coverage is 18.40%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #4440      +/-   ##
==========================================
- Coverage   74.12%   73.67%   -0.46%     
==========================================
  Files         137      137              
  Lines       12219    12332     +113     
==========================================
+ Hits         9057     9085      +28     
- Misses       2964     3049      +85     
  Partials      198      198              
Impacted Files Coverage Δ
cmd/contour/gatewayprovisioner.go 0.00% <0.00%> (ø)
internal/provisioner/controller/gatewayclass.go 12.82% <12.50%> (+12.82%) ⬆️
internal/provisioner/controller/gateway.go 8.07% <30.95%> (+8.07%) ⬆️

@sunjayBhatia
Copy link
Member

I don't love only testing this controller logic via E2E's, but it does work pretty well and the alternatives are either a bunch of fakes/mocks for the Client which can get messy, or using envtest (which ends up looking a lot like E2E's, but runs locally so faster, but also doesn't always work like a real cluster which can cause some weirdness). Any thoughts?

having this same debate w/ the work to add a new runnable that preheats the cache/dag on contour startup, some combo of envtest and mocks will probably be what i end up doing since i just want to make sure at a lower level objects are sent to the event handler etc. and there isn't something easily observable via an e2e test

slightly different than this case since you do have the status element to observe as a behavioral output of the controller running, though if we end up pulling status updating etc. into another async component, that might change so setting up the controller with fakes might be nice then

this maybe goes back to some thoughts we had around sticking with Controllers vs. setting up informers and event handlers which are a much simpler abstraction to test, if we stick with the former we probably need to invest a little time into thinking about a better way to test things more granularly (envtest or otherwise) and/or create better abstractions that the main controller logic uses that we can then unit test (hard to justify sometimes bc it feels like an abstraction for abstraction's sake)

Signed-off-by: Steve Kriss <krisss@vmware.com>
@skriss skriss added the release-note/small A small change that needs one line of explanation in the release notes. label Apr 1, 2022
Signed-off-by: Steve Kriss <krisss@vmware.com>
@skriss
Copy link
Member Author

skriss commented Apr 1, 2022

I don't love only testing this controller logic via E2E's, but it does work pretty well and the alternatives are either a bunch of fakes/mocks for the Client which can get messy, or using envtest (which ends up looking a lot like E2E's, but runs locally so faster, but also doesn't always work like a real cluster which can cause some weirdness). Any thoughts?

having this same debate w/ the work to add a new runnable that preheats the cache/dag on contour startup, some combo of envtest and mocks will probably be what i end up doing since i just want to make sure at a lower level objects are sent to the event handler etc. and there isn't something easily observable via an e2e test

slightly different than this case since you do have the status element to observe as a behavioral output of the controller running, though if we end up pulling status updating etc. into another async component, that might change so setting up the controller with fakes might be nice then

this maybe goes back to some thoughts we had around sticking with Controllers vs. setting up informers and event handlers which are a much simpler abstraction to test, if we stick with the former we probably need to invest a little time into thinking about a better way to test things more granularly (envtest or otherwise) and/or create better abstractions that the main controller logic uses that we can then unit test (hard to justify sometimes bc it feels like an abstraction for abstraction's sake)

Yeah, in this case the E2E's are effective, just slower.

I'm not opposed to introducing envtest for some of this stuff, we just need to be aware of the limitations of each approach to testing and try not to get too much duplication across all of them.

For now, I'm going to do some experimenting with tests using the fake controller-runtime client (which is implemented as a simple in-mem store of objects) -- I've had success with that approach on other projects and I think we might be able to get decent mileage out of the fake client at least for the provisioner, where our "output" is really just creating Kubernetes resources. Will look to do that in separate PRs.

// GatewayClasses.
if err := c.Watch(
&source.Kind{Type: &contour_api_v1alpha1.ContourDeployment{}},
handler.EnqueueRequestsFromMapFunc(r.mapContourDeploymentToGatewayClasses),
Copy link
Member

Choose a reason for hiding this comment

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

for the future, will we need to implement this differently (custom handler that ignores the update event?) so that updates to ContourDeployment resources don't trigger a reconcile? (and updates to GatewayClasses do not cause a re-reconfiguration of the Contour installation for an existing Gateway)

Copy link
Member Author

@skriss skriss Apr 1, 2022

Choose a reason for hiding this comment

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

Yeah good question - I think there are a couple different ways we could go about implementing, but my plan had been to revise the logic that's in the EnsureObject functions, to not do full updates if the object already exists, but instead to only update those fields that should be updated. So things coming from GatewayClass would not flow through to updates to the existing objects, but e.g. updates to Listener definitions would flow through as updates to the existing objects. I think we probably need some logic like that regardless, because if you take that example of Listeners being updated, we need to ensure when we do push those updates through, that things derived from GatewayClass don't also get updated to reflect the current state of the GatewayClass.

Copy link
Member

@sunjayBhatia sunjayBhatia Apr 1, 2022

Choose a reason for hiding this comment

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

ah i see, do the logic further down the line of processing an update 👍🏽

@skriss skriss merged commit 9d6cf1d into projectcontour:main Apr 4, 2022
@skriss skriss deleted the pr-gw-class-params-conditions branch April 6, 2022 19:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release-note/small A small change that needs one line of explanation in the release notes.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants