package core.aws.remote.ec2; import core.aws.client.AWS; import core.aws.remote.EnvTag; import core.aws.remote.Loader; import core.aws.resource.Resources; import core.aws.resource.ec2.Instance; import core.aws.resource.ec2.InstanceState; import core.aws.resource.ec2.KeyPair; import core.aws.resource.ec2.SecurityGroup; import core.aws.resource.image.Image; import core.aws.util.StreamHelper; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; /** * @author neo */ public class InstanceLoader extends Loader { public InstanceLoader(Resources resources, List<EnvTag> tags) { super(resources, tags); } @Override public void load() { Map<String, EnvTag> instanceIdLocalResourceIdMappings = new HashMap<>(); all(Instance.class) .forEach(tag -> instanceIdLocalResourceIdMappings.put(tag.remoteResourceId, tag)); if (!instanceIdLocalResourceIdMappings.isEmpty()) loadInstances(instanceIdLocalResourceIdMappings); } private void loadInstances(Map<String, EnvTag> instanceIdLocalResourceIdMappings) { List<com.amazonaws.services.ec2.model.Instance> remoteInstances = AWS.ec2.describeInstances(instanceIdLocalResourceIdMappings.keySet()); // link sg and key pair for remote only instances remoteInstances.stream() .filter(remoteInstance -> !InstanceState.TERMINATED.equalsTo(remoteInstance.getState()) && !InstanceState.SHUTTING_DOWN.equalsTo(remoteInstance.getState())) .forEach(remoteInstance -> { String instanceId = remoteInstance.getInstanceId(); EnvTag tag = instanceIdLocalResourceIdMappings.get(instanceId); String resourceId = tag.resourceId(); Instance instance = resources.find(Instance.class, resourceId).orElseGet(() -> { Instance remoteOnlyInstance = new Instance(resourceId); // link sg and key pair for remote only instances String remoteSGId = remoteInstance.getSecurityGroups().get(0).getGroupId(); linkSecurityGroup(remoteOnlyInstance, remoteSGId); String remoteKeyName = remoteInstance.getKeyName(); linkKeyPair(remoteOnlyInstance, remoteKeyName); resources.add(remoteOnlyInstance); return remoteOnlyInstance; }); if ("ami".equals(tag.type())) { resources.find(Image.class, tag.amiImageId()).ifPresent(image -> image.unfinishedBakeInstances.add(instance)); } instance.foundInRemote(); instance.remoteInstances.add(remoteInstance); }); } private void linkKeyPair(Instance instance, String remoteKeyName) { Optional<KeyPair> keyPair = resources.stream().flatMap(StreamHelper.instanceOf(KeyPair.class)) .filter(key -> key.remoteKeyPair != null && remoteKeyName.equals(key.remoteKeyPair.getKeyName())) .reduce(StreamHelper.onlyOne()); if (keyPair.isPresent()) instance.keyPair = keyPair.get(); } private void linkSecurityGroup(Instance instance, String remoteSGId) { Optional<SecurityGroup> securityGroup = resources.stream().flatMap(StreamHelper.instanceOf(SecurityGroup.class)) .filter(sg -> sg.remoteSecurityGroup != null && remoteSGId.equals(sg.remoteSecurityGroup.getGroupId())) .reduce(StreamHelper.onlyOne()); if (securityGroup.isPresent()) instance.securityGroup = securityGroup.get(); } }