【问题标题】:How to get current hostname from Ansible module?如何从 Ansible 模块获取当前主机名?
【发布时间】:2020-01-22 10:31:46
【问题描述】:

我正在开发自定义 Ansible 模块来控制 Vagrant 控制多个 VM 服务器上的多个 VM 节点,遵循指南 https://docs.ansible.com/ansible/latest/dev_guide/developing_modules_general.html。据我了解,Ansible 遍历所有指定的目标主机并在它们上执行run_module,允许在每个主机上执行module.run_command

但我需要知道我正在哪个主机上执行当前命令。我可以将remote_host={{ inventory_hostname }} 添加到MODULE_ARGS-a 选项ansible),然后以module.params['remote_host'] 访问它,但这不是很方便。有没有其他方法可以直接从 Ansible 模块 Python 代码中获取主机名?

【问题讨论】:

    标签: ansible


    【解决方案1】:

    调查了这个问题,在互联网上搜索,文档(如果你扩展 Ansible 而不仅仅是使用,那真的不是很好)和 Ansible 源代码,我自己找到了答案。

    完全来自模块 - 这是不可能的。模块在远程主机上执行,无法访问此类信息。但是为了执行这个插件,可以使用,准确地说是动作插件。有关他们的基本信息,请访问https://docs.ansible.com/ansible/latest/dev_guide/developing_plugins.html

    动作插件就像模块执行的包装器,与之相反,它们在控制主机上执行,而不是在远程主机上执行。

    例如,这样的演示插件会将一些关于执行环境的信息附加到我的自定义vagrant 模块输出中(但在这个示例模块中并不重要,它可以是任何,我们只讨论执行环境信息):

    #!/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

    如果你使用 Ansible 命令ansible 192.168.3.2 -m vagrant -a '...' -u vbox --ask-pass -i hosts-a 参数是我自定义模块特有的,没关系质疑和省略)输出将如下:

    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)。

    注意 - Ansible 应该知道您的自定义模块和插件的路径。为此,我将环境变量 ANSIBLE_LIBRARY 用于我的模块,将ANSIBLE_ACTION_PLUGINS 用于我的动作插件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-02-16
      • 2012-11-05
      • 2013-09-04
      • 1970-01-01
      • 2017-02-10
      • 2019-09-14
      • 2021-06-10
      相关资源
      最近更新 更多