You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stratos.apache.org by ga...@apache.org on 2015/10/09 16:35:32 UTC

[19/32] stratos git commit: Creating security groups automatically for load balancers.

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 <sw...@students.iiit.ac.in>
Authored: Wed Jul 29 08:12:27 2015 +0000
Committer: swapnilpatilRajaram <sw...@students.iiit.ac.in>
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.";
 }