Skip to content

client-go/util/jsonpath: resolve #16707 by outputting json for non-primitive types #89660

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

Merged

Conversation

pjferrell
Copy link
Contributor

@pjferrell pjferrell commented Mar 30, 2020

What type of PR is this?
/kind bug

What this PR does / why we need it:
When printing JSONPATH results, this changes the display format of non-primitive types from Go-syntax to JSON. This improves readability for maps/slices and simplifies processing outputs in other tools.

Which issue(s) this PR fixes:

Fixes #16707
Fixes #67268

Special notes for your reviewer:

Does this PR introduce a user-facing change?:

jsonpath support in kubectl / client-go serializes complex types (maps / slices / structs) as json instead of Go-syntax.

Additional documentation e.g., KEPs (Kubernetes Enhancement Proposals), usage docs, etc.:


@k8s-ci-robot k8s-ci-robot added release-note Denotes a PR that will be considered when it comes time to generate release notes. do-not-merge/invalid-commit-message Indicates that a PR should not merge because it has an invalid commit message. kind/bug Categorizes issue or PR as related to a bug. size/S Denotes a PR that changes 10-29 lines, ignoring generated files. labels Mar 30, 2020
@k8s-ci-robot
Copy link
Contributor

Thanks for your pull request. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please follow instructions at https://git.k8s.io/community/CLA.md#the-contributor-license-agreement to sign the CLA.

It may take a couple minutes for the CLA signature to be fully registered; after that, please reply here with a new comment and we'll verify. Thanks.


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/test-infra repository. I understand the commands that are listed here.

@k8s-ci-robot k8s-ci-robot added cncf-cla: no Indicates the PR's author has not signed the CNCF CLA. needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. needs-priority Indicates a PR lacks a `priority/foo` label and requires one. labels Mar 30, 2020
@k8s-ci-robot
Copy link
Contributor

Welcome @pjferrell!

It looks like this is your first PR to kubernetes/kubernetes 🎉. Please refer to our pull request process documentation to help your PR have a smooth ride to approval.

You will be prompted by a bot to use commands during the review process. Do not be afraid to follow the prompts! It is okay to experiment. Here is the bot commands documentation.

You can also check if kubernetes/kubernetes has its own contribution guidelines.

You may want to refer to our testing guide if you run into trouble with your tests not passing.

If you are having difficulty getting your pull request seen, please follow the recommended escalation practices. Also, for tips and tricks in the contribution process you may want to read the Kubernetes contributor cheat sheet. We want to make sure your contribution gets all the attention it needs!

Thank you, and welcome to Kubernetes. 😃

@k8s-ci-robot k8s-ci-robot added the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label Mar 30, 2020
@k8s-ci-robot
Copy link
Contributor

Hi @pjferrell. Thanks for your PR.

I'm waiting for a kubernetes member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

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/test-infra repository.

@k8s-ci-robot k8s-ci-robot requested review from sttts and yliaog March 30, 2020 18:21
@k8s-ci-robot k8s-ci-robot added sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. and removed needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. labels Mar 30, 2020
@pjferrell pjferrell force-pushed the kubectl-jsonpath-nonprimitive-types branch from b4d3a0b to 631cd15 Compare March 30, 2020 18:22
@k8s-ci-robot k8s-ci-robot added cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. and removed cncf-cla: no Indicates the PR's author has not signed the CNCF CLA. labels Mar 30, 2020
@pjferrell pjferrell force-pushed the kubectl-jsonpath-nonprimitive-types branch from 631cd15 to eac9368 Compare March 30, 2020 18:27
@k8s-ci-robot k8s-ci-robot removed the do-not-merge/invalid-commit-message Indicates that a PR should not merge because it has an invalid commit message. label Mar 30, 2020
@pjferrell
Copy link
Contributor Author

/assign @smarterclayton

@brianpursley
Copy link
Member

/ok-to-test

@k8s-ci-robot k8s-ci-robot added ok-to-test Indicates a non-member PR verified by an org member that is safe to test. and removed needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Apr 12, 2020
@brianpursley
Copy link
Member

Hi @pjferrell
Thanks for the PR.

if you edit your original message to change Fixes # 16707 to Fixes #16707 (remove the space) it will turn that into a link to the issue which will help the reviewers.

var text []byte
var err error
if r.Kind() == reflect.Interface && (r.Elem().Kind() == reflect.Map ||
r.Elem().Kind() == reflect.Slice || r.Elem().Kind() == reflect.Struct) {
Copy link
Member

@brianpursley brianpursley Apr 12, 2020

Choose a reason for hiding this comment

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

Do you want this change to apply for slice and struct? I thought the issue was only about map. I guess I would need to see some unit tests around those types to understand how the output would be different. (By the way, I'm not saying this is wrong, just unsure what the effect is)

Copy link
Contributor Author

@pjferrell pjferrell Apr 13, 2020

Choose a reason for hiding this comment

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

Based on the comments in #16707 (@thockin last comment and others), it appeared favorable to address all non-primitive types which could be represented by json. Go-style output of structs does not contain attribute/key names and slices are printed without comma separators, which makes passing these outputs to other tools more difficult.

Copy link
Contributor Author

@pjferrell pjferrell Apr 13, 2020

Choose a reason for hiding this comment

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

The current test failure is an example jsonpath output where the slice was previously output is Go-style instead of json.

Expected was the old output, and actual is the proper json representation of the slice.

--- FAIL: TestTokenOutput (0.00s)
    --- PASS: TestTokenOutput/JSON_output (0.00s)
    --- PASS: TestTokenOutput/YAML_output (0.00s)
    --- PASS: TestTokenOutput/Go_template_output (0.00s)
    --- PASS: TestTokenOutput/text_output (0.00s)
    --- FAIL: TestTokenOutput/jsonpath_output (0.00s)
        token_test.go:449: failed TestTokenOutput:
            
            expected:
            abcdef.1234567890123456 [system:bootstrappers:kubeadm:default-node-token]
            
            actual:
            abcdef.1234567890123456 ["system:bootstrappers:kubeadm:default-node-token"]

This test case was fixed and added to commit.

Copy link
Member

@brianpursley brianpursley Apr 13, 2020

Choose a reason for hiding this comment

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

Can you add a unit test to cover the slice and struct scenarios?
Something like this might work to cover both (slice with multiple structs):

{range .items[1]}{.status.addresses} {end}

I'm just thinking it will be good to have this to show the expected output and prevent any future regression.

Copy link
Contributor Author

@pjferrell pjferrell Apr 15, 2020

Choose a reason for hiding this comment

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

I've added several test cases for slices of each primitive type.

@brianpursley
Copy link
Member

/retest

@pjferrell pjferrell force-pushed the kubectl-jsonpath-nonprimitive-types branch from eac9368 to 1c6352a Compare April 13, 2020 06:20
@neolit123
Copy link
Member

neolit123 commented Apr 15, 2020

/approve
for cmd/kubeadm

/area kubectl
/priority backlog
(backlog, given this has been an issue for a while)

@k8s-ci-robot k8s-ci-robot added area/kubectl priority/backlog Higher priority than priority/awaiting-more-evidence. and removed needs-priority Indicates a PR lacks a `priority/foo` label and requires one. labels Apr 15, 2020
@pjferrell pjferrell force-pushed the kubectl-jsonpath-nonprimitive-types branch from d657a1c to f092c38 Compare April 16, 2020 10:21
@lavalamp
Copy link
Member

/assign

@lavalamp
Copy link
Member

As long as this is a client-side change, which it seems to be, I'm fine with it (thanks for all the tests). I think someone from SIG CLI should sign off on it, then I'm happy to approve for the api machinery OWNERs files.

/assign @pwittrock @seans3 @apelisse

@pjferrell
Copy link
Contributor Author

pjferrell commented Apr 28, 2020

@lavalamp It does change the default output behavior for complex objects to json instead of go-syntax. IMO it would be a positive change, but it could break a script expecting go-style output ("1 2 3" vs "[1,2,3]"). I fixed all kubernetes test cases (3) that used the go-style output.

CRD AdditionalPrinter columns would be affected if the path specified by user points to a struct/map/slice.

The cli flag provides an output option to display a json slice of results (consistent with how other jsonpath implementations output).

@lavalamp
Copy link
Member

lavalamp commented Apr 28, 2020 via email

@apelisse
Copy link
Member

I see a couple of comments from informed people that make sense to me:

From #33890 (comment):

Single values are used to provide lists of arguments. Changing the format would break all scripts using it.

The printing of complex values is a bug, and can be fixed.

From #33890 (comment):

The go type dumps are borderline useless. We can either say JSON or we can
define our own format.

@lavalamp
Copy link
Member

/approve
/lgtm

OK that's good enough for me

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Apr 28, 2020
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: lavalamp, neolit123, pjferrell

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

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel 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 Apr 28, 2020
@pjferrell
Copy link
Contributor Author

/retest

@k8s-ci-robot k8s-ci-robot merged commit 0c3c2cd into kubernetes:master Apr 29, 2020
@k8s-ci-robot k8s-ci-robot added this to the v1.19 milestone Apr 29, 2020
@thockin
Copy link
Member

thockin commented May 15, 2020

This is awesome!

Now how do I format a JSON list without a trailing comma?

kubectl get nodes -o jsonpath='{"{"}{range .items[*]}"{.metadata.name}": {.metadata.labels},{end}{"}"}' | jq .
parse error: Expected another key-value pair at line 1, column 1582

:P

@brianpursley
Copy link
Member

brianpursley commented May 15, 2020

Its probably not what you're looking for, but you could use sed to remove it...

kubectl get nodes -o jsonpath='{"{"}{range .items[*]}"{.metadata.name}": {.metadata.labels},{end}{"}"}' | sed 's/\(.*\),/\1/' | jq

Are you thinking there should be some kind of conditional rendering? ...maybe some new thing like {separator ","} that conditionally renders only when it is a separating range iterations?

Is jsonpath an actual spec?

Also, if it were able to render \b, then you could add a \b after the {end} to "backspace away" the last comma. A little hacky but might be a simple way to do it if it actually worked.

@lavalamp
Copy link
Member

lavalamp commented May 15, 2020

IMO just use jq if you want to do that, it's much simpler.

To do it without jq, I would do something exceedingly stupid, e.g.

$ echo "[x,y,]" | (head -c -3; echo "]")
[x,y]

@lavalamp
Copy link
Member

I haven't tested it but a jq script should look something like this:

jq '[.items[*] | {.metadata.name, .metadata.labels}]'

(Yes, I feel guilty for being this nerdy about jq)

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. area/kubeadm area/kubectl cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/bug Categorizes issue or PR as related to a bug. lgtm "Looks good to me", indicates that a PR is ready to be merged. ok-to-test Indicates a non-member PR verified by an org member that is safe to test. priority/backlog Higher priority than priority/awaiting-more-evidence. release-note Denotes a PR that will be considered when it comes time to generate release notes. sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. sig/cli Categorizes an issue or PR as relevant to SIG CLI. sig/cluster-lifecycle Categorizes an issue or PR as relevant to SIG Cluster Lifecycle. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet