-
Notifications
You must be signed in to change notification settings - Fork 29
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 json parameter to get JSON output from ansible.command* #11
base: master
Are you sure you want to change the base?
Conversation
Thanks for the PR. As noted in Slack discussion, while for This will help us to further support the pack, instead of adding modify/parse layers on top of stdout where the correct result is not guaranteed. So I'm more about addressing this in upstream. |
So, long term in stackstorm we shouldn't be depending on the ansible callback plugin to continue using stdout. Perhaps that means that we don't mess with the ansible-playbook until the change is actually made. However, I don't want to wait for the same callback plugin with [1] ansible/ansible#17122 is linked to PR ansible/ansible#17448, which was closed because they don't want to guarantee clean machine parseable stdout output (quote from @mattclay in ansible/ansible#17122 (comment)):
|
b5eee72
to
edaad61
Compare
Hey, I just cleaned up the flake and lint warnings. What if I bagged/stashed the ansible-playbook changes, and made this PR focus only on |
I just trimmed this change so that it is only focused on |
I've tested this with:
Just getting stdout is still available via:
I'm going to add something about this to the readme. Other than that, what would it take to get this merged as 0.6.0? |
I think this is merge ready. |
Both this and #14 specify version 0.6.0. Whichever is merged second should change to 0.7.0 |
Quotes around the extra-vars JSON only make sense in a shell. Shells strip those quotes off and pass the whole thing in to the application. Ansible couldn't parse or understand the JSON with the quotes in place, so remove them and fix the tests accordingly.
This adds a json parameter to ansible.command and ansible.command_local. Using this parameter ensures that the stdout from a command is valid JSON. This is especially helpful to make variables/facts from the setup module (for example) available in an st2 workflow. To make this work, we depend on ansible's --tree parameter to save the output for each node in the 'tree' directory. We ignore all of ansible's stdout, and instead feed the contents of all of the tree/node files in one big json object (key is node name, and value is the output). Bump to 0.6.0 Signed-off-by: Jacob Floyd <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I appreciate the efforts, but won't merge this PR before we try the right way by providing fixes in Ansible upstream (as said before #11 (comment)).
We need to be more consistent in the official pack. In a meantime you can use your own st2 pack install https://github/your/pack
.
As a first step, I submitted PR to Ansible that fixed ANSIBLE_STDOUT_CALLBACK
in ansible ad-hoc: ansible/ansible#26098 which was merged really quick yesterday and backported to both 2.3
and 2.2
.
The next step would be adding missing functionality in json
callback plugin: https://github.com/ansible/ansible/blob/67eae347cd8c80c60c65435be9dbfb4530ea4548/lib/ansible/plugins/callback/json.py#L60 to make it work for ansible adhoc.
@cognifloyd I'd be glad if you can help with that.
Having desired functionality in upstream, from the stackstorm-ansible
pack I agree that adding new --json
param would be a good idea.
Hope that makes sense.
With ansible/ansible#32280, fixing the json callback plugin for adhoc command output makes sense. I didn't see a point before because @mattclay said that callbacks should be using files not stdout. ansible/ansible#32280, however shows an effort to clean up the stdout so we can actually rely on valid JSON in stdout, not just in files. @bcoca did warn, however, that:
So, we could filter out everything before the first "{" and return that as stdout (or something like that). But that little bit of "filtering", only required when verbose is enabled, should be easy enough to maintain. :) =========== As far as what has to be done to make the JSON callback work with ansible-adhoc (I'm making notes partially for my own benefit): This ansible/ansible#26098 (comment) points out at least one method that needs to be adjusted. Changing def v2_runner_on_ok(self, result, **kwargs):
host = result._host
self.results[-1]['tasks'][-1]['hosts'][host.name] = result._result (lines 58-60 of callback/json.py) The issue here is that it saves the results but never prints them out. Looking at
And it turns out (I had no idea!), that So, though it would be cool to include information in JSON output that is currently only mentioned in the In the future, it would be nice to extend it even further so that the |
OK. So the JSON callback can't do what we want because it would have to print a stream of objects instead of printing one object at the end of the run to work with adhoc commands. To remedy that, I submitted ansible/ansible#32304. Hopefully they accept it and get it in soon. Once that's in, I can follow up with JSON callback changes to support adhoc commands. |
@cognifloyd Cool thing! |
status update: So, we can use json callback with ansible ad-hoc commands now, but the stdout might not be parseable as other things in ansible also write messages directly to stdout. The upstream response so far is: Use intermediate files. That is what this PR did, use intermediate files. The ansible-runner might be a viable alternative to running |
This adds a
json
parameter toansible.command
andansible.command_local
.Using this parameter ensures that the stdout from a command is valid JSON.
This is especially helpful to make variables/facts from the setup module (for example)
available in an st2 workflow.
To make this work, we depend on ansible's
--tree
parameter to save the output foreach node in the 'tree' directory. We ignore all of ansible's stdout, and instead feed
the contents of all of the tree/node files in one big json object (key is node name, and
value is the output).