-
Notifications
You must be signed in to change notification settings - Fork 6.5k
feat: Support nested objects in merge generator using go templates (Issue #12836) #17145
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
base: master
Are you sure you want to change the base?
Conversation
|
So after reading the original issues comments a little more carefully, I also tried the suggested flattening from this comment. I'm not totally against this approach, but it also has it's problems to consider: Hierarchy CollisionAssume the following parameters generated: - values:
name: "a"
- values.name: "a"The flatten approach generates the same maps for both of these, equal to the second example. The merge generator would then consider those maps to be equal and if used as merge key, merge on them. This might be a problem, depending on the expected outcome. But especially for setups fetching values from some users, this makes these users now responsible thinking about the equality of those values. I personally would avoid having values in such a structure, it seems confusing, but in a more complex settings this might just be the case. And in a more complex case, I personally would prefer the merging to be strictly correct instead of silently merging those. The go template version has this problem, too: - values:
name: "a"
- values: "map[name: a]"These equal for the merge key Key CollisionAssume the following parameter generated: - values:
name: "one"
values.name: "two"Flattening simply starts flattening with the first key, but the second key generating the same flat key overwrites the first value, making the resulting map contain only As with hierarchy collisions, IMHO I'd try to avoid these confusing names. But, a more complex scenario might have them from user provided input. And again, I personally would prefer the merging to be strictly correct instead of silently assuming those are equal. The go template version does not have this problem as it will insert type information. Complex Value KeysAssume the following parameter generated: - cluster: "some-cluster-a"
values:
location: "germany"
gpus: "many"
- app_name: "my-ai-app"
values:
location: "germany"
gpus: "many"This might be a use case for a single merge key, I'm aware, that this might also be an error prone use-case. If the cluster gains a label, the app suddenly does not match any more, but with templating the individual fields in the merge key, the ApplicationSet author is in control of that. The go template version does not have this problem as the source information is not flattened. |
|
Hello everyone, Is there any idea yet of which version this fix might land in? |
|
Hey @remicode ! Thx for the question. I did the initial implementation and then got busy with other stuff, so the rest of communicating this fell along the wayside. I assume, this PR has been under the radar since then. I still think the implementation idea is ok and I'd love to get feedback for it and bring this issue into a release version. I'm not a member of any team from ArgoCD, I think I can fit pinging them about this in after easter. Depending on their capacity, it might still take a while, though. |
|
Thanks for the update @girstenbrei. When you do ping someone from the team, if there is anything I can do to help let me know and i'll be happy to pitch in. |
|
Related to #13118 |
|
I am looking forward to have this feature in argocd. when will it be merged? |
|
Any chance of reviving this? I would be happy to put in some work if we have a path forward. Being able to use |
|
@iNoahNothing Hi there! Thank you for the interest, the hold up is the following: using nested objects in the merge-keys field technically changes the semantics of this field. Previously, a field with But, on the other hand, one can argue that this is how people actually expect this to work (at least I did) and the number of people who actually have keys in with a dot in them will be low. So the next steps discussed where to write up the exact cases that this change would break to be able to judge the involved risk. Ideally those also would be test-cases. That's where I stopped due to missing capacity. If you have resources, it would be great if you could jump in for the write up and / or test cases. I also adjusted docs a little, but a second opinion on edge cases would be great, those are easily missed. Hope I could help, |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #17145 +/- ##
==========================================
+ Coverage 60.03% 60.05% +0.01%
==========================================
Files 344 343 -1
Lines 57781 57881 +100
==========================================
+ Hits 34689 34758 +69
- Misses 20333 20351 +18
- Partials 2759 2772 +13 ☔ View full report in Codecov by Sentry. |
1eeac21 to
5a84df8
Compare
|
Greets everyone, BlockersThe main blocker has been, that switching to goTemplating for the merge keys Merge keys with dotsPreviously, if your merge key contained dots, they would mergeKeys:
- "company.org/config"
generators:
- list:
elements:
- "company.org/config": "marker"
- company:
org/config: "A"
- list:
elements:
- "company.org/config": "marker"
- company:
org/config: "B"If we switch this to goTemplates, it will not merge any more. However, currently UpdatesChangesI updated the implementation, tests and docs for how merge keys are interpreted. This includes simple keys compatible with fasttemplate like: - key
- nested.keyIt should enable easier migration from fasttemplate to goTemplates, simple keys This (AFAIK) should be strictly correct now. Every auto-converted key is a valid InvariantsThe following assumptions need to hold. I tried to verify them as best as I
Next stepsMigration documentation is still missing. Where should I write up this? It's main component should be to inform users about the need to use the index |
|
@crenshaw-dev any chance of getting this in an upcoming release? |
Signed-off-by: Christoph Girstenbrei <[email protected]>
Signed-off-by: Christoph Girstenbrei <[email protected]>
Signed-off-by: Christoph Girstenbrei <[email protected]>
Signed-off-by: Christoph Girstenbrei <[email protected]>
Signed-off-by: Christoph Girstenbrei <[email protected]>
Signed-off-by: Christoph Girstenbrei <[email protected]>
Signed-off-by: Christoph Girstenbrei <[email protected]>
Signed-off-by: Christoph Girstenbrei <[email protected]>
Signed-off-by: Christoph Girstenbrei <[email protected]>
Signed-off-by: Christoph Girstenbrei <[email protected]>
Signed-off-by: Christoph Girstenbrei <[email protected]>
Signed-off-by: Christoph Girstenbrei <[email protected]>
Signed-off-by: Christoph Girstenbrei <[email protected]>
this would be awesome. |
Checklist:
Closes #12836
Overview
This PR follows the proposal from the original Issue #12836 . Nothing changes for users with
goTemplate: false. UsinggoTemplate: truemakes themergeKeysvalid Go templates. All objects present in a parameter set from a downstream generator can be accessed through this Go Template, as well as all templating functions.Implementation
Without go templating enabled, nothing changes. The same mechanism is used to index parameter sets:
https://github.com/girstenbrei/argo-cd/blob/master/applicationset/generators/merge.go#L176-L178
With go templating, instead of having the parameter set represented by the value at the merge key for each merge key, the templated value for these keys is used.
https://github.com/girstenbrei/argo-cd/blob/master/applicationset/generators/merge.go#L160-L175
The Good
I think this might just work. No changes in any Files, mergeKeys just support nested objects now the same way golang templates support nested objects.
The Ugly
When is a template a template?
The "heuristic" when a mergeKey is a goTemplate is pretty naive.
https://github.com/girstenbrei/argo-cd/blob/master/applicationset/generators/merge.go#L164-L165
You could set merge Keys containing '{{' && '}}' but they are not go templates, maybe you have a generator generating a template to be filled later and for some reason you need the key to be the template. ATM I'd argue, that deliberate usage of this seems unlikely. Maybe people generate templates in values. No generator in Argo does this in the merge keys.
Map ordering
It might be possible to shoot yourself in the foot with this. Although map ordering is apparently guaranteed in golang templates 12, this is limited to the case that 'keys are of basic type with a defined order'. Parameter sets are of type
map[string]interface{}which should always make them fall into this category, I'm just not sure.Footnotes
https://forum.golangbridge.org/t/text-template-sort-map/5688 ↩
https://pkg.go.dev/text/template#hdr-Actions ↩