一千萬個為什麽

搜索

如何在Ansible中檢測具有私有IP的接口



我打算在我們的服務器(主要是CentOS 7,一些CentOS 6)上重新配置 iptables ,使用不同的網絡配置,一些使用1Gbit接口,一些使用10Gbit,一些使用VLAN,一些使用配置LACP。

我想使用Ansible,但無法找到如何檢測什麽inteface具有私人地址。私人地址,我們可以從庫存中獲得 ansible_ssh_host

有沒有Ansible模塊可以幫忙?或者我應該寫shell/Python腳本?

我檢查了StackOverflow和ServerFault上的所有解決方案,但沒有發現任何內容。

轉載註明原文: 如何在Ansible中檢測具有私有IP的接口

一共有 2 個回答:

Peter的模塊不能在CentOS中工作,我編寫自己的模塊:

#!/usr/bin/python
# encoding: utf-8

import subprocess
from ansible.module_utils.basic import *
from netaddr import IPNetwork

def get_priv_interface_info_for_ip(ip):
    network_config = subprocess.Popen(["/usr/sbin/ip", "-o", "addr", "show"], stdout=subprocess.PIPE)
    result = network_config.stdout.read()
    interface = ""
    network = ''
    ip_addr = ip
    for str in result.split("\n"):
        if 'inet ' in str:
            if ip in str:
                interface = str[3:str.find(" ", 3)]
                network = IPNetwork(str[str.find("net", 3) + 4:str.find("/", 3) + 3]).cidr

    return interface, ip_addr, network

def get_pub_interface_info_for_ip(ip):
    network_config = subprocess.Popen(["/usr/sbin/ip", "-o", "addr", "show"], stdout=subprocess.PIPE)
    result = network_config.stdout.read()
    interface = ''
    network = ''
    ip_addr = ''
    for str in result.split("\n"):
        if 'inet ' in str:
            if ip not in str and '127.0.0.1' not in str:
                print str
                interface = str[3:str.find(" ", 3)]
                network = IPNetwork(str[str.find("net", 3) + 4:str.find("/", 3) + 3]).cidr
                ip_addr = str[str.find("net", 3) + 4:str.find("/", 3)]

    return interface, ip_addr, network

def main(argv=None):
    if argv is None:
        argv = sys.argv

    fields = {"ip": {"required": True, "type": "str"}}
    module = AnsibleModule(argument_spec=fields)
    my_ip = module.params['ip']
    ifname_priv, ip_priv, network_priv = get_priv_interface_info_for_ip(my_ip)
    ifname_pub, ip_pub, network_pub = get_pub_interface_info_for_ip(my_ip)


    module.exit_json(changed=True, ifname_priv=ifname_priv, ip_priv=my_ip, network_priv=str(network_priv), ifname_pub=ifname_pub, ip_pub=ip_pub, network_pub=str(network_pub))


if __name__ == '__main__':
    main()

它適用於具有兩個網絡接口的服務器,並提供有關公共和專用網絡接口的信息。

該模塊的實際版本可以在我的GitHub 中找到。

我在Ansible找不到它,所以我在幾周前寫了一些東西來幫助:

import fcntl
import json
import os
import platform
import subprocess
import socket
import struct
import re
from random import randint
import time
from ansible.module_utils.basic import *

def get_interface_info_for_ip(ip):

  ifconfig_process = subprocess.Popen(['/sbin/ifconfig'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  ifconfig_stdout_lines, ifconfig_stderr_lines = ifconfig_process.communicate()

  for ifconfig_stdout_line in ifconfig_stdout_lines.split('\n'):
    if 'mtu' in ifconfig_stdout_line.split():
      current_ifdesc = ''
      current_mtu = ''
      current_ip = ''
      current_netmask = ''
      current_mac = ''
      ifdesc_line_match = re.match(r'(?P[a-zA-Z0-9]+):.+mtu\s+(?P[0-9]+)', ifconfig_stdout_line )
      if ifdesc_line_match:
        current_ifdesc = ifdesc_line_match.groupdict()['ifdesc']
        current_mtu = ifdesc_line_match.groupdict()['mtu']

    if 'inet' in ifconfig_stdout_line.split():
      inet_line_match = re.match(r'\s+inet\s+(?P[0-9.]+)\s+netmask\s+(?P[0-9.]+)', ifconfig_stdout_line)
      if inet_line_match:
         current_ip = inet_line_match.groupdict()['ip']
         current_netmask = inet_line_match.groupdict()['netmask']

    if 'ether' in ifconfig_stdout_line.split():
      ether_line_match = re.match(r'\s+ether\s+(?P[0-9a-f:]+)', ifconfig_stdout_line)
      if ether_line_match:
         current_mac = ether_line_match.groupdict()['mac']

    if current_ifdesc and current_mtu and current_ip and current_netmask and current_mac and current_ip == ip:
      return current_ifdesc, current_mtu, current_ip, current_netmask, current_mac

def main(argv=None):
    if argv is None:
      argv = sys.argv

    module = AnsibleModule(
        argument_spec = dict(
           silo_ip = dict(required=True),
        )
    )
    my_ip = module.params['ip']
    ifdesc, mtu, ip, netmask, mac = get_interface_info_for_ip(my_ip)

    module.exit_json(changed=True, ifdesc=ifdesc, ip=ip, mac=mac, netmask=netmask, mtu=mtu)

if __name__ == '__main__':
    main()

調用文件 get_ip_facts ,把它放在你的庫路徑中,並用下面的方法調用它:

name: get facts for ip address
get_ip_facts: ip={{ whatever_your_ip_is }}