简体   繁体   English

在回调插件中使用“ set_fact”获取事实集的值

[英]Get value of a fact set with 'set_fact' inside a callback plugin

Ansible 2.3 Ansible 2.3

I have a callback plugin which notifies an external service when a playbook is finished. 我有一个回调插件,当剧本完成时会通知外部服务。 During the play, this callback plugin collects different information like the play variables and error messages, which is sent with the HTTP request. 在播放期间,此回调插件会收集不同的信息,例如播放变量和错误消息,这些信息与HTTP请求一起发送。 Example: 例:

{
    "status": 1, 
    "activity": 270,
    "error": "Task xyz failed with message: failure message",
    "files": [ "a.txt", "b.cfg" ]
}

Some of this information comes from variables set during the play itself, it could be anything relevant for that play: the path to a file, a list of changed resources, etc. 这些信息中的一部分来自在播放过程中设置的变量,可能与该播放有关,包括文件的路径,更改的资源列表等。

Right now I'm doing something particularly ugly to collect what I need based on task names: 现在,我正在做一些特别丑陋的事情,以根据任务名称收集我需要的东西:

def v2_runner_on_ok(self, result):

    if result._task.action == 'archive':
        if result._task.name == 'Create archive foo':
            self.body['path'] = result._result['path']

    if result._task.action == 'ec2':
        if result._task.name == 'Start instance bar':
            self.body['ec2_id'] = result._result['id']

   # do it for every task which generates "interesting" info

Obviously this doesn't scale and breaks if the task name changes. 显然,如果任务名称更改,此操作将无法缩放并中断。

To keep it generic I've been thinking about agreeing on a fact name, say add_to_body , which would be added to the body dictionary whenever it exists. 为了保持通用性,我一直在考虑就事实名称达成一致,例如add_to_body ,只要存在,它将被添加到body字典中。 I like this approach because it's particularly easy to register a couple of variables during the play and use them to assemble a fact at the end of a play. 我喜欢这种方法,因为在播放过程中注册几个变量并在播放结束时使用它们来组合一个事实特别容易。 Example: 例:

---

- name: Demo play
  hosts: localhost
  gather_facts: False

  tasks:

    - name: Create temporary file 1
      tempfile:
        path: '/tmp'
      register: reg_tmp_1

    - name: Create temporary file 2
      tempfile:
        path: '/tmp'
      register: reg_tmp_2

    - name: Set add_to_body fact
      set_fact:
        add_to_body: "{{ { 'reg_tmp_1': reg_tmp_1.path,
                           'reg_tmp_2': reg_tmp_2.path } }}"

    - debug: var=add_to_body

However I can't find a way to access the value of a fact after a set_fact action, neither by looking at the result object nor by trying to access the hostvars for the current host (which is apparently not possible inside a callback plugin ). 但是,我无法找到一种方法来通过set_fact操作访问事实的值,既set_fact查看result对象,也set_fact尝试访问当前主机的hostvars来实现(这显然在回调插件中不可能的 )。

What would you suggest to work around this limitation? 您建议如何解决此限制?

Hmm, you mix some things in here. 嗯,你在这里混一些东西。
If you want to call API in v2_runner_on_ok after each task, you should handle add_to_body in task context. 如果要在每个任务之后在v2_runner_on_ok调用API,则应在任务上下文中处理add_to_body
But in your example you set add_to_body after several tasks – this way you'd better write action plugin (eg send_to_my_service ) and call it instead of set_fact with required parameters. 但是在您的示例中,您在完成多个任务之后设置了add_to_body这样,您最好编写动作插件(例如send_to_my_service )并调用它,而不是使用必需的参数调用set_fact

Here's example how you can use add_to_body in task context: 这是在任务上下文中如何使用add_to_body的示例:

---
- hosts: localhost
  gather_facts: no

  tasks:
    - command: echo hello world
      vars:
        add_to_body:
          - path
    - file:
        dest: /tmp/zzz
        state: touch
      vars:
        add_to_body:
          - dest

Callback: 打回来:

def v2_runner_on_ok(self, result):
    if 'add_to_body' in result._task.vars:
        res = dict()
        for i in result._task.vars['add_to_body']:
            if i in result._result:
                res[i] = result._result[i]
            else:
                display.warning('add_to_body: asked to add "{}", but property not found'.format(i))
        display.v(res)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM