Ansible ad-hoc命令按键或属性过滤JSON输出 [英] Ansible ad-hoc command filter JSON output by key or property

查看:223
本文介绍了Ansible ad-hoc命令按键或属性过滤JSON输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想过滤即席Ansible命令的JSON输出-例如获取多台主机的一长串"事实",并仅显示一个可能是几个级别,例如ansible_lsb.description,因此我可以快速比较它们正在运行的软件版本,检查准确的时间或时区,等等.

I'd like to filter the JSON output of ad-hoc ansible commands - e.g. grab the long list of "facts" for multiple hosts, and show only one that could be several levels deep, such as ansible_lsb.description, so I can quickly compare what versions of software they're running, check accurate times or timezones, whatever.

这有效:

ansible myserver -m setup -a 'filter=ansible_lsb'
myserver | SUCCESS => {
    "ansible_facts": {
        "ansible_lsb": {
            "codename": "wheezy",
            "description": "Debian GNU/Linux 7.11 (wheezy)",
            "id": "Debian",
            "major_release": "7",
            "release": "7.11"
        }
    },
    "changed": false
}

但是,由于设置模块文档状态,过滤器选项仅过滤ansible_facts下方的第一级子项",因此失败:

However, as the setup module docs state, "the filter option filters only the first level subkey below ansible_facts", so this fails:

ansible myserver -m setup -a 'filter=ansible_lsb.description'
myserver | SUCCESS => {
    "ansible_facts": {},
    "changed": false
}

(尽管仅供参考,您也可以在其他地方使用点符号,例如任务的

(though for reference, you can use dot notation in other places such as a task's when conditional)

有没有一种方法可以在显示输出之前过滤JSON密钥?

Is there a way to filter the JSON keys before the output is displayed?

推荐答案

标准setup模块只能对顶级"事实应用过滤器.

Standard setup module can apply filter only on "top-level" facts.

要实现所需的功能,可以使用名称为setup的动作插件来应用自定义过滤器.

To achieve what you want, you can make an action plugin with setup name to apply custom filters.

工作示例./action_plugins/setup.py:

from ansible.plugins.action import ActionBase

class ActionModule(ActionBase):

    def run(self, tmp=None, task_vars=None):

        def lookup(obj, path):
            return reduce(dict.get, path.split('.'), obj)

        result = super(ActionModule, self).run(tmp, task_vars)

        myfilter = self._task.args.get('myfilter', None)

        module_args = self._task.args.copy()
        if myfilter:
            module_args.pop('myfilter')

        module_return = self._execute_module(module_name='setup', module_args=module_args, task_vars=task_vars, tmp=tmp)

        if not module_return.get('failed') and myfilter:
            return {"changed":False, myfilter:lookup(module_return['ansible_facts'], myfilter)}
        else:
            return module_return

它调用原始的setup模块剥离myfilter参数,然后如果任务没有失败并且设置了myfilter,则通过简单的reduce实现过滤结果.查找功能非常简单,因此它不适用于列表,仅适用于对象.

It calls original setup module stripping myfilter parameter, then filters result with simple reduce implementation if task is not failed and myfilter is set. Lookup function is very simple, so it will not work with lists, only with objects.

结果:

$ ansible myserver -m setup -a "myfilter=ansible_lsb.description"
myserver | SUCCESS => {
    "ansible_lsb.description": "Ubuntu 12.04.4 LTS",
    "changed": false
}

这篇关于Ansible ad-hoc命令按键或属性过滤JSON输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆