Ansible

时间:2015-09-01 05:26:44

标签: python postgresql sockets ansible ansible-playbook

有没有办法在Ansible group_vars文件或Ansible使用的Jinja2模板中将任意字符串解析为主机名?比方说,我想在global_vars/all中定义一个变量,该变量将包含www.google.com解析为的几个IP地址之一。在这个例子中,我使用www.google.com作为可以解析为多个IP地址的字符串的示例,但我不能使用Ansible hostvars作为地址,因为我不能ssh到它。

我尝试连接Pythonic socket.gethostbyname(),但无法正确使用语法。最多,我的变量变成了一个文字“socket.gethostbyname('my-host-1')”。

我知道我可以回退到shell脚本并利用shell中提供的工具,但我想知道在Ansible中是否有一种优雅的方法来实现这一点。

问题的更多细节是我需要使用允许主机的IP地址填充Postgres HBA配置文件。我无法使用其主机名,因为目标部署没有基于主机名的HBA所需的反向DNS。

我真的希望Postgres解析配置文件中的名称并将其与客户端的IP地址进行匹配,而不是反向查找客户端的IP地址,然后匹配主机名字符串。但这太过于期待,而且等待的时间太长。我现在需要一个解决方法,我想留在Ansible中,而不必将其卸载到外部脚本中。

感谢您阅读此内容!

4 个答案:

答案 0 :(得分:10)

您可以为此创建一个查找插件:

Ansible 1.x:

import ansible.utils as utils
import ansible.errors as errors
import socket

class LookupModule(object):

    def __init__(self, basedir=None, **kwargs):
        self.basedir = basedir

    def run(self, terms, inject=None, **kwargs):

        if not isinstance(terms, basestring):
            raise errors.AnsibleError("ip lookup expects a string (hostname)")

        return [socket.gethostbyname(terms)]

Ansible 2.x:

import ansible.utils as utils
import ansible.errors as errors
from ansible.plugins.lookup import LookupBase
import socket

class LookupModule(LookupBase):

    def __init__(self, basedir=None, **kwargs):
        self.basedir = basedir

    def run(self, terms, variables=None, **kwargs):

        hostname = terms[0]

        if not isinstance(hostname, basestring):
            raise errors.AnsibleError("ip lookup expects a string (hostname)")

        return [socket.gethostbyname(hostname)]

将此相对于您的剧本保存为lookup_plugins/ip.py

然后将其用作{{ lookup('ip', 'www.google.com') }}

答案 1 :(得分:2)

查找插件udondan提到的是"对"这样做的方法(尽管API更改为2.0,因此请注意,如果你采用这种方式,你会定位哪个版本)。如果您只是想要快速和肮脏的东西,以下应该有效:

- hosts: yourhosts
  tasks:
  - local_action: shell dig +short host-to-lookup-here.com
    changed_when: false
    register: dig_output

  - set_fact:
      looked_up_ips: "{{ dig_output.stdout_lines }}"

  - debug: msg="found ip {{ item }}"
    with_items: looked_up_ips

事实上,looking_up_ips将是一个可从模板中访问的映射IP列表,或者您需要在...中使用它的任何内容...

答案 2 :(得分:2)

为了完整起见,显然我们已经在盒子里装了一个挖掘查找插件,因为大约1.9可以很好地包装它(h / t Duncan Hutty):

https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/lookup/dig.py

答案 3 :(得分:1)

正如@nitzmahone所建议的,dig插件可以完全用于此目的。例如:

- name: Simple A record (IPV4 address) lookup for example.com
  debug: msg="{{ lookup('dig', 'example.com.')}}"

打印

MSG:

  93.184.216.34

注意:您必须先安装dnspython才能使其正常运行。您可以使用

进行安装
pip install dnspython