Creating security groups automatically for load balancers.

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

Branch: refs/heads/gsoc-projects-2015
Commit: f6396ffe9b90c84b755eb8aa7685103073946b1d
Parents: c979a0d
Author: swapnilpatilRajaram <[email protected]>
Authored: Wed Jul 29 08:12:27 2015 +0000
Committer: swapnilpatilRajaram <[email protected]>
Committed: Wed Jul 29 08:12:27 2015 +0000

----------------------------------------------------------------------
 .../aws-extension/src/main/assembly/bin.xml     |   2 +-
 .../aws-extension/src/main/bin/aws-extension.sh |   2 +-
 .../aws-extension/src/main/conf/aws.properties  |   6 +
 .../apache/stratos/aws/extension/AWSHelper.java | 159 ++++++++++++++++---
 .../stratos/aws/extension/AWSLoadBalancer.java  |  11 +-
 .../apache/stratos/aws/extension/Constants.java |   4 +-
 6 files changed, 153 insertions(+), 31 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/stratos/blob/f6396ffe/extensions/load-balancer/aws-extension/src/main/assembly/bin.xml
----------------------------------------------------------------------
diff --git a/extensions/load-balancer/aws-extension/src/main/assembly/bin.xml 
b/extensions/load-balancer/aws-extension/src/main/assembly/bin.xml
index 036ad1c..ba0ad12 100644
--- a/extensions/load-balancer/aws-extension/src/main/assembly/bin.xml
+++ b/extensions/load-balancer/aws-extension/src/main/assembly/bin.xml
@@ -41,7 +41,7 @@
                 <include>jndi.properties</include>
                 <include>log4j.properties</include>
                 <include>thrift-client-config.xml</include>
-                <include>aws-credentials.conf</include>
+                <include>aws.properties</include>
             </includes>
         </fileSet>
         <fileSet>

http://git-wip-us.apache.org/repos/asf/stratos/blob/f6396ffe/extensions/load-balancer/aws-extension/src/main/bin/aws-extension.sh
----------------------------------------------------------------------
diff --git 
a/extensions/load-balancer/aws-extension/src/main/bin/aws-extension.sh 
b/extensions/load-balancer/aws-extension/src/main/bin/aws-extension.sh
index 4451ace..19936ae 100755
--- a/extensions/load-balancer/aws-extension/src/main/bin/aws-extension.sh
+++ b/extensions/load-balancer/aws-extension/src/main/bin/aws-extension.sh
@@ -26,7 +26,7 @@ lib_path=${script_path}/../lib/
 class_path=`echo ${lib_path}/*.jar | tr ' ' ':'`
 properties="-Djndi.properties.dir=${script_path}/../conf
             
-Dlog4j.properties.file.path=${script_path}/../conf/log4j.properties
-            -Daws.credentials.file=${script_path}/../conf/aws-credentials.conf
+            -Daws.properties.file=${script_path}/../conf/aws.properties
             
-Djavax.net.ssl.trustStore=${script_path}/../security/client-truststore.jks
             -Djavax.net.ssl.trustStorePassword=wso2carbon
             
-Dthrift.client.config.file.path=${script_path}/../conf/thrift-client-config.xml

http://git-wip-us.apache.org/repos/asf/stratos/blob/f6396ffe/extensions/load-balancer/aws-extension/src/main/conf/aws.properties
----------------------------------------------------------------------
diff --git 
a/extensions/load-balancer/aws-extension/src/main/conf/aws.properties 
b/extensions/load-balancer/aws-extension/src/main/conf/aws.properties
new file mode 100644
index 0000000..05ebded
--- /dev/null
+++ b/extensions/load-balancer/aws-extension/src/main/conf/aws.properties
@@ -0,0 +1,6 @@
+access-key=
+secret-key=
+# load-balancer-prefix should contain only alphabets and dashes and should not 
exceed 25 characters.
+load-balancer-prefix=LB-
+# security group will be created if does not exist. Should contain only ASCII 
characters and should not exceed 255 characters.
+load-balancer-security-group-name=lb-security-group
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/stratos/blob/f6396ffe/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSHelper.java
----------------------------------------------------------------------
diff --git 
a/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSHelper.java
 
b/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSHelper.java
index 1520674..f2e742c 100644
--- 
a/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSHelper.java
+++ 
b/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSHelper.java
@@ -28,6 +28,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Properties;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -36,6 +37,11 @@ import 
org.apache.stratos.load.balancer.extension.api.exception.LoadBalancerExte
 
 import com.amazonaws.ClientConfiguration;
 import com.amazonaws.auth.BasicAWSCredentials;
+import com.amazonaws.services.ec2.AmazonEC2Client;
+import com.amazonaws.services.ec2.model.AuthorizeSecurityGroupIngressRequest;
+import com.amazonaws.services.ec2.model.CreateSecurityGroupRequest;
+import com.amazonaws.services.ec2.model.CreateSecurityGroupResult;
+import com.amazonaws.services.ec2.model.IpPermission;
 import 
com.amazonaws.services.elasticloadbalancing.AmazonElasticLoadBalancingClient;
 import com.amazonaws.services.elasticloadbalancing.model.*;
 
@@ -45,11 +51,16 @@ public class AWSHelper {
        private String lbPrefix;
        private int lbSequence;
        private Object lbSequenceMutex;
+       private String lbSecurityGroupName;
+       private String lbSecurityGroupDescription;
+
+       private ConcurrentHashMap<String, String> regionToSecurityGroupIdMap;
 
        private BasicAWSCredentials awsCredentials;
        private ClientConfiguration clientConfiguration;
 
        AmazonElasticLoadBalancingClient lbClient;
+       AmazonEC2Client ec2Client;
 
        private static final Log log = LogFactory.getLog(AWSHelper.class);
 
@@ -57,15 +68,15 @@ public class AWSHelper {
                // Read values for awsAccessKey, awsSecretKey etc. from config 
file
                // Throw a proper exception / log warning if cant read 
credentials ?
 
-               String awsCredentialsFile = System
-                               .getProperty(Constants.AWS_CREDENTIALS_FILE);
+               String awsPropertiesFile = System
+                               .getProperty(Constants.AWS_PROPERTIES_FILE);
 
                Properties properties = new Properties();
 
                InputStream inputStream = null;
 
                try {
-                       inputStream = new FileInputStream(awsCredentialsFile);
+                       inputStream = new FileInputStream(awsPropertiesFile);
 
                        properties.load(inputStream);
 
@@ -74,27 +85,42 @@ public class AWSHelper {
                        this.awsSecretKey = properties
                                        .getProperty(Constants.AWS_SECRET_KEY);
 
-                       if(this.awsAccessKey.isEmpty() || 
this.awsSecretKey.isEmpty())
-                       {
-                               throw new 
LoadBalancerExtensionException("Invalid AWS credentials.");
+                       if (this.awsAccessKey.isEmpty() || 
this.awsSecretKey.isEmpty()) {
+                               throw new LoadBalancerExtensionException(
+                                               "Invalid AWS credentials.");
                        }
 
                        this.lbPrefix = 
properties.getProperty(Constants.LB_PREFIX);
 
-                       if(this.lbPrefix.isEmpty() || this.lbPrefix.length() > 
25)
-                       {
-                               throw new 
LoadBalancerExtensionException("Invalid load balancer prefix.");
+                       if (this.lbPrefix.isEmpty() || this.lbPrefix.length() > 
25) {
+                               throw new LoadBalancerExtensionException(
+                                               "Invalid load balancer 
prefix.");
                        }
 
                        lbSequence = 0;
                        lbSequenceMutex = new Object();
 
+                       this.lbSecurityGroupName = properties
+                                       
.getProperty(Constants.LOAD_BALANCER_SECURITY_GROUP_NAME);
+
+                       if (this.lbSecurityGroupName.isEmpty()
+                                       || this.lbSecurityGroupName.length() > 
255) {
+                               throw new LoadBalancerExtensionException(
+                                               "Invalid load balancer security 
group name.");
+                       }
+
+                       this.lbSecurityGroupDescription = 
Constants.LOAD_BALANCER_SECURITY_GROUP_DESCRIPTION;
+
+                       regionToSecurityGroupIdMap = new 
ConcurrentHashMap<String, String>();
+
                        awsCredentials = new BasicAWSCredentials(awsAccessKey, 
awsSecretKey);
                        clientConfiguration = new ClientConfiguration();
 
                        lbClient = new 
AmazonElasticLoadBalancingClient(awsCredentials,
                                        clientConfiguration);
 
+                       ec2Client = new AmazonEC2Client(awsCredentials, 
clientConfiguration);
+
                } catch (IOException e) {
                        log.error("Error reading aws configuration file.");
                        throw new LoadBalancerExtensionException(
@@ -108,8 +134,7 @@ public class AWSHelper {
                }
        }
 
-       public int getNextLBSequence()
-       {
+       public int getNextLBSequence() {
                synchronized (lbSequenceMutex) {
                        lbSequence++;
                        return lbSequence;
@@ -140,10 +165,16 @@ public class AWSHelper {
 
                
createLoadBalancerRequest.setAvailabilityZones(availabilityZones);
 
-               lbClient.setEndpoint("elasticloadbalancing." + region
-                               + ".amazonaws.com");
-
                try {
+                       String securityGroupId = 
getSecurityGroupIdForRegion(region);
+
+                       List<String> securityGroups = new ArrayList<String>();
+                       securityGroups.add(securityGroupId);
+
+                       
createLoadBalancerRequest.setSecurityGroups(securityGroups);
+
+                       lbClient.setEndpoint("elasticloadbalancing." + region
+                                       + ".amazonaws.com");
 
                        CreateLoadBalancerResult clbResult = lbClient
                                        
.createLoadBalancer(createLoadBalancerRequest);
@@ -206,7 +237,7 @@ public class AWSHelper {
                try {
                        lbClient.setEndpoint("elasticloadbalancing." + region
                                        + ".amazonaws.com");
-                       
+
                        RegisterInstancesWithLoadBalancerResult result = 
lbClient
                                        
.registerInstancesWithLoadBalancer(registerInstancesWithLoadBalancerRequest);
                        return;
@@ -239,7 +270,7 @@ public class AWSHelper {
                try {
                        lbClient.setEndpoint("elasticloadbalancing." + region
                                        + ".amazonaws.com");
-                       
+
                        DeregisterInstancesFromLoadBalancerResult result = 
lbClient
                                        
.deregisterInstancesFromLoadBalancer(deregisterInstancesFromLoadBalancerRequest);
                        return;
@@ -272,7 +303,7 @@ public class AWSHelper {
                try {
                        lbClient.setEndpoint("elasticloadbalancing." + region
                                        + ".amazonaws.com");
-                       
+
                        DescribeLoadBalancersResult result = lbClient
                                        
.describeLoadBalancers(describeLoadBalancersRequest);
 
@@ -297,9 +328,11 @@ public class AWSHelper {
         * @param region
         * @return list of instances attached
         */
-       public List<Instance> getAttachedInstances(String loadBalancerName, 
String region) {
+       public List<Instance> getAttachedInstances(String loadBalancerName,
+                       String region) {
                try {
-                       LoadBalancerDescription lbDescription = 
getLoadBalancerDescription(loadBalancerName, region);
+                       LoadBalancerDescription lbDescription = 
getLoadBalancerDescription(
+                                       loadBalancerName, region);
 
                        if (lbDescription == null) {
                                log.warn("Could not find description of load 
balancer "
@@ -398,9 +431,11 @@ public class AWSHelper {
         * @param region
         * @return list of instances attached to load balancer
         */
-       public List<Listener> getAttachedListeners(String loadBalancerName, 
String region) {
+       public List<Listener> getAttachedListeners(String loadBalancerName,
+                       String region) {
                try {
-                       LoadBalancerDescription lbDescription = 
getLoadBalancerDescription(loadBalancerName, region);
+                       LoadBalancerDescription lbDescription = 
getLoadBalancerDescription(
+                                       loadBalancerName, region);
 
                        if (lbDescription == null) {
                                log.warn("Could not find description of load 
balancer "
@@ -427,6 +462,80 @@ public class AWSHelper {
 
        }
 
+       public String createSecurityGroup(String groupName, String description,
+                       String region) throws LoadBalancerExtensionException {
+               if (groupName == null || groupName.isEmpty()) {
+                       throw new LoadBalancerExtensionException(
+                                       "Invalid Security Group Name.");
+               }
+
+               CreateSecurityGroupRequest createSecurityGroupRequest = new 
CreateSecurityGroupRequest();
+               createSecurityGroupRequest.setGroupName(groupName);
+               createSecurityGroupRequest.setDescription(description);
+
+               try {
+                       ec2Client.setEndpoint("ec2." + region + 
".amazonaws.com");
+
+                       CreateSecurityGroupResult createSecurityGroupResult = 
ec2Client
+                                       
.createSecurityGroup(createSecurityGroupRequest);
+
+                       return createSecurityGroupResult.getGroupId();
+
+               } catch (Exception e) {
+                       e.printStackTrace();
+                       throw new LoadBalancerExtensionException(
+                                       "Could not create security group.");
+               }
+
+       }
+
+       public void addInboundRuleToSecurityGroup(String groupId, String region)
+                       throws LoadBalancerExtensionException {
+               if (groupId == null || groupId.isEmpty()) {
+                       throw new LoadBalancerExtensionException(
+                                       "Invalid security group Id for 
addInboundRuleToSecurityGroup.");
+               }
+
+               AuthorizeSecurityGroupIngressRequest 
authorizeSecurityGroupIngressRequest = new 
AuthorizeSecurityGroupIngressRequest();
+               authorizeSecurityGroupIngressRequest.setGroupId(groupId);
+               authorizeSecurityGroupIngressRequest.setCidrIp("0.0.0.0/0");
+               authorizeSecurityGroupIngressRequest.setFromPort(0);
+               authorizeSecurityGroupIngressRequest.setToPort(65535);
+               authorizeSecurityGroupIngressRequest.setIpProtocol("tcp");
+
+               try {
+                       ec2Client.setEndpoint("ec2." + region + 
".amazonaws.com");
+
+                       ec2Client
+                                       
.authorizeSecurityGroupIngress(authorizeSecurityGroupIngressRequest);
+
+               } catch (Exception e) {
+                       throw new LoadBalancerExtensionException(
+                                       "Could not add inbound rule to security 
group " + groupId
+                                                       + ".");
+               }
+       }
+
+       public String getSecurityGroupIdForRegion(String region)
+                       throws LoadBalancerExtensionException {
+               if (region == null)
+                       return null;
+
+               if (this.regionToSecurityGroupIdMap.contains(region)) {
+                       return this.regionToSecurityGroupIdMap.get(region);
+               } else {
+                       String securityGroupId = createSecurityGroup(
+                                       this.lbSecurityGroupName, 
this.lbSecurityGroupDescription,
+                                       region);
+                       this.regionToSecurityGroupIdMap.put(region, 
securityGroupId);
+
+                       // Also add the inbound rule
+                       addInboundRuleToSecurityGroup(securityGroupId, region);
+
+                       return securityGroupId;
+               }
+       }
+
        /**
         * Returns the Listeners required for the service. Listeners are derived
         * from the proxy port, port and protocol values of the service.
@@ -461,13 +570,15 @@ public class AWSHelper {
         * @return name of the load balancer
         * @throws LoadBalancerExtensionException
         */
-       public String generateLoadBalancerName() throws 
LoadBalancerExtensionException {
+       public String generateLoadBalancerName()
+                       throws LoadBalancerExtensionException {
                String name = null;
 
                name = lbPrefix + getNextLBSequence();
 
-               if(name.length() > 32)
-                       throw new LoadBalancerExtensionException("Load 
balanacer name length exceeded");
+               if (name.length() > 32)
+                       throw new LoadBalancerExtensionException(
+                                       "Load balanacer name length exceeded");
 
                return name;
        }

http://git-wip-us.apache.org/repos/asf/stratos/blob/f6396ffe/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSLoadBalancer.java
----------------------------------------------------------------------
diff --git 
a/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSLoadBalancer.java
 
b/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSLoadBalancer.java
index 7bf93e8..4eff571 100644
--- 
a/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSLoadBalancer.java
+++ 
b/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSLoadBalancer.java
@@ -24,6 +24,7 @@ import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -39,12 +40,12 @@ public class AWSLoadBalancer implements LoadBalancer {
        private static final Log log = LogFactory.getLog(AWSLoadBalancer.class);
 
        // A map <clusterId, load balancer id>
-       private HashMap<String, LoadBalancerInfo> clusterIdToLoadBalancerMap;
+       private ConcurrentHashMap<String, LoadBalancerInfo> 
clusterIdToLoadBalancerMap;
 
        private AWSHelper awsHelper;
 
        public AWSLoadBalancer() throws LoadBalancerExtensionException {
-               clusterIdToLoadBalancerMap = new HashMap<String, 
LoadBalancerInfo>();
+               clusterIdToLoadBalancerMap = new ConcurrentHashMap<String, 
LoadBalancerInfo>();
                awsHelper = new AWSHelper();
        }
 
@@ -151,7 +152,8 @@ public class AWSLoadBalancer implements LoadBalancer {
                                                List<Listener> 
listenersToAddToLoadBalancer = new ArrayList<Listener>();
 
                                                List<Listener> 
listenersForThisCluster = awsHelper
-                                                               
.getRequiredListeners(clusterMembers.iterator().next());
+                                                               
.getRequiredListeners(clusterMembers.iterator()
+                                                                               
.next());
 
                                                for (Listener listener : 
listenersForThisCluster) {
                                                        if (attachedListeners 
== null
@@ -195,7 +197,8 @@ public class AWSLoadBalancer implements LoadBalancer {
                                                                
.iterator().next().getInstanceId());
 
                                                List<Listener> 
listenersForThisCluster = awsHelper
-                                                               
.getRequiredListeners(clusterMembers.iterator().next());
+                                                               
.getRequiredListeners(clusterMembers.iterator()
+                                                                               
.next());
 
                                                String loadBalancerDNSName = 
awsHelper
                                                                
.createLoadBalancer(loadBalancerName,

http://git-wip-us.apache.org/repos/asf/stratos/blob/f6396ffe/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/Constants.java
----------------------------------------------------------------------
diff --git 
a/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/Constants.java
 
b/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/Constants.java
index d03915c..f3ffb94 100644
--- 
a/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/Constants.java
+++ 
b/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/Constants.java
@@ -29,8 +29,10 @@ public class Constants {
     public static final String NETWORK_PARTITION_ID = "network.partition.id";
     public static final String CLUSTER_ID = "cluster.id";
     public static final String SERVICE_NAME = "service.name";
-    public static final String AWS_CREDENTIALS_FILE="aws.credentials.file";
+    public static final String AWS_PROPERTIES_FILE="aws.properties.file";
     public static final String AWS_ACCESS_KEY = "access-key";
     public static final String AWS_SECRET_KEY = "secret-key";
     public static final String LB_PREFIX = "load-balancer-prefix";
+    public static final String LOAD_BALANCER_SECURITY_GROUP_NAME = 
"load-balancer-security-group-name";
+    public static final String LOAD_BALANCER_SECURITY_GROUP_DESCRIPTION = 
"Security group for load balancers created for Apache Stratos.";
 }

Reply via email to