Prechádzať zdrojové kódy

iptables host check warning shows on centos 5.9 even if iptables are stopped (Jonathan Hurley via ncole)

Nate Cole 11 rokov pred
rodič
commit
adaf32e642

+ 108 - 25
ambari-agent/src/main/python/ambari_agent/HostInfo.py

@@ -35,6 +35,25 @@ from common_functions import OSCheck
 
 logger = logging.getLogger()
 
+# OS info
+OS_VERSION = OSCheck().get_os_major_version()
+OS_TYPE = OSCheck.get_os_type()
+OS_FAMILY = OSCheck.get_os_family()
+
+# OS constants
+OS_UBUNTU_DEBIAN = 'debian'
+OS_UBUNTU = 'ubuntu'
+OS_FEDORA = 'fedora'
+OS_OPENSUSE = 'opensuse'
+OS_SUSE = 'suse'
+OS_SUSE_ENTERPRISE = 'sles'
+
+# service cmd
+SERVICE_CMD = "/sbin/service"
+
+# on ubuntu iptables service is called ufw
+if OS_FAMILY == OS_UBUNTU_DEBIAN:
+  SERVICE_CMD = "/usr/sbin/service"
 
 class HostInfo:
   # List of project names to be used to find alternatives folders etc.
@@ -102,18 +121,6 @@ class HostInfo:
   # default timeout for async invoked processes
   TIMEOUT_SECONDS = 60
   RESULT_UNAVAILABLE = "unable_to_determine"
-
-  OS_FAMILY = OSCheck.get_os_family()
-  OS_UBUNTU_DEBIAN = 'debian'
-  # service cmd
-  SERVICE_CMD = "/sbin/service"
-  FIREWALL_SERVICE_NAME = "iptables"
-  # on ubuntu iptables service is called ufw
-  if OS_FAMILY == OS_UBUNTU_DEBIAN:
-    SERVICE_CMD = "/usr/sbin/service"
-    FIREWALL_SERVICE_NAME = "ufw"
-
-  FIREWALL_STATUS_CMD = "%s %s status" % (SERVICE_CMD, FIREWALL_SERVICE_NAME)
   
   DEFAULT_SERVICE_NAME = "ntpd"
   SERVICE_STATUS_CMD = "%s %s status" % (SERVICE_CMD, DEFAULT_SERVICE_NAME)
@@ -279,20 +286,25 @@ class HostInfo:
     else:
      return self.current_umask
 
+  def getFirewallObject(self):
+    if OS_TYPE == OS_UBUNTU:
+      return UbuntuFirewallChecks()
+    elif OS_TYPE == OS_FEDORA and int(OS_VERSION) >= 18:
+      return Fedora18FirewallChecks()
+    elif OS_TYPE == OS_SUSE or OS_TYPE == OS_OPENSUSE or OS_TYPE == OS_SUSE_ENTERPRISE:
+      return SuseFirewallChecks()
+    else:
+      return FirewallChecks()
 
-  def checkIptables(self):
-    iptablesIsRunning = True
-    try:
-      iptables = subprocess.Popen(["iptables", "-S"], stdout=subprocess.PIPE)
-      stdout = iptables.communicate()
-      if stdout == ('-P INPUT ACCEPT\n-P FORWARD ACCEPT\n-P OUTPUT ACCEPT\n', None):
-        iptablesIsRunning = False
-    except:
-      pass
-    return iptablesIsRunning
-
-
+  def getFirewallObjectTypes(self):
+    # To support test code, so tests can loop through the types
+    return (FirewallChecks,
+            UbuntuFirewallChecks,
+            Fedora18FirewallChecks,
+            SuseFirewallChecks)
 
+  def checkIptables(self):
+    return self.getFirewallObject().check_iptables()
 
   """ Return various details about the host
   componentsMapped: indicates if any components are mapped to this host
@@ -364,6 +376,77 @@ class HostInfo:
     pass
 
 
+class FirewallChecks(object):
+  def __init__(self):
+    self.FIREWALL_SERVICE_NAME = "iptables"
+    self.SERVICE_CMD = SERVICE_CMD
+    self.SERVICE_SUBCMD = "status"
+
+  def get_command(self):
+    return "%s %s %s" % (self.SERVICE_CMD, self.FIREWALL_SERVICE_NAME, self.SERVICE_SUBCMD)
+
+  def check_result(self, retcode, out, err):
+      return retcode == 0
+
+  def check_iptables(self):
+    retcode, out, err = self.run_os_command(self.get_command())
+    return self.check_result(retcode, out, err)
+
+  def get_running_result(self):
+    # To support test code.  Expected ouput from run_os_command.
+    return (0, "", "")
+
+  def get_stopped_result(self):
+    # To support test code.  Expected output from run_os_command.
+    return (3, "", "")
+    
+  def run_os_command(self, cmd):
+    if type(cmd) == str:
+      cmd = shlex.split(cmd)
+      
+    process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE,
+      stderr=subprocess.PIPE)
+                               
+    (stdoutdata, stderrdata) = process.communicate()
+    return process.returncode, stdoutdata, stderrdata    
+
+
+class UbuntuFirewallChecks(FirewallChecks):
+  def __init__(self):
+    super(UbuntuFirewallChecks, self).__init__()
+
+    self.FIREWALL_SERVICE_NAME = "ufw"
+    self.SERVICE_CMD = 'service'
+
+  def check_result(self, retcode, out, err):
+    # On ubuntu, the status command returns 0 whether running or not
+    return out and len(out) > 0 and out.strip() != "ufw stop/waiting"
+
+  def get_running_result(self):
+    # To support test code.  Expected ouput from run_os_command.
+    return (0, "ufw start/running", "")
+
+  def get_stopped_result(self):
+    # To support test code.  Expected output from run_os_command.
+    return (0, "ufw stop/waiting", "")
+
+
+class Fedora18FirewallChecks(FirewallChecks):
+  def __init__(self):
+    self.FIREWALL_SERVICE_NAME = "firewalld.service"
+
+  def get_command(self):
+    return "systemctl is-active firewalld.service"
+
+
+class SuseFirewallChecks(FirewallChecks):
+  def __init__(self):
+    self.FIREWALL_SERVICE_NAME = "SuSEfirewall2"
+
+  def get_command(self):
+    return "/sbin/SuSEfirewall2 status"
+
+
 def main(argv=None):
   h = HostInfo()
   struct = {}
@@ -372,4 +455,4 @@ def main(argv=None):
 
 
 if __name__ == '__main__':
-  main()
+  main()

+ 19 - 14
ambari-agent/src/test/python/ambari_agent/TestHostInfo.py

@@ -31,6 +31,7 @@ with patch("platform.linux_distribution", return_value = ('redhat','11','Final')
   from ambari_agent.HostCheckReportFileHandler import HostCheckReportFileHandler
   from ambari_agent.PackagesAnalyzer import PackagesAnalyzer
   from ambari_agent.HostInfo import HostInfo
+  from ambari_agent.HostInfo import FirewallChecks
   from ambari_agent.Hardware import Hardware
   from ambari_agent.AmbariConfig import AmbariConfig
   from resource_management.core.system import System
@@ -252,9 +253,11 @@ class TestHostInfo(TestCase):
   @patch.object(HostInfo, 'etcAlternativesConf')
   @patch.object(HostInfo, 'hadoopVarRunCount')
   @patch.object(HostInfo, 'hadoopVarLogCount')
-  def test_hostinfo_register_suse(self, hvlc_mock, hvrc_mock, eac_mock, cf_mock, jp_mock,
+  @patch.object(HostInfo, 'checkIptables')
+  def test_hostinfo_register_suse(self, cit_mock, hvlc_mock, hvrc_mock, eac_mock, cf_mock, jp_mock,
                              cls_mock, cu_mock, gir_mock, gipbr_mock, gipbn_mock,
                              gpd_mock, aip_mock, aap_mock, whcf_mock, os_umask_mock, get_os_type_mock):
+    cit_mock.return_value = True
     hvlc_mock.return_value = 1
     hvrc_mock.return_value = 1
     gipbr_mock.return_value = ["pkg1"]
@@ -509,22 +512,24 @@ class TestHostInfo(TestCase):
 
     self.assertEquals(result[0]['name'], 'config1')
     self.assertEquals(result[0]['target'], 'real_path_to_conf')
-
-
-  @patch("subprocess.Popen")
-  def test_checkIptables(self, subproc_popen_mock):
-    hostInfo = HostInfo()
-    p = MagicMock()
-
-    subproc_popen_mock.return_value = p
     
-    result = hostInfo.checkIptables()
-    self.assertTrue(result == True)
-
-    result = hostInfo.checkIptables()
-    self.assertFalse(result == False)
 
+  @patch.object(FirewallChecks, "run_os_command")
+  def test_IpTablesRunning(self, run_os_command_mock):
+    hostInfo = HostInfo()
+    for firewallType in hostInfo.getFirewallObjectTypes():
+      firewall = firewallType()
+      run_os_command_mock.return_value = firewall.get_running_result()
+      self.assertTrue(firewall.check_iptables())
 
 
+  @patch.object(FirewallChecks, "run_os_command")
+  def test_IpTablesStopped(self, run_os_command_mock):
+    hostInfo = HostInfo()
+    for firewallType in hostInfo.getFirewallObjectTypes():
+      firewall = firewallType()
+      run_os_command_mock.return_value = firewall.get_stopped_result()
+      self.assertFalse(firewall.check_iptables())
+      
 if __name__ == "__main__":
   unittest.main()

+ 4 - 1
ambari-agent/src/test/python/ambari_agent/TestRegistration.py

@@ -28,18 +28,21 @@ with patch("platform.linux_distribution", return_value = ('Suse','11','Final')):
   from ambari_agent.Register import Register
   from ambari_agent.AmbariConfig import AmbariConfig
   from ambari_agent.HostInfo import HostInfo
+  from ambari_agent.HostInfo import FirewallChecks
   from common_functions import OSCheck
 
 class TestRegistration(TestCase):
+  @patch.object(FirewallChecks, "run_os_command")
   @patch.object(OSCheck, "get_os_type")
   @patch.object(OSCheck, "get_os_version")
-  def test_registration_build(self, get_os_version_mock, get_os_type_mock):
+  def test_registration_build(self, get_os_version_mock, get_os_type_mock, run_os_cmd_mock):
     config = AmbariConfig().getConfig()
     tmpdir = tempfile.gettempdir()
     config.set('agent', 'prefix', tmpdir)
     config.set('agent', 'current_ping_port', '33777')
     get_os_type_mock.return_value = "suse"
     get_os_version_mock.return_value = "11"
+    run_os_cmd_mock.return_value = (3, "", "")
     ver_file = os.path.join(tmpdir, "version")
     with open(ver_file, "w") as text_file:
       text_file.write("1.3.0")