@Override public void process(AmazonEC2Async amazonEC2Async, Instance instance) { amazonEC2Async.stopInstancesAsync( new StopInstancesRequest().withInstanceIds(instance.getInstanceId()), new AsyncHandler<StopInstancesRequest, StopInstancesResult>() { @Override public void onError(Exception exception) { log.warn("something went wrong stopping the server {}", exception.getLocalizedMessage()); } @Override public void onSuccess(StopInstancesRequest request, StopInstancesResult result) { onSuccessStop(instance); } }); }
@Override public AmazonEC2Async amazonEC2Async() { User user = authenticationService.getCurrentUser(); String accessKey = user.getAwsKey(); String secretKey = user.getAwsSecret(); String region = user.getAwsRegion(); if (secretKey.equals("") || accessKey.equals("") || region.equals("")) { return null; } BasicAWSCredentials basicAWSCredentials = new BasicAWSCredentials( accessKey, secretKey); return AmazonEC2AsyncClientBuilder.standard().withRegion(region) .withCredentials(new AWSStaticCredentialsProvider(basicAWSCredentials)) .build(); }
@Override public AmazonEC2Async amazonEC2Async(User user) { String accessKey = user.getAwsKey(); String secretKey = user.getAwsSecret(); String region = user.getAwsRegion(); if (secretKey.equals("") || accessKey.equals("") || region.equals("")) { return null; } BasicAWSCredentials basicAWSCredentials = new BasicAWSCredentials( accessKey, secretKey); return AmazonEC2AsyncClientBuilder.standard().withRegion(region) .withCredentials(new AWSStaticCredentialsProvider(basicAWSCredentials)) .build(); }
public void createSnapshotFromTagName(TagNameRequest tagNameRequest, Context context) { LambdaLogger logger = context.getLogger(); logger.log("create ebs snapshot from tag name Start. backup target[" + tagNameRequest + "]"); String regionName = System.getenv("AWS_DEFAULT_REGION"); AmazonEC2Async client = RegionUtils.getRegion(regionName).createClient(AmazonEC2AsyncClient.class, new DefaultAWSCredentialsProviderChain(), cc); try { List<Volume> volumes = describeBackupVolumes(client, tagNameRequest); for (Volume volume : volumes) { createSnapshot(volume.getVolumeId(), tagNameRequest.getGenerationCount(), context); } } finally { client.shutdown(); } }
String createAMI(ImageCreateRequest request, Context context) { LambdaLogger logger = context.getLogger(); AmazonEC2Async client = createEC2Client(); String imageId = null; try { Future<CreateImageResult> result = client .createImageAsync(new CreateImageRequest(request.getInstanceId(), request.getAmiName()) .withNoReboot(request.isNoReboot())); while (!result.isDone()) { Thread.sleep(1000); } imageId = result.get().getImageId(); logger.log("AMI Create Request End. instanceId[" + request.getInstanceId() + "] noReboot[" + request.isNoReboot() + "] imageId[" + imageId + "]"); } catch (Exception e) { throw new RuntimeException("An unexpected error at the time of AMI creation has occurred", e); } finally { client.shutdown(); } return imageId; }
List<String> getSnapshotIdsFromImageId(AmazonEC2Async client, ImageCreateRequest request, Context context) { // LambdaLogger logger = context.getLogger(); String imageId = request.getImageId(); DescribeImagesResult result = client.describeImages(new DescribeImagesRequest().withImageIds(imageId)); List<String> snapshotIds = new ArrayList<String>(); for (Image image : result.getImages()) { for (BlockDeviceMapping block : image.getBlockDeviceMappings()) { snapshotIds.add(block.getEbs().getSnapshotId()); } } return snapshotIds; }
public String getInstanceStateName(InstanceRequest instanceRequest, Context context) { AmazonEC2Async client = createEC2Client(); try { DescribeInstancesResult result = client .describeInstances(new DescribeInstancesRequest().withInstanceIds(instanceRequest.getInstanceId())); List<Instance> instances = result.getReservations().get(0).getInstances(); if (instances.size() != 1) { throw new RuntimeException("instance can not be found."); } return instances.get(0).getState().getName(); } finally { client.shutdown(); } }
StopInstancesResult stopInstance(InstanceRequest instanceRequest, Context context) { AmazonEC2Async client = createEC2Client(); try { StopInstancesRequest req = new StopInstancesRequest(); req.setInstanceIds(Arrays.asList(instanceRequest.getInstanceId())); Future<StopInstancesResult> result = client.stopInstancesAsync(req); while (!result.isDone()) { Thread.sleep(100); } return result.get(); } catch (Exception e) { throw new RuntimeException("unexpected error has occured in the stop instance request.", e); } finally { client.shutdown(); } }
StartInstancesResult startInstance(InstanceRequest instanceRequest, Context context) { AmazonEC2Async client = createEC2Client(); try { StartInstancesRequest req = new StartInstancesRequest(); req.setInstanceIds(Arrays.asList(instanceRequest.getInstanceId())); Future<StartInstancesResult> result = client.startInstancesAsync(req); while (!result.isDone()) { Thread.sleep(100); } return result.get(); } catch (Exception e) { throw new RuntimeException("unexpected error has occured in the start instance request.", e); } finally { client.shutdown(); } }
void attachSnapshotTags(AmazonEC2Async client, String sourceSnapshotId, String snapshotId) { DescribeSnapshotsResult result = client .describeSnapshots(new DescribeSnapshotsRequest().withSnapshotIds(sourceSnapshotId)); List<Snapshot> snapshots = result.getSnapshots(); if (snapshots.size() != 1) { throw new RuntimeException("snapshot can not found. sourceSnapshotId[" + snapshotId + "]"); } List<Tag> sourceSnapshotTags = snapshots.get(0).getTags(); List<Tag> tags = new ArrayList<Tag>(); tags.addAll(sourceSnapshotTags); tags.add(new Tag("SourceSnapshotId", sourceSnapshotId)); tags.add(new Tag("BackupType", "copy-snapshot")); // overwrite CreateTagsRequest snapshotTagsRequest = new CreateTagsRequest().withResources(snapshotId); snapshotTagsRequest.setTags(tags); client.createTags(snapshotTagsRequest); }
@Override public Iterable<Instance> syncAll(AmazonEC2Async amazonEC2Async) { DescribeInstancesRequest request = new DescribeInstancesRequest(); DescribeInstancesResult response = amazonEC2Async.describeInstances(request); return processResponse(response); }
@Override public void run() { for (User user : authenticationService.getLocalUsers()) { AmazonEC2Async amazonEC2Async = ec2UserClient.amazonEC2Async(user); if (amazonEC2Async != null) { Iterable<Instance> instances = ec2Sync.syncAll(amazonEC2Async); for (Instance instance : instances) { notificationService.send("server_refresh", "server_refresh", jsonTransformService.write(instance)); } } } }
@Override public void run() { Iterable<Instance> instances = instanceRepository.findAllByStateAndSwordfishIsTrueAndProductionIsFalse("running"); for (Instance instance : instances) { User user = authenticationService.getLocalUserById(instance.getUserId()); AmazonEC2Async amazonEC2Async = ec2UserClient.amazonEC2Async(user); ec2Stop.process(amazonEC2Async, instance); } }
List<Volume> describeBackupVolumes(AmazonEC2Async client, TagNameRequest target) { Filter tagKey = new Filter().withName("tag-key").withValues("Backup"); Filter tagValue = new Filter().withName("tag-value").withValues(target.getTagName()); DescribeVolumesRequest req = new DescribeVolumesRequest().withFilters(tagKey, tagValue); DescribeVolumesResult result = client.describeVolumes(req); return result.getVolumes(); }
void attachSnapshotTags(AmazonEC2Async client, String volumeId, String snapshotId) { List<Tag> tags = new ArrayList<Tag>(); tags.add(new Tag("VolumeId", volumeId)); tags.add(new Tag("BackupType", "snapshot")); CreateTagsRequest snapshotTagsRequest = new CreateTagsRequest().withResources(snapshotId); snapshotTagsRequest.setTags(tags); client.createTags(snapshotTagsRequest); }
void pargeEbsSnapshot(AmazonEC2Async client, String volumeId, int generationCount, Context context) { LambdaLogger logger = context.getLogger(); logger.log("Parge snapshot start. VolumeId[" + volumeId + "] generationCount[" + generationCount + "]"); List<Filter> filters = new ArrayList<>(); filters.add(new Filter().withName("volume-id").withValues(volumeId)); filters.add(new Filter().withName("tag:VolumeId").withValues(volumeId)); filters.add(new Filter().withName("tag:BackupType").withValues("snapshot")); DescribeSnapshotsRequest snapshotRequest = new DescribeSnapshotsRequest().withFilters(filters); DescribeSnapshotsResult snapshotResult = client.describeSnapshots(snapshotRequest); List<Snapshot> snapshots = snapshotResult.getSnapshots(); Collections.sort(snapshots, new SnapshotComparator()); int snapshotSize = snapshots.size(); if (generationCount < snapshotSize) { for (int i = 0; i < snapshotSize - generationCount; i++) { Snapshot snapshot = snapshots.get(i); if (SnapshotState.Completed.toString().equals(snapshot.getState())) { String snapshotId = snapshot.getSnapshotId(); pargeSnapshot(client, snapshotId); logger.log("Parge EBS snapshot. snapshotId[" + snapshotId + "] volumeId[" + volumeId + "]"); } } } }
void createImageTags(AmazonEC2Async client, ImageCreateRequest imageCreateRequest, Context context) { try { // LambdaLogger logger = context.getLogger(); String instanceId = imageCreateRequest.getInstanceId(); String imageId = imageCreateRequest.getImageId(); List<Tag> tags = new ArrayList<Tag>(); tags.add(new Tag("InstanceId", instanceId)); tags.add(new Tag("BackupType", "image")); String requestDate = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmm")); tags.add(new Tag("RequestDate", requestDate)); // Tag to AMI CreateTagsRequest createTagsRequest = new CreateTagsRequest().withResources(imageId); createTagsRequest.setTags(tags); Future<CreateTagsResult> amiTagsResult = client.createTagsAsync(createTagsRequest); while (!amiTagsResult.isDone()) { Thread.sleep(100); } // Tag to EBS Snapshot tags.add(new Tag("ImageId", imageId)); // snapshotにはimageIdを付けておく。 List<String> snapshotIds = getSnapshotIdsFromImageId(client, imageCreateRequest, context); CreateTagsRequest snapshotTagsRequest = new CreateTagsRequest().withResources(snapshotIds); snapshotTagsRequest.setTags(tags); Future<CreateTagsResult> snapshotTagsResult = client.createTagsAsync(snapshotTagsRequest); while (!snapshotTagsResult.isDone()) { Thread.sleep(100); } } catch (Exception e) { context.getLogger().log("[ERROR][ImageStateCheckAndParge] message[" + e.getMessage() + "] stackTrace[" + getStackTrace(e) + "] [" + imageCreateRequest + "]"); } }
String getImageState(AmazonEC2Async client, ImageCreateRequest createAMIRequest, Context context) { // LambdaLogger logger = context.getLogger(); String imageId = createAMIRequest.getImageId(); DescribeImagesRequest req = new DescribeImagesRequest().withImageIds(imageId); DescribeImagesResult result = client.describeImages(req); return result.getImages().get(0).getState(); }
@Override public void handleRequest(InputStream is, OutputStream os, Context context) { LambdaLogger logger = context.getLogger(); String regionName = System.getenv("AWS_DEFAULT_REGION"); AmazonEC2Async client = RegionUtils.getRegion(regionName).createClient(AmazonEC2AsyncClient.class, new DefaultAWSCredentialsProviderChain(), cc); try { ObjectMapper om = new ObjectMapper(); DeregisterImageRequest event = om.readValue(is, DeregisterImageRequest.class); String imageId = event.getDetail().getRequestParameters().getImageId(); logger.log("Deregister AMI parge snapshot Start. ImageId[" + imageId + "]"); List<Snapshot> snapshots = describeSnapshot(client, imageId, context); if (snapshots.size() == 0) { logger.log("Target of snapshot there is nothing."); } else { snapshots.stream().forEach(s -> pargeSnapshot(client, s.getSnapshotId(), context)); } logger.log("[SUCCESS][DeregisterImage]has been completed successfully." + imageId); } catch (Exception e) { logger.log("[ERROR][DeregisterImage]An unexpected error has occurred. message[" + e.getMessage() + "]"); } finally { client.shutdown(); } }
private List<Snapshot> describeSnapshot(AmazonEC2Async client, String imageId, Context context) { Filter filter = new Filter().withName("description") .withValues("Created by CreateImage(*) for " + imageId + " from *"); DescribeSnapshotsRequest request = new DescribeSnapshotsRequest().withFilters(filter); DescribeSnapshotsResult result = client.describeSnapshots(request); return result.getSnapshots(); }
void pargeEbsSnapshot(AmazonEC2Async client, String sourceSnapshotId, String snapshotId, int generationCount, Context context) { LambdaLogger logger = context.getLogger(); logger.log( "Parge snapshot start. SnapshotId[" + sourceSnapshotId + "] generationCount[" + generationCount + "]"); // get volumeId from tags String volumeId = getVolumeIdFromTag(client, snapshotId); // describe filter tag VolumeId List<Filter> filters = new ArrayList<>(); filters.add(new Filter().withName("tag:VolumeId").withValues(volumeId)); filters.add(new Filter().withName("tag:BackupType").withValues("copy-snapshot")); DescribeSnapshotsRequest snapshotRequest = new DescribeSnapshotsRequest().withFilters(filters); DescribeSnapshotsResult snapshotResult = client.describeSnapshots(snapshotRequest); // snapshot作成開始日でソートします。(古い→新しい) List<Snapshot> snapshots = snapshotResult.getSnapshots(); Collections.sort(snapshots, new SnapshotComparator()); // 世代管理保持数 < snapshotの数の場合、対象をpargeします。 int snapshotSize = snapshots.size(); if (generationCount < snapshotSize) { for (int i = 0; i < snapshotSize - generationCount; i++) { Snapshot snapshot = snapshots.get(i); // (念のため)snapshotのステータスが完了しているものだけをparge対象とする。 if (SnapshotState.Completed.toString().equals(snapshot.getState())) { String pargeSnapshotId = snapshot.getSnapshotId(); pargeSnapshot(client, pargeSnapshotId); logger.log("Parge EBS snapshot. snapshotId[" + pargeSnapshotId + "]"); } } } }
String getVolumeIdFromTag(AmazonEC2Async client, String snapshotId) { List<Tag> snapshotTag = client.describeSnapshots(new DescribeSnapshotsRequest().withSnapshotIds(snapshotId)) .getSnapshots().get(0).getTags(); String volumeId = null; for (Tag tag : snapshotTag) { if ("VolumeId".equals(tag.getKey())) { volumeId = tag.getValue(); } } if (volumeId == null) { throw new RuntimeException("volumeId can not found snapshot. snapshotId[" + snapshotId + "]"); } return volumeId; }
protected AmazonEC2Async createEC2Client() { String regionName = System.getenv("AWS_DEFAULT_REGION"); return RegionUtils.getRegion(regionName).createClient(AmazonEC2AsyncClient.class, new DefaultAWSCredentialsProviderChain(), cc); }
void imageStateCheckAndParge(Message message, ImageStateCheckAndPargeRequest request, Context context) { LambdaLogger logger = context.getLogger(); // parse sqs message ObjectMapper om = new ObjectMapper(); ImageCreateRequest createAMIRequest; try { createAMIRequest = om.readValue(message.getBody(), ImageCreateRequest.class); } catch (IOException e) { deleteQueueMessage(message, request, context); throw new RuntimeException("SQS message could not be parsed"); } // Control multiple activation of Lambda String instanceId = createAMIRequest.getInstanceId(); boolean isLockAcquisition = new LambdaLock().lock(instanceId, context); if (!isLockAcquisition) { logger.log("[ERROR][ImageStateCheckAndParge][" + instanceId + "]You can not acquire a lock."); return; } long sendMessageTime = createAMIRequest.getSendMessageTimeMillis() + 1000 * createAMIRequest.getImageCreatedTimeoutSec(); long now = System.currentTimeMillis(); // Status check of the instance has timed out or not if (sendMessageTime < now) { deleteQueueMessage(message, request, context); throw new RuntimeException("Status check of the instance has timed out. " + createAMIRequest); } AmazonEC2Async client = createEC2Client(); try { String imageState = getImageState(client, createAMIRequest, context); if (ImageState.Available.toString().equals(imageState)) { createImageTags(client, createAMIRequest, context); pargeImage(client, createAMIRequest, context); deleteQueueMessage(message, request, context); } logger.log("[SUCCESS][" + createAMIRequest.getInstanceId() + "] " + "Creation of AMI, additional tags, generation management has completed successfully. [" + createAMIRequest + "]"); } finally { client.shutdown(); } }
public void checkInstanceState(Message message, String stateName, InstanceCheckStateRequest checkInstanceStateRequest, Context context) { LambdaLogger logger = context.getLogger(); ObjectMapper om = new ObjectMapper(); InstanceRequest instanceRequest; try { instanceRequest = om.readValue(message.getBody(), InstanceRequest.class); } catch (IOException e) { deleteQueueMessage(message, checkInstanceStateRequest, context); throw new RuntimeException("SQS message could not be parsed"); } long sendMessageTime = instanceRequest.getSendMessageTimeMillis() + 1000 * instanceRequest.getInstanceStateCheckTimeoutSec(); long now = System.currentTimeMillis(); // Status check of the instance has timed out or not if (sendMessageTime < now) { deleteQueueMessage(message, checkInstanceStateRequest, context); throw new RuntimeException("Status check of the instance has timed out. " + instanceRequest); } AmazonEC2Async client = createEC2Client(); try { DescribeInstancesResult result = client .describeInstances(new DescribeInstancesRequest().withInstanceIds(instanceRequest.getInstanceId())); List<Instance> instances = result.getReservations().get(0).getInstances(); if (instances.size() != 1) { deleteQueueMessage(message, checkInstanceStateRequest, context); throw new RuntimeException("instance can not be found."); } Instance instance = instances.get(0); if (stateName.equals(instance.getState().getName())) { deleteQueueMessage(message, checkInstanceStateRequest, context); logger.log("[SUCCESS][" + instanceRequest.getInstanceId() + "][checkInstanceState][" + stateName + "] Status check of the instance is completed successfully. " + instanceRequest + "]"); } } finally { client.shutdown(); } }
/** * Find the snapshot the volumeId the key, to get a copy of the latest * Snapshot * * @param volumeIdRequest * VolumeIdRequest * @param context * Context */ public void copySnapshotFromVolumeId(VolumeIdRequest volumeIdRequest, Context context) { LambdaLogger logger = context.getLogger(); String regionName = System.getenv("AWS_DEFAULT_REGION"); AmazonEC2Async client = RegionUtils.getRegion(regionName).createClient(AmazonEC2AsyncClient.class, new DefaultAWSCredentialsProviderChain(), cc); try { String volumeId = volumeIdRequest.getVolumeId(); boolean isLockAcquisition = new LambdaLock().lock(volumeId, context); if (!isLockAcquisition) { logger.log("[ERROR][EBSCopySnapshot][" + volumeId + "]You can not acquire a lock."); return; } List<Filter> filters = new ArrayList<>(); filters.add(new Filter().withName("volume-id").withValues(volumeId)); filters.add(new Filter().withName("tag:VolumeId").withValues(volumeId)); filters.add(new Filter().withName("tag:BackupType").withValues("snapshot")); DescribeSnapshotsRequest snapshotRequest = new DescribeSnapshotsRequest().withFilters(filters); DescribeSnapshotsResult snapshotResult = client.describeSnapshots(snapshotRequest); // sort and get latest snapshot List<Snapshot> snapshots = snapshotResult.getSnapshots(); Collections.sort(snapshots, new SnapshotComparator()); int snapshotsSize = snapshots.size(); if (snapshotsSize == 0) { throw new RuntimeException("The copy source snapshot can not be found"); } Snapshot snapshot = snapshots.get(snapshots.size() - 1); String sourceSnapshotId = snapshot.getSnapshotId(); copySnapshot(sourceSnapshotId, volumeIdRequest.getDestinationRegion(), volumeIdRequest.getGenerationCount(), context); } catch (Exception e) { logger.log("[ERROR][EBSCopySnapshot][" + volumeIdRequest.getVolumeId() + "] message[" + e.getMessage() + "] stackTrace[" + getStackTrace(e) + "]"); } finally { client.shutdown(); } }
/** * Sync all Instance data down from AWS * * @param amazonEC2Async {@link AmazonEC2Async} set with required credentials * @return Iterable list of all instances and their latest data */ Iterable<Instance> syncAll(AmazonEC2Async amazonEC2Async);
AmazonEC2Async amazonEC2Async();
AmazonEC2Async amazonEC2Async(User user);
void process(AmazonEC2Async amazonEC2Async, Instance instance);