Added inbound rule to security group based on the port mappings of a member in 
the cluster.


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

Branch: refs/heads/gsoc-projects-2015
Commit: cae92c5e53386566dfd933557b6ca7068be2c61f
Parents: 1a2097e
Author: swapnilpatilRajaram <[email protected]>
Authored: Mon Aug 3 14:27:28 2015 +0000
Committer: swapnilpatilRajaram <[email protected]>
Committed: Mon Aug 3 14:27:28 2015 +0000

----------------------------------------------------------------------
 .../aws-extension/src/main/conf/aws.properties  |   8 +-
 .../apache/stratos/aws/extension/AWSHelper.java | 159 ++++++++++++++-----
 .../stratos/aws/extension/AWSLoadBalancer.java  | 145 ++++++++++-------
 .../apache/stratos/aws/extension/Constants.java |   2 +
 4 files changed, 219 insertions(+), 95 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/stratos/blob/cae92c5e/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
index 05ebded..d4cc18a 100644
--- a/extensions/load-balancer/aws-extension/src/main/conf/aws.properties
+++ b/extensions/load-balancer/aws-extension/src/main/conf/aws.properties
@@ -3,4 +3,10 @@ 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
+load-balancer-security-group-name=lb-security-group
+# CIDR IP which can be set as allowed source IP of incoming requests for 
security group mentioned in 'load-balancer-security-group-name'
+# 0.0.0.0/0 allows all IPs
+allowed-cidr-ip=0.0.0.0/0
+# Internet Protocol allowed for incoming requests for security group mentioned 
in 'load-balancer-security-group-name'. 
+# Comma separated e.g. tcp,udp
+allowed-protocols=tcp

http://git-wip-us.apache.org/repos/asf/stratos/blob/cae92c5e/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 164625f..b822939 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
@@ -55,10 +55,13 @@ public class AWSHelper {
        private String awsAccessKey;
        private String awsSecretKey;
        private String lbPrefix;
-       private AtomicInteger lbSequence;
-
        private String lbSecurityGroupName;
        private String lbSecurityGroupDescription;
+       private String allowedCidrIpForLBSecurityGroup;
+
+       private AtomicInteger lbSequence;
+
+       private List<String> allowedProtocolsForLBSecurityGroup;
 
        private ConcurrentHashMap<String, String> regionToSecurityGroupIdMap;
 
@@ -114,6 +117,30 @@ public class AWSHelper {
                                                "Invalid load balancer security 
group name.");
                        }
 
+                       this.allowedCidrIpForLBSecurityGroup = properties
+                                       
.getProperty(Constants.ALLOWED_CIDR_IP_KEY);
+
+                       if (this.allowedCidrIpForLBSecurityGroup.isEmpty()) {
+                               throw new LoadBalancerExtensionException(
+                                               "Invalid allowed CIDR IP.");
+                       }
+
+                       String allowedProtocols = properties
+                                       
.getProperty(Constants.ALLOWED_PROTOCOLS);
+
+                       if (allowedProtocols.isEmpty()) {
+                               throw new LoadBalancerExtensionException(
+                                               "Please specify at least one 
Internet protocol.");
+                       }
+
+                       String[] protocols = allowedProtocols.split(",");
+
+                       this.allowedProtocolsForLBSecurityGroup = new 
ArrayList<String>();
+
+                       for (String protocol : protocols) {
+                               
this.allowedProtocolsForLBSecurityGroup.add(protocol);
+                       }
+
                        this.lbSecurityGroupDescription = 
Constants.LOAD_BALANCER_SECURITY_GROUP_DESCRIPTION;
 
                        regionToSecurityGroupIdMap = new 
ConcurrentHashMap<String, String>();
@@ -143,6 +170,14 @@ public class AWSHelper {
                return lbSequence.getAndIncrement();
        }
 
+       public String getLbSecurityGroupName() {
+               return lbSecurityGroupName;
+       }
+
+       public List<String> getAllowedProtocolsForLBSecurityGroup() {
+               return allowedProtocolsForLBSecurityGroup;
+       }
+
        /**
         * Creates a load balancer and returns its DNS name. Useful when a new
         * cluster is added.
@@ -151,7 +186,7 @@ public class AWSHelper {
         * @param listeners
         * @param region
         * @return DNS name of newly created load balancer
-        * @throws LoadBalancerExtensionException 
+        * @throws LoadBalancerExtensionException
         */
        public String createLoadBalancer(String name, List<Listener> listeners,
                        String region) throws LoadBalancerExtensionException {
@@ -185,7 +220,8 @@ public class AWSHelper {
                        return clbResult.getDNSName();
 
                } catch (AmazonClientException e) {
-                       throw new LoadBalancerExtensionException("Could not 
create load balancer " + name, e);
+                       throw new LoadBalancerExtensionException(
+                                       "Could not create load balancer " + 
name, e);
                }
 
        }
@@ -380,10 +416,8 @@ public class AWSHelper {
 
        }
 
-       public String getSecurityGroupId(String groupName, String region)
-       {
-               if(groupName == null || groupName.isEmpty())
-               {
+       public String getSecurityGroupId(String groupName, String region) {
+               if (groupName == null || groupName.isEmpty()) {
                        return null;
                }
 
@@ -395,15 +429,16 @@ public class AWSHelper {
                describeSecurityGroupsRequest.setGroupNames(groupNames);
 
                try {
-                       
ec2Client.setEndpoint(String.format(Constants.EC2_ENDPOINT_URL_FORMAT, region));
+                       ec2Client.setEndpoint(String.format(
+                                       Constants.EC2_ENDPOINT_URL_FORMAT, 
region));
 
                        DescribeSecurityGroupsResult 
describeSecurityGroupsResult = ec2Client
                                        
.describeSecurityGroups(describeSecurityGroupsRequest);
 
-                       List<SecurityGroup> securityGroups = 
describeSecurityGroupsResult.getSecurityGroups();
+                       List<SecurityGroup> securityGroups = 
describeSecurityGroupsResult
+                                       .getSecurityGroups();
 
-                       if( securityGroups != null && securityGroups.size() > 0)
-                       {
+                       if (securityGroups != null && securityGroups.size() > 
0) {
                                return securityGroups.get(0).getGroupId();
                        }
                } catch (AmazonClientException e) {
@@ -425,7 +460,8 @@ public class AWSHelper {
                createSecurityGroupRequest.setDescription(description);
 
                try {
-                       
ec2Client.setEndpoint(String.format(Constants.EC2_ENDPOINT_URL_FORMAT, region));
+                       ec2Client.setEndpoint(String.format(
+                                       Constants.EC2_ENDPOINT_URL_FORMAT, 
region));
 
                        CreateSecurityGroupResult createSecurityGroupResult = 
ec2Client
                                        
.createSecurityGroup(createSecurityGroupRequest);
@@ -440,30 +476,85 @@ public class AWSHelper {
 
        }
 
-       public void addInboundRuleToSecurityGroup(String groupId, String region)
-                       throws LoadBalancerExtensionException {
+       public void addInboundRuleToSecurityGroup(String groupId, String region,
+                       String protocol, int port) 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");
+               boolean ruleAlreadyPresent = false;
+
+               DescribeSecurityGroupsRequest describeSecurityGroupsRequest = 
new DescribeSecurityGroupsRequest();
+
+               List<String> groupIds = new ArrayList<String>();
+               groupIds.add(groupId);
+
+               describeSecurityGroupsRequest.setGroupIds(groupIds);
+
+               SecurityGroup secirutyGroup = null;
 
                try {
-                       
ec2Client.setEndpoint(String.format(Constants.EC2_ENDPOINT_URL_FORMAT, region));
+                       ec2Client.setEndpoint(String.format(
+                                       Constants.EC2_ENDPOINT_URL_FORMAT, 
region));
 
-                       ec2Client
-                                       
.authorizeSecurityGroupIngress(authorizeSecurityGroupIngressRequest);
+                       DescribeSecurityGroupsResult 
describeSecurityGroupsResult = ec2Client
+                                       
.describeSecurityGroups(describeSecurityGroupsRequest);
+
+                       List<SecurityGroup> securityGroups = 
describeSecurityGroupsResult
+                                       .getSecurityGroups();
 
+                       if (securityGroups != null && securityGroups.size() > 
0) {
+                               secirutyGroup = securityGroups.get(0);
+                       }
                } catch (AmazonClientException e) {
-                       throw new LoadBalancerExtensionException(
-                                       "Could not add inbound rule to security 
group " + groupId
-                                                       + ".");
+                       log.debug("Could not describe security groups.", e);
+               }
+
+               if (secirutyGroup != null) {
+                       List<IpPermission> existingPermissions = secirutyGroup
+                                       .getIpPermissions();
+
+                       IpPermission neededPermission = new IpPermission();
+                       neededPermission.setFromPort(port);
+                       neededPermission.setToPort(port);
+                       neededPermission.setIpProtocol(protocol);
+
+                       Collection<String> ipRanges = new HashSet<String>();
+                       ipRanges.add(this.allowedCidrIpForLBSecurityGroup);
+
+                       neededPermission.setIpRanges(ipRanges);
+
+                       if (existingPermissions.contains(neededPermission)) {
+                               ruleAlreadyPresent = true;
+                       }
+               }
+
+               if (!ruleAlreadyPresent) {
+                       AuthorizeSecurityGroupIngressRequest 
authorizeSecurityGroupIngressRequest = new 
AuthorizeSecurityGroupIngressRequest();
+                       
authorizeSecurityGroupIngressRequest.setGroupId(groupId);
+                       authorizeSecurityGroupIngressRequest
+                                       
.setCidrIp(this.allowedCidrIpForLBSecurityGroup);
+                       authorizeSecurityGroupIngressRequest.setFromPort(port);
+                       authorizeSecurityGroupIngressRequest.setToPort(port);
+                       
authorizeSecurityGroupIngressRequest.setIpProtocol(protocol);
+
+                       try {
+                               ec2Client.setEndpoint(String.format(
+                                               
Constants.EC2_ENDPOINT_URL_FORMAT, region));
+
+                               ec2Client
+                                               
.authorizeSecurityGroupIngress(authorizeSecurityGroupIngressRequest);
+
+                       } catch (AmazonClientException e) {
+
+                               // if(!e.getMessage().contains("already exist"))
+                               // {
+                               throw new LoadBalancerExtensionException(
+                                               "Could not add inbound rule to 
security group "
+                                                               + groupId + 
".");
+                               // }
+                       }
                }
        }
 
@@ -476,20 +567,16 @@ public class AWSHelper {
                        return this.regionToSecurityGroupIdMap.get(region);
                } else {
                        // Get the the security group id if it is already 
present.
-                       String securityGroupId = 
getSecurityGroupId(this.lbSecurityGroupName, region);
+                       String securityGroupId = getSecurityGroupId(
+                                       this.lbSecurityGroupName, region);
 
-                       if(securityGroupId == null)
-                       {
-                               securityGroupId = createSecurityGroup(
-                                       this.lbSecurityGroupName, 
this.lbSecurityGroupDescription,
-                                       region);
+                       if (securityGroupId == null) {
+                               securityGroupId = 
createSecurityGroup(this.lbSecurityGroupName,
+                                               
this.lbSecurityGroupDescription, region);
                        }
 
                        this.regionToSecurityGroupIdMap.put(region, 
securityGroupId);
 
-                       // Also add the inbound rule
-                       addInboundRuleToSecurityGroup(securityGroupId, region);
-
                        return securityGroupId;
                }
        }

http://git-wip-us.apache.org/repos/asf/stratos/blob/cae92c5e/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 f9e2e32..c3b80c7 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
@@ -51,10 +51,11 @@ public class AWSLoadBalancer implements LoadBalancer {
                awsHelper = new AWSHelper();
        }
 
-       /* 
-        * configure method iterates over topology and configures the AWS load 
balancers needed.
-        * Configuration may involve creating a new load balancer for a 
cluster, updating existing load balancers
-        * or deleting unwanted load balancers.
+       /*
+        * configure method iterates over topology and configures the AWS load
+        * balancers needed. Configuration may involve creating a new load 
balancer
+        * for a cluster, updating existing load balancers or deleting unwanted 
load
+        * balancers.
         */
        public boolean configure(Topology topology)
                        throws LoadBalancerExtensionException {
@@ -81,7 +82,8 @@ public class AWSLoadBalancer implements LoadBalancer {
                                                // 1. Get all the instances 
attached
                                                // Add/remove instances as 
necessary
 
-                                               // attachedInstances list is 
useful in finding out what all new instances
+                                               // attachedInstances list is 
useful in finding out what
+                                               // all new instances
                                                // should be attached to this 
load balancer.
                                                List<Instance> 
attachedInstances = awsHelper
                                                                
.getAttachedInstances(loadBalancerName, region);
@@ -109,7 +111,8 @@ public class AWSLoadBalancer implements LoadBalancer {
                                                                                
                .getInstanceId()));
 
                                                                if 
(attachedInstances == null
-                                                                               
|| !attachedInstances.contains(instance)) {
+                                                                               
|| !attachedInstances
+                                                                               
                .contains(instance)) {
                                                                        
instancesToAddToLoadBalancer.add(instance);
                                                                }
                                                        }
@@ -129,62 +132,87 @@ public class AWSLoadBalancer implements LoadBalancer {
 
                                                if (clusterMembers.size() > 0) {
 
-//                                                     try
-//                                                     {
-                                                               // a unique 
load balancer name with user-defined prefix and a sequence number.
-                                                               String 
loadBalancerName = awsHelper
-                                                                               
.generateLoadBalancerName();
-
-                                                               String region = 
awsHelper.getAWSRegion(clusterMembers
-                                                                               
.iterator().next().getInstanceId());
-
-                                                               // list of AWS 
listeners obtained using port mappings of one of the members of the cluster.
-                                                               List<Listener> 
listenersForThisCluster = awsHelper
-                                                                               
.getRequiredListeners(clusterMembers.iterator()
-                                                                               
                .next());
-
-                                                               // DNS name of 
load balancer which was created.
-                                                               // This is used 
in the domain mapping of this cluster.
-                                                               String 
loadBalancerDNSName = awsHelper
-                                                                               
.createLoadBalancer(loadBalancerName,
-                                                                               
                listenersForThisCluster, region);
+                                                       // try
+                                                       // {
+                                                       // a unique load 
balancer name with user-defined
+                                                       // prefix and a 
sequence number.
+                                                       String loadBalancerName 
= awsHelper
+                                                                       
.generateLoadBalancerName();
+
+                                                       String region = 
awsHelper
+                                                                       
.getAWSRegion(clusterMembers.iterator()
+                                                                               
        .next().getInstanceId());
+
+                                                       // list of AWS 
listeners obtained using port
+                                                       // mappings of one of 
the members of the cluster.
+                                                       List<Listener> 
listenersForThisCluster = awsHelper
+                                                                       
.getRequiredListeners(clusterMembers
+                                                                               
        .iterator().next());
+
+                                                       // DNS name of load 
balancer which was created.
+                                                       // This is used in the 
domain mapping of this
+                                                       // cluster.
+                                                       String 
loadBalancerDNSName = awsHelper
+                                                                       
.createLoadBalancer(loadBalancerName,
+                                                                               
        listenersForThisCluster, region);
+
+                                                       // Also add the inbound 
rule
+                                                       // For each listener, 
add a new rule with load
+                                                       // balancer port as 
allowed protocol.
+
+                                                       for (Listener listener 
: listenersForThisCluster) {
+                                                               int port = 
listener.getLoadBalancerPort();
+
+                                                               for (String 
protocol : awsHelper
+                                                                               
.getAllowedProtocolsForLBSecurityGroup()) {
+                                                                       
awsHelper
+                                                                               
        .addInboundRuleToSecurityGroup(
+                                                                               
                        awsHelper
+                                                                               
                                        .getSecurityGroupId(
+                                                                               
                                                        awsHelper
+                                                                               
                                                                        
.getLbSecurityGroupName(),
+                                                                               
                                                        region),
+                                                                               
                        region, protocol, port);
+                                                               }
+                                                       }
 
-                                                               log.info("Load 
balancer '" + loadBalancerDNSName
-                                                                               
+ "' created for cluster '"
-                                                                               
+ cluster.getClusterId());
+                                                       log.info("Load balancer 
'" + loadBalancerDNSName
+                                                                       + "' 
created for cluster '"
+                                                                       + 
cluster.getClusterId());
 
-                                                               // register 
instances to LB
-                                                               List<Instance> 
instances = new ArrayList<Instance>();
+                                                       // register instances 
to LB
+                                                       List<Instance> 
instances = new ArrayList<Instance>();
 
-                                                               for (Member 
member : clusterMembers) {
-                                                                       String 
instanceId = member.getInstanceId();
+                                                       for (Member member : 
clusterMembers) {
+                                                               String 
instanceId = member.getInstanceId();
 
-                                                                       
log.debug("Instance id : "
-                                                                               
        + awsHelper.getAWSInstanceName(instanceId));
+                                                               
log.debug("Instance id : "
+                                                                               
+ awsHelper
+                                                                               
                .getAWSInstanceName(instanceId));
 
-                                                                       
Instance instance = new Instance();
-                                                                       
instance.setInstanceId(awsHelper
-                                                                               
        .getAWSInstanceName(instanceId));
+                                                               Instance 
instance = new Instance();
+                                                               
instance.setInstanceId(awsHelper
+                                                                               
.getAWSInstanceName(instanceId));
 
-                                                                       
instances.add(instance);
-                                                               }
+                                                               
instances.add(instance);
+                                                       }
 
-                                                               
awsHelper.registerInstancesToLoadBalancer(
-                                                                               
loadBalancerName, instances, region);
+                                                       
awsHelper.registerInstancesToLoadBalancer(
+                                                                       
loadBalancerName, instances, region);
 
-                                                               // Create 
domain mappings
+                                                       // Create domain 
mappings
 
-                                                               
LoadBalancerInfo loadBalancerInfo = new LoadBalancerInfo(
-                                                                               
loadBalancerName, region);
+                                                       LoadBalancerInfo 
loadBalancerInfo = new LoadBalancerInfo(
+                                                                       
loadBalancerName, region);
 
-                                                               
clusterIdToLoadBalancerMap.put(cluster.getClusterId(),
-                                                                               
loadBalancerInfo);
-                                                               
activeClusters.add(cluster.getClusterId());
-//                                                     }
-//                                                     
catch(LoadBalancerExtensionException e)
-//                                                     {
-//                                                             log.debug(e);
-//                                                     }
+                                                       
clusterIdToLoadBalancerMap.put(
+                                                                       
cluster.getClusterId(), loadBalancerInfo);
+                                                       
activeClusters.add(cluster.getClusterId());
+                                                       // }
+                                                       // 
catch(LoadBalancerExtensionException e)
+                                                       // {
+                                                       // log.debug(e);
+                                                       // }
                                                }
                                        }
                                }
@@ -213,8 +241,8 @@ public class AWSLoadBalancer implements LoadBalancer {
        }
 
        /*
-        * start method is called after extension if configured first time.
-        * Does nothing but logs the message.
+        * start method is called after extension if configured first time. Does
+        * nothing but logs the message.
         */
        public void start() throws LoadBalancerExtensionException {
 
@@ -222,8 +250,8 @@ public class AWSLoadBalancer implements LoadBalancer {
        }
 
        /*
-        * reload method is called every time after extension if configured.
-        * Does nothing but logs the message.
+        * reload method is called every time after extension if configured. 
Does
+        * nothing but logs the message.
         */
        public void reload() throws LoadBalancerExtensionException {
                // Check what is appropriate to do here.
@@ -247,8 +275,9 @@ public class AWSLoadBalancer implements LoadBalancer {
 }
 
 /**
- * Used to store load balancer name and the region in which it is created.
- * This helps in finding region while calling API methods to modify/delete a 
load balancer.
+ * Used to store load balancer name and the region in which it is created. This
+ * helps in finding region while calling API methods to modify/delete a load
+ * balancer.
  */
 class LoadBalancerInfo {
        private String name;

http://git-wip-us.apache.org/repos/asf/stratos/blob/cae92c5e/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 ea6a359..0792e00 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
@@ -37,6 +37,8 @@ public class Constants {
     public static final String LOAD_BALANCER_SECURITY_GROUP_DESCRIPTION = 
"Security group for load balancers created for Apache Stratos.";
     public static final String ELB_ENDPOINT_URL_FORMAT = 
"elasticloadbalancing.%s.amazonaws.com";
     public static final String EC2_ENDPOINT_URL_FORMAT = 
"ec2.%s.amazonaws.com";
+    public static final String ALLOWED_CIDR_IP_KEY = "allowed-cidr-ip";
+    public static final String ALLOWED_PROTOCOLS = "allowed-protocols";
     public static final int LOAD_BALANCER_NAME_MAX_LENGTH = 32;
     public static final int LOAD_BALANCER_PREFIX_MAX_LENGTH = 25;
     public static final int SECURITY_GROUP_NAME_MAX_LENGTH = 255;

Reply via email to