2016-10-21 3 views
0

Я хотел бы отфильтровать вывод JSON для ad-hoc-совместимых команд - например, возьмите длинный список «facts» для нескольких хостов и покажите только один, который может быть на несколько уровней, например ansible_lsb.description, поэтому я могу быстро сравнить, какие версии программного обеспечения они запускают, проверять точное время или время, независимо от того.Ansible ad-hoc командный фильтр JSON вывод по ключу или свойству

Это работает:

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 
} 

Однако, как setup module docs состояния "опционный фильтр фильтры только первый подраздел уровня ниже ansible_facts", так что это не удается:

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

(хотя для справки , вы можете использовать точечную нотацию в других местах, например when conditional)

Есть ли способ фильтровать ключи JSON до выхода ut отображается?

ответ

1

Модуль setup может применять фильтр только для фактов «верхнего уровня».

Чтобы достичь желаемого, вы можете создать плагин действий с именем setup для применения пользовательских фильтров.

Рабочий пример ./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 установлен. Функция поиска очень проста, поэтому она не будет работать со списками, только с объектами.

Результат:

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

Спасибо! Работает хорошо. –