BROOKLYN-137 stopIptables and openIptables don't work on CentOS7

- Adding preliminary support for firewalld
- Starting/stopping/restrting of firewalld service
- Adding rules via firewalld's direct interface
- Tests


Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/524fd80f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/524fd80f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/524fd80f

Branch: refs/heads/master
Commit: 524fd80feb08bbc0ec47952e9919dc23889b4817
Parents: 2556b29
Author: Yavor Yanchev <[email protected]>
Authored: Mon Jun 22 10:03:08 2015 +0300
Committer: Yavor Yanchev <[email protected]>
Committed: Mon Jun 22 10:52:47 2015 +0300

----------------------------------------------------------------------
 .../location/jclouds/JcloudsLocation.java       | 33 +++++--
 .../brooklyn/util/ssh/IptablesCommands.java     | 52 +++++++++++
 .../util/ssh/IptablesCommandsFirewalldTest.java | 94 ++++++++++++++++++++
 3 files changed, 173 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/524fd80f/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocation.java
----------------------------------------------------------------------
diff --git 
a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocation.java
 
b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocation.java
index 15ea553..e839c3f 100644
--- 
a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocation.java
+++ 
b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocation.java
@@ -364,7 +364,15 @@ public class JcloudsLocation extends 
AbstractCloudMachineProvisioningLocation im
                 ? (OsFamily.WINDOWS == os.getFamily()) 
                 : (OsFamily.WINDOWS == confFamily);
     }
-
+    
+    public boolean isNodeFirewalldEnabled(NodeMetadata node) {
+        String OS = node.getOperatingSystem().getFamily().toString();
+        String version = node.getOperatingSystem().getVersion();
+        return node.getOperatingSystem().getVersion().startsWith("7") &&
+             (node.getOperatingSystem().getFamily().equals(OsFamily.RHEL) ||
+              node.getOperatingSystem().getFamily().equals(OsFamily.CENTOS));
+    }
+    
     protected Semaphore getMachineCreationSemaphore() {
         return checkNotNull(getConfig(MACHINE_CREATION_SEMAPHORE), 
MACHINE_CREATION_SEMAPHORE.getName());
     }
@@ -868,9 +876,17 @@ public class JcloudsLocation extends 
AbstractCloudMachineProvisioningLocation im
                             LOG.info("No ports to open in iptables (no inbound 
ports) for {} at {}", machineLocation, this);
                         } else {
                             customisationForLogging.add("open iptables");
-
-                            List<String> iptablesRules = 
createIptablesRulesForNetworkInterface(inboundPorts);
-                            
iptablesRules.add(IptablesCommands.saveIptablesRules());
+                            
+                            List<String> iptablesRules = Lists.newArrayList();
+                            
+                            if (isNodeFirewalldEnabled(node)) {
+                                for (Integer port : inboundPorts) {
+                                    
iptablesRules.add(IptablesCommands.addFirewalldRule(Chain.INPUT, Protocol.TCP, 
port, Policy.ACCEPT));
+                                 }
+                            } else {
+                                iptablesRules = 
createIptablesRulesForNetworkInterface(inboundPorts);
+                                
iptablesRules.add(IptablesCommands.saveIptablesRules());
+                            }
                             List<String> batch = Lists.newArrayList();
                             // Some entities, such as Riak (erlang based) have 
a huge range of ports, which leads to a script that
                             // is too large to run (fails with a broken pipe). 
Batch the rules into batches of 50
@@ -894,8 +910,13 @@ public class JcloudsLocation extends 
AbstractCloudMachineProvisioningLocation im
                         LOG.warn("Ignoring flag OPEN_IPTABLES on Windows 
location {}", machineLocation);
                     } else {
                         customisationForLogging.add("stop iptables");
-
-                        List<String> cmds = 
ImmutableList.of(IptablesCommands.iptablesServiceStop(), 
IptablesCommands.iptablesServiceStatus());
+                        
+                        List<String> cmds = ImmutableList.<String>of();
+                        if (isNodeFirewalldEnabled(node)) {
+                            cmds = 
ImmutableList.of(IptablesCommands.firewalldServiceStop(), 
IptablesCommands.firewalldServiceStatus());
+                        } else {
+                            cmds = 
ImmutableList.of(IptablesCommands.iptablesServiceStop(), 
IptablesCommands.iptablesServiceStatus());
+                        }
                         
((SshMachineLocation)machineLocation).execCommands("Stopping iptables", cmds);
                     }
                 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/524fd80f/utils/common/src/main/java/brooklyn/util/ssh/IptablesCommands.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/ssh/IptablesCommands.java 
b/utils/common/src/main/java/brooklyn/util/ssh/IptablesCommands.java
index c5164aa..7d7d8ce 100644
--- a/utils/common/src/main/java/brooklyn/util/ssh/IptablesCommands.java
+++ b/utils/common/src/main/java/brooklyn/util/ssh/IptablesCommands.java
@@ -89,6 +89,33 @@ public class IptablesCommands {
         return iptablesService("status");
     }
 
+    @Beta // implementation not portable across distros
+    public static String firewalldService(String cmd) {
+        return sudo(alternatives(
+                BashCommands.ifExecutableElse1("systemctl", "systemctl " + cmd 
+ " firewalld"),
+                "/usr/bin/systemctl " + cmd + " firewalld"));
+    }
+
+    @Beta // implementation not portable across distros
+    public static String firewalldServiceStop() {
+        return firewalldService("stop");
+    }
+
+    @Beta // implementation not portable across distros
+    public static String firewalldServiceStart() {
+        return firewalldService("start");
+    }
+
+    @Beta // implementation not portable across distros
+    public static String firewalldServiceRestart() {
+        return firewalldService("restart");
+    }
+
+    @Beta // implementation not portable across distros
+    public static String firewalldServiceStatus() {
+        return firewalldService("status");
+    }
+    
     /**
      * Returns the command that saves iptables rules on file.
      *
@@ -201,4 +228,29 @@ public class IptablesCommands {
         return addIptablesRule(direction, chain, networkInterface, 
protocol.convert(), port, policy);
     }
 
+    /**
+     * Returns the command that adds firewalld direct rule.
+     *
+     * @return Returns the command that adds firewalld direct rule.
+     */
+    public static String addFirewalldRule(Chain chain, 
brooklyn.util.net.Protocol protocol, int port, Policy policy) {
+        return addFirewalldRule(chain, Optional.<String>absent(), protocol, 
port, policy);
+    }
+    
+    /**
+     * Returns the command that adds firewalld direct rule.
+     *
+     * @return Returns the command that adds firewalld direct rule.
+     */
+    public static String addFirewalldRule(Chain chain, Optional<String> 
networkInterface, brooklyn.util.net.Protocol protocol, int port, Policy policy) 
{
+        String command = new String("/usr/bin/firewall-cmd");
+        String commandPermanent = new String("/usr/bin/firewall-cmd 
--permanent");
+        
+        String interfaceParameter = String.format("%s", 
networkInterface.isPresent() ? " -i " + networkInterface.get() : "");
+        
+        String commandParameters = String.format(" --direct --add-rule ipv4 
filter %s 0 %s -p %s --dport %d -j %s", 
+                                                                chain, 
interfaceParameter,  protocol, port, policy);
+        
+        return sudo(chain(command + commandParameters, commandPermanent + 
commandParameters));
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/524fd80f/utils/common/src/test/java/brooklyn/util/ssh/IptablesCommandsFirewalldTest.java
----------------------------------------------------------------------
diff --git 
a/utils/common/src/test/java/brooklyn/util/ssh/IptablesCommandsFirewalldTest.java
 
b/utils/common/src/test/java/brooklyn/util/ssh/IptablesCommandsFirewalldTest.java
new file mode 100644
index 0000000..28c1c34
--- /dev/null
+++ 
b/utils/common/src/test/java/brooklyn/util/ssh/IptablesCommandsFirewalldTest.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package brooklyn.util.ssh;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import brooklyn.util.net.Protocol;
+import brooklyn.util.ssh.IptablesCommands.Chain;
+import brooklyn.util.ssh.IptablesCommands.Policy;
+
+public class IptablesCommandsFirewalldTest {
+    private static final String addFirewalldRule = "( if test \"$UID\" -eq 0; 
then "
+            + "( ( /usr/bin/firewall-cmd --direct --add-rule ipv4 filter INPUT 
0  -p tcp --dport 3306 -j ACCEPT "
+            + "&& /usr/bin/firewall-cmd --permanent --direct --add-rule ipv4 
filter INPUT 0  -p tcp --dport 3306 -j ACCEPT ) ); "
+            + "else echo \"( /usr/bin/firewall-cmd --direct --add-rule ipv4 
filter INPUT 0  -p tcp --dport 3306 -j ACCEPT "
+            + "&& /usr/bin/firewall-cmd --permanent --direct --add-rule ipv4 
filter INPUT 0  -p tcp --dport 3306 -j ACCEPT )\" "
+            + "| sudo -E -n -S -s -- bash ; fi )";
+
+    private static final String firewalldService = "( if test \"$UID\" -eq 0; 
then ( ( { "
+            + "which systemctl && systemctl status firewalld ; } || 
/usr/bin/systemctl status firewalld ) ); "
+            + "else echo \"( { which systemctl && systemctl status firewalld ; 
} || "
+            + "/usr/bin/systemctl status firewalld )\" | sudo -E -n -S -s -- 
bash ; fi )";
+
+    private static final String firewalldServiceRestart = "( if test \"$UID\" 
-eq 0; then ( ( { "
+            + "which systemctl && systemctl restart firewalld ; } || "
+            + "/usr/bin/systemctl restart firewalld ) ); else echo \"( { "
+            + "which systemctl && systemctl restart firewalld ; } || 
/usr/bin/systemctl restart firewalld )\" | "
+            + "sudo -E -n -S -s -- bash ; fi )";
+
+    private static final String firewalldServiceStart = "( if test \"$UID\" 
-eq 0; then ( ( { "
+            + "which systemctl && systemctl start firewalld ; } "
+            + "|| /usr/bin/systemctl start firewalld ) ); "
+            + "else echo \"( { which systemctl && systemctl start firewalld ; 
} || "
+            + "/usr/bin/systemctl start firewalld )\" | sudo -E -n -S -s -- 
bash ; fi )";
+
+    private static final String firewalldServiceStatus = "( if test \"$UID\" 
-eq 0; then ( ( { "
+            + "which systemctl && systemctl status firewalld ; "
+            + "} || /usr/bin/systemctl status firewalld ) ); else echo \"( { "
+            + "which systemctl && systemctl status firewalld ; } || "
+            + "/usr/bin/systemctl status firewalld )\" | sudo -E -n -S -s -- 
bash ; fi )";
+
+    private static final String firewalldServiceStop = "( if test \"$UID\" -eq 
0; then ( ( { "
+            + "which systemctl && systemctl stop firewalld ; } || 
/usr/bin/systemctl stop firewalld ) ); "
+            + "else echo \"( { which systemctl && systemctl stop firewalld ; } 
|| "
+            + "/usr/bin/systemctl stop firewalld )\" | sudo -E -n -S -s -- 
bash ; fi )";
+
+    @Test
+    public void testAddFirewalldRule() {
+        Assert.assertEquals(IptablesCommands.addFirewalldRule(Chain.INPUT,
+                Protocol.TCP, 3306, Policy.ACCEPT), addFirewalldRule);
+    }
+
+    @Test
+    public void testFirewalldService() {
+        Assert.assertEquals(IptablesCommands.firewalldService("status"), 
firewalldService);
+    }
+
+    @Test
+    public void testFirewalldServiceRestart() {
+        Assert.assertEquals(IptablesCommands.firewalldServiceRestart(), 
firewalldServiceRestart);
+    }
+
+    @Test
+    public void testFirewalldServiceStart() {
+        Assert.assertEquals(IptablesCommands.firewalldServiceStart(), 
firewalldServiceStart);
+    }
+
+    @Test
+    public void testFirewalldServiceStatus() {
+        Assert.assertEquals(IptablesCommands.firewalldServiceStatus(), 
firewalldServiceStatus);
+    }
+
+    @Test
+    public void testFirewalldServiceStop() {
+        Assert.assertEquals(IptablesCommands.firewalldServiceStop(), 
firewalldServiceStop);
+    }
+}

Reply via email to