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

make salt-api arg/kwarg handling the same as cli for all clients #50124

Closed
wants to merge 5 commits into from

Conversation

mattp-
Copy link
Contributor

@mattp- mattp- commented Oct 19, 2018

What does this PR do?

both cherrypy and saltnado now pass all args through parse_input to
allow for behavior equivalent to salt cli yaml based arg parsing. This
will allow for pepper to behave more like salt cli, or direct api users.

also included is a minor feature to saltnado/cherrypy, a new X-Salt-Version
header for usage in pepper to determine if this feature among others
is available to use.

What issues does this PR fix or reference?

will fix saltstack/pepper#99 when equivalent pepper changes are made.

Previous Behavior

yaml based foo=bar args are not passed through parse_input

New Behavior

args are passed through parse_input

Tests written?

yes

Commits signed with GPG?

No

Please review Salt's Contributing Guide for best practices.

See GitHub's page on GPG signing for more information about signing commits with GPG.

@ghost ghost self-requested a review October 19, 2018 00:01
both cherrypy and saltnado now pass all args through parse_input to
allow for behavior equivalent to salt cli yaml based arg parsing. This
will allow for pepper to behave more like salt cli, or direct api users.
@mattp-
Copy link
Contributor Author

mattp- commented Oct 19, 2018

@rallytime I notice you disabled one of the other saltnado tests for being too flaky, the one I've added is essentially the same. It's not clear to me what race condition was the problem, but we can turn this test off for now as well if you like.

Copy link
Contributor

@gtmanfred gtmanfred left a comment

Choose a reason for hiding this comment

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

looks like we just need some tests expected results updated for this change, and also pylint has one error, otherwise this looks perfect.

Thanks!
Daniel

@mchugh19
Copy link
Contributor

I'd suggest throwing something into the release notes as well. Modifying the args/kwargs handling of salt-api and the version header is a pretty large (and positive) change.

in order for pepper to have some way to determine whether features are
available or bugs are fixed in the master it is talking to, the version
needs to be exposed, this does that.
@mattp-
Copy link
Contributor Author

mattp- commented Oct 19, 2018

@gtmanfred ok, should have the tests/lint fixed up. will let jenkins chew on it for a bit
@mchugh19 seems reasonable, but i think generally the release note management is done by the release team when they cut releases, not in this PR :)

@gtmanfred
Copy link
Contributor

Nope, we do it in the PRs when we add features, it would be great to include this in the Neon release notes.

@mattp-
Copy link
Contributor Author

mattp- commented Oct 19, 2018

ah gotcha, added salt-api release notes to neon.rst

mattp- added a commit to bloomberg/pepper that referenced this pull request Oct 19, 2018
rather than attempting to deconstruct args locally to fully reproduce
the proper low state to pass to the api, we instead leave the kwargs as
is. The reason for this is the RunnerClient will deconstruct and
deserialize nested yaml args. We could equivalently do that locally but
it seems pepper tries to be a no-dependency dist so we just hand off the
work instead.

This PR partially depends on release of saltstack/salt#50124
to determine if a release is neon or newer; however, we can safely assume that if
the salt_version header is not provided in a request it is a salt-api
older than that.

Fixes saltstack#57
mattp- added a commit to bloomberg/pepper that referenced this pull request Oct 19, 2018
rather than attempting to deconstruct args locally to fully reproduce
the proper low state to pass to the api, we instead leave the kwargs as
is. The reason for this is the RunnerClient will deconstruct and
deserialize nested yaml args. We could equivalently do that locally but
it seems pepper tries to be a no-dependency dist so we just hand off the
work instead.

This PR partially depends on release of saltstack/salt#50124
to determine if a release is neon or newer; however, we can safely assume that if
the salt_version header is not provided in a request it is a salt-api
older than that.

Fixes saltstack#57
lowstate isn't necessarily a single dict, it can be a list of dicts.
_get_lowstate wasn't accounting for that properly.
@rallytime
Copy link
Contributor

@whiteinge Is this something you'd like to review?

@whiteinge
Copy link
Contributor

Thanks for the ping, @rallytime. This functionality should already be baked into Salt and I did not include this functionality in salt-api on purpose for the reasons described below. That said, I'll happily defer to the wishes of the core team and any contributors that want to put in the actual work. Please consider or disregard as you see fit.

Parsing the arg=val strings into kwargs is a central workflow in Salt and thus should live in a central place and work consistently regardless if you are calling Salt from the CLI, from a REST API, from a Python wrapper, HTML form fields, a Slack bot, and many, many other examples we've seen. The best central place to do that is Salt's Python API (LocalClient, RunnerClient, WheelClient, etc). That is what the above-linked Pepper issue is discussing. All those client interfaces should run the arg (singular) array values through the utils function we have that splits arg=val strings apart and parses the right-hand side of that as YAML. I know for certain this has worked correctly in the past for LocalClient and RunnerClient (I don't recall offhand where WheelClient stood), because I have used it many, many times and even wrote tests for some of it. However this functionality has also regressed more than once (again the Pepper discussion) and I can't speak to the current state of things.

def test_cmd_sync_arg_kwarg_parsing(self):
low = {
'client': 'runner',
'fun': 'test.arg',
'arg': [
'foo',
'bar=off',
'baz={qux: 123}'
],
'kwarg': {
'quux': 'Quux',
},
'quuz': 'on',
}
low.update(self.eauth_creds)
ret = self.runner.cmd_sync(low)
self.assertEqual(ret, {
'args': ['foo'],
'kwargs': {
'bar': False,
'baz': {
'qux': 123,
},
'quux': 'Quux',
'quuz': 'on',
},
})

IMO the best fix is to figure out how to prevent future regressions, to keep this functionality in the *client interfaces and to not to bake this into salt-api.

A concrete example of why this is best done in Salt instead of salt-api is this discussion about the Slack engine. A Slack bot would be accepting arg=val strings because people are typing them into a chat interface -- just like the CLI, just like webhooks, just like Pepper, just like HTML forms, etc. It would be ideal for any module type that goes through the Python API (not just the REST API which of course uses the Python API, just like all the other module types) to not have to reinvent this over and over.

It is easier to put this into salt-api, for sure, and fixing this (and avoiding future regressions) in core may be quite difficult indeed (#39472). But I do feel that is the better solution.

My $0.02. I sincerely wish whoever takes either path good luck and godspeed. 😄

@mattp-
Copy link
Contributor Author

mattp- commented Oct 24, 2018

@whiteinge thanks for chiming in, appreciate your input. I actually did start off with a separate PR to put parse_input in localclient directly (#49886), however after some chat with @cachedout / @terminalmage we were hesitant to put a change in localclient directly that manhandles args since its such a sensitive codepath (some tests surfaced expected behavior in the contrary). however if 'arg={yaml: foo}' is a documented behavior of localclient at the api layer, I think the original change makes sense, and we can change those tests.
That said, I don't call the shots on what goes into salt either :) I lean towards your proposal since runnerclient already works that way. Anyone else have any thoughts/decisions?

@rallytime
Copy link
Contributor

I agree with @whiteinge on this one. I wasn't aware of that history. Thanks for filling that in!

I am definitely curious what @cachedout and @terminalmage may have to say, given @whiteinge's explanation above.

@terminalmage terminalmage self-requested a review November 7, 2018 21:14
@terminalmage
Copy link
Contributor

I need to re-evaluate this, I did not see all the conversation here.

@mattp-
Copy link
Contributor Author

mattp- commented Nov 28, 2018

per slack convo with @terminalmage im going to close this in favor of #49886 once that is fixed up and ready for merge.

@mattp- mattp- closed this Nov 28, 2018
mattp- added a commit to bloomberg/pepper that referenced this pull request Mar 12, 2019
rather than attempting to deconstruct args locally to fully reproduce
the proper low state to pass to the api, we instead leave the kwargs as
is. The reason for this is the RunnerClient will deconstruct and
deserialize nested yaml args. We could equivalently do that locally but
it seems pepper tries to be a no-dependency dist so we just hand off the
work instead.

This PR partially depends on release of saltstack/salt#50124
to determine if a release is neon or newer; however, we can safely assume that if
the salt_version header is not provided in a request it is a salt-api
older than that.

Fixes saltstack#57
@mchugh19
Copy link
Contributor

WIth #49886 being merged, the release notes and X-Salt-Version header from this PR would still be very helpful and resolve part of #42491

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

pepper vs. salt has different test.arg_repr output types
6 participants