如何从 Ansible 模块获取当前主机名? [英] How to get current hostname from Ansible module?

查看:49
本文介绍了如何从 Ansible 模块获取当前主机名?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在按照指南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?

推荐答案

调查了这个问题,在互联网上搜索,文档(如果你是扩展 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 插件就像是模块执行的包装器,与它们相反,它们在控制主机上执行,而不是在远程主机上执行.

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

这是演示代码,这里只是打印了所需的信息.如果需要在模块中使用它,那么 module_args 应该在 _execute_module 调用之前更新.

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_fileinventory_hostname(正是针对什么问题)和groups,它们正是我们需要的那些执行环境信息传入插件代码.例如 groups 字典只是解析库存文件信息,我在那里正好有两个组(ci_vm_serversci_vm_nodes)并且创建了两个组由 Ansible 提供并且是特殊的(allungrouped).

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆