Repository: stratos Updated Branches: refs/heads/stratos-4.1.x 1ca6cdd5d -> f977732b2
Fixes for STRATOS-1616 and STRATOS-1617 Project: http://git-wip-us.apache.org/repos/asf/stratos/repo Commit: http://git-wip-us.apache.org/repos/asf/stratos/commit/56581dae Tree: http://git-wip-us.apache.org/repos/asf/stratos/tree/56581dae Diff: http://git-wip-us.apache.org/repos/asf/stratos/diff/56581dae Branch: refs/heads/stratos-4.1.x Commit: 56581daeced3fce4e257fde4bca48761b132eef0 Parents: 1ca6cdd Author: gayangunarathne <[email protected]> Authored: Mon Nov 16 12:38:36 2015 +0530 Committer: gayangunarathne <[email protected]> Committed: Mon Nov 16 19:25:11 2015 +0530 ---------------------------------------------------------------------- .../aws-extension/src/main/bin/aws-extension.sh | 4 +- .../aws-extension/src/main/conf/aws.properties | 9 + .../apache/stratos/aws/extension/AWSHelper.java | 209 ++++++++++++++++--- .../stratos/aws/extension/AWSLoadBalancer.java | 20 +- .../apache/stratos/aws/extension/Constants.java | 5 + 5 files changed, 208 insertions(+), 39 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/stratos/blob/56581dae/extensions/load-balancer/modules/aws-extension/src/main/bin/aws-extension.sh ---------------------------------------------------------------------- diff --git a/extensions/load-balancer/modules/aws-extension/src/main/bin/aws-extension.sh b/extensions/load-balancer/modules/aws-extension/src/main/bin/aws-extension.sh index 630a9e2..3ee421a 100755 --- a/extensions/load-balancer/modules/aws-extension/src/main/bin/aws-extension.sh +++ b/extensions/load-balancer/modules/aws-extension/src/main/bin/aws-extension.sh @@ -38,8 +38,8 @@ properties="-Djndi.properties.dir=${script_path}/../conf -Dcluster.id=cluster-1 -Dservice.name=service-1 -Dterminate.lbs.on.extension.stop=false - -Dterminate.lb.on.cluster.removal=true - -Doperating.in.vpc=false + -Dterminate.lb.on.cluster.removal=false + -Doperating.in.vpc=true -Denable.cross.zone.load.balancing=true" http://git-wip-us.apache.org/repos/asf/stratos/blob/56581dae/extensions/load-balancer/modules/aws-extension/src/main/conf/aws.properties ---------------------------------------------------------------------- diff --git a/extensions/load-balancer/modules/aws-extension/src/main/conf/aws.properties b/extensions/load-balancer/modules/aws-extension/src/main/conf/aws.properties index 5a399ba..ca03afe 100644 --- a/extensions/load-balancer/modules/aws-extension/src/main/conf/aws.properties +++ b/extensions/load-balancer/modules/aws-extension/src/main/conf/aws.properties @@ -23,6 +23,15 @@ secret-key= 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 +# security-group-id. If this is defined, load-balancer-security-group-name will not be considered +load-balancer-security-group-id= +# load balancer subnets - applicable if operating inside a VPC +subnet-ids= +# load balancer vpc id - applicable if operating inside a VPC +vpc-ids= +# load balancer scheme - in a VPC, if the value is set to 'internal', will create an internal load +# balancer with a DNS name that resolves to private IP addresses +load-balancer-scheme=internal # 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 http://git-wip-us.apache.org/repos/asf/stratos/blob/56581dae/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSHelper.java ---------------------------------------------------------------------- diff --git a/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSHelper.java b/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSHelper.java index 2f8760a..b29a47b 100644 --- a/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSHelper.java +++ b/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSHelper.java @@ -53,12 +53,16 @@ public class AWSHelper { private String awsSecretKey; private String lbPrefix; private String lbSecurityGroupName; + private String lbSecurityGroupId; private String lbSecurityGroupDescription; private String allowedCidrIpForLBSecurityGroup; private int statisticsInterval; private String sslCertificateId; private String appStickySessionCookie; private Set<String> initialZones = new HashSet<>(); + private Set<String> subnetIds = new HashSet<>(); + private Set<String> vpcIds = new HashSet<>(); + private String lbScheme; private AtomicInteger lbSequence; @@ -113,12 +117,19 @@ public class AWSHelper { this.lbSecurityGroupName = properties .getProperty(Constants.LOAD_BALANCER_SECURITY_GROUP_NAME); - if (this.lbSecurityGroupName.isEmpty() - || this.lbSecurityGroupName.length() > Constants.SECURITY_GROUP_NAME_MAX_LENGTH) { - throw new LoadBalancerExtensionException( - "Invalid load balancer security group name."); + lbSecurityGroupId = properties.getProperty(Constants.LOAD_BALANCER_SECURITY_GROUP_ID); + + if ((lbSecurityGroupId == null || lbSecurityGroupId.isEmpty()) && (this.lbSecurityGroupName.isEmpty() + || this.lbSecurityGroupName.length() > Constants.SECURITY_GROUP_NAME_MAX_LENGTH)) { + throw new LoadBalancerExtensionException("Either security group name or security " + + "group id is required"); } +// if (this.lbSecurityGroupName.isEmpty() || this.lbSecurityGroupName.length() > +// Constants.SECURITY_GROUP_NAME_MAX_LENGTH) { +// throw new LoadBalancerExtensionException("Invalid load balancer security group name."); +// } + // Read the SSL certificate Id. This is mandatory if only we are using HTTPS as the front end protocol. // http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/using-elb-listenerconfig-quickref.html this.sslCertificateId = properties @@ -178,6 +189,20 @@ public class AWSHelper { "\\s*"))); } + String commaSeparatedSubnetIds = properties.getProperty(Constants.SUBNET_IDS); + if (commaSeparatedSubnetIds != null && !commaSeparatedSubnetIds.isEmpty()) { + subnetIds.addAll(Arrays.asList(commaSeparatedSubnetIds.trim().split("\\s*," + + "\\s*"))); + } + + String commaSeparatedVPCIds = properties.getProperty(Constants.VPC_IDS); + if (commaSeparatedVPCIds != null && !commaSeparatedVPCIds.isEmpty()) { + vpcIds.addAll(Arrays.asList(commaSeparatedVPCIds.trim().split("\\s*," + + "\\s*"))); + } + + lbScheme = properties.getProperty(Constants.LB_SCHEME); + regionToSecurityGroupIdMap = new ConcurrentHashMap<String, String>(); awsCredentials = new BasicAWSCredentials(awsAccessKey, awsSecretKey); @@ -246,15 +271,36 @@ public class AWSHelper { // availabilityZones.add(getAvailabilityZoneFromRegion(region)); // // createLoadBalancerRequest.setAvailabilityZones(availabilityZones); - createLoadBalancerRequest.setAvailabilityZones(availabilityZones); + try { if (inVPC) { - String securityGroupId = getSecurityGroupIdForRegion(region); + List<String> securityGroups = new ArrayList<String>(); - securityGroups.add(securityGroupId); + if (!vpcIds.isEmpty()) { + for (String vpcId : vpcIds) { + String securityGroupId = getSecurityGroupIdForRegion(region, vpcId); + securityGroups.add(securityGroupId); + } + } else { + String securityGroupId = getSecurityGroupIdForRegion(region, null); + securityGroups.add(securityGroupId); + } createLoadBalancerRequest.setSecurityGroups(securityGroups); + + // set subnet ids + if (!getSubnetIds().isEmpty()) { + createLoadBalancerRequest.setSubnets(subnetIds); + } + + // set scheme to 'internal' if specified + if (getLbScheme() != null && getLbScheme().equals(Constants.LB_SCHEME_INTERNAL)) { + createLoadBalancerRequest.setScheme(getLbScheme()); + } + } else { + // set initial availability zones + createLoadBalancerRequest.setAvailabilityZones(availabilityZones); } elbClient.setEndpoint(String.format( @@ -309,8 +355,7 @@ public class AWSHelper { public void registerInstancesToLoadBalancer(String loadBalancerName, List<Instance> instances, String region) { - log.info("Registering following instance(s) to load balancer " - + loadBalancerName); + log.info("Registering following instance(s) to load balancer " + loadBalancerName); for (Instance instance : instances) { log.info(instance.getInstanceId()); @@ -319,17 +364,27 @@ public class AWSHelper { RegisterInstancesWithLoadBalancerRequest registerInstancesWithLoadBalancerRequest = new RegisterInstancesWithLoadBalancerRequest( loadBalancerName, instances); + RegisterInstancesWithLoadBalancerResult registerInstancesWithLBRes = null; + try { elbClient.setEndpoint(String.format( Constants.ELB_ENDPOINT_URL_FORMAT, region)); - elbClient + registerInstancesWithLBRes = elbClient .registerInstancesWithLoadBalancer(registerInstancesWithLoadBalancerRequest); } catch (AmazonClientException e) { log.error("Could not register instances to load balancer " + loadBalancerName, e); } + + if (registerInstancesWithLBRes != null && registerInstancesWithLBRes.getInstances().size() > 0) { + log.info("Total instances attached to the LB " + loadBalancerName + " : " + + registerInstancesWithLBRes.getInstances().size()); + + } else { + log.warn("No instances attached to the LB " + loadBalancerName); + } } /** @@ -484,11 +539,17 @@ public class AWSHelper { } DescribeSecurityGroupsRequest describeSecurityGroupsRequest = new DescribeSecurityGroupsRequest(); - - List<String> groupNames = new ArrayList<String>(); - groupNames.add(groupName); - - describeSecurityGroupsRequest.setGroupNames(groupNames); + if (AWSExtensionContext.getInstance().isOperatingInVPC()) { + if (getVpcIds().size() > 0) { + // vpc id filter + Set<Filter> filters = getFilters(getVpcIds().iterator().next(), lbSecurityGroupName); + describeSecurityGroupsRequest.setFilters(filters); + } else { + List<String> groupNames = new ArrayList<String>(); + groupNames.add(groupName); + describeSecurityGroupsRequest.setGroupNames(groupNames); + } + } try { ec2Client.setEndpoint(String.format( @@ -502,6 +563,8 @@ public class AWSHelper { if (securityGroups != null && securityGroups.size() > 0) { return securityGroups.get(0).getGroupId(); + } else { + log.warn("Could not find security group id for group " + groupName); } } catch (AmazonClientException e) { log.debug("Could not describe security groups.", e); @@ -520,7 +583,8 @@ public class AWSHelper { * @throws LoadBalancerExtensionException */ public String createSecurityGroup(String groupName, String description, - String region) throws LoadBalancerExtensionException { + String region, String vpcId) throws + LoadBalancerExtensionException { if (groupName == null || groupName.isEmpty()) { throw new LoadBalancerExtensionException( "Invalid Security Group Name."); @@ -529,6 +593,9 @@ public class AWSHelper { CreateSecurityGroupRequest createSecurityGroupRequest = new CreateSecurityGroupRequest(); createSecurityGroupRequest.setGroupName(groupName); createSecurityGroupRequest.setDescription(description); + if (vpcId != null) { + createSecurityGroupRequest.setVpcId(vpcId); + } try { ec2Client.setEndpoint(String.format( @@ -589,7 +656,10 @@ public class AWSHelper { if (securityGroups != null && securityGroups.size() > 0) { secirutyGroup = securityGroups.get(0); + } else { + log.warn("No Security Groups found for group id " + groupId); } + } catch (AmazonClientException e) { log.error("Could not describe security groups.", e); } @@ -626,14 +696,15 @@ public class AWSHelper { ec2Client.setEndpoint(String.format( Constants.EC2_ENDPOINT_URL_FORMAT, region)); - ec2Client - .authorizeSecurityGroupIngress(authorizeSecurityGroupIngressRequest); + ec2Client.authorizeSecurityGroupIngress(authorizeSecurityGroupIngressRequest); } catch (AmazonClientException e) { throw new LoadBalancerExtensionException( "Could not add inbound rule to security group " + groupId + ".", e); } + } else { + log.info("Rules already present for security group " + groupId); } } @@ -643,30 +714,88 @@ public class AWSHelper { * in that region. * * @param region + * @param vpcId * @return Id of the security group * @throws LoadBalancerExtensionException */ - public String getSecurityGroupIdForRegion(String region) + public String getSecurityGroupIdForRegion(String region, String vpcId) throws LoadBalancerExtensionException { - if (region == null) - return null; +// if (region == null) +// return null; +// +// if (this.regionToSecurityGroupIdMap.contains(region)) { +// return this.regionToSecurityGroupIdMap.get(region); +// } else { +// // Get the the security group id if it is already present. +// String securityGroupId = getSecurityGroupId( +// this.lbSecurityGroupName, region); +// +// if (securityGroupId == null) { +// securityGroupId = createSecurityGroup(this.lbSecurityGroupName, +// this.lbSecurityGroupDescription, region, vpcId); +// } +// +// this.regionToSecurityGroupIdMap.put(region, securityGroupId); +// +// return securityGroupId; +// } + + // if lb security group id is defined, use that, do not create a new security group + if (lbSecurityGroupId != null && !lbSecurityGroupId.isEmpty()) { + return lbSecurityGroupId; + } - if (this.regionToSecurityGroupIdMap.contains(region)) { - return this.regionToSecurityGroupIdMap.get(region); + // check if the security group is already exists + DescribeSecurityGroupsRequest describeSecurityGroupsReq = new + DescribeSecurityGroupsRequest(); + // set filter for vpc id + if (vpcId != null) { + Set<Filter> filters = getFilters(vpcId, lbSecurityGroupName); + describeSecurityGroupsReq.setFilters(filters); } else { - // Get the the security group id if it is already present. - String securityGroupId = getSecurityGroupId( - this.lbSecurityGroupName, region); + // no vpc id defined, assume default vpc + List<String> groupNames = new ArrayList<String>(); + groupNames.add(lbSecurityGroupName); + describeSecurityGroupsReq.setGroupNames(groupNames); + } - if (securityGroupId == null) { - securityGroupId = createSecurityGroup(this.lbSecurityGroupName, - this.lbSecurityGroupDescription, region); - } + DescribeSecurityGroupsResult describeSecurityGroupsRes = null; + try { + ec2Client.setEndpoint(String.format( + Constants.EC2_ENDPOINT_URL_FORMAT, region)); - this.regionToSecurityGroupIdMap.put(region, securityGroupId); + describeSecurityGroupsRes = ec2Client.describeSecurityGroups(describeSecurityGroupsReq); + if (describeSecurityGroupsRes != null && describeSecurityGroupsRes.getSecurityGroups() != null) { + // already exists, return the id + if(describeSecurityGroupsRes.getSecurityGroups().size() > 0) { + return describeSecurityGroupsRes.getSecurityGroups().get(0).getGroupId(); + } + } - return securityGroupId; + } catch (AmazonClientException e) { + throw new LoadBalancerExtensionException(e.getMessage(), e); } + return createSecurityGroup(this.lbSecurityGroupName, this.lbSecurityGroupDescription, region, vpcId); + } + + private Set<Filter> getFilters(String vpcId, String securityGroupName) { + // vpc id filter + Filter vpcIdFilter = new Filter(); + vpcIdFilter.setName("vpc-id"); + Set<String> singleVpcIdSet = new HashSet<>(); + singleVpcIdSet.add(vpcId); + vpcIdFilter.setValues(singleVpcIdSet); + // group name filter + Filter groupNameFilter = new Filter(); + groupNameFilter.setName("group-name"); + Set<String> singleGroupNameSet = new HashSet<>(); + singleGroupNameSet.add(securityGroupName); + groupNameFilter.setValues(singleGroupNameSet); + + Set<Filter> filters = new HashSet<>(); + filters.add(vpcIdFilter); + filters.add(groupNameFilter); + return filters; } /** @@ -1099,4 +1228,20 @@ public class AWSHelper { public Set<String> getInitialZones() { return initialZones; } + + public Set<String> getSubnetIds () { + return subnetIds; + } + + public String getLbScheme() { + return lbScheme; + } + + public Set<String> getVpcIds() { + return vpcIds; + } + + public String getLbSecurityGroupIdDefinedInConfiguration () { + return lbSecurityGroupId; + } } http://git-wip-us.apache.org/repos/asf/stratos/blob/56581dae/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSLoadBalancer.java ---------------------------------------------------------------------- diff --git a/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSLoadBalancer.java b/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSLoadBalancer.java index 11890d3..62f9882 100644 --- a/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSLoadBalancer.java +++ b/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSLoadBalancer.java @@ -133,7 +133,7 @@ public class AWSLoadBalancer implements LoadBalancer { } // update LB with the zones - if (!availabilityZones.isEmpty()) { + if (!availabilityZones.isEmpty() && !AWSExtensionContext.getInstance().isOperatingInVPC()) { awsHelper.addAvailabilityZonesForLoadBalancer(loadBalancerName, availabilityZones, region); } } @@ -182,12 +182,22 @@ public class AWSLoadBalancer implements LoadBalancer { // Add the inbound rule the security group of the load balancer // For each listener, add a new rule with load balancer port as allowed protocol in the security group. + // if security group id is defined, directly use that for (Listener listener : listenersForThisCluster) { int port = listener.getLoadBalancerPort(); - for (String protocol : awsHelper.getAllowedProtocolsForLBSecurityGroup()) { - awsHelper.addInboundRuleToSecurityGroup(awsHelper.getSecurityGroupId(awsHelper - .getLbSecurityGroupName(), region), region, protocol, port); + if (awsHelper.getLbSecurityGroupIdDefinedInConfiguration() != null && !awsHelper. + getLbSecurityGroupIdDefinedInConfiguration().isEmpty()) { + for (String protocol : awsHelper.getAllowedProtocolsForLBSecurityGroup()) { + awsHelper.addInboundRuleToSecurityGroup(awsHelper.getLbSecurityGroupIdDefinedInConfiguration(), + region, protocol, port); + } + } else if (awsHelper.getLbSecurityGroupName() != null && !awsHelper + .getLbSecurityGroupName().isEmpty()) { + for (String protocol : awsHelper.getAllowedProtocolsForLBSecurityGroup()) { + awsHelper.addInboundRuleToSecurityGroup(awsHelper.getSecurityGroupId(awsHelper + .getLbSecurityGroupName(), region), region, protocol, port); + } } } @@ -220,7 +230,7 @@ public class AWSLoadBalancer implements LoadBalancer { awsHelper.registerInstancesToLoadBalancer(loadBalancerName, instances, region); // update LB with the zones - if (!availabilityZones.isEmpty()) { + if (!availabilityZones.isEmpty() && !AWSExtensionContext.getInstance().isOperatingInVPC()) { awsHelper.addAvailabilityZonesForLoadBalancer(loadBalancerName, availabilityZones, region); } http://git-wip-us.apache.org/repos/asf/stratos/blob/56581dae/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/Constants.java ---------------------------------------------------------------------- diff --git a/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/Constants.java b/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/Constants.java index ebda3c4..20db2d9 100644 --- a/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/Constants.java +++ b/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/Constants.java @@ -34,6 +34,7 @@ public class Constants { 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_ID = "load-balancer-security-group-id"; 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"; @@ -61,5 +62,9 @@ public class Constants { public static final String OPERATIMG_IN_VPC = "operating.in.vpc"; public static final String ENABLE_CROSS_ZONE_LOADBALANCING = "enable.cross.zone.load.balancing"; public static final String INITIAL_AVAILABILITY_ZONES = "initial-availability-zones"; + public static final String SUBNET_IDS = "subnet-ids"; + public static final String VPC_IDS = "vpc-ids"; + public static final String LB_SCHEME = "load-balancer-scheme"; + public static final String LB_SCHEME_INTERNAL = "internal"; public static final String EC2_AVAILABILITY_ZONE_PROPERTY = "EC2_AVAILABILITY_ZONE"; }
