brooklyn-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aleds...@apache.org
Subject [1/3] brooklyn-server git commit: Effector for opening inbound ports in security group
Date Wed, 24 Aug 2016 00:13:04 GMT
Repository: brooklyn-server
Updated Branches:
  refs/heads/master 375bb88de -> 434e26211


Effector for opening inbound ports in security group

- Live tests examining security groups

  (the effector will return error when called before machine location is provisioned)


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/6d7765b8
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/6d7765b8
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/6d7765b8

Branch: refs/heads/master
Commit: 6d7765b8cf023030de766bcb11f551765450ad46
Parents: 375bb88
Author: Valentin Aitken <bostko@gmail.com>
Authored: Thu Jul 28 03:13:18 2016 +0300
Committer: Valentin Aitken <bostko@gmail.com>
Committed: Tue Aug 23 16:32:39 2016 +0300

----------------------------------------------------------------------
 .../jclouds/networking/NetworkingEffectors.java | 100 +++++++++++++++++
 software/base/pom.xml                           |  12 +--
 .../entity/software/base/SoftwareProcess.java   |   3 +
 .../software/base/SoftwareProcessImpl.java      |   4 +
 .../location/NetworkEffectorsEc2LiveTests.java  |  45 ++++++++
 .../location/NetworkingEffectorsLiveTests.java  | 108 +++++++++++++++++++
 6 files changed, 265 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6d7765b8/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/networking/NetworkingEffectors.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/networking/NetworkingEffectors.java
b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/networking/NetworkingEffectors.java
new file mode 100644
index 0000000..7244123
--- /dev/null
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/networking/NetworkingEffectors.java
@@ -0,0 +1,100 @@
+/*
+ * 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 org.apache.brooklyn.location.jclouds.networking;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Range;
+import com.google.common.reflect.TypeToken;
+import org.apache.brooklyn.api.effector.Effector;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.effector.EffectorBody;
+import org.apache.brooklyn.core.effector.Effectors;
+import org.apache.brooklyn.location.jclouds.JcloudsMachineLocation;
+import org.apache.brooklyn.util.collections.MutableList;
+import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.brooklyn.util.net.Cidr;
+import org.apache.brooklyn.util.net.Networking;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.net.domain.IpProtocol;
+
+import java.util.List;
+
+import static com.google.common.base.Predicates.instanceOf;
+import static com.google.common.collect.Iterables.tryFind;
+import static org.apache.brooklyn.core.location.Locations.getLocationsCheckingAncestors;
+
+public class NetworkingEffectors {
+    // Intentionally not use CloudLocationConfig.INBOUND_PORTS to make richer syntax and
rename it to differ it from the first in a ConfigBag
+    public static final ConfigKey<List<String>> INBOUND_PORTS_LIST = ConfigKeys.newConfigKey(new
TypeToken<List<String>>() {}, "inbound.ports.list",
+            "Ports to open from the effector", ImmutableList.<String>of());
+    public static final ConfigKey<IpProtocol> INBOUND_PORTS_LIST_PROTOCOL = ConfigKeys.newConfigKey(new
TypeToken<IpProtocol>() {}, "inbound.ports.list.protocol",
+            "Protocol for ports to open. Possible values: TCP, UDP, ICMP, ALL.", IpProtocol.TCP);
+
+    public static final ConfigKey<JcloudsMachineLocation> JCLOUDS_MACHINE_LOCATIN =
ConfigKeys.newConfigKey(JcloudsMachineLocation.class, "jcloudsMachineLocation");
+
+    @SuppressWarnings("unchecked")
+    public static final Effector<Iterable<IpPermission>> OPEN_INBOUND_PORTS_IN_SECURITY_GROUP_EFFECTOR
= (Effector<Iterable<IpPermission>>)(Effector<?>)Effectors.effector(Iterable.class,
"openPortsInSecurityGroup")
+                .parameter(INBOUND_PORTS_LIST)
+                .parameter(INBOUND_PORTS_LIST_PROTOCOL)
+                .description("Open ports in Cloud Security Group. If called before machine
location is provisioned, it will fail.")
+                .impl(new OpenPortsInSecurityGroupBody())
+                .build();
+
+    @SuppressWarnings("rawtypes")
+    private static class OpenPortsInSecurityGroupBody extends EffectorBody<Iterable>
{
+        @Override
+        public Iterable<IpPermission> call(ConfigBag parameters) {
+            List<String> rawPortRules = parameters.get(INBOUND_PORTS_LIST);
+            IpProtocol ipProtocol = parameters.get(INBOUND_PORTS_LIST_PROTOCOL);
+            JcloudsMachineLocation jcloudsMachineLocation = parameters.get(JCLOUDS_MACHINE_LOCATIN);
+            Preconditions.checkNotNull(ipProtocol, INBOUND_PORTS_LIST_PROTOCOL.getName()
+ " cannot be null");
+            Preconditions.checkNotNull(rawPortRules, INBOUND_PORTS_LIST.getName() + " cannot
be null");
+            MutableList.Builder<IpPermission> ipPermissionsBuilder = MutableList.builder();
+            for (Range<Integer> portRule : Networking.portRulesToRanges(rawPortRules).asRanges())
{
+                ipPermissionsBuilder.add(
+                        IpPermission.builder()
+                                .ipProtocol(ipProtocol)
+                                .fromPort(portRule.lowerEndpoint())
+                                .toPort(portRule.upperEndpoint())
+                                .cidrBlock(Cidr.UNIVERSAL.toString())
+                                .build());
+            }
+            JcloudsLocationSecurityGroupCustomizer customizer = JcloudsLocationSecurityGroupCustomizer.getInstance(entity());
+
+            if (jcloudsMachineLocation == null) {
+                Optional<Location> jcloudsMachineLocationOptional = tryFind(
+                        (Iterable<Location>) getLocationsCheckingAncestors(null, entity()),
+                        instanceOf(JcloudsMachineLocation.class));
+                if (!jcloudsMachineLocationOptional.isPresent()) {
+                    throw new IllegalArgumentException("Tried to execute open ports effector
on an entity with no JcloudsMachineLocation");
+                } else {
+                    jcloudsMachineLocation = (JcloudsMachineLocation)jcloudsMachineLocationOptional.get();
+                }
+            }
+            Iterable<IpPermission> ipPermissionsToAdd = ipPermissionsBuilder.build();
+            customizer.addPermissionsToLocation(jcloudsMachineLocation, ipPermissionsToAdd);
+            return ipPermissionsToAdd;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6d7765b8/software/base/pom.xml
----------------------------------------------------------------------
diff --git a/software/base/pom.xml b/software/base/pom.xml
index 7e0d4fd..daec1dc 100644
--- a/software/base/pom.xml
+++ b/software/base/pom.xml
@@ -70,6 +70,11 @@
             <artifactId>brooklyn-policy</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.brooklyn</groupId>
+            <artifactId>brooklyn-locations-jclouds</artifactId>
+            <version>${project.version}</version>
+        </dependency>
 
         <dependency>
             <groupId>org.freemarker</groupId>
@@ -111,13 +116,6 @@
             <version>${project.version}</version>
             <scope>test</scope>
         </dependency>
-        <!-- bring in jclouds for testing -->
-        <dependency>
-            <groupId>org.apache.brooklyn</groupId>
-            <artifactId>brooklyn-locations-jclouds</artifactId>
-            <version>${project.version}</version>
-            <scope>test</scope>
-        </dependency>
         <dependency>
             <groupId>${jclouds.groupId}</groupId>
             <artifactId>jclouds-core</artifactId>

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6d7765b8/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcess.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcess.java
b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcess.java
index 133ced5..05bdd15 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcess.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcess.java
@@ -147,6 +147,9 @@ public interface SoftwareProcess extends Entity, Startable {
     @SetFromFlag("runDir")
     AttributeSensorAndConfigKey<String,String> RUN_DIR = BrooklynConfigKeys.RUN_DIR;
 
+    ConfigKey<Boolean> ADD_OPEN_INBOUND_PORTS_EFFECTOR = ConfigKeys.newBooleanConfigKey("effector.add.openInboundPorts",
+            "Flag which adds effector for opening ports through Cloud security groups", false);
+
     ConfigKey<Boolean> OPEN_IPTABLES = ConfigKeys.newBooleanConfigKey("openIptables",
             "Whether to open the INBOUND_PORTS via iptables rules; " +
             "if true then ssh in to run iptables commands, as part of machine provisioning",
false);

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6d7765b8/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcessImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcessImpl.java
b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcessImpl.java
index 5abc8e9..0d4dbda 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcessImpl.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcessImpl.java
@@ -28,6 +28,7 @@ import java.util.TimerTask;
 import java.util.concurrent.Callable;
 import java.util.concurrent.TimeUnit;
 
+import org.apache.brooklyn.location.jclouds.networking.NetworkingEffectors;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -130,6 +131,9 @@ public abstract class SoftwareProcessImpl extends AbstractEntity implements
Soft
     public void init() {
         super.init();
         getLifecycleEffectorTasks().attachLifecycleEffectors(this);
+        if (Boolean.TRUE.equals(getConfig(ADD_OPEN_INBOUND_PORTS_EFFECTOR))) {
+            getMutableEntityType().addEffector(NetworkingEffectors.OPEN_INBOUND_PORTS_IN_SECURITY_GROUP_EFFECTOR);
+        }
     }
     
     @Override

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6d7765b8/software/base/src/test/java/org/apache/brooklyn/entity/software/base/location/NetworkEffectorsEc2LiveTests.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/location/NetworkEffectorsEc2LiveTests.java
b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/location/NetworkEffectorsEc2LiveTests.java
new file mode 100644
index 0000000..bf7a67b
--- /dev/null
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/location/NetworkEffectorsEc2LiveTests.java
@@ -0,0 +1,45 @@
+/*
+ * 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 org.apache.brooklyn.entity.software.base.location;
+
+import com.google.common.collect.ImmutableMap;
+import org.testng.annotations.Test;
+
+import java.util.Map;
+
+public class NetworkEffectorsEc2LiveTests extends NetworkingEffectorsLiveTests {
+    public static final String PROVIDER = "aws-ec2";
+    public static final String REGION_NAME = "us-east-1";
+    public static final String LOCATION_SPEC = PROVIDER + (REGION_NAME == null ? "" : ":"
+ REGION_NAME);
+
+    @Test(groups = "Live")
+    public void testPassSecurityGroupParameters() {
+        super.testPassSecurityGroupParameters();
+    }
+
+    @Override
+    public String getLocationSpec() {
+        return LOCATION_SPEC;
+    }
+
+    @Override
+    public Map<String, Object> getLocationProperties() {
+        return ImmutableMap.<String, Object>of("imageId", "us-east-1/ami-a96b01c0",
"hardwareId", "t1.micro");
+    }
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6d7765b8/software/base/src/test/java/org/apache/brooklyn/entity/software/base/location/NetworkingEffectorsLiveTests.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/location/NetworkingEffectorsLiveTests.java
b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/location/NetworkingEffectorsLiveTests.java
new file mode 100644
index 0000000..482432c
--- /dev/null
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/location/NetworkingEffectorsLiveTests.java
@@ -0,0 +1,108 @@
+/*
+ * 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 org.apache.brooklyn.entity.software.base.location;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+import org.apache.brooklyn.api.effector.Effector;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.mgmt.Task;
+import org.apache.brooklyn.core.mgmt.internal.EffectorUtils;
+import org.apache.brooklyn.core.test.BrooklynAppLiveTestSupport;
+import org.apache.brooklyn.entity.software.base.EmptySoftwareProcess;
+import org.apache.brooklyn.entity.software.base.SoftwareProcess;
+import org.apache.brooklyn.location.jclouds.JcloudsLocation;
+import org.apache.brooklyn.location.jclouds.JcloudsMachineLocation;
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.domain.SecurityGroup;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.net.domain.IpProtocol;
+import org.testng.annotations.Test;
+
+import java.util.Map;
+import java.util.Set;
+
+import static org.apache.brooklyn.location.jclouds.networking.NetworkingEffectors.INBOUND_PORTS_LIST;
+import static org.apache.brooklyn.location.jclouds.networking.NetworkingEffectors.INBOUND_PORTS_LIST_PROTOCOL;
+import static org.apache.brooklyn.test.Asserts.assertTrue;
+import static org.jclouds.net.domain.IpProtocol.TCP;
+import static org.jclouds.net.domain.IpProtocol.UDP;
+
+public abstract class NetworkingEffectorsLiveTests extends BrooklynAppLiveTestSupport {
+    @Test(groups = "Live")
+    public void testPassSecurityGroupParameters() {
+        EmptySoftwareProcess emptySoftwareProcess = app.createAndManageChild(EntitySpec.create(EmptySoftwareProcess.class)
+                .configure(SoftwareProcess.ADD_OPEN_INBOUND_PORTS_EFFECTOR, true));
+
+        JcloudsLocation jcloudsLocation = (JcloudsLocation)mgmt.getLocationRegistry().getLocationManaged(getLocationSpec(),
getLocationProperties());
+        app.start(ImmutableList.of(jcloudsLocation));
+
+        Optional<Location> jcloudsMachineLocation = Iterables.tryFind(emptySoftwareProcess.getLocations(),
Predicates.instanceOf(JcloudsMachineLocation.class));
+        if (!jcloudsMachineLocation.isPresent()) {
+            throw new IllegalArgumentException("Tried to execute open ports effector on an
entity with no JcloudsMachineLocation");
+        }
+        ComputeService computeService = ((JcloudsMachineLocation)jcloudsMachineLocation.get()).getParent().getComputeService();
+        String nodeId = ((JcloudsMachineLocation)jcloudsMachineLocation.get()).getNode().getId();
+        final SecurityGroupExtension securityApi = computeService.getSecurityGroupExtension().get();
+
+        Effector<Iterable<IpPermission>> openPortsInSecurityGroup = (Effector<Iterable<IpPermission>>)EffectorUtils.findEffectorDeclared(emptySoftwareProcess,
"openPortsInSecurityGroup").get();
+        Task<Iterable<IpPermission>> task = EffectorUtils.invokeEffectorAsync(emptySoftwareProcess,
openPortsInSecurityGroup,
+                ImmutableMap.of(INBOUND_PORTS_LIST.getName(), "234,324,550-1050"));
+        Iterable<IpPermission> effectorResult = task.getUnchecked();
+        for (Predicate<IpPermission> ipPermissionPredicate : ImmutableList.of(ruleExistsPredicate(234,
234, TCP), ruleExistsPredicate(324, 324, TCP), ruleExistsPredicate(550, 1050, TCP))) {
+            assertTrue(Iterables.tryFind(effectorResult, ipPermissionPredicate).isPresent());
+        }
+
+        task = EffectorUtils.invokeEffectorAsync(emptySoftwareProcess, openPortsInSecurityGroup,
+                ImmutableMap.of(INBOUND_PORTS_LIST.getName(), "234,324,550-1050", INBOUND_PORTS_LIST_PROTOCOL.getName(),
"UDP"));
+        effectorResult = task.getUnchecked();
+        for (Predicate<IpPermission> ipPermissionPredicate : ImmutableList.of(ruleExistsPredicate(234,
234, UDP), ruleExistsPredicate(324, 324, UDP), ruleExistsPredicate(550, 1050, UDP))) {
+            assertTrue(Iterables.tryFind(effectorResult, ipPermissionPredicate).isPresent());
+        }
+
+        Set<SecurityGroup> groupsOnNode = securityApi.listSecurityGroupsForNode(nodeId);
+        SecurityGroup securityGroup = Iterables.getOnlyElement(groupsOnNode);
+
+        assertTrue(Iterables.tryFind(securityGroup.getIpPermissions(), ruleExistsPredicate(234,
234, TCP)).isPresent());
+        assertTrue(Iterables.tryFind(securityGroup.getIpPermissions(), ruleExistsPredicate(324,
324, TCP)).isPresent());
+        assertTrue(Iterables.tryFind(securityGroup.getIpPermissions(), ruleExistsPredicate(550,
1050, TCP)).isPresent());
+
+        assertTrue(Iterables.tryFind(securityGroup.getIpPermissions(), ruleExistsPredicate(234,
234, UDP)).isPresent());
+        assertTrue(Iterables.tryFind(securityGroup.getIpPermissions(), ruleExistsPredicate(324,
324, UDP)).isPresent());
+        assertTrue(Iterables.tryFind(securityGroup.getIpPermissions(), ruleExistsPredicate(550,
1050, UDP)).isPresent());
+    }
+
+    protected Predicate<IpPermission> ruleExistsPredicate(final int fromPort, final
int toPort, final IpProtocol ipProtocol) {
+        return new Predicate<IpPermission>() {
+            public boolean apply(IpPermission ipPermission) {
+                return ipPermission.getFromPort() == fromPort && ipPermission.getToPort()
== toPort && ipPermission.getIpProtocol() == ipProtocol;
+            }
+        };
+    }
+
+    public abstract String getLocationSpec();
+
+    public abstract Map<String, Object> getLocationProperties();
+}


Mime
View raw message