编写Ansible模块并自定义Facts例子

作者:简简单单 2014-08-01

背景介绍:
Ansible自带的Facts有很多,但很多时候并不够用。
比如,Ansible就没有ansible_private_ipv4_address这样一个Facts,用来保存私网IP地址。
而我们恰恰就需要这样的一个Facts,因为我们有很多服务器的默认网卡并非是eth0,有的是bond0,eth1,em0,em1等,而公网IP地址与私网IP地址也并没有固定的绑定在某个网卡上,很多时候还是虚拟网卡。
还好,我们可以通过编写Ansible模块并自定义Facts来实现。

具体步骤:

 代码如下 复制代码

[root@idc-server2 ~]# ifconfig

eth0      Link encap:Ethernet  HWaddr 1B:2B:3B:4B:5B:6B
          inet addr:172.16.1.2  Bcast:172.16.1.255  Mask:255.255.252.0
...

eth1      Link encap:Ethernet  HWaddr 1A:2A:3A:4A:5A:6A
          inet addr:100.100.100.100  Bcast:100.100.100.255  Mask:255.255.255.240
...

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
...
[root@idc-server1 ansible]# vim myfacts.yml

---
- hosts: idc-server2
  roles:
  - myfacts
[root@idc-server1 ansible]# mkdir -p roles/myfacts/{tasks,templates}

[root@idc-server1 ansible]# vim roles/myfacts/tasks/main.yml

---
- name: run myfacts module to get customized facts
  myfacts: get_facts=yes

- name: update file with the customized facts
  template: src=myfacts.txt.j2 dest=/tmp/myfacts.txt
[root@idc-server1 ansible]# vim roles/myfacts/templates/myfacts.txt.j2

ansible_private_ipv4_address : {{ ansible_private_ipv4_address }}
[root@idc-server1 ansible]# mkdir /usr/share/ansible/heylinux
[root@idc-server1 ansible]# vim /usr/share/ansible/heylinux/myfacts

#!/usr/bin/python

import sys
import json
import shlex
import commands
import re

def get_ansible_private_ipv4_address():
    iprex = "(^192.168)|(^10.)|(^172.1[6-9])|(^172.2[0-9])|(^172.3[0-1])"
    output = commands.getoutput("""/sbin/ifconfig |grep "Link encap" |awk '{print $1}' |grep -wv 'lo'""")
    nics = output.split('n')
    t_nic_info = ""
    for i in nics:
        ipaddr = commands.getoutput("""/sbin/ifconfig %s |grep -w "inet addr" |cut -d: -f2 | awk '{print $1}'""" % (i))
        if re.match(iprex,ipaddr):
            ansible_private_ipv4_address = ipaddr
    return ansible_private_ipv4_address


args_file = sys.argv[1]
args_data = file(args_file).read()

arguments = shlex.split(args_data)
for arg in arguments:
    if "=" in arg:
        (key, value) = arg.split("=")
        if key == "get_facts" and value == "yes":
            ansible_private_ipv4_address = get_ansible_private_ipv4_address()
          
            print json.dumps({
               "changed" : False,
               "ansible_facts" : {
                  "ansible_private_ipv4_address" : ansible_private_ipv4_address
               }
            })
            sys.exit(0)

print json.dumps({
    "changed" : False
})
[root@idc-server1 ansible]# ansible-playbook -u root myfacts.yml -i hosts

PLAY [idc1-server2] ***************************************************************

GATHERING FACTS ***************************************************************
ok: [idc1-server2]

TASK: [myfacts | run myfacts module to get customized facts] **************
ok: [idc1-server2]

TASK: [myfacts | update file with the customized facts] *********************
changed: [idc1-server2]

PLAY RECAP ********************************************************************
idc1-server2                   : ok=3    changed=1    unreachable=0    failed=0 
[root@idc-server1 ansible]# ssh idc1-server2 'cat /tmp/myfacts.txt'

ansible_private_ipv4_address : 172.16.1.2

相关文章

精彩推荐