下面有一个游戏,我试图在回调插件中获取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' }}
而非扩展/已解决的值。
一般情况下,是否有一种简洁的方法来获取所有播放属性的集合,其中包含剧本中定义的已解析值?
答案 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
)