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

Runtime type checks of Unstructured content #55297

Closed
wants to merge 1 commit into from

Conversation

ash2k
Copy link
Member

@ash2k ash2k commented Nov 8, 2017

What this PR does / why we need it:
Adds a flag that can be enabled via UNSTRUCTURED_INVALID_TYPE_DETECTOR environment variable to do strict type checks in Unstructured code. It can be used in unit and integration tests to catch bugs. This is similar to existing flags:

DefaultConverter = NewConverter(parseBool(os.Getenv("KUBE_PATCH_CONVERSION_DETECTOR")))

and
mutationDetectionEnabled, _ = strconv.ParseBool(os.Getenv("KUBE_CACHE_MUTATION_DETECTOR"))

Special notes for your reviewer:
This is a follow up for #51940. I don't know how to enable this in unit, integration tests (also when run via Bazel). Any ideas?

Release note:

NONE

/kind feature
/sig api-machinery
/assign @sttts

@k8s-ci-robot k8s-ci-robot added release-note-none Denotes a PR that doesn't merit a release note. kind/feature Categorizes issue or PR as related to a new feature. sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Nov 8, 2017
@k8s-github-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: ash2k
We suggest the following additional approver: sttts

Assign the PR to them by writing /assign @sttts in a comment when ready.

Associated issue: 51940

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 cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label Nov 8, 2017
@@ -99,6 +122,9 @@ func NestedInt64(obj map[string]interface{}, fields ...string) (int64, bool) {
return 0, false
}
i, ok := val.(int64)
if !ok && invalidTypeDetectionEnabled {
Copy link
Contributor

Choose a reason for hiding this comment

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

My understanding of the bool in the return values is to allow this situation. It's a bit strange to panic.

@sttts
Copy link
Contributor

sttts commented Nov 8, 2017

Why not check the types on all the setters and every code path which creates an Unstructured. Then we get caller which is responsible for wrong types. If everything "incoming" is type-correct, we don't have to check in the getters.

@@ -183,6 +231,9 @@ func setNestedFieldNoCopy(obj map[string]interface{}, value interface{}, fields
if valMap, ok := val.(map[string]interface{}); ok {
m = valMap
} else {
if invalidTypeDetectionEnabled {
Copy link
Contributor

Choose a reason for hiding this comment

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

do we do deep type checking? We should, go recursively go into the map[string]interface{}, compare the deepcopy func.

@mbohlool
Copy link
Contributor

mbohlool commented Nov 9, 2017

/cc @lavalamp

@lavalamp
Copy link
Member

lavalamp commented Nov 9, 2017

I am terrified by having test code that gets compiled into production binaries. It's also not obvious to me that things that trigger this would definitely be errors.

@sttts
Copy link
Contributor

sttts commented Nov 10, 2017

It's also not obvious to me that things that trigger this would definitely be errors.

We have a strict implicit typing of the content in Unstructured. The algorithms like deepcopy and serialization depend on that and fall over or worse, return inconsistent results. These are errors. If we don't find them in tests, we will hit them in production. We can choose: add additional type-checking in unit or integration tests (not in e2e, so e2e will be exactly like production) or live with the uncertainity that we never checked the types.

@sttts
Copy link
Contributor

sttts commented Nov 13, 2017

/ok-to-test

@k8s-ci-robot k8s-ci-robot removed the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label Nov 13, 2017
@ash2k
Copy link
Member Author

ash2k commented Nov 15, 2017

Why not check the types on all the setters and every code path which creates an Unstructured. Then we get caller which is responsible for wrong types. If everything "incoming" is type-correct, we don't have to check in the getters.

@sttts You are right, this should be enough and we already do that - for any slice/map/interface{} data we do a deep copy which checks types recursively. This code was more to catch issues introduced by putting invalid types directly into Object field of an Unstructured. If we don't care about that this PR is not needed. I'm ok to close it, no problem.
I have checked (briefly) existing k/k code that uses the Object field and only found one issue in a test.

"ownerReferences": []map[string]string{

This should be

"ownerReferences": []interface{}{
	map[string]interface{}{
		// ...
	},
},

However I'd like to keep some cleanups from this PR - can submit another one if we decide this one is not needed.

@sttts
Copy link
Contributor

sttts commented Nov 15, 2017

for any slice/map/interface{} data we do a deep copy which checks types recursively.

but we don't panic on type-error, but should probably.

Yes, please keep the cleanups!

@ash2k
Copy link
Member Author

ash2k commented Nov 15, 2017

for any slice/map/interface{} data we do a deep copy which checks types recursively.

but we don't panic on type-error, but should probably.

What do you mean? We do panic in json deep copy:

@sttts
Copy link
Contributor

sttts commented Nov 16, 2017

What do you mean? We do panic in json deep copy:

right, so every code path with SetNestedField at the end is fine. We have SetNestedSlice and SetNestedMap which do not deepcopy. But if my Gogland is right, they are not used. Can we remove them?

@ash2k
Copy link
Member Author

ash2k commented Nov 16, 2017

Both of them just delegate to SetNestedField(). So they do deep copy.

func SetNestedMap(obj map[string]interface{}, value map[string]interface{}, fields ...string) bool {
return SetNestedField(obj, value, fields...)
}

func SetNestedSlice(obj map[string]interface{}, value []interface{}, fields ...string) bool {
return SetNestedField(obj, value, fields...)
}

@sttts
Copy link
Contributor

sttts commented Nov 16, 2017

Both of them just delegate to SetNestedField(). So they do deep copy.

Right, should take some more time reviewing this or change my glasses :) Then we are on the safe side. Good!

@ash2k ash2k mentioned this pull request Nov 19, 2017
k8s-github-robot pushed a commit that referenced this pull request Nov 20, 2017
Automatic merge from submit-queue (batch tested with PRs 55615, 56010, 55990). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

Unstructured cleanups

**What this PR does / why we need it**:
Cleanups for `Unstructured`/`UnstructuredList` extracted from #55297.

**Release note**:
```release-note
NONE
```
/sig api-machinery
/kind enhancement
/assign @sttts
@k8s-github-robot
Copy link

@ash2k 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 Nov 21, 2017
@ash2k
Copy link
Member Author

ash2k commented Nov 27, 2017

Most of the checks have been incorporated into #55168. I'm closing this PR, at least for now. Please reopen if this functionality is needed.

@ash2k ash2k closed this Nov 27, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/feature Categorizes issue or PR as related to a new feature. needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. release-note-none Denotes a PR that doesn't merit a release note. sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. 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.

None yet

6 participants