如何从Ansible模块获取当前主机名? [英] How to get current hostname from Ansible module?
问题描述
我正在按照指南 https://docs.ansible.com/ansible/latest/dev_guide/developing_modules_general.html .据我了解,Ansible遍历所有指定的目标主机并在它们上执行run_module
,从而允许在每个主机上执行module.run_command
.
I'm developing custom Ansible module to control Vagrant controlled multiple VM nodes on multiple VM servers following guide https://docs.ansible.com/ansible/latest/dev_guide/developing_modules_general.html. As far as I understand, Ansible iterates over all specified target hosts and executes run_module
on them, allowing to module.run_command
on each host.
但是我需要知道我正在哪台主机上执行当前命令.我可以将remote_host={{ inventory_hostname }}
添加到MODULE_ARGS
(ansible
的-a
选项),然后以module.params['remote_host']
的身份访问它,但这不是很方便.还有其他方法可以直接从Ansible模块Python代码获取主机名吗?
But I need to know on which host I am executing current command. I can add remote_host={{ inventory_hostname }}
to MODULE_ARGS
(-a
option of ansible
) and then access it as module.params['remote_host']
but it is not very convenient. Is there other way to get hostname directly from Ansible module Python code?
推荐答案
研究了该问题,在Internet中搜索了文档(如果您扩展Ansible而不是仅仅使用它,这的确不是很好)以及Ansible源代码并找到了答案独自一人.
Investigated the issue, searched in Internet, docs (it is really not very good if you are extending Ansible and not just using) and Ansible source code and found answer by myself.
完全来自模块-这是不可能的.模块在远程主机上执行,无法访问此类信息.但是要执行此插件,可以使用动作插件.有关它们的基本信息,请访问 https://docs.ansible.com/ansible/latest/dev_guide/developing_plugins.html .
Exactly from module - it is impossible. Modules are executed on remote hosts and have no access to such information. But to perform this plugins could be used, action plugins to be precise. Basic info about them is available at https://docs.ansible.com/ansible/latest/dev_guide/developing_plugins.html.
动作插件就像模块执行的包装器,相反,它们是在控制主机上执行的,而不是在远程主机上执行的.
Action plugins are like wrappers to modules execution and in contrast to them are executed on control host, not on remote ones.
例如,此类演示插件会将一些有关执行环境的信息附加到我的自定义vagrant
模块输出中(但在此示例模块中,这无关紧要,可以是任意的,我们仅讨论执行环境信息):
For example such demo plugin will append some info about execution environment to my custom vagrant
module output (but in this example module does not matter, it could be any, we are discussing only execution environment info):
#!/usr/bin/python3
from ansible.plugins.action import ActionBase
class ActionModule(ActionBase):
def run(self, tmp=None, task_vars=None):
super(ActionModule, self).run(tmp, task_vars)
module_args = self._task.args.copy()
module_return = self._execute_module(module_name='vagrant',
module_args=module_args,
task_vars=task_vars,
tmp=tmp)
module_return['ansible_facts']['inventory_file'] = str(task_vars['inventory_file'])
module_return['ansible_facts']['inventory_hostname'] = str(task_vars['inventory_hostname'])
module_return['ansible_facts']['groups'] = str(task_vars['groups'])
return module_return
这是演示代码,此处仅打印所需的信息.如果需要在模块中使用它,则应在_execute_module
调用之前更新module_args
.
This is demo code, here desired info is just printed. If it is needed to use it in module then module_args
should be updated before _execute_module
call.
如果您使用Ansible命令ansible 192.168.3.2 -m vagrant -a '...' -u vbox --ask-pass -i hosts
(-a
参数特定于我的自定义模块,则无所谓并省略)输出将如下所示:
If you use Ansible command ansible 192.168.3.2 -m vagrant -a '...' -u vbox --ask-pass -i hosts
(-a
arguments are specific to my custom module, does not matter to question and omitted) output will be as follows:
192.168.3.2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python",
"groups": "{'all': ['192.168.3.1', '192.168.3.2', '192.168.3.3', '192.168.3.5', '192.168.3.6', '192.168.3.7', '192.168.3.11', '192.168.3.12', '192.168.3.21', '192.168.3.22', '192.168.3.23', '192.168.3.24', '192.168.3.31', '192.168.3.32', '192.168.3.33', '192.168.3.34', '192.168.3.35', '192.168.3.36', '192.168.3.37', '192.168.3.38', '192.168.3.39', '192.168.3.30', '192.168.3.51', '192.168.3.52', '192.168.3.61', '192.168.3.62', '192.168.3.71', '192.168.3.72'], 'ungrouped': [], 'ci_vm_servers': ['192.168.3.1', '192.168.3.2', '192.168.3.3', '192.168.3.5', '192.168.3.6', '192.168.3.7'], 'ci_vm_nodes': ['192.168.3.11', '192.168.3.12', '192.168.3.21', '192.168.3.22', '192.168.3.23', '192.168.3.24', '192.168.3.31', '192.168.3.32', '192.168.3.33', '192.168.3.34', '192.168.3.35', '192.168.3.36', '192.168.3.37', '192.168.3.38', '192.168.3.39', '192.168.3.30', '192.168.3.51', '192.168.3.52', '192.168.3.61', '192.168.3.62', '192.168.3.71', '192.168.3.72']}",
"inventory_file": "/home/dvinokurov/work/Avigdor-ansible/tools/ansible/hosts",
"inventory_hostname": "192.168.3.2"
},
"changed": true,
"command": "up",
"message": "OK",
"node_index": "2",
"original_message": "Execute \"up\"",
"remote_host": "192.168.3.2"
}
这里最重要的是inventory_file
,inventory_hostname
(正是针对什么问题)和groups
,它们正是我们在插件代码中传递的那些执行环境信息.例如,groups
字典只是解析的清单文件信息,我在那里恰好有两个组(ci_vm_servers
和ci_vm_nodes
),两个组由Ansible创建并且很特殊(all
和ungrouped
).
Most important here are inventory_file
, inventory_hostname
(exactly for what question was) and groups
, they are exactly those execution environment info that we passed in plugin code. groups
dictionary for example is just parsed inventory file info, I've got exactly two groups there (ci_vm_servers
and ci_vm_nodes
) and two groups are created by Ansible and are special (all
and ungrouped
).
注意-Ansible应该知道自定义模块和插件的路径.为此,我将环境变量ANSIBLE_LIBRARY
用于模块,将ANSIBLE_ACTION_PLUGINS
用于操作插件.
Notice - Ansible should be aware of paths both to your custom modules and plugins. For that I used environment variable ANSIBLE_LIBRARY
for my modules and ANSIBLE_ACTION_PLUGINS
for my action plugins.
这篇关于如何从Ansible模块获取当前主机名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!