Ansible回调插件:如何通过扩展变量来获取播放属性值?

时间:2017-09-20 11:27:20

标签: ansible

下面有一个游戏,我试图在回调插件中获取remote_user属性的已解析值。

- name:          test play
  hosts:         "{{ hosts_pattern }}"
  strategy:      free
  gather_facts:  no
  remote_user:   "{{ my_remote_user if my_remote_user is defined else 'default_user' }}"
  tasks:
     - name:     a test task
       shell:    whoami && hostname

我目前正在访问play字段属性,如下所示:

 def v2_playbook_on_play_start(self, play):
     self._play_remote_user = play.remote_user

我还尝试在v2_playbook_on_task_start内保存remote_user以查看是否可行,this is where the templated task name is made available

def v2_playbook_on_task_start(self, task, is_conditional):
    self._tasks[task._uuid].remote_user = task.remote_user
    self._tasks[task._uuid].remote_user_2 = task._get_parent_attribute('remote_user')

但是,上述所有情况都会给我{{ my_remote_user if my_remote_user is defined else 'default_user' }}而非扩展/已解决的值。

一般情况下,是否有一种简洁的方法来获取所有播放属性的集合,其中包含剧本中定义的已解析值?

3 个答案:

答案 0 :(得分:1)

我认为没有一种简单的方法可以实现这一目标。

PlayContext在task_executor here中被模板化 在所有回调方法都已通知后,就会发生这种情况 因此,您应该手动使用Templar类(但我不确定您是否可以获得正确的变量上下文以使其正常工作)。

答案 1 :(得分:0)

信用证明康斯坦丁的提示是使用Templar类。

我想出了一个Ansible 2.3.1的解决方案 - 不完全确定它是否是最佳的,但似乎可以工作。这是一个示例代码:

from ansible.plugins.callback import CallbackBase
from ansible.template import Templar
from ansible.plugins.strategy import SharedPluginLoaderObj

class CallbackModule(CallbackBase):
    CALLBACK_VERSION = 2.0
    CALLBACK_TYPE = 'notification'
    CALLBACK_NAME = 'your_name'

    def __init__(self):
        super(CallbackModule, self).__init__()
        # other shenanigans

    def v2_playbook_on_start(self, playbook):
        self.playbook = playbook

    def v2_playbook_on_play_start(self, play):
        self.play = play


    def _all_vars(self, host=None, task=None):
        # host and task need to be specified in case 'magic variables' (host vars, group vars, etc) need to be loaded as well
        return self.play.get_variable_manager().get_vars(
            loader=self.playbook.get_loader(),
            play=self.play,
            host=host,
            task=task
        )

    def v2_runner_on_ok(self, result):
        templar = Templar(loader=self.playbook.get_loader(),
                  shared_loader_obj=SharedPluginLoaderObj(),
                  variables=self._all_vars(host=result._host, task=result._task))

        remote_user = templar.template(self.play.remote_user)
        # do something with templated remote_user

答案 2 :(得分:0)

对于操作插件而言,非常容易。
ActionBase类已经具有模板和加载器属性。 可以遍历task_vars并使用Templar.template

呈现所有内容
for k in task_vars:
    new_module_args = merge_hash(
        new_module_args,
        {k: self._templar.template(task_vars.get(k, None))}
    )

并调用模块

        result = self._execute_module(
            module_name='my_module',
            task_vars=task_vars,
            module_args=new_module_args
        )