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 specifying secret values as strings #22059

Closed
wants to merge 1 commit into from

Conversation

liggitt
Copy link
Member

@liggitt liggitt commented Feb 26, 2016

Proof of concept for #19575 (comment), intended to make it possible to produce Secret definitions from templates.

Allows specifying secret values to the API in v1.Secrets as "string:literal string value", in addition to the existing base64 []byte serialization ("bGl0ZXJhbCBzdHJpbmcgdmFsdWU="). The conversion is one-way, output is always base64 for backwards compatibility. No additional escaping/unescaping or manipulation of the content is done. The conversion process is:

  1. Attempt to decode content as base64
  2. If decode fails, and the content starts with string:, remove the string: prefix and use the remaining bytes as the content.

With this change, a Secret could be created like this:

{
  "kind":"Secret",
  "apiVersion":"v1",
  "metadata":{"name":"mysecret"},
  "data":{
    "username": "string:myuser",
    "password": "string:mypassword"
  }
}

This change is Reviewable

@k8s-github-robot k8s-github-robot added kind/api-change Categorizes issue or PR as related to adding, removing, or otherwise changing an API size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Feb 26, 2016
@pmorie
Copy link
Member

pmorie commented Feb 26, 2016

Gut reaction is I think this has the highest probability of success of all the options i've seen for this.

@thockin
Copy link
Member

thockin commented Mar 3, 2016

is this really worthwhile?

@liggitt
Copy link
Member Author

liggitt commented Mar 3, 2016

Not sure yet. Creating secrets from templates or user input is currently pretty rough.

@k8s-github-robot k8s-github-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Mar 18, 2016
@smarterclayton
Copy link
Contributor

Definitely the cleanest option.

@pmorie
Copy link
Member

pmorie commented Apr 24, 2016

I think we should reconsider this for 1.3

@thockin
Copy link
Member

thockin commented Apr 30, 2016

Why? Is this really a significant source of user pain?

@smarterclayton
Copy link
Contributor

Yes. It makes any for of config templates extremely difficult to use for
user input secrets unless your template language also offers a nice base64
encoder.

On Apr 30, 2016, at 1:23 AM, Tim Hockin notifications@github.com wrote:

Why? Is this really a significant source of user pain?


You are receiving this because you commented.
Reply to this email directly or view it on GitHub
#22059 (comment)

@thockin
Copy link
Member

thockin commented May 1, 2016

ok. I guess I buy this, but I hate the solution. No I do not have a
better one that is back-compatible.

On Sat, Apr 30, 2016 at 9:27 AM, Clayton Coleman notifications@github.com
wrote:

Yes. It makes any for of config templates extremely difficult to use for
user input secrets unless your template language also offers a nice base64
encoder.

On Apr 30, 2016, at 1:23 AM, Tim Hockin notifications@github.com wrote:

Why? Is this really a significant source of user pain?


You are receiving this because you commented.
Reply to this email directly or view it on GitHub
<
#22059 (comment)


You are receiving this because you were assigned.
Reply to this email directly or view it on GitHub
#22059 (comment)

@liggitt
Copy link
Member Author

liggitt commented May 1, 2016

I agree that it's a "worst, except for all the others" sort of thing

@pmorie
Copy link
Member

pmorie commented May 1, 2016

Least worst amongst a curated array of terrible solutions

On Sun, May 1, 2016 at 9:52 AM, Jordan Liggitt notifications@github.com
wrote:

I agree that it's a "worst, except for all the others" sort of thing


You are receiving this because you commented.
Reply to this email directly or view it on GitHub
#22059 (comment)

@k8s-github-robot k8s-github-robot added size/L Denotes a PR that changes 100-499 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 May 1, 2016
@liggitt liggitt force-pushed the base64 branch 6 times, most recently from 219ae60 to aa8c9ed Compare May 2, 2016 01:15
@liggitt liggitt changed the title DO NOT MERGE - Allow specifying secret values as strings Allow specifying secret values as strings May 2, 2016
@k8s-github-robot k8s-github-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label May 8, 2016
@k8s-github-robot k8s-github-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label May 20, 2016
@k8s-github-robot k8s-github-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label May 20, 2016
@k8s-bot
Copy link

k8s-bot commented May 20, 2016

GCE e2e build/test passed for commit 83381ea.

@liggitt liggitt added release-note Denotes a PR that will be considered when it comes time to generate release notes. and removed release-note-label-needed labels May 24, 2016
@k8s-github-robot
Copy link

@liggitt PR needs rebase

@k8s-github-robot k8s-github-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label May 28, 2016
@ncdc
Copy link
Member

ncdc commented Jun 27, 2016

@thockin @bgrant0607 are you all ok with proceeding with something like this?

@bgrant0607
Copy link
Member

@ncdc @liggitt @pmorie

Adding new fields is complicated, but this also breaks compatibility for secret consumers, which would likely try to decode the fields as base64.

@liggitt
Copy link
Member Author

liggitt commented Jun 29, 2016

@bgrant0607 this is a one way conversion on write to enable templates or other writers that don't have base64 conversion capabilities. Output is always base64, so secret consumers aren't affected

@bgrant0607
Copy link
Member

@liggitt Ah, I didn't read the description carefully enough.

So it breaks the rule that the server shouldn't ever mutate fields populated by the client. :-)

I definitely would not want to do this anywhere else, since it would break kubectl apply and probably other things. However, users shouldn't use kubectl apply on secrets, so that reason isn't relevant in this case. Are there other get+diff or hash implementations we need to be concerned out?

@smarterclayton
Copy link
Contributor

On Jun 28, 2016, at 11:46 PM, Brian Grant notifications@github.com wrote:

@liggitt https://github.com/liggitt Ah, I didn't read the description
carefully enough.

So it breaks the rule that the server shouldn't ever mutate fields
populated by the client. :-)

I definitely would not want to do this anywhere else, since it would break
kubectl apply and probably other things. However, users shouldn't use
kubectl apply on secrets, so that reason isn't relevant in this case. Are
there other get+diff or hash implementations we need to be concerned out?

Isn't apply already broken on new fields we add (even if backward compat)?
Ie have field A, add new field B which if A is set is ignored, but if the
user applies B without A, A is merged ignoring B? So either way user
intent gets lost with apply across field changes. Adding a new new field
"stringData" that is converted to "data" would have to be dropped on the
server side anyway.

@bgrant0607
Copy link
Member

@smarterclayton New fields whose purpose overlaps existing fields break all forms of updates.

So, yes, I'm not suggesting new string fields.

Rather than a string: prefix, what about a bool field to indicate that all the fields should be interpreted as strings?

@ncdc
Copy link
Member

ncdc commented Jun 29, 2016

@bgrant0607 I had considered something like that (either a field or an annotation) but I wasn't sure if it made sense to persist that bool. I guess we could always reset it to false prior to storing it in etcd.

@liggitt
Copy link
Member Author

liggitt commented Jun 29, 2016

Rather than a string: prefix, what about a bool field to indicate that all the fields should be interpreted as strings?

I was hoping to limit the changes to the unmarshal phase, especially since I don't really want protobuf to have to change for this.

I also like the ability to do it per value, rather than applying to the whole object (makes a patch nice if you want to update one key's value using a string value)

Also, a separate boolean field that says "change the meaning of this other field" means that old servers can accidentally accept string data as binary data {"dataAreStrings":true,"data":{"key":"abcd"}} would be misunderstood by an old server, rather than throwing an error

@ncdc
Copy link
Member

ncdc commented Jun 29, 2016

I do like the per-value application as well

@bgrant0607
Copy link
Member

@liggitt @ncdc

I dislike the precedent this sets, and the lack of discoverability. The latter could be addressed via documentation on the API fields, but I'm going to throw out a few other ideas first.

We could use an alternative API endpoint (a subresource or alternate resource path) to indicate that a different type is being sent, which would contain both a string map and a byte map, but the object created and persisted would only contain the current Secret resource (bytes).

Or, we could add the string map to Secret, and clear it once the object was created, similar to the rollbackTo stanza in Deployment -- intended for imperative APIs rather than normal declarative/REST usage.

@smarterclayton
Copy link
Contributor

On Jun 29, 2016, at 6:57 PM, Brian Grant notifications@github.com wrote:

@liggitt https://github.com/liggitt @ncdc https://github.com/ncdc

I dislike the precedent this sets, and the lack of discoverability. The
latter could be addressed via documentation on the API fields, but I'm
going to throw out a few other ideas first.

We could use an alternative API endpoint (a subresource or alternate
resource path) to indicate that a different type is being sent, which would
contain both a string map and a byte map, but the object created and
persisted would only contain the current Secret resource (bytes).

We'd have to create an alternate resource path, since subresources wouldn't
be usable in lists or templates.

Or, we could add the string map to Secret, and clear it once the object was
created, similar to the rollbackTo stanza in Deployment -- intended for
imperative APIs rather than normal declarative/REST usage.

I'm fine with that as well.

@liggitt
Copy link
Member Author

liggitt commented Jun 30, 2016

I agree on precedent (weird APIs-within-an-API) and discoverability.

Of the options, I like a peer stringData map[string]string field the best, documented as a write-only convenience, and never output when reading a Secret from the API.

I would expect the stringData keys/values to always be moved to the data map, overwriting existing keys in the data map. That would allow patch to work as expected.

The one shortcoming is that there's no way to tell if the server knows about stringData without inspecting the Secret that got created... I was hoping to have a system an old server would reject rather than create a Secret with missing data, but I can live without it

@smarterclayton
Copy link
Contributor

smarterclayton commented Jun 30, 2016 via email

@liggitt
Copy link
Member Author

liggitt commented Jun 30, 2016

opened #28263 with the proposed peer field approach

@liggitt
Copy link
Member Author

liggitt commented Jun 30, 2016

closing in favor of #28263

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/api-change Categorizes issue or PR as related to adding, removing, or otherwise changing an API needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. release-note Denotes a PR that will be considered when it comes time to generate release notes. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants