From 9543078d417a8795ae6dd7fbb773b71051a6544a Mon Sep 17 00:00:00 2001 From: Jeremy Collins Date: Tue, 14 Jan 2020 15:37:59 -0500 Subject: [PATCH 1/2] Refactor ELB instances to include state Trying to refactor this to more closely match the API/Model of AWS while also providing the ability to get the current live instances within a Gyro workflow. The issue is that if you use query for an ELB and grab the instances while in a workflow the instances might be missing since they could have been added in a previous workflow stage. Gyro doesn't automatically refresh after the stage so the next stage won't see them. Specifically happens if an autoscale group is adding the instances to the ELB. --- .../gyro/aws/elb/LoadBalancerInstance.java | 39 ++++++++++++ .../gyro/aws/elb/LoadBalancerResource.java | 62 ++++++++++++++++--- 2 files changed, 92 insertions(+), 9 deletions(-) create mode 100644 src/main/java/gyro/aws/elb/LoadBalancerInstance.java diff --git a/src/main/java/gyro/aws/elb/LoadBalancerInstance.java b/src/main/java/gyro/aws/elb/LoadBalancerInstance.java new file mode 100644 index 000000000..86d36ae7b --- /dev/null +++ b/src/main/java/gyro/aws/elb/LoadBalancerInstance.java @@ -0,0 +1,39 @@ +package gyro.aws.elb; + +import gyro.aws.ec2.InstanceResource; +import gyro.core.GyroInstance; +import gyro.core.resource.Diffable; +import gyro.core.resource.Output; + +public class LoadBalancerInstance extends Diffable { + + private InstanceResource instance; + private String state; + + public GyroInstance getInstance() { + return instance; + } + + public void setInstance(InstanceResource instance) { + this.instance = instance; + } + + @Output + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + @Override + public String primaryKey() { + if (instance != null) { + return instance.getId(); + } + + return ""; + } + +} diff --git a/src/main/java/gyro/aws/elb/LoadBalancerResource.java b/src/main/java/gyro/aws/elb/LoadBalancerResource.java index 3475832ad..361c8735b 100644 --- a/src/main/java/gyro/aws/elb/LoadBalancerResource.java +++ b/src/main/java/gyro/aws/elb/LoadBalancerResource.java @@ -30,8 +30,12 @@ import gyro.core.resource.Updatable; import gyro.core.scope.State; +import software.amazon.awssdk.services.ec2.Ec2Client; +import software.amazon.awssdk.services.ec2.model.DescribeInstancesResponse; +import software.amazon.awssdk.services.ec2.model.Reservation; import software.amazon.awssdk.services.elasticloadbalancing.ElasticLoadBalancingClient; import software.amazon.awssdk.services.elasticloadbalancing.model.CreateLoadBalancerResponse; +import software.amazon.awssdk.services.elasticloadbalancing.model.DescribeInstanceHealthResponse; import software.amazon.awssdk.services.elasticloadbalancing.model.DescribeLoadBalancerAttributesResponse; import software.amazon.awssdk.services.elasticloadbalancing.model.DescribeLoadBalancersResponse; import software.amazon.awssdk.services.elasticloadbalancing.model.Instance; @@ -44,7 +48,9 @@ import software.amazon.awssdk.services.elasticloadbalancing.model.TagKeyOnly; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; @@ -92,7 +98,7 @@ public class LoadBalancerResource extends AwsResource implements Copyable instances; + private Set instances; private Set listener; private String name; private String scheme; @@ -129,7 +135,7 @@ public void setHealthCheck(HealthCheckResource healthCheck) { * The instances to associate with this load balancer. */ @Updatable - public Set getInstances() { + public Set getInstances() { if (instances == null) { instances = new LinkedHashSet<>(); } @@ -137,7 +143,7 @@ public Set getInstances() { return instances; } - public void setInstances(Set instances) { + public void setInstances(Set instances) { this.instances = instances; } @@ -421,8 +427,7 @@ public void copyFrom(LoadBalancerDescription description) { setScheme(description.scheme()); setHostedZoneId(description.canonicalHostedZoneNameID()); - getInstances().clear(); - description.instances().forEach(i -> getInstances().add(findById(InstanceResource.class, i.instanceId()))); + setInstances(liveInstances()); getSecurityGroups().clear(); description.securityGroups().forEach(r -> getSecurityGroups().add(findById(SecurityGroupResource.class, r))); @@ -479,12 +484,12 @@ private LoadBalancerDescription getLoadBalancer(ElasticLoadBalancingClient clien } private Set toInstances() { - Set instance = new LinkedHashSet<>(); - for (InstanceResource instanceResource : getInstances()) { - instance.add(Instance.builder().instanceId(instanceResource.getId()).build()); + Set instances = new LinkedHashSet<>(); + for (LoadBalancerInstance instance : getInstances()) { + instances.add(Instance.builder().instanceId(instance.getInstance().getGyroInstanceId()).build()); } - return instance; + return instances; } private List toListeners() { @@ -503,4 +508,43 @@ private List toListeners() { return listeners; } + public Set liveInstances() { + ElasticLoadBalancingClient client = createClient(ElasticLoadBalancingClient.class); + + DescribeInstanceHealthResponse response = client.describeInstanceHealth(r -> r.loadBalancerName(getName())); + Map instanceStates = new HashMap<>(); + for (InstanceState instanceState : response.instanceStates()) { + instanceStates.put(instanceState.instanceId(), instanceState); + } + + List instanceIds = new ArrayList<>(instanceStates.keySet()); + if (!instanceIds.isEmpty()) { + Ec2Client ec2Client = createClient(Ec2Client.class); + DescribeInstancesResponse instancesResponse = ec2Client.describeInstances(r -> r.instanceIds(instanceIds)); + + Set instances = new HashSet<>(); + for (Reservation reservation : instancesResponse.reservations()) { + for (software.amazon.awssdk.services.ec2.model.Instance ec2Instance : reservation.instances()) { + LoadBalancerInstance instance = new LoadBalancerInstance(); + instance.setInstance(getInstanceResource(ec2Instance)); + instance.setState(instanceStates.get(ec2Instance.instanceId()).state()); + + instances.add(instance); + } + } + + System.out.println(instances); + + return instances; + } + + return Collections.emptySet(); + } + + private InstanceResource getInstanceResource(software.amazon.awssdk.services.ec2.model.Instance instance) { + InstanceResource instanceResource = newSubresource(InstanceResource.class); + instanceResource.copyFrom(instance); + return instanceResource; + } + } From 5f16d954717351303338472fbdafdea107db8a12 Mon Sep 17 00:00:00 2001 From: Jeremy Collins Date: Tue, 21 Jan 2020 16:34:07 -0500 Subject: [PATCH 2/2] Remove System.out --- src/main/java/gyro/aws/elb/LoadBalancerResource.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/gyro/aws/elb/LoadBalancerResource.java b/src/main/java/gyro/aws/elb/LoadBalancerResource.java index 361c8735b..4943055bb 100644 --- a/src/main/java/gyro/aws/elb/LoadBalancerResource.java +++ b/src/main/java/gyro/aws/elb/LoadBalancerResource.java @@ -533,8 +533,6 @@ public Set liveInstances() { } } - System.out.println(instances); - return instances; }