feat: `emitStringData` boolean for secretGenerator
This allows users to pass emitStringData: true to the secretGenerator, alongside the type option.
When enabled, UTF-8 strings are output in plainText stringData, and non-UTF strings and any binary data fallback to the default behavior of being base64 encoded in data.
This is very similar to the default, kyaml behavior of loading values into ConfigMap's data and binaryData fields.
This feature provides a general U/X improvement for people using kustomize interactively, and also allows Flux users to template into generated secrets. (Flux users already can and do template into ConfigMaps, so we want to give people more secure mechanisms in kustomize-controller)
- test: add secretGenerator testcases
- feat: support emitStringData in secretGenerator
- test: test emitStringData in secretGenerator
resolves #5142 #1444 #1261 #793
This PR has multiple commits, and the default merge method is: merge. You can request commits to be squashed using the label: tide/merge-method-squash
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-sigs/prow repository.
/assign
[APPROVALNOTIFIER] This PR is NOT APPROVED
This pull-request has been approved by: matheuscscp, stealthybox Once this PR has been reviewed and has the lgtm label, please ask for approval from koba1t. For more information see the Code Review Process.
The full list of commands accepted by this bot can be found here.
Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment
I've just done a fresh rebase. @koba1t, is there any way I can help out in reviewing this patch? Thanks :)
@stealthybox So, Sorry for the late review.
- The field name
stringData: trueis associated with the field name of a secret resource, but is it possible to change it to a more descriptive field name, such asnoEncode: true? - As a test scenario, could you verify that when adding a secondary secretGenerator with
stringData: falseto asecretGeneratorconfigured withstringData: trueusing thebehavior: mergeoption, the resultingdatais properly base64 encoded?
How about outputStringData?
@matheuscscp
What I'm trying to say is that field names should be clear enough that users can immediately understand how they'll behave when seeing them in this PR.
The name stringData likely comes from the existence of a stringData field in secret resources, but it doesn't actually explain the behavior in kustomize.
For example, in the case of stringData, it's not clear whether this refers to string input or what exactly is being stringified, or in the case of outputStringData, it's not clear whether this controls the output destination or something else.
could you verify that when adding a secondary secretGenerator with stringData: false to a secretGenerator configured with stringData: true using the behavior: merge option, the resulting data is properly base64 encoded?
@koba1t, thanks for pointing out this out. I've added tests for the following cases in test: field overrides for configMapGenerator + secretGenerator 67fc288:
-
- merge encoded data fields onto a generated secret with stringData
-
- override encoded data fields with stringData for secretGenerator producing a Secret that successfully uses the new value in the Kubernetes API
-
- override stringData fields with encoded data for secretGenerator producing a Secret that silently fails to use the new value in the Kubernetes API
-
- override encoded binaryData fields with data for configMapGenerator producing an invalid ConfigMap
-
- override data fields with encoded binaryData for configMapGenerator producing an invalid ConfigMap
The 4 cases where fields override using a different encoding output duplicate fields. This is existing ConfigMapGenerator behavior that is undesirable. This existing buggy behavior becomes new Secret-gen behavior. I can fix both of these in a followup PR as discussed privately in our Slack dm.
Here is an example of what that fix could look like: https://github.com/stealthybox/kustomize/commit/e95e85414fc1c4883e8843f02ce1c85502813d9f
Regarding the field name, I understand the concern of stringData as a bool not fully expressing the behavior.
I would hope the doc-string helps clarify this beyond just the name.
In the most recent issue,
an end-user requests a stringData bool in the generatorOptions. https://github.com/kubernetes-sigs/kustomize/issues/5142#issue-1677002716,
@seh and @annasong20 confirm the boolean field stringData should be added to SecretArgs and exposed directly on secretGenerator. https://github.com/kubernetes-sigs/kustomize/issues/5142#issuecomment-1560999171
A separate end-user suggests the boolean field should be called useStringData. https://github.com/kubernetes-sigs/kustomize/issues/5142#issuecomment-2519878579
The title of unrelated issue (https://github.com/kubernetes-sigs/kustomize/issues/1261) is "Support StringData option in SecretArgs".
Considering end-user, contributor, and maintainer responses, stringData seems to be the agreed upon field name that is most natural. I think the word "stringData" must at least be contained within the field name.
noEncode implies that there isn't a fallback encoding behavior when there is.
I don't think noEncode works.
I'd also challenge that stringData doesn't make sense.
Most of the fields on generator options across the project are passthrough fields that end up in the output:
labelsannotationsimmutabletype(for Secrets only -- defaults to "Opaque" when not supplied)
The new field isn't a passthrough value field -- it changes generator behavior. disableNameSuffixHash is a similar behavioral field that describes the generated output implicitly.
That's why secretGenerator[].stringData = true in my head automatically talks about the output of the generator.
in the case of stringData, it's not clear whether this refers to string input or what exactly is being stringified
This is fair. there are a lot of fields when you consider input fields like env, envs ,files, and literals mixing with output fields like type and annotations and behavioral fields like behavior and disableNameSuffixHash.
Disambiguation would need to come from the doc-string and examples.
I'm happy to add examples to:
- https://kubernetes.io/docs/tasks/configmap-secret/managing-secret-using-kustomize/#create-a-secret.
site/content/en/docs/Tasks/secret_generator.md
in the case of outputStringData, it's not clear whether this controls the output destination or something else.
I disagree that outputStringData is unclear. There is only one output of a generator.
I think these are decent options for field names:
- stringData
- outputStringData
- generateStringData
- setStringData
- preferStringDataOutput
- disableBase64ForStringData
The default behavior of a configMapGenerator already includes heuristic auto-encoding behavior for binaryData, and that doesn't show up in any field names. It's just the way a kustomize generator works.
Thanks for considering these points. I don't want to be overly pedantic, and I know the behavior is complex. Naming this field is tricky. I think examples and the doc-strings on the field name should help people understand what it does exactly. I don't think we should give this field any name that inaccurately implies that it performs or prevents behaviors that it does not. Because the behavior is complex, the name either needs to be somewhat ambiguous, or very detailed and lengthy.
Do you like stringData or any of the other names I suggested?
Yeah this field has to explain itself, it has to have stringData on its name somehow. Anything else would be garbage for explaining what it does.
unrelated to field names, here's one way to fix the existing broken configMapGenerator behavior: https://github.com/stealthybox/kustomize/commit/e95e85414fc1c4883e8843f02ce1c85502813d9f I would send this in a followup PR.
I think "stringData" would be a deceiving name for this new field. My suggestion today is "emitStringData".
I've proactively renamed the field to emitStringData in the types, docs, and test names.
Tests are passing.
Now that the field name is disambiguated from the stringData fields in the test output and docstrings, it's easy to rename it to whatever we decide :+1:.
@koba1t and I considered in our Slack dm's whether a string value field could work:
field: "data" # "stringData" | "binaryData"
This could be a generic way to solve this problem for both ConfigMap and Secret generators, but it also creates more error states and is harder to grep for in existing code + discover in auto-complete.
I prefer the emitStringData boolean field.
If we want support for explicit encoding in ConfigMap generator, I propose we do so by adding emitBinaryData as a boolean in another PR.
Hi friends, if there's no further contest on the field name, I'd love to get this reviewed for a merge. I'm happy to write some docs examples.
I want to draft a change for the merge behavior bugfix in https://github.com/stealthybox/kustomize/commit/e95e85414fc1c4883e8843f02ce1c85502813d9f .
After these changes make their way into kustomize, kubectl needs to update kustomize before we can pull this feature into Flux. I'd like to be able to do that before KubeCon NA and the Flux 2.7 release.
cc @koba1t @seh
Hi @stealthybox
So sorry to delay response to this topics. I'm doing all my work on kustomize completely outside of my job, so the time I can dedicate is extremely limited.
I simply want to avoid making the secretGenerator interface overly complex and ensure it remains consistent and intuitive for users.
Therefore, I proposed the field method to unify the interface definition with configMapGenerator.
And, Above all, I think it makes it clear “what goes where.”
but it also creates more error states
I agree, but I don't think it's difficult since it's just checking whether it matches specific hardcodes in the kustomize code.
harder to grep for in existing code + discover in auto-complete.
I personally didn't understand this part, so could you explain it in more detail?
Personally, I have concerns about defining this as a boolean, considering the possibility that we might need to output to fields other than stringData in the future.
I believe, what we want to achieve is not a simple on/off operation that can be defined with a boolean, but rather a selection operation that allows specifying the output destination.