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); + } +}
