bug4811: some initial ALB create/delete logic

This commit is contained in:
Axel Uhl committed 2020-07-11 09:39:09 +02:00
1 parent eaf7290911
commit 8681eb5cea
9 files changed
+85 -36

No files matched your search

@@ -29,7 +29,6 @@ import com.sap.sse.common.Duration;
import com.sap.sse.common.TimePoint;
import com.sap.sse.landscape.application.ApplicationProcessMetrics;
import com.sap.sse.landscape.aws.impl.AmazonMachineImage;
import com.sap.sse.landscape.aws.impl.AwsAvailabilityZoneImpl;
import com.sap.sse.landscape.aws.impl.AwsRegion;
import com.sap.sse.landscape.ssh.SSHKeyPair;
@@ -63,7 +62,7 @@ public class ConnectivityTest {
@Test
public void testConnectivity() {
final AwsInstance host = landscape.launchHost(landscape.getImage(region, "ami-01b4b27a5699e33e6"),
new AwsAvailabilityZoneImpl("eu-west-2b", region), "Axel", Collections.singleton(()->"sg-0b2afd48960251280"));
landscape.getAvailabilityZoneByName(region, "eu-west-2b"), "Axel", Collections.singleton(()->"sg-0b2afd48960251280"));
try {
assertNotNull(host);
} finally {
@@ -133,7 +132,7 @@ public class ConnectivityTest {
private void testSshConnectWithKey(final String keyName) throws InterruptedException, JSchException {
final AwsInstance host = landscape.launchHost(landscape.getImage(region, "ami-01b4b27a5699e33e6"),
new AwsAvailabilityZoneImpl("eu-west-2b", region), keyName, Collections.singleton(()->"sg-0b2afd48960251280"));
landscape.getAvailabilityZoneByName(region, "eu-west-2b"), keyName, Collections.singleton(()->"sg-0b2afd48960251280"));
try {
assertNotNull(host);
logger.info("Created instance with ID "+host.getInstanceId());
@@ -213,7 +212,11 @@ public class ConnectivityTest {
public void createEmptyLoadBalancerTest() {
final String albName = "MyAlb"+new Random().nextInt();
final ApplicationLoadBalancer alb = landscape.createLoadBalancer(albName, region);
assertNotNull(alb);
assertEquals(albName, alb.getName());
try {
assertNotNull(alb);
assertEquals(albName, alb.getName());
} finally {
landscape.deleteLoadBalancer(alb);
}
}
}
@@ -1,6 +1,7 @@
package com.sap.sse.landscape.aws;
import com.sap.sse.common.Named;
import com.sap.sse.landscape.Region;
/**
* Represents an AWS Application Load Balancer (ALB). When created, a default configuration with the following
@@ -25,4 +26,8 @@ public interface ApplicationLoadBalancer extends Named {
void addRules(Iterable<LoadBalancerRule> rulesToAdd);
void deleteRules(Iterable<LoadBalancerRule> rulesToDelete);
Region getRegion();
String getArn();
}
@@ -1,7 +1,9 @@
package com.sap.sse.landscape.aws;
import com.sap.sse.landscape.AvailabilityZone;
import com.sap.sse.landscape.aws.impl.AwsRegion;
public interface AwsAvailabilityZone extends AvailabilityZone {
@Override
AwsRegion getRegion();
}
@@ -10,6 +10,7 @@ import com.sap.sse.landscape.SecurityGroup;
import com.sap.sse.landscape.application.ApplicationProcessMetrics;
import com.sap.sse.landscape.aws.impl.AmazonMachineImage;
import com.sap.sse.landscape.aws.impl.AwsLandscapeImpl;
import com.sap.sse.landscape.aws.impl.AwsRegion;
import com.sap.sse.landscape.ssh.SSHKeyPair;
import software.amazon.awssdk.services.cloudwatch.CloudWatchClient;
@@ -54,7 +55,7 @@ public interface AwsLandscape<ShardingKey, MetricsT extends ApplicationProcessMe
* the SSH key pair name to use when launching; this will grant root access with the corresponding
* private key; see also {@link #getKeyPairInfo(Region, String)}
*/
default AwsInstance launchHost(MachineImage<AwsInstance> fromImage, AvailabilityZone az, String keyName, Iterable<SecurityGroup> securityGroups) {
default AwsInstance launchHost(MachineImage<AwsInstance> fromImage, AwsAvailabilityZone az, String keyName, Iterable<SecurityGroup> securityGroups) {
return launchHosts(1, fromImage, az, keyName, securityGroups).iterator().next();
}
@@ -66,7 +67,7 @@ public interface AwsLandscape<ShardingKey, MetricsT extends ApplicationProcessMe
* the SSH key pair name to use when launching; this will grant root access with the corresponding
* private key; see also {@link #getKeyPairInfo(Region, String)}
*/
Iterable<AwsInstance> launchHosts(int numberOfHostsToLaunch, MachineImage<AwsInstance> fromImage, AvailabilityZone az,
Iterable<AwsInstance> launchHosts(int numberOfHostsToLaunch, MachineImage<AwsInstance> fromImage, AwsAvailabilityZone az,
String keyName, Iterable<SecurityGroup> securityGroups);
AmazonMachineImage getImage(Region region, String imageId);
@@ -143,4 +144,8 @@ public interface AwsLandscape<ShardingKey, MetricsT extends ApplicationProcessMe
ApplicationLoadBalancer createLoadBalancer(String name, Region region);
Iterable<AvailabilityZone> getAvailabilityZones(Region awsRegion);
AwsAvailabilityZone getAvailabilityZoneByName(AwsRegion region, String availabilityZoneName);
void deleteLoadBalancer(ApplicationLoadBalancer alb);
}
@@ -9,8 +9,11 @@ public class ApplicationLoadBalancerImpl implements ApplicationLoadBalancer {
private static final long serialVersionUID = -5297220031399131769L;
final LoadBalancer loadBalancer;
private final com.sap.sse.landscape.Region region;
public ApplicationLoadBalancerImpl(LoadBalancer loadBalancer) {
public ApplicationLoadBalancerImpl(com.sap.sse.landscape.Region region, LoadBalancer loadBalancer) {
this.region = region;
this.loadBalancer = loadBalancer;
}
@@ -24,6 +27,16 @@ public class ApplicationLoadBalancerImpl implements ApplicationLoadBalancer {
return loadBalancer.dnsName();
}
@Override
public String getArn() {
return loadBalancer.loadBalancerArn();
}
@Override
public com.sap.sse.landscape.Region getRegion() {
return region;
}
@Override
public Iterable<LoadBalancerRule> getRules() {
// TODO Auto-generated method stub
@@ -1,20 +1,21 @@
package com.sap.sse.landscape.aws.impl;
import com.sap.sse.landscape.Region;
import com.sap.sse.common.impl.NamedImpl;
import com.sap.sse.landscape.aws.AwsAvailabilityZone;
public class AwsAvailabilityZoneImpl implements AwsAvailabilityZone {
public class AwsAvailabilityZoneImpl extends NamedImpl implements AwsAvailabilityZone {
private static final long serialVersionUID = 7081008193504850891L;
private final String id;
private final Region region;
private final AwsRegion region;
public AwsAvailabilityZoneImpl(String id, Region region) {
super();
public AwsAvailabilityZoneImpl(String id, String name, AwsRegion region) {
super(name);
this.id = id;
this.region = region;
}
public AwsAvailabilityZoneImpl(software.amazon.awssdk.services.ec2.model.AvailabilityZone az) {
this(az.zoneName(), new AwsRegion(az.regionName()));
this(az.zoneId(), az.zoneName(), new AwsRegion(az.regionName()));
}
@Override
@@ -23,7 +24,7 @@ public class AwsAvailabilityZoneImpl implements AwsAvailabilityZone {
}
@Override
public Region getRegion() {
public AwsRegion getRegion() {
return region;
}
@@ -16,8 +16,8 @@ import com.sap.sse.landscape.AvailabilityZone;
import com.sap.sse.landscape.Log;
import com.sap.sse.landscape.Metrics;
import com.sap.sse.landscape.Process;
import com.sap.sse.landscape.Region;
import com.sap.sse.landscape.SecurityGroup;
import com.sap.sse.landscape.aws.AwsAvailabilityZone;
import com.sap.sse.landscape.aws.AwsInstance;
import com.sap.sse.landscape.aws.AwsLandscape;
import com.sap.sse.landscape.ssh.JCraftLogAdapter;
@@ -28,10 +28,10 @@ import software.amazon.awssdk.services.ec2.model.Instance;
public class AwsInstanceImpl implements AwsInstance {
private final String instanceId;
private final AvailabilityZone availabilityZone;
private final AwsAvailabilityZone availabilityZone;
private final AwsLandscape<?, ?> landscape;
public AwsInstanceImpl(String instanceId, AvailabilityZone availabilityZone, AwsLandscape<?, ?> landscape) {
public AwsInstanceImpl(String instanceId, AwsAvailabilityZone availabilityZone, AwsLandscape<?, ?> landscape) {
this.instanceId = instanceId;
this.availabilityZone = availabilityZone;
this.landscape = landscape;
@@ -149,10 +149,10 @@ public class AwsInstanceImpl implements AwsInstance {
@Override
public AvailabilityZone getAvailabilityZone() {
return new AwsAvailabilityZoneImpl(getInstance().placement().availabilityZone(), getRegion());
return availabilityZone;
}
private Region getRegion() {
private AwsRegion getRegion() {
return availabilityZone.getRegion();
}
@@ -21,6 +21,7 @@ import com.sap.sse.landscape.application.ApplicationProcessMetrics;
import com.sap.sse.landscape.application.ApplicationReplicaSet;
import com.sap.sse.landscape.application.Scope;
import com.sap.sse.landscape.aws.ApplicationLoadBalancer;
import com.sap.sse.landscape.aws.AwsAvailabilityZone;
import com.sap.sse.landscape.aws.AwsInstance;
import com.sap.sse.landscape.aws.AwsLandscape;
import com.sap.sse.landscape.aws.persistence.DomainObjectFactory;
@@ -40,12 +41,10 @@ import software.amazon.awssdk.services.ec2.model.CreateKeyPairRequest;
import software.amazon.awssdk.services.ec2.model.CreateKeyPairResponse;
import software.amazon.awssdk.services.ec2.model.DeleteKeyPairRequest;
import software.amazon.awssdk.services.ec2.model.DescribeAvailabilityZonesRequest;
import software.amazon.awssdk.services.ec2.model.DescribeAvailabilityZonesResponse;
import software.amazon.awssdk.services.ec2.model.DescribeImagesRequest;
import software.amazon.awssdk.services.ec2.model.DescribeImagesResponse;
import software.amazon.awssdk.services.ec2.model.DescribeInstancesRequest;
import software.amazon.awssdk.services.ec2.model.DescribeKeyPairsRequest;
import software.amazon.awssdk.services.ec2.model.Filter;
import software.amazon.awssdk.services.ec2.model.ImportKeyPairRequest;
import software.amazon.awssdk.services.ec2.model.Instance;
import software.amazon.awssdk.services.ec2.model.InstanceType;
@@ -53,10 +52,12 @@ import software.amazon.awssdk.services.ec2.model.KeyPairInfo;
import software.amazon.awssdk.services.ec2.model.Placement;
import software.amazon.awssdk.services.ec2.model.RunInstancesRequest;
import software.amazon.awssdk.services.ec2.model.RunInstancesResponse;
import software.amazon.awssdk.services.ec2.model.Subnet;
import software.amazon.awssdk.services.ec2.model.TerminateInstancesRequest;
import software.amazon.awssdk.services.elasticloadbalancingv2.ElasticLoadBalancingV2Client;
import software.amazon.awssdk.services.elasticloadbalancingv2.model.CreateLoadBalancerRequest;
import software.amazon.awssdk.services.elasticloadbalancingv2.model.CreateLoadBalancerResponse;
import software.amazon.awssdk.services.elasticloadbalancingv2.model.DeleteLoadBalancerRequest;
import software.amazon.awssdk.services.elasticloadbalancingv2.model.DescribeLoadBalancersRequest;
import software.amazon.awssdk.services.elasticloadbalancingv2.model.LoadBalancer;
import software.amazon.awssdk.services.elasticloadbalancingv2.model.SubnetMapping;
@@ -156,11 +157,34 @@ public class AwsLandscapeImpl<ShardingKey, MetricsT extends ApplicationProcessMe
Region awsRegion = getRegion(region);
final ElasticLoadBalancingV2Client client = getLoadBalancingClient(awsRegion);
final Iterable<AvailabilityZone> availabilityZones = getAvailabilityZones(region);
final SubnetMapping[] subnetMappings = Util.toArray(Util.map(getSubnetsForAvailabilityZones(awsRegion, availabilityZones),
subnet->SubnetMapping.builder().subnetId(subnet.subnetId()).build()), new SubnetMapping[0]);
final CreateLoadBalancerResponse response = client
.createLoadBalancer(CreateLoadBalancerRequest.builder().name(name)
.subnetMappings(SubnetMapping.builder().subnetMappings)
.build());
return new ApplicationLoadBalancerImpl(response.loadBalancers().iterator().next());
.subnetMappings(subnetMappings).build());
return new ApplicationLoadBalancerImpl(region, response.loadBalancers().iterator().next());
}
@Override
public void deleteLoadBalancer(ApplicationLoadBalancer alb) {
getLoadBalancingClient(getRegion(alb.getRegion())).deleteLoadBalancer(DeleteLoadBalancerRequest.builder().loadBalancerArn(alb.getArn()).build());
}
/**
* Grabs all subnets that are default subnet for any of the availability zones specified
*/
private Iterable<Subnet> getSubnetsForAvailabilityZones(Region region, Iterable<AvailabilityZone> azs) {
return Util.filter(getEc2Client(region).describeSubnets().subnets(), subnet -> subnet.defaultForAz()
&& Util.contains(Util.map(azs, az -> az.getId()), subnet.availabilityZoneId()));
}
@Override
public AwsAvailabilityZone getAvailabilityZoneByName(AwsRegion region, String availabilityZoneName) {
final software.amazon.awssdk.services.ec2.model.AvailabilityZone awsAz = getEc2Client(getRegion(region))
.describeAvailabilityZones(
DescribeAvailabilityZonesRequest.builder().zoneNames(availabilityZoneName).build())
.availabilityZones().iterator().next();
return new AwsAvailabilityZoneImpl(awsAz);
}
@Override
@@ -168,7 +192,7 @@ public class AwsLandscapeImpl<ShardingKey, MetricsT extends ApplicationProcessMe
final LoadBalancer loadBalancer = getLoadBalancingClient(getRegion(region))
.describeLoadBalancers(DescribeLoadBalancersRequest.builder().loadBalancerArns(loadBalancerArn).build())
.loadBalancers().iterator().next();
return new ApplicationLoadBalancerImpl(loadBalancer);
return new ApplicationLoadBalancerImpl(region, loadBalancer);
}
@Override
@@ -298,7 +322,7 @@ public class AwsLandscapeImpl<ShardingKey, MetricsT extends ApplicationProcessMe
}
@Override
public Iterable<AwsInstance> launchHosts(int numberOfHostsToLaunch, MachineImage<AwsInstance> fromImage, AvailabilityZone az,
public Iterable<AwsInstance> launchHosts(int numberOfHostsToLaunch, MachineImage<AwsInstance> fromImage, AwsAvailabilityZone az,
String keyName, Iterable<SecurityGroup> securityGroups) {
if (!fromImage.getRegion().equals(az.getRegion())) {
throw new IllegalArgumentException("Trying to launch an instance in region "+az.getRegion()+
@@ -335,12 +359,7 @@ public class AwsLandscapeImpl<ShardingKey, MetricsT extends ApplicationProcessMe
@Override
public Iterable<AvailabilityZone> getAvailabilityZones(com.sap.sse.landscape.Region awsRegion) {
final DescribeAvailabilityZonesResponse zones = getEc2Client(getRegion(awsRegion)).describeAvailabilityZones(
DescribeAvailabilityZonesRequest.builder().filters(Filter.builder().name(name))build());
final List<software.amazon.awssdk.services.ec2.model.AvailabilityZone> azs = zones.availabilityZones();
for (final software.amazon.awssdk.services.ec2.model.AvailabilityZone az : azs) {
az.
}
return Util.map(zones.availabilityZones(), AwsAvailabilityZoneImpl::new);
return Util.map(getEc2Client(getRegion(awsRegion)).describeAvailabilityZones().availabilityZones(),
AwsAvailabilityZoneImpl::new);
}
}
@@ -1,8 +1,9 @@
package com.sap.sse.landscape;
import com.sap.sse.common.Named;
import com.sap.sse.common.WithID;
public interface AvailabilityZone extends WithID {
public interface AvailabilityZone extends Named, WithID {
@Override
String getId();