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

🐛 Allow nested maps in Go types #518

Merged
merged 6 commits into from
Sep 16, 2021

Conversation

Porges
Copy link
Contributor

@Porges Porges commented Nov 11, 2020

These map to nested maps in CRDs. Also improve an error message.

I have marked this as a bug, as the omission of support for these nested maps seems like an oversight, since there is already support for and tests for nested maps in the deep-copy code (in legacy_deepcopy_cases.go).

Note that in addition a type like map[string]Foo where Foo has a field map[string]string is already permitted, so this only allows an “unwrapped” version of the above. (An example of this is also added into the test as part of this PR.)

This will help address some cases in #287.

@k8s-ci-robot k8s-ci-robot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label Nov 11, 2020
@k8s-ci-robot k8s-ci-robot added the size/M Denotes a PR that changes 30-99 lines, ignoring generated files. label Nov 11, 2020
@Porges
Copy link
Contributor Author

Porges commented Nov 12, 2020

I noticed that previously an error was being generated, but it does not get surfaced anywhere and controller-gen does not fail. Is there something else that needs fixing here?

@munnerz
Copy link
Member

munnerz commented Dec 18, 2020

On the other hand maybe this doesn't work with Kubernetes itself? We shall soon find out!

Using maps in Kubernetes API resources at all is not recommended (as per the sig-architecture api-conventions doc):
https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#lists-of-named-subobjects-preferred-over-maps

Not too sure if it's something the project still wants to accept anyway - but it'd be good for us to encourage following the api conventions doc through the feature-set exposed

@Porges
Copy link
Contributor Author

Porges commented Dec 20, 2020

On the other hand maybe this doesn't work with Kubernetes itself? We shall soon find out!

Using maps in Kubernetes API resources at all is not recommended (as per the sig-architecture api-conventions doc):
https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#lists-of-named-subobjects-preferred-over-maps

Not too sure if it's something the project still wants to accept anyway - but it'd be good for us to encourage following the api conventions doc through the feature-set exposed

In our case we are accepting specs for external resources which require maps and nested maps in their configuration. Without support in controller-gen and friends we have to accept arbitrary JSON in the spec (and maybe write a custom acceptor/validator). Perhaps controller-gen could produce a warning along the lines of "maps are not recommended for use in Kubernetes APIs", or require a flag to enable support? There is precedence for similar things where float values are “not recommended” but are permitted with a flag to enable them.

@vijtrip2
Copy link

vijtrip2 commented Mar 5, 2021

This will also unblock ACK (AWS Controllers for Kubernetes) project. ACK uses controller-gen to create Kubernetes custom resources for AWS resources. There are AWS resources which contain nested map and fails with controller-gen.


I also second @Porges 's thought here.
Perhaps controller-gen could produce a warning along the lines of "maps are not recommended for use in Kubernetes APIs", or require a flag to enable support? There is precedence for similar things where float values are “not recommended” but are permitted with a flag to enable them

@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Mar 6, 2021
These map to nested maps in CRDs. Also improve an error message.
@k8s-ci-robot k8s-ci-robot added size/S Denotes a PR that changes 10-29 lines, ignoring generated files. and removed needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Mar 7, 2021
Copy link

@vijtrip2 vijtrip2 left a comment

Choose a reason for hiding this comment

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

LGTM!

@vijtrip2
Copy link

vijtrip2 commented Mar 8, 2021

/assign @DirectXMan12

vijtrip2 added a commit to vijtrip2/apigatewayv2-controller that referenced this pull request Mar 15, 2021
* Regenerating apigatewayv2 service controllers after repo split.
* Using aws-sdk-go 1.35.5 because latest sdk-go is not compatible with controller-gen 0.4.0 . The PR for compatibilty is tracked here kubernetes-sigs/controller-tools#518
@munnerz
Copy link
Member

munnerz commented Apr 7, 2021

Sorry for the delay on this - for context, I do not have approval rights here :)

In our case we are accepting specs for external resources which require maps and nested maps in their configuration.

Embedding external types (i.e. ones that were not originally designed to be used as part of a Kubernetes API) is also something that has been typically best avoided. I would always strongly recommend either building your own abstraction over these types (and writing functions that can be used to convert from your API type to the external project's types), or otherwise using something like apiextensions.JSON as you noted.

When you begin to generate e.g. openapi schemas, conversion functions, and even DeepCopy functions, you can quickly run into all sorts of issues if you have embedded an external type. I'm conscious that by supporting it, we'd encourage this kind of thing in other projects/APIs.

I can appreciate that there are some projects wanting to use maps, but I think as a project we should help users to do the right thing. Interested to hear viewpoints from others (cc @DirectXMan12 @pwittrock)

@k8s-ci-robot k8s-ci-robot added size/M Denotes a PR that changes 30-99 lines, ignoring generated files. and removed size/S Denotes a PR that changes 10-29 lines, ignoring generated files. labels Apr 19, 2021
@Porges
Copy link
Contributor Author

Porges commented Apr 19, 2021

@munnerz The kinds of things we are embedding are configurations, so it's nice for the end user if the configuration format is the same inside Kubernetes or outside it.


With regards to API complexity: I'd note that you can already write map[string]Foo where Foo contains a map[string]… field, so allowing map[string]map[string]… is essentially the same, but dropping one layer of indirection. This to me seems the strongest argument for permitting it, since something “almost isomorphic” is already permitted.

I’ve added an example of this to the test file.

@DirectXMan12
Copy link
Contributor

With regards to API complexity: I'd note that you can already write map[string]Foo

This is not supposed to be possible, and I'd almost consider it a bug that we allow it. At the very least, it's a non-reccomended type -- maps in Kubernetes APIs are generally restricted to scalar values, and the occasional slice in very specific circumstances. Otherwise, Kubernetes-style associated lists are the reccomended pattern.

@DirectXMan12
Copy link
Contributor

/hold

@k8s-ci-robot k8s-ci-robot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Apr 30, 2021
@k8s-triage-robot
Copy link

Issues go stale after 90d of inactivity.
Mark the issue as fresh with /remove-lifecycle stale.
Stale issues rot after an additional 30d of inactivity and eventually close.

If this issue is safe to close now please do so with /close.

Send feedback to sig-contributor-experience at kubernetes/community.
/lifecycle stale

@k8s-ci-robot k8s-ci-robot added the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Aug 4, 2021
@Porges
Copy link
Contributor Author

Porges commented Aug 5, 2021

/remove-lifecycle stale

@k8s-ci-robot k8s-ci-robot removed the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Aug 5, 2021
@smarterclayton
Copy link

smarterclayton commented Sep 15, 2021

To comment directly here, kube discourages but does not disallow certain constructs in core apis. I would not consider any construct described here as dangerous, nor would I say our api conventions are a counter to the stated goal for CRDs to allow the kube server to accommodate new concepts to extend Kube. As an API reviewer I might guide a core API author away from map of map, but that should not constrain how users can express valid CRD APIs in wide use.

Map of map should absolutely be allowed under a CRD, and in general any valid JSON structure should be allowed inside of the body of a CRD (any limitations are bugs).

@alvaroaleman
Copy link
Member

/test all

Copy link
Member

@alvaroaleman alvaroaleman left a comment

Choose a reason for hiding this comment

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

/label tide/merge-method-squash
/hold cancel
/assign @vincepri

@k8s-ci-robot k8s-ci-robot added tide/merge-method-squash Denotes a PR that should be squashed by tide when it merges. and removed do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. labels Sep 15, 2021
@alvaroaleman
Copy link
Member

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Sep 15, 2021
@Porges
Copy link
Contributor Author

Porges commented Sep 15, 2021

@smarterclayton Map of map should absolutely be allowed under a CRD, and in general any valid JSON structure should be allowed inside of the body of a CRD (any limitations are bugs).

In that case the array-value case should be loosened as well (currently only map[…][]string is permitted). But I won’t do it in this PR, for fear of postponing it 😉

@vijtrip2
Copy link

/assign @droot

@alvaroaleman
Copy link
Member

@Porges can you resolve the merge conflicts, please?

@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Sep 16, 2021
@k8s-ci-robot k8s-ci-robot removed lgtm "Looks good to me", indicates that a PR is ready to be merged. needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. labels Sep 16, 2021
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: alvaroaleman, Porges, vijtrip2

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 /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Sep 16, 2021
@Porges
Copy link
Contributor Author

Porges commented Sep 16, 2021

@alvaroaleman can you resolve the merge conflicts, please?

voilà!

@alvaroaleman
Copy link
Member

/test all
/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Sep 16, 2021
@k8s-ci-robot k8s-ci-robot merged commit 14c7780 into kubernetes-sigs:master Sep 16, 2021
@Porges Porges deleted the nested-maps branch September 16, 2021 20:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. size/M Denotes a PR that changes 30-99 lines, ignoring generated files. tide/merge-method-squash Denotes a PR that should be squashed by tide when it merges.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants