命令按键或属性过滤

命令按键或属性过滤

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

问题描述

我想过滤临时 ansible 命令的 JSON 输出 - 例如获取多台主机的facts"的长列表,并只显示一个可能是几个级别的深度,例如 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 输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-30 20:32