Closed narg95 closed 4 years ago
@narg95 Patching doesn't support that. It will replace the value of settings
rather than merging the values.
I'd suggest use ConfigMapGenerator from files. For different base or overlays, you can adjust different the file content.
It seems to be a common practice to store config files in ConfigMap properties. It would be great to be able to use a pattern / regex to replace for instance a port that is set in a nginx.conf.
I need this as well.
Another option would be to pass along var references to the external program as environment variables and use the output of that program as the configmap. @Liujingfang1, would that be better aligned with the philosophy of kustomize?
Hi @Liujingfang1,
I'd suggest use ConfigMapGenerator from files. For different base or overlays, you can adjust different the file content.
In a greenfield project I will do as suggested, but I am porting an application, that uses a rather complex json config file, to kubernetes, so using a ConfigMapGenerator will not be ideal because I would have to repeate the whole JSON file for a trivial json property change. I currently solve it post-processing kustomize's output with envsubst
but this is something I want to avoid therefore it would be great that kustomize would help me to do so.
If this is a wanted feature I am willing to invest some time in a PR, but if this is something very specific to my use-case I rather solve it by using configMap literals, which can be re-used and overrided, and add a sidecar that converts it to the expected application config json format.
@Liujingfang1 let me know your thoughts!
@narg95 According to the comment history here, it could be a common use case. If would be nice if Kustomize can provide some convenience here.
The example listed is a JSON file as the value. There are other cases as well. For example, I may have the configmap generated from following files
key1=value1
key2=value2
There is no limitation on what type of files can be used to create a ConfigMap. How to detect the format and apply proper merging is tricky.
@Liujingfang1 thanks for your feedback!
I may have the configmap generated from following files
did you mean: "generated from a file with the following values" right?
There is no limitation on what type of files can be used to create a ConfigMap.
right, it should be extensible to incrementally support more patching strategies, we can start with strategy-merge
for json and yaml, then props (key=value)
, later json-6902
.
The following example shows my two-cents proposal :) , note the new patchContent
attribute, it contains patch strategy to apply:
kustomization with patch
-base: ../base/my-app/
configMapGenerator:
- name: demo-settings
behavior: merge
patchContent: json-strategic-merge
- file: my-app-settings=patch.json
- literals:
- foo= -|
{
"logLevel": "info"
}
patch.json
{
"version": "2.0-rc1",
"args": ["--debug-mode", "off"]
}
base/my-app/kustomization.yaml
configMapGenerator:
name: demo-settings
- file: my-app-settings.json
- literals:
- logging-config: -|
{
"log-level": "debug",
"output": "stdout"
}
my-app-settings.json
{
"name": "my app",
"environment": "demo",
"version": "1.0",
"args": ["--debug-mode"]
}
kind: ConfigMap
apiVersion: v1
metadata:
name: demo-settings
data:
my-app-settings.json: -|
{
"name": "my app",
"environment": "demo",
"version": "2.0-rc1", // PATCHED
"args": ["--debug-mode=off"] // PATCHED
}
logging-config: -|
{
"log-level": "info", // PATCHED
"output": "stdout"
}
I'd love to hear your opinions @Liujingfang1 @dperetti @ajbouh !
One more option to discuss here: make it possible to render configmap/secret content as templates, e.g. golang templates.
I understand that kustomize's awesomeness stems from the fact that it does not use templating to build kubernetes objects which are structured data by nature. But configmap/secret content is opaque data, so making it possible to render with templates sounds cool.
For example make it work like helm template processing, but only for configmap/secret content. Maybe other literal field content, e.g. JSON stored in annotations.
Here's a very rough sketch of how this might look like:
#### base/app.properties
foo={{ .Values.foo }}
bar={{ .Values.bar }}
#### base/values-defaults.yaml
foo: 'foo-value'
bar: 'bar-value'
#### base/kustomization.yaml
valueSources:
- values-defaults.yaml
configMapGenerator
- name: myJavaServerProps
render:
# the values for rendering app.properties will come from "valueSources", which might get enriched in overlays
- app.properties
#### overlays/production/production-values.yaml
bar: 'bar-value-production'
#### overlays/production/kustomization.yaml
valueSources:
- production-values.yaml
bases:
# the base gets rendered using combined value sources: "production-values.yaml" overlaid on top of "base/values-defaults.yaml"
- ../base/
I'm not presenting an API for review here as it definitely needs more thought, but more an idea of what you could accomplish with it.
Attemping to summarize:
Say you want to use kustomize to make the configmaps used in production differ in some way from that used in development and staging.
Mixins might work. Suppose the configmap held a java properties file (k=v pairs, one per line), and one wanted to use kustomize to “edit” the value for one particular key. The kustomize way to do this would be to split the file - put the bulk of the k=v’s into a configmap in the base, then put the particular k=v in an overlay and get the final configmap as a merger (example) which then goes to production or development, etc. This works because kustomize understands that particular file format. It knows the values are whatever comes between the =
and EOL characters.
More generally, configmap values are opaque to k8s - they could be a simple port number, or some snippet of json/javascript/lisp/whatever.
A scheme to allow kustomize to edit any configmap value would have to be in the form of an unstructured edit, e.g.
@narg95 focusses on a structured JSON edit instead of an unstructure edit, to address the particular case of an app being ported to k8s that consumes some complex JSON config file, and @narg95 wants to apply structured edits (e.g. to get loglevel:info in production instead of loglevel:debug).
@narg95 SGTM - can you write a short KEP (e.g 892, 886) - you pretty much have the meat of it above - and then provide the impl? Do you have any notion of how common this might be? It’s a structured edit, so it’s consistent with kustomize in that sense.
As an aside, Secrets are getting a big upgrade, where we allow a plugin to generate KV pairs (since the V’s are not just opaque - they are secret). This isn’t an patch mechanism (create KV’s only), and it’s not going to be active in configmaps - but folks on this thread might be interested.
@monopole Maybe I'm missing something, but adding another file to configMap is not actually a merge. What we do want (speaking for my company) is to have some basic common application.conf, and some custom additions to it, like dev.conf/stage.conf which are ok to just to append to common config. With your example https://github.com/kubernetes-sigs/kustomize/blob/master/examples/combineConfigs.md we'll achieve two separate config files, which are not supported at the moment.
this is another case where variables would help like https://github.com/kontena/mortar has
@narg95 this can be done in the following way:
Below is in a file resources.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: demo-configmap
data:
settings: |-
{
foo: $(foo),
bar: $(bar)
}
The kustomization file looks like
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- resources.yaml
configMapGenerator:
- name: demo-configmap-parameters
env: params.env
generatorOptions:
disableNameSuffixHash: true
vars:
- name: foo
objref:
kind: ConfigMap
name: demo-configmap-parameters
apiVersion: v1
fieldref:
fieldpath: data.foo
- name: bar
objref:
kind: ConfigMap
name: demo-configmap-parameters
apiVersion: v1
fieldref:
fieldpath: data.bar
configurations:
- params.yaml
params.env contains
foo=foo_1
bar=bar_2
params.yaml contains
varReference:
- path: data/settings
kind: ConfigMap
Note that this inserts an extra ConfigMap which you would probably delete afterwards. eg
$ ☞ kubectl create ns demo 1>/dev/null && kustomize build | kubectl apply -f - -n demo 1>/dev/null && kubectl delete cm demo-configmap-parameters -n demo 1>/dev/null && kubectl get cm demo-configmap -oyaml -n demo && kubectl delete ns demo 1>/dev/null
outputs
apiVersion: v1
data:
settings: |-
{
foo: "foo_1",
bar: "bar_2"
}
kind: ConfigMap
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","data":{"settings":"{\n foo: \"foo_1\",\n bar: \"bar_2\"\n}"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"demo-configmap","namespace":"demo"}}
creationTimestamp: "2019-04-07T14:47:54Z"
name: demo-configmap
namespace: demo
resourceVersion: "40657790"
selfLink: /api/v1/namespaces/demo/configmaps/demo-configmap
uid: 203db6aa-5944-11e9-9a72-42010a8a016c
@kkasravi works fine except the config hash (if enabled) won't be updated when vars change, which result in the deployment can not rolling update. cc @Liujingfang1
Hi @kkasravi, thanks for the explanation and the code!
I ended up with a similar solution but in my case at that time I generated all the configs with kustomize config save -d ./configs
and I appended my custom configuration including the path data/setings
from configmaps. I did it so because from my understanding the custom configurations did not get merged with defaults so I did not wanted to lose kustomize's default config. But in your example you just added a new configuration so I am wondering if you get the defaults plus the ones defined in your params.yml
file.
Hi, just met the same issue here.
Without going into templating or "smart" merging, being able to concatenate multiple file under the same key in the config map would make a huge difference. I think the current syntax is neat and doesn't have to change but having (as in the example):
base/kustomization.yml
configMapGenerator:
- name: my-configmap
files:
- settings.cfg
overlays/prod/kustomization.yml
configMapGenerator:
- name: my-configmap
behavior: merge
files:
- settings.cfg
Should result in a configmap with a single key settings.cfg
and the content of both files concatenated.
It is not optimal since it requires using the same file names but would still be a big improvement in maintainability.
Hi, same problem here. @benjamin-bergia solution would be enough even for us, solving problems when multiple files cannot be loaded.
@SilverXXX @benjamin-bergia The configMapGenerator overlay does not seems to work write. There is bug in the Resource.replace/merge implementation and we end up with invalid labels:
apiVersion: v1
data:
settings.cfg: |
Content of the overlay settings.cfg
kind: ConfigMap
metadata:
annotations: {}
labels: {}
name: my-configmap-8gkkcddg96
@ikatson @monopole @Liujingfang1 I think this another use case where the autovar PR
We are basically able to achieve exactly what ikatson was asking without templating and by levering multiple key features of kustomize. Have a look at the third solution
The output is basically the following:
apiVersion: v1
data:
app.properties: |
foo=production-foo-value
bar=production-foo-value
kind: ConfigMap
metadata:
name: myJavaServerProps-7m6dhd66bg
---
apiVersion: v1
kind: Values
metadata:
name: file1
spec:
bar: production-foo-value
foo: production-foo-value
Nothing?
Sometimes the unresponsive attitude of kustomize team about open issues/prs are really sad.
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-testing, kubernetes/test-infra and/or fejta. /lifecycle stale
/remove-lifecycle stale
Will there ever be a valid solution for patching a JSON ConfigMap
? The lame workaround right now is to copy the full JSON file into every overlay and manually override it like:
base/thing/kustomization.yaml
configMapGenerator:
- name: thing-config
files:
- config/thing-config.json
overlay/foo/kustomization.yaml
configMapGenerator:
- name: thing-config
behavior: merge
files:
- thing-config.json
This is really error prone and not ideal. Is there not some way we can use patchesJson6902
here to patch a JSON file? That's what it was intended for, but so far I've yet to work out a config that works with this kind of setup.
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-testing, kubernetes/test-infra and/or fejta. /lifecycle stale
Stale issues rot after 30d of inactivity.
Mark the issue as fresh with /remove-lifecycle rotten
.
Rotten issues close after an additional 30d of inactivity.
If this issue is safe to close now please do so with /close
.
Send feedback to sig-testing, kubernetes/test-infra and/or fejta. /lifecycle rotten
Rotten issues close after 30d of inactivity.
Reopen the issue with /reopen
.
Mark the issue as fresh with /remove-lifecycle rotten
.
Send feedback to sig-testing, kubernetes/test-infra and/or fejta. /close
@fejta-bot: Closing this issue.
Just a note to say this is still needed...
not sure if i can/should but /reopen the ability to patch structured configmaps is such a pain point in older apps, particularly in javaland.
@afirth: You can't reopen an issue/PR unless you authored it or you are a collaborator.
Open a new issue
On 6. Apr 2021, at 21.08, Kubernetes Prow Robot @.***> wrote:
@afirth: You can't reopen an issue/PR unless you authored it or you are a collaborator.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.
How do we do this now that var is deprecated?
I don't think varReference works anymore either when we replace with replacements
/remove-lifecycle rotten
Hi all,
I want to patch a literal json from a configMap item, but I have not found an example in the docu, do you know if that is possible? For example, assuming the following configmap:
Base configMap
I want to apply this patch:
So the resulting configMap looks like:
Thanks !
P.S. Great job with kustomize!