Repository: ambari
Updated Branches:
  refs/heads/trunk a6ab3881c -> c4bbeeb29


AMBARI-19415. Network interface check returns no value if there is no 
`ifconfig` command. (Masahiro Tanaka via yusaku)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/c4bbeeb2
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/c4bbeeb2
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/c4bbeeb2

Branch: refs/heads/trunk
Commit: c4bbeeb29d8f9e3b04d20e38570769f3cc3fdec6
Parents: a6ab388
Author: Yusaku Sako <yus...@hortonworks.com>
Authored: Sat Jan 21 09:49:40 2017 -0800
Committer: Yusaku Sako <yus...@hortonworks.com>
Committed: Sat Jan 21 09:49:40 2017 -0800

----------------------------------------------------------------------
 .../src/main/python/ambari_agent/Facter.py      | 44 ++++++++++++++----
 .../test/python/ambari_agent/TestHardware.py    | 47 ++++++++++++++++++++
 2 files changed, 82 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/c4bbeeb2/ambari-agent/src/main/python/ambari_agent/Facter.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/Facter.py 
b/ambari-agent/src/main/python/ambari_agent/Facter.py
index 3643ff7..7e92c1b 100644
--- a/ambari-agent/src/main/python/ambari_agent/Facter.py
+++ b/ambari-agent/src/main/python/ambari_agent/Facter.py
@@ -375,15 +375,18 @@ class FacterLinux(Facter):
   # selinux command
   GET_SE_LINUX_ST_CMD = "/usr/sbin/sestatus"
   GET_IFCONFIG_SHORT_CMD = "ifconfig -s"
+  GET_IP_LINK_CMD = "ip link"
   GET_UPTIME_CMD = "cat /proc/uptime"
   GET_MEMINFO_CMD = "cat /proc/meminfo"
 
   def __init__(self, config):
     super(FacterLinux,self).__init__(config)
     self.DATA_IFCONFIG_SHORT_OUTPUT = FacterLinux.setDataIfConfigShortOutput()
+    self.DATA_IP_LINK_OUTPUT = FacterLinux.setDataIpLinkOutput()
     self.DATA_UPTIME_OUTPUT = FacterLinux.setDataUpTimeOutput()
     self.DATA_MEMINFO_OUTPUT = FacterLinux.setMemInfoOutput()
 
+  # Returns the output of `ifconfig -s` command
   @staticmethod
   def setDataIfConfigShortOutput():
 
@@ -394,6 +397,17 @@ class FacterLinux(Facter):
       log.warn("Can't execute {0}".format(FacterLinux.GET_IFCONFIG_SHORT_CMD))
     return ""
 
+  # Returns the output of `ip link` command
+  @staticmethod
+  def setDataIpLinkOutput():
+
+    try:
+      result = os.popen(FacterLinux.GET_IP_LINK_CMD).read()
+      return result
+    except OSError:
+      log.warn("Can't execute {0}".format(FacterLinux.GET_IP_LINK_CMD))
+    return ""
+
   @staticmethod
   def setDataUpTimeOutput():
 
@@ -438,6 +452,14 @@ class FacterLinux(Facter):
     result = re.sub(r',$', "", result)
     return result
 
+  def return_ifnames_from_ip_link(self, ip_link_output):
+    list = []
+    prog = re.compile("^\d")
+    for line in ip_link_output.splitlines():
+      if prog.match(line):
+        list.append(line.split()[1].rstrip(":"))
+    return ",".join(list)
+
   def data_return_first(self, patern, data):
     full_list = re.findall(patern, data)
     result = ""
@@ -452,13 +474,12 @@ class FacterLinux(Facter):
     import struct
     primary_ip = self.getIpAddress().strip()
 
-    for line in self.DATA_IFCONFIG_SHORT_OUTPUT.splitlines()[1:]:
-      if line.strip():
-        i = line.split()[0]
-        ip_address_by_ifname = self.get_ip_address_by_ifname(i.strip())
+    for ifname in self.getInterfaces().split(","):
+      if ifname.strip():
+        ip_address_by_ifname = self.get_ip_address_by_ifname(ifname)
         if ip_address_by_ifname is not None:
           if primary_ip == ip_address_by_ifname.strip():
-            return socket.inet_ntoa(fcntl.ioctl(socket.socket(socket.AF_INET, 
socket.SOCK_DGRAM), 35099, struct.pack('256s', i))[20:24])
+            return socket.inet_ntoa(fcntl.ioctl(socket.socket(socket.AF_INET, 
socket.SOCK_DGRAM), 35099, struct.pack('256s', ifname))[20:24])
 
     return None
       
@@ -483,11 +504,16 @@ class FacterLinux(Facter):
   # Return interfaces
   def getInterfaces(self):
     result = 
self.return_first_words_from_list(self.DATA_IFCONFIG_SHORT_OUTPUT.splitlines()[1:])
-    if result == '':
-      log.warn("Can't get a network interfaces list from 
{0}".format(self.DATA_IFCONFIG_SHORT_OUTPUT))
-      return 'OS NOT SUPPORTED'
-    else:
+    # If the host has `ifconfig` command, then return that result.
+    if result != '':
       return result
+    # If the host has `ip` command, then return that result.
+    result = self.return_ifnames_from_ip_link(self.DATA_IP_LINK_OUTPUT)
+    if result != '':
+      return result
+    # If the host has neither `ifocnfig` command nor `ip` command, then return 
"OS NOT SUPPORTED"
+    log.warn("Can't get a network interfaces list from 
{0}".format(self.DATA_IFCONFIG_SHORT_OUTPUT))
+    return 'OS NOT SUPPORTED'
 
   # Return uptime seconds
   def getUptimeSeconds(self):

http://git-wip-us.apache.org/repos/asf/ambari/blob/c4bbeeb2/ambari-agent/src/test/python/ambari_agent/TestHardware.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/ambari_agent/TestHardware.py 
b/ambari-agent/src/test/python/ambari_agent/TestHardware.py
index ff3b40b..79205cf 100644
--- a/ambari-agent/src/test/python/ambari_agent/TestHardware.py
+++ b/ambari-agent/src/test/python/ambari_agent/TestHardware.py
@@ -43,6 +43,12 @@ eth0   1500   0     9986      0      0      0     5490      
0      0      0 BMRU
 eth1   1500   0        0      0      0      0        6      0      0      0 
BMRU
 eth2   1500   0        0      0      0      0        6      0      0      0 
BMRU
 lo    16436   0        2      0      0      0        2      0      0      0 
LRU'''))
+@patch.object(FacterLinux, "setDataIpLinkOutput", 
new=MagicMock(return_value='''1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc 
noqueue state UNKNOWN mode DEFAULT qlen 1
+    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
+2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state 
UP mode DEFAULT qlen 1000
+    link/ether 08:00:27:d3:e8:0f brd ff:ff:ff:ff:ff:ff
+3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state 
UP mode DEFAULT qlen 1000
+    link/ether 08:00:27:09:92:3a brd ff:ff:ff:ff:ff:ff'''))
 class TestHardware(TestCase):
  
   @patch.object(Hardware, "osdisks", new=MagicMock(return_value=[]))
@@ -443,6 +449,47 @@ SwapFree:        1598676 kB
 
     self.assertEquals(expected_mounts_left, mounts_left)
 
+@not_for_platform(PLATFORM_WINDOWS)
+@patch.object(platform, "linux_distribution", 
new=MagicMock(return_value=('Suse', '11', 'Final')))
+@patch.object(socket, "getfqdn", 
new=MagicMock(return_value="ambari.apache.org"))
+@patch.object(socket, "gethostbyname", 
new=MagicMock(return_value="192.168.1.1"))
+@patch.object(FacterLinux, "setDataIfConfigShortOutput", 
new=MagicMock(return_value=''))
+@patch.object(FacterLinux, "setDataIpLinkOutput", 
new=MagicMock(return_value='''1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc 
noqueue state UNKNOWN mode DEFAULT qlen 1
+    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
+2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state 
UP mode DEFAULT qlen 1000
+    link/ether 08:00:27:d3:e8:0f brd ff:ff:ff:ff:ff:ff
+3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state 
UP mode DEFAULT qlen 1000
+    link/ether 08:00:27:09:92:3a brd ff:ff:ff:ff:ff:ff'''))
+class TestHardwareWithoutIfConfig(TestCase):
+  @patch("fcntl.ioctl")
+  @patch("socket.socket")
+  @patch("struct.pack")
+  @patch("socket.inet_ntoa")
+  @patch.object(FacterLinux, "get_ip_address_by_ifname")
+  @patch.object(Facter, "getIpAddress")
+  @patch.object(OSCheck, "get_os_type")
+  @patch.object(OSCheck, "get_os_version")
+  def test_facterDataIpLinkOutput(self, get_os_version_mock,
+                                  get_os_type_mock, getIpAddress_mock, 
get_ip_address_by_ifname_mock,
+                                  inet_ntoa_mock, struct_pack_mock,
+                                  socket_socket_mock, fcntl_ioctl_mock):
+
+    getIpAddress_mock.return_value = "10.0.2.15"
+    get_ip_address_by_ifname_mock.return_value = "10.0.2.15"
+    inet_ntoa_mock.return_value = "255.255.255.0"
+
+    get_os_type_mock.return_value = "suse"
+    get_os_version_mock.return_value = "11"
+    config = None
+    result = Facter(config).facterInfo()
+
+    self.assertTrue(inet_ntoa_mock.called)
+    self.assertTrue(get_ip_address_by_ifname_mock.called)
+    self.assertTrue(getIpAddress_mock.called)
+    self.assertEquals(result['ipaddress'], '10.0.2.15')
+    self.assertEquals(result['netmask'], '255.255.255.0')
+    self.assertEquals(result['interfaces'], 'lo,enp0s3,enp0s8')
+
 
 if __name__ == "__main__":
   unittest.main()

Reply via email to