-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
feat: skip name prefix/suffix by kind #1485
Conversation
Introduces a new config field, `namePrefixSuffixSkip`, that takes a list of gvk arguments. For example: ``` namePrefixSuffixSkip: - apiVersion: storage.k8s.io/v1 kind: StorageClass ``` For any matching group/version and kind, kustomize will preserve the original resource name even if `namePrefix` and `nameSuffix` are defined.
Welcome @sethp-nr! |
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: sethp-nr The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
@@ -56,13 +58,16 @@ func MakeDefaultConfig() *TransformerConfig { | |||
// sortFields provides determinism in logging, tests, etc. | |||
func (t *TransformerConfig) sortFields() { | |||
sort.Sort(t.NamePrefix) | |||
sort.Sort(t.NameSuffix) |
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'm not sure if this was intentionally omitted or not, but I noticed it was absent as part of this change. Happy to pull this into a separate PR if you'd rather.
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.
When the sorting was added the name suffix transformation hadn't been implemented yet. Almost certain it being missing here was just an oversight when the suffix support was added later.
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.
This will be great to have thanks for working on it!
In my opinion using the fsSlice type instead of adding a new gvkSlice would make this simpler. The fieldSpec type already embeds gvk.Gvk and could be used for this config as well. The path and create fields may be unnecessary for this case but doesn't seem like enough of a problem to need a more specialized config type just for this transformer.
@@ -56,13 +58,16 @@ func MakeDefaultConfig() *TransformerConfig { | |||
// sortFields provides determinism in logging, tests, etc. | |||
func (t *TransformerConfig) sortFields() { | |||
sort.Sort(t.NamePrefix) | |||
sort.Sort(t.NameSuffix) |
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.
When the sorting was added the name suffix transformation hadn't been implemented yet. Almost certain it being missing here was just an oversight when the suffix support was added later.
Thanks for the feedback @richardmarshall! I went with a new type because I couldn't see a way to have the path and create fields make sense, and so someone might find themself in the position where they got an error about being unable to merge differing That said, it is quite a narrow possibility. I'll remove the |
@sethp-nr @richardmarshall @Liujingfang1 @monopole The current PR seems to introduce a special case for suffix/prefix for an issue which much more global as described here: #896. We will have a to double the number of fields in the transformation config for all the other If one the otherside we add a "Skip" field to FieldSpec type FieldSpec struct {
gvk.Gvk `json:",inline,omitempty" yaml:",inline,omitempty"`
Path string `json:"path,omitempty" yaml:"path,omitempty"`
CreateIfNotPresent bool `json:"create,omitempty" yaml:"create,omitempty"`
Skip bool `json:"skip,omitempty" yaml:"skip,omitempty"`
} we would be able to we would be able to:
|
@jbrette Ah, good call out for the general case. Had a can't see forrest for the trees moment there. That said I'm conflicted on the idea of combining general field specs with the set to skip. I definitely see the Primarily it would make the case where a user wants to skip all transformers for a specific FieldSpec challenging. They would need to add an entry to every transformers configuration that might end up touching what they would like to be ignored. Also in the future if we add additional transformers they would then need to update their configuration to account for it as well or potentially face unexpected side effects. An alternative would be to define a new configuration key for the sole purpose of defining what should be skipped by transformers. type SkipSpec struct {
FieldSpec `json:",inline,omitempty" yaml:",inline,omitempty"`
Transformers []string `json:"transformers,omitempty" yaml:"transformers,omitempty"`
} Where the behavior of the The default transformer config for this to account for the current skipping for CustomResourceDefinitions in the name prefixsuffix transformer could then be something along the lines of: skipTransformation:
- kind: CustomResourceDefinitions
transformers:
- prefixsuffix This pattern would also make adding additional skipping behavior not require adjustments to the FieldSpec type. An example being being able to skip based on the name of an object. |
Thank you for putting thoughts on this. I agree being able to skip is something we should consider to support.
I did consider add the
For this one, I don't think we need to add an extra field in kustomization.yaml to support this. The skipping should be part of the transformation config. I'd like the solutions to be generic, backward compatible with previous transformer configs and easy to solve all kinds of Skips. Considering the various transformers and the type of skipping users may want them to do, there are several kinds of Skips:
How about we keep using current
The configuration file for transformers can be
|
@Liujingfang1 @richardmarshall @sethp-nr @monopole I started to prototype an idea based on patch to change the configurations of transformer themselves. Indeed sometimes a user wants add to transformer config, sometime he wants to add entries, sometimes he wants to completely replace the list of entries. This is basically the JSON patch operations that kustomize can already apply on a resmap. In on word, if the TransformerConfig object could implement the ResMap api, this would address a lot of those issue because the user could change the configuration of transformer by adding apply a JSONPatch to it (The current JSONPath operation is add). Without going this far (aka TransfomerConfig implements ResMap API), I started with adding a JSONOp field to the FieldSpec instead of simple Skip boolean: See here Even for the simple skip boolean, the hardest part of the implementation is detecting conflicts between skip and add: The code has to be able to understand what is the intersection of the fieldspec between the add and the skip. For instance if you have:
it means that the transformer has to be able to understand that it needs to apply the transformation to mycrd,groupa,version10 but not to mycrd,groupa,version22. |
What is the purpose of that? The custom configurations of transformers should from the same set of files. Users can directly edit those files, they don't need to patch them.
This is already supported in current transformer configuration that you can specify in kustomization.yaml. They are merged into the default one. |
@Liujingfang1 @richardmarshall @sethp-nr @monopole Sorry I probably did not describe properly what I saw. If it is possible to completely override the default configuration, I'm not sure that we have to do any code change to kustomize. In the current example of name prefix/suffix we just have to tell the user to replace nameprefix:
- path: metadata/name by nameprefix:
- path: metadata/name
kind: kind1
- path: metadata/name
kind: kind2 Same thing would be applicable for commonLabel, selector.... when a user has something specific to do, he just override the default config completly. |
I agree and that's what I was trying to convey, sorry if that wasn't clear. My thought was instead of adding unique transformation configs for every transformer we instead add a global transformation skip config. Would still be part of the tranformerconfig (managed through To use the examples you gave for
In my opinion this would end up being rather cumbersome for users, especially for transformers such as prefixsuffix. Having to explicitly opt-in every kind that is desired for transformation would be very challenging for larger kustomizations and prone to errors as new resources are added. |
Thanks so much for all the discussion! It sounds like there's an open question on how best to configure the "skip" behavior. So far I've seen options: A. For each plugin, add a specific skip configuration field (roughly as implemented for PrefixSuffixTransformer here) While I appreciate the flexibility option C offers, I have to say that as an end-user I would find it fairly unapproachable – how would I discover what patch to use to turn off the NamePrefixSuffixTransformer on just one Kind? I am also fairly concerned about poking a hole in the "additive-only" mental model I've developed about Kustomize – right or wrong, I would not expect a higher layer to un-do some configuration I did in my base. Regarding option B, it sounds like there's a sub-question around whether that list is specified in plugin-major order (For plugin A, skip field specs S) or in field-major order (For field spec S, skip plugins A and B). In my use-case, I'm publishing a StorageClass for consumption outside my Kustomize directory (i.e. outside the purview of namereference), so there's not a whole lot of difference to me as I'm only specifying a single pair. So far I don't see any way that we can avoid writing plugin-specific config and skip code, so either shape seems about as easy to implement. I’m happy to pursue any one of those strategies for this PR, but regardless of which you all would prefer, I would hope we can pick something that can be done incrementally – meaning we could agree on the format here, but not necessarily gate this change on an implementation for every plugin. Let me know how you think is best to proceed! I really appreciate everyone's time and thoughtfulness 😄 |
@sethp-nr @richardmarshall @Liujingfang1 Hi all. I merged what we spoke about in the comments and the work that @sethp-nr had already done into one pull request: #1491 so that we can see what is user friendly and what is not. From a pure technical standpoint, the PrefixSuffixTransformer and NamespaceTransformer are now leveraging the new feature. It is still really rough and test coverage is really limited. Would be nice if we could find a way to share the workload, test it really well before asking to merge it into master. |
I second this concern.
The way I was thinking about the idea for option B was
I agree with @Liujingfang1 that this has big enough ramifications that we should drive consensus on the implementation through a KEP. |
@Liujingfang1 @richardmarshall @sethp-nr Here is the corresponding KEP |
It seems most of the context is already here, rather tl;drFor the case described here, it's possible to get the This unit test provides a custom config to The downside is having to explicitly list all the Longer opinionRecommendationIf tempted to add new transformation-related fields to
In all cases, you get reusable custom We should deprecate the Background (for those interested)The v1, v2 code path
The post v3 code path
|
@monopole thanks for the lengthy bit of history, context, and thoughts on this subject.
As @jbrette stated in the KEP comments, this currently doesn't work with official kustomize releases as the It also doesn't work for the namereference and refvar transformers which are still special cases that haven't been moved to the plugin model. If they were usable in this model they would be cases where the user experience would be pretty poor given the significant number of FieldSpecs in their respective default configurations. In general I worry about this approach being a pretty big hurdle for new users. While the current system is somewhat arcane (especially considering the rather limited documentation we have in place). It at least is a pretty small ask to have to add a single FieldSpec to a file and include that in the kustomization to enable a new field for a transformer. Having to now move the transformer bits out of the kustomization file entirely and recreate the whole plugin config externally feels like something that would be not only be difficult for new comers but also difficult to maintain. Users explicitly configuring a transformer would not be able to take advantage of updates to the default config as new versions of kustomize are released.
Unless I'm missing something I don't see how we would do this in one step with the current plugin config system. Are you thinking that this would be achieved by performing two kustomize builds? phase 1: A kustomization that includes the plugin configs as resources and manipulates them as needed.
Do you have an example of what this setup would look like? |
@richardmarshall @jbrette Right you are. Somehow b4 vacation i'd set out to get the builtins to run from the statically compiled versions, and then came back thinking i'd already done the work - my apologies. Fixed by #1532, PTAL. The unit tests confirming that builtin plugins could accept custom config were actually loading and running
Just one At the highest level, the YAML coming from that particular kustomzation sequence is interpreted as a transformer config, simply by specifying it in the W/r to your other comment about the relative difficult of explaining how to customize kustomize - i.e. continuing to evolve the global TransformerConfig and add more complexity to fields in the kustomization file, vs. encouraging plugin use - and the problem of where to put all those FieldSpecs (especially for NameReference)... I'm concerned too. working on an example to inform this some more. |
👍
Ah! yes got it now. Completely overlooked the implications of leveraging the resource accumulator to load the transformer/generator configs.
😆
After the "oh, of course you can do that" realization it seems useful, though a bit bizarre, will play with this model a bit to form a more concrete opinion. |
The following test is an example of custom config for the PrefixSuffixTransformer. the plugin's config is currently oriented towards specifying which kinds to modify and ignoring others. The following test has custom configuration for the LabelTransformer, showing Moreover, the test shows how to bundle custom config for transformers into a reusable base. |
@monopole I think those two files are gone from master, could you care to point out a solution to skip a single resource by name? |
@sethp-nr: PR needs rebase. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
@dvaldivia I was looking for the linked example as well. Here they are, https://github.com/kubernetes-sigs/kustomize/tree/bf119bf5b7ab3b51cba5845832ae1cc9807d553e/api/internal/target. |
Introduces a new config field,
namePrefixSuffixSkip
, that takes a listof gvk arguments. For example:
For any matching group/version and kind, kustomize will preserve the
original resource name even if
namePrefix
andnameSuffix
aredefined.
Fixes #519