Conversation
negz
left a comment
There was a problem hiding this comment.
This looks great overall - I like the direction. Thanks @erhancagirici!
apis/common/v2/resource.go
Outdated
|
|
||
| package v2 | ||
|
|
||
| import v1 "github.com/crossplane/crossplane-runtime/apis/common/v1" |
There was a problem hiding this comment.
Is there a way to avoid having the v2 package depend on v1 types?
There was a problem hiding this comment.
Technically yes, but I see two ways, both having its own drawback:
most of apis/common/v1 actually has many shared constructs not particularly "v1", like ManagementPolicies, Conditions, Selector, Reference types etc.
- If we duplicate them, we end up with same but different structs, which needs superfluous handling in various places.
- One option can be to refactor common stuff mentioned above to its own package, but that also kind of breaks existing imports in the ecosystem.
Open to ideas here
There was a problem hiding this comment.
Maybe we could:
- Move the shared stuff to
apis/common/common.go - Have both common/v1 and common/v2 import common
- Add type aliases in the v1 package to avoid breaking folks
I think I prefer that approach. I agree that v1 is a bit of a misnomer in the first place.
The other options I considered are:
- Duplicate the types in both places. I like that this decouples the two APIs, but it forces us to have two implementations of any function that uses these types, which I think is a non-starter.
- Duplicate the types in both places, also add internal versions, update our functions to work on the internal versions, and generate code to translate between v1/v2 and internal. This seems like the best approach in theory, but it's a ton of work for these little utility types.
There was a problem hiding this comment.
We just had an offline sync with @erhancagirici on this and the above proposal sounds good in general. We discussed some details like linter complaining about common as a package name and whether we should put a deprecation notice on v1 aliased types/consts/funcs.
At the end, we feel good about suppressing linter on package name and going with common as suggested. apis/common is there since the begining and we're fine for it as a package name. Regarding the deprecation notice, we believe it would be good not to force consumers to immediately switch to the new place to minimize the required changes for now. So, if linter complains and forces consumers to migrate, then we should better not do it now (and track with an issue to do it later). This is something @erhancagirici will check and see.
There was a problem hiding this comment.
I have pushed the changes with the type aliasing approach.
One side note: I had to bump the controller-tools to 0.18.0 to consume following fixes about type aliases.
kubernetes-sigs/controller-tools#1061
kubernetes-sigs/controller-tools#1122
This bump transitively upgraded google.golang.org/protobuf to v1.36.5 which had some minor changes in the generated protobuf files (backward-compatible).
I haven't added the depreciation notices to aliased types in apis/common/v1 yet, as they cause large amount of linter warnings. I'll create a follow-up issue for this.
| // UnpublishConnection is no-op since PublishConnection only creates resources | ||
| // that will be garbage collected by Kubernetes when the managed resource is | ||
| // deleted. | ||
| func (a *APILocalSecretPublisher) UnpublishConnection(_ context.Context, _ resource.LocalConnectionSecretOwner, _ ConnectionDetails) error { | ||
| return nil | ||
| } |
There was a problem hiding this comment.
iirc this'll always be a no-op now that external secret stores are gone.
No strong feelings about removing it now though - we could follow up later.
There was a problem hiding this comment.
let's have this as a follow-up
pkg/reconciler/managed/publisher.go
Outdated
| return false, errors.New(errSecretStoreDisabled) | ||
| // PublishConnection calls each ConnectionPublisher.PublishConnection serially. It returns the first error it | ||
| // encounters, if any. | ||
| func (pc LocalPublisherChain) PublishConnection(ctx context.Context, o resource.LocalConnectionSecretOwner, c ConnectionDetails) (bool, error) { |
There was a problem hiding this comment.
Do we still need this with external secret stores gone? I think we'll always publish to one secret.
(Again not urgent to remove it though.)
There was a problem hiding this comment.
Agreed, this was needed for the WithLocalConnectionPublishers(p ...ConnectionPublisher) reconciler option, which is already irrelevant.
A question is, the original(legacy) one of becomes irrelevant too. Should we remove this one to make our intention clear? or keep it for the sake of not causing a code changes in the (native) providers for existing legacy resources?
crossplane-runtime/pkg/reconciler/managed/reconciler.go
Lines 702 to 706 in f5f608c
Maybe make it no-op with deprecated comment?
There was a problem hiding this comment.
I'd lean toward just removing it. Either way it's going to be work for upstream provider authors. If it's gone, it's more obvious they need to do that work.
I don't feel strongly though.
There was a problem hiding this comment.
I'll remove this and PublisherChain and keep an unexported version for unit testing purposes for cases we need to mock.
eb6e96e to
812d411
Compare
negz
left a comment
There was a problem hiding this comment.
Great work @erhancagirici! This is a smaller diff overall than I expected, which is good. None of my comments are blocking.
| // is enabled. | ||
| // Deprecated: this is intended for LegacyManaged resources that had deletionPolicy | ||
| // ModernManaged resources should use NewManagementPoliciesResolver. | ||
| func NewLegacyManagementPoliciesResolver(managementPolicyEnabled bool, managementPolicy xpv1.ManagementPolicies, deletionPolicy xpv1.DeletionPolicy, o ...ManagementPoliciesResolverOption) ManagementPoliciesChecker { |
There was a problem hiding this comment.
Nit: Some of these long var names are a bit redundant. Not blocking though, and I can see it matches the existing implementation.
pkg/reconciler/managed/publisher.go
Outdated
| return false, errors.New(errSecretStoreDisabled) | ||
| // PublishConnection calls each ConnectionPublisher.PublishConnection serially. It returns the first error it | ||
| // encounters, if any. | ||
| func (pc LocalPublisherChain) PublishConnection(ctx context.Context, o resource.LocalConnectionSecretOwner, c ConnectionDetails) (bool, error) { |
There was a problem hiding this comment.
I'd lean toward just removing it. Either way it's going to be work for upstream provider authors. If it's gone, it's more obvious they need to do that work.
I don't feel strongly though.
|
|
||
| var _ reconcile.Reconciler = &Reconciler{} | ||
|
|
||
| func TestModernReconciler(t *testing.T) { |
There was a problem hiding this comment.
I do wonder whether there's diminishing returns in completely duplicating the test file. I imagine a lot of these subtest scenarios use the same code regardless of whether it's a legacy or a modern MR, right?
It seems like having two test files could be a bit of a pain - we'll need to add and update them both whenever we update the tests. On the other hand it does seem like the most defensive/conservative approach to make sure both legacy and modern MRs work with all parts of the reconciler.
There was a problem hiding this comment.
As you mentioned, this was mostly for being defensive. I tried to pinpoint the "common" tests ( relying only on the "base" managed functional), though ended up duplicating most already to cover some unvisited codepaths.
We might consider following up later with a refactored test setup, that runs the tests as a matrix for legacy vs modern maybe?
|
Officially deferring my reviewer powers to @turkenh if there's any other questions or concerns while I'm out on vacation. 😉 |
8e150cd to
b069fec
Compare
Signed-off-by: Erhan Cagirici <erhan@upbound.io>
Signed-off-by: Erhan Cagirici <erhan@upbound.io>
Signed-off-by: Erhan Cagirici <erhan@upbound.io>
fixes deepcopy method generation for structs that has aliased types Signed-off-by: Erhan Cagirici <erhan@upbound.io>
Signed-off-by: Erhan Cagirici <erhan@upbound.io>
Signed-off-by: Erhan Cagirici <erhan@upbound.io>
| - linters: | ||
| - revive | ||
| text: "var-naming: avoid meaningless package names" | ||
| path: apis/common |
There was a problem hiding this comment.
Could we add a //nolint directive instead? https://github.com/crossplane/crossplane/tree/main/contributing#explain-nolint-directives
There was a problem hiding this comment.
opted for this, because had to repeat this for all the new files, and nolint directives were appearing at the very top and potentially in godoc. not strongly opinionated though
turkenh
left a comment
There was a problem hiding this comment.
Looks good to me, thanks @erhancagirici 🙌
| ns = r.from.GetNamespace() | ||
| } | ||
|
|
||
| if err := r.client.List(ctx, req.To.List, client.MatchingLabels(req.Selector.MatchLabels), client.InNamespace(req.Namespace)); err != nil { |
There was a problem hiding this comment.
Should this use ns instead of req.Namespace ?
There was a problem hiding this comment.
good catch, fixed
Signed-off-by: Erhan Cagirici <erhan@upbound.io>
Description of your changes
New V2 apis and removals to facilitate namespaced MRs.
v2
ManagedResourceSpecAPI:writeConnectionSecretToRefdropsnamespacefield and accepts local secret references.providerConfigRefbecomes typed and requireskind.apiGroupis intentionally left out, it is expected to be inferred by the provider code. NamespaceddeletionPolicyis removed. New resources should rely onmanagementPoliciesto control external resource deletion.External Secret Store support is removed
publishConnectionDetailsTois removed from both cluster-scoped (legacy) and namespace-scoped (modern) MR specs.ConnectionDetailsPublisherTointerface is removed.Cross-namespace cross-resource references:
Introduced
NamespacedResolutionRequest,NamespacedResolutionResponse,NamespacedMultiResolutionRequest,NamespacedMultiResolutionResponsetypes along withAPINamespacedResolver. In the new types, references and selectors in the resolution requests can include optional namespace parameter. Otherwise, they will default to MR namespaces.I have:
earthly +reviewableto ensure this PR is ready for review.backport release-x.ylabels to auto-backport this PR.Need help with this checklist? See the cheat sheet.