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

Add binary configmap #57938

Merged
merged 4 commits into from Jan 26, 2018
Merged

Conversation

dims
Copy link
Member

@dims dims commented Jan 6, 2018

Reviving code from #33549 submitted by @zreigz

What this PR does / why we need it:
Add support for binary files in ConfigMap

Which issue(s) this PR fixes (optional, in fixes #<issue number>(, fixes #<issue_number>, ...) format, will close the issue(s) when PR gets merged):
Fixes #32432

Special notes for your reviewer:

Sample API data:

apiVersion: v1
kind: ConfigMap
data:
  foo: text value
binaryData:
  bar: jmjKxUGNs/WqDQ==

Release note:

ConfigMap objects now support binary data via a new `binaryData` field. When using `kubectl create configmap --from-file`, files containing non-UTF8 data will be placed in this new field in order to preserve the non-UTF8 data. Use of this feature requires 1.10+ apiserver and kubelets.

@k8s-ci-robot k8s-ci-robot added 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. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels Jan 6, 2018
@k8s-github-robot k8s-github-robot added the kind/api-change Categorizes issue or PR as related to adding, removing, or otherwise changing an API label Jan 6, 2018
@dims
Copy link
Member Author

dims commented Jan 6, 2018

New variation based on discussion in #57899

@dims
Copy link
Member Author

dims commented Jan 6, 2018

/assign @liggitt
/assign @thockin

@@ -4353,6 +4353,12 @@ func ValidateConfigMap(cfg *core.ConfigMap) field.ErrorList {
}
totalSize += len(value)
}
for key, value := range cfg.BinaryData {
for _, msg := range validation.IsConfigMapKey(key) {
allErrs = append(allErrs, field.Invalid(field.NewPath("binarydata").Key(key), key, msg))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

binaryData

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed!

@@ -4353,6 +4353,12 @@ func ValidateConfigMap(cfg *core.ConfigMap) field.ErrorList {
}
totalSize += len(value)
}
for key, value := range cfg.BinaryData {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also need to ensure there is no key duplication between data and binarydata maps

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see note from @smarterclayton here, there was an ask to remove that validation i believe:
9ba0da8#r100961600

Copy link
Member

@liggitt liggitt Jan 7, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm... allowing the same key in both data and binaryData seems buggy and undefined...

also, from #33549 (comment):

Needs a much more descriptive comment, including a description of the validation rules (must not overlap with data)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@smarterclayton can you please chime in?

@thockin
Copy link
Member

thockin commented Jan 7, 2018 via email

@dims dims force-pushed the add-binary-configmap branch 2 times, most recently from 8aaaee1 to 3b810dd Compare January 7, 2018 14:29
@dims
Copy link
Member Author

dims commented Jan 7, 2018

/test pull-kubernetes-verify
/test pull-kubernetes-bazel-test

@dims
Copy link
Member Author

dims commented Jan 8, 2018

What we have today is as follows

  • staging/src/k8s.io/api/core/v1/types.go:

    1. type ConfigMap struct
      • has field Data - which is a map of string to string
    2. type Secret struct
      • has field Data - which is a map of string to byte array
      • has write-only convenience field StringData - which is a map of string to string
      • has optional field Type - only possible value is "Opaque"
  • pkg/apis/core/types.go:

    1. type ConfigMap struct
      • has field Data - which is a map of string to string
    2. type Secret struct
      • has field Data - which is a map of string to byte array
      • has optional field Type

Proposal is to:

  • proposed field BinaryData to type ConfigMap (both spots) - which is a map of string to byte array, this will enable to functionality needed to save binary files using ConfigMap.

Problems still that need to be thought about:

  • Data field is different between Secret and ConfigMap, one takes map with byte array values and another takes string values. This is an existing problem, not introduced by this PR
  • with this PR we will have BinaryData in ConfigMap and StringData in ConfigMap (and Data in both!) which seems bad.
    1. Do we make sure both have BinaryData and StringData?
    2. In ConfigMap, we will have two buckets stored in etcd (Data and BinaryData), while in Secret, we have only one. Does it matter to the end user as long as we have validation rules that the buckets cannot have duplicate items?
  • Do we need a Type in ConfigMap to be consistent with Secret's Type?

Suggestions welcome!

( cc @thockin @liggitt @smarterclayton )

@liggitt
Copy link
Member

liggitt commented Jan 8, 2018

Do we make sure both have BinaryData and StringData?

I don't think so. The existing data field in Secret objects can express both binary and text content. I don't think the improved usability of representing text as text outweighs the loss of compatibility with old clients that wouldn't know about any new field.

In ConfigMap, we will have two buckets stored in etcd (Data and BinaryData), while in Secret, we have only one. Does it matter to the end user as long as we have validation rules that the buckets cannot have duplicate items?

the objects are fundamentally different today, and ConfigMap is less expressive than Secret. duplicating the same data in multiple fields won't work (see https://github.com/kubernetes/community/blob/master/contributors/devel/api_changes.md#backward-compatibility-gotchas - "A single feature/property cannot be represented using multiple spec fields in the same API version simultaneously")

I probably wouldn't try to harmonize the two types here. This change makes ConfigMap as expressive as Secret.

@dims
Copy link
Member Author

dims commented Jan 8, 2018

+1 @liggitt. i agree.

@roberthbailey roberthbailey removed their assignment Jan 8, 2018
@dims
Copy link
Member Author

dims commented Jan 9, 2018

/assign @smarterclayton

},
"binaryData": {
"type": "object",
"description": "Data contains the binary data. Each key must consist of alphanumeric characters, '-', '_' or '.'."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better description here, and improve the existing data description. binaryData contains configuration data that is not required to be UTF-8 and .... Describe how the two fields validate together. Describe why I would use one or the other.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@smarterclayton
Copy link
Contributor

I agree with Jordan's position - V2 can pick up the pieces, as long as validation is crisp, this is the best way I can see to add the feature without breaking old clients. The minor ugliness seems outweighed by the value in the config map.

I'd like to see the api description significantly improved so users understand when to use each, and understand that keys are exclusive. Improve both. Otherwise makes sense to do this change.

@dims
Copy link
Member Author

dims commented Jan 9, 2018

@smarterclayton @liggitt thanks for the guidance, looks like we are on the right track. will add validation, update description, add some tests over the next few days.

@dims
Copy link
Member Author

dims commented Jan 9, 2018

/hold

@k8s-ci-robot k8s-ci-robot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jan 9, 2018
@@ -4383,8 +4383,22 @@ type ConfigMap struct {

// Data contains the configuration data.
// Each key must consist of alphanumeric characters, '-', '_' or '.'.
// The value must be a string (UTF-8). If the value has byte
// sequences not in the UTF-8 range, please use the BinaryData field.
// The keys stored in Data should not overlap with the keys in
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

must not overlap

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -4383,8 +4383,22 @@ type ConfigMap struct {

// Data contains the configuration data.
// Each key must consist of alphanumeric characters, '-', '_' or '.'.
// The value must be a string (UTF-8). If the value has byte
// sequences not in the UTF-8 range, please use the BinaryData field.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

values with non-UTF-8 byte sequences must use the binaryData field

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@dims
Copy link
Member Author

dims commented Jan 23, 2018

/retest

@dims
Copy link
Member Author

dims commented Jan 23, 2018

thanks @thockin i've added a comment and rebased the PR to latest master as well.

@k8s-github-robot k8s-github-robot removed the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Jan 23, 2018
@liggitt
Copy link
Member

liggitt commented Jan 23, 2018

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Jan 23, 2018
@dims
Copy link
Member Author

dims commented Jan 23, 2018

/test pull-kubernetes-e2e-kops-aws

1 similar comment
@dims
Copy link
Member Author

dims commented Jan 23, 2018

/test pull-kubernetes-e2e-kops-aws

@dims
Copy link
Member Author

dims commented Jan 25, 2018

@pmorie @saad-ali @thockin @matchstick - Can one of you please approve for "pkg/volume/configmap"? thanks!

@saad-ali
Copy link
Member

/lgtm
/approve

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: cblecker, dims, liggitt, saad-ali

Associated issue: #32432

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these OWNERS Files:

You can indicate your approval by writing /approve in a comment
You can cancel your approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jan 26, 2018
@k8s-github-robot
Copy link

/test all [submit-queue is verifying that this PR is safe to merge]

@dims
Copy link
Member Author

dims commented Jan 26, 2018

/test pull-kubernetes-unit

@k8s-github-robot
Copy link

/test all [submit-queue is verifying that this PR is safe to merge]

@k8s-github-robot
Copy link

Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions here.

@k8s-github-robot k8s-github-robot merged commit 27d01b5 into kubernetes:master Jan 26, 2018
@@ -148,7 +148,7 @@ not their metadata (e.g. the Data of a ConfigMap, but nothing in ObjectMeta).
obj interface{}
expect int
}{
{"ConfigMap", v1.ConfigMap{}, 3},
{"ConfigMap", v1.ConfigMap{}, 4},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't you have also updated the hash function to include the new binary data field in the hash? @liggitt @dims

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/api-change Categorizes issue or PR as related to adding, removing, or otherwise changing an API lgtm "Looks good to me", indicates that a PR is ready to be merged. 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.

Enable ConfigMaps to store binary files as well as character files.