/** * Checks whether image is present. * * @param amiID * @return <code>Image </code> if the matches one of the amiID * */ public Image resolveAMI(String amiID) throws APPlatformException { LOGGER.debug("resolveAMI('{}') entered", amiID); DescribeImagesRequest dir = new DescribeImagesRequest(); dir.withImageIds(amiID); DescribeImagesResult describeImagesResult = getEC2() .describeImages(dir); List<Image> images = describeImagesResult.getImages(); for (Image image : images) { LOGGER.debug(image.getImageId() + "==" + image.getImageLocation() + "==" + image.getName()); return image; } throw new APPlatformException(Messages.getAll("error_invalid_image") + amiID); }
@Test public void testResolveAMIFound() throws Exception { ec2mock.createDescribeImagesResult("image1"); Image result = ec2comm.resolveAMI("image1"); assertEquals("image1", result.getImageId()); ArgumentCaptor<DescribeImagesRequest> argCaptor = ArgumentCaptor .forClass(DescribeImagesRequest.class); verify(ec2).describeImages(argCaptor.capture()); DescribeImagesRequest dir = argCaptor.getValue(); for (Filter filter : dir.getFilters()) { if (filter.getName().equals("name")) { assertEquals("image1", filter.getValues().get(0)); } } }
@Test public void testCreateInstanceUserData() throws Exception { String userData = "line1\nline2\n"; String userDataBase64 = Base64.encodeBase64String(userData.getBytes()); File myFile = createUserDataFile(userData); try { URL fileUrl = myFile.toURI().toURL(); parameters.put(PropertyHandler.USERDATA_URL, new Setting( PropertyHandler.USERDATA_URL, fileUrl.toString())); ec2mock.createRunInstancesResult("instance2"); ec2mock.createDescribeImagesResult("image1"); ec2mock.createDescribeSubnetsResult("subnet-a77430d0"); ec2mock.createDescribeSecurityGroupResult("subnet-a77430d0", "security_group1,security_group2"); ec2mock.createDescribeInstancesResult("instance1", "ok", "1.2.3.4"); Image image = ec2comm.resolveAMI("image1"); ec2comm.createInstance(image); String result = ph.getAWSInstanceId(); assertEquals("instance2", result); ArgumentCaptor<RunInstancesRequest> arg1 = ArgumentCaptor .forClass(RunInstancesRequest.class); verify(ec2).runInstances(arg1.capture()); RunInstancesRequest rir = arg1.getValue(); assertEquals(userDataBase64, rir.getUserData()); } finally { myFile.delete(); } }
@Test public void testCreateInstanceUserDataMalformedUrl() throws Exception { try { parameters.put(PropertyHandler.USERDATA_URL, new Setting( PropertyHandler.USERDATA_URL, "MALFORMED_URL")); ec2mock.createRunInstancesResult("instance2"); ec2mock.createDescribeImagesResult("image1"); ec2mock.createDescribeSubnetsResult("subnet-a77430d0"); ec2mock.createDescribeSecurityGroupResult("subnet-a77430d0", "security_group1,security_group2"); ec2mock.createDescribeInstancesResult("instance1", "ok", "1.2.3.4"); Image image = ec2comm.resolveAMI("image1"); ec2comm.createInstance(image); assertTrue("Exception expected", false); } catch (APPlatformException ape) { assertTrue(ape.getMessage(), ape.getMessage().contains("MALFORMED_URL")); } }
@Test public void testCreateInstanceUserDataInvalidPath() throws Exception { File myFile = createUserDataFile("test123"); try { URL fileUrl = myFile.toURI().toURL(); parameters.put(PropertyHandler.USERDATA_URL, new Setting( PropertyHandler.USERDATA_URL, fileUrl.toString() + "_notexisting")); ec2mock.createRunInstancesResult("instance2"); ec2mock.createDescribeImagesResult("image1"); ec2mock.createDescribeSubnetsResult("subnet-a77430d0"); ec2mock.createDescribeSecurityGroupResult("subnet-a77430d0", "security_group1,security_group2"); ec2mock.createDescribeInstancesResult("instance1", "ok", "1.2.3.4"); Image image = ec2comm.resolveAMI("image1"); ec2comm.createInstance(image); assertTrue("Exception expected", false); } catch (APPlatformException ape) { assertTrue("Error message not as expected", ape.getMessage() .contains("cannot find the file") || ape.getMessage().contains("No such file")); } finally { myFile.delete(); } }
@Test public void testCreateInstanceSecurityGroupsMultiple() throws Exception { parameters.put(PropertyHandler.SECURITY_GROUP_NAMES, new Setting( PropertyHandler.SECURITY_GROUP_NAMES, "security_group1, security_group2")); ec2mock.createRunInstancesResult("instance3"); ec2mock.createDescribeImagesResult("image1"); ec2mock.createDescribeSubnetsResult("subnet-a77430d0"); ec2mock.createDescribeSecurityGroupResult("subnet-a77430d0", "security_group1,security_group2"); ec2mock.createDescribeInstancesResult("instance1", "ok", "1.2.3.4"); Image image = ec2comm.resolveAMI("image1"); ec2comm.createInstance(image); String result = ph.getAWSInstanceId(); assertEquals("instance3", result); ArgumentCaptor<RunInstancesRequest> arg1 = ArgumentCaptor .forClass(RunInstancesRequest.class); verify(ec2).runInstances(arg1.capture()); RunInstancesRequest rir = arg1.getValue(); // Network interfaces and an instance-level security groups may not be // specified on the same request.. assertEquals(2, rir.getNetworkInterfaces().get(0).getGroups().size()); // assertEquals("security_group1", rir.getSecurityGroups().get(0)); // assertEquals("security_group2", rir.getSecurityGroups().get(1)); }
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; }
@Test public void isAmiWithTagExistTrue() { AmazonEC2 ec2Client = mock(AmazonEC2.class); AmiTagCheckService amiTagCheckService = new AmiTagCheckService(ec2Client); String amiId = "ami-1234abcd"; String tagName = "sometag"; String tagValue = "someval"; when(ec2Client.describeImages( new DescribeImagesRequest() .withFilters(new Filter().withName(tagName).withValues(tagValue)) .withFilters(new Filter().withName("image-id").withValues(amiId)) ) ).thenReturn( new DescribeImagesResult().withImages(new Image()) ); // invoke method under test assertTrue(amiTagCheckService.isAmiWithTagExist(amiId, tagName, tagValue)); }
@Override @Cacheable(cacheNames = "ami-details", cacheManager = "oneDayTTLCacheManager") public Map<String, String> getAmiDetails(final String accountId, final Region region, final String amiId) { final ImmutableMap.Builder<String, String> result = ImmutableMap.builder(); result.put("ami_id", amiId); final AmazonEC2Client ec2 = clientProvider.getClient(AmazonEC2Client.class, accountId, region); final Optional<Image> ami = Optional.ofNullable(new DescribeImagesRequest().withImageIds(amiId)) .map(ec2::describeImages) .map(DescribeImagesResult::getImages) .map(List::stream) .flatMap(Stream::findFirst); ami.map(Image::getName).ifPresent(name -> result.put("ami_name", name)); ami.map(Image::getOwnerId).ifPresent(owner -> result.put("ami_owner_id", owner)); return result.build(); }
@Override protected void process(final EC2InstanceContext context) { final LifecycleEntity lifecycleEntity = new LifecycleEntity(); lifecycleEntity.setEventType(context.getEventName()); lifecycleEntity.setEventDate(getLifecycleDate(context)); lifecycleEntity.setAccountId(context.getAccountId()); lifecycleEntity.setRegion(context.getRegionAsString()); lifecycleEntity.setInstanceId(context.getInstanceId()); context.getAmiId().ifPresent(lifecycleEntity::setImageId); context.getAmi().map(Image::getName).ifPresent(lifecycleEntity::setImageName); final Optional<ApplicationEntity> application = context.getApplicationId().map(ApplicationEntity::new); if (!application.isPresent()) { log.warn("Could not determine applicationId. Skip processing of LifecyclePlugin."); return; } final Optional<VersionEntity> version = context.getVersionId().map(VersionEntity::new); if (!version.isPresent()) { log.warn("Could not determine versionId. Skip processing of LifecyclePlugin."); return; } applicationLifecycleService.saveLifecycle(application.get(), version.get(), lifecycleEntity); }
@Override protected void process(final EC2InstanceContext context) { if (!context.isTaupageAmi().orElse(false)) { violationSink.put( context.violation() .withType(WRONG_AMI) .withPluginFullyQualifiedClassName(AmiPlugin.class) .withMetaInfo(ImmutableMap.of( "ami_owner_id", context.getAmi().map(Image::getOwnerId).orElse(""), "ami_id", context.getAmiId().orElse(""), "ami_name", context.getAmi().map(Image::getName).orElse(""))) .build()); } }
@Test public void testApplyAmiFound() throws Exception { when(ec2InstanceContextMock.getAmiId()).thenReturn(Optional.of(AMI_ID)); when(ec2InstanceContextMock.getClient(eq(AmazonEC2Client.class))).thenReturn(amazonEC2ClientMock); final DescribeImagesRequest describeImagesRequest = new DescribeImagesRequest().withImageIds(AMI_ID); when(amazonEC2ClientMock.describeImages(eq(describeImagesRequest))) .thenReturn(new DescribeImagesResult() .withImages(newArrayList(new Image() .withImageId(AMI_ID) .withName(AMI_NAME)) ) ); final Optional<Image> result = amiProvider.apply(ec2InstanceContextMock); assertThat(result).isPresent(); verify(ec2InstanceContextMock).getAmiId(); verify(ec2InstanceContextMock).getClient(eq(AmazonEC2Client.class)); verify(amazonEC2ClientMock).describeImages(eq(describeImagesRequest)); }
@Test public void testApplyAmiNotFound() throws Exception { when(ec2InstanceContextMock.getAmiId()).thenReturn(Optional.of(AMI_ID)); when(ec2InstanceContextMock.getClient(eq(AmazonEC2Client.class))).thenReturn(amazonEC2ClientMock); final DescribeImagesRequest describeImagesRequest = new DescribeImagesRequest().withImageIds(AMI_ID); when(amazonEC2ClientMock.describeImages(eq(describeImagesRequest))) .thenReturn(null); final Optional<Image> result = amiProvider.apply(ec2InstanceContextMock); assertThat(result).isEmpty(); verify(ec2InstanceContextMock).getAmiId(); verify(ec2InstanceContextMock).getClient(eq(AmazonEC2Client.class)); verify(amazonEC2ClientMock).describeImages(eq(describeImagesRequest)); }
@Test public void testApplyAmiNotFoundWithException() throws Exception { when(ec2InstanceContextMock.getAmiId()).thenReturn(Optional.of(AMI_ID)); when(ec2InstanceContextMock.getClient(eq(AmazonEC2Client.class))).thenReturn(amazonEC2ClientMock); final DescribeImagesRequest describeImagesRequest = new DescribeImagesRequest().withImageIds(AMI_ID); when(amazonEC2ClientMock.describeImages(eq(describeImagesRequest))) .thenThrow(new AmazonClientException("oops, I did it again... Britney")); final Optional<Image> result = amiProvider.apply(ec2InstanceContextMock); assertThat(result).isEmpty(); verify(ec2InstanceContextMock).getAmiId(); verify(ec2InstanceContextMock).getClient(eq(AmazonEC2Client.class)); verify(amazonEC2ClientMock).describeImages(eq(describeImagesRequest)); }
public void deleteImage(Image image) { String imageId = image.getImageId(); logger.info("delete image, imageId={}", imageId); ec2.deregisterImage(new DeregisterImageRequest(imageId)); // our image always uses EBS as first and only drive List<BlockDeviceMapping> mappings = image.getBlockDeviceMappings(); if (!mappings.isEmpty()) { EbsBlockDevice ebs = mappings.get(0).getEbs(); if (ebs != null) { String snapshotId = ebs.getSnapshotId(); logger.info("delete snapshot, snapshotId={}", snapshotId); ec2.deleteSnapshot(new DeleteSnapshotRequest(snapshotId)); } } }
public List<VirtualMachineImage> listImages(String ... imageIds) { checkNotNull(imageIds); checkArgument(imageIds.length >= 1); List<Image> images = newArrayList(); try { images = ec2_.describeImages(new DescribeImagesRequest().withImageIds(imageIds)).getImages(); } catch (AmazonClientException exception) { LOG.error(exception.getMessage()); } return IMAGES_FUNCTION.apply(images); }
String lookupImageId(String imgName) { DescribeImagesRequest req = new DescribeImagesRequest(); if(imgName == null || imgName.length() == 0) return null; req.setRequestCredentials(creds); DescribeImagesResult result = ec2Client.describeImages(); for(Image image : result.getImages()) { if(image.getName() != null && image.getName().equals(imgName)) return image.getImageId(); } return null; }
@Override public Event add(Ec2Ami newResource) { Image image = newResource.getResource(); String state = image.getState(); switch (state) { case "available": return createEvent(null, newResource, EventType.Ec2_AMI_Registered); case "deregistered": return createEvent(null, newResource, EventType.Ec2_AMI_Deregistered); case "pending": return createEvent(null, newResource, EventType.Ec2_AMI_Pending); default: log.error("not handled instance state:{}", state); return createEvent(null, newResource, EventType.Unknown); } }
@Override public List<AbstractResource<?>> describeAMIs(Account account, Region region, DateTime dt, Ec2Filter... filters) { AmazonEC2 ec2 = findClient(account, region); DescribeImagesRequest req = new DescribeImagesRequest(); for (Ec2Filter filter : filters) { Filter f = new Filter().withName(filter.getName()).withValues(filter.getValues()); req.withFilters(f); } log.debug("start describing amis for account:{} in region:{} via api", account.getId() + "=>" + account.getName(), region); DescribeImagesResult res = ec2.describeImages(req); List<List<LaunchPermission>> imageLaunchPermissions = new ArrayList<>(); for (Image image : res.getImages()) { imageLaunchPermissions.add(findImageLaunchPermissions(account, region, image.getImageId())); } return converter.toEc2AMIs(res.getImages(), imageLaunchPermissions, account.getId(), region, dt); }
@Test public void testCreateInstance() throws Exception { ec2mock.createRunInstancesResult("instance1"); ec2mock.createDescribeImagesResult("image1"); ec2mock.createDescribeSubnetsResult("subnet-a77430d0"); ec2mock.createDescribeSecurityGroupResult("subnet-a77430d0", "security_group1,security_group2"); ec2mock.createDescribeInstancesResult("instance1", "ok", "1.2.3.4"); Image image = ec2comm.resolveAMI("image1"); ec2comm.createInstance(image); String result = ph.getAWSInstanceId(); assertEquals("instance1", result); ArgumentCaptor<RunInstancesRequest> arg1 = ArgumentCaptor .forClass(RunInstancesRequest.class); verify(ec2).runInstances(arg1.capture()); RunInstancesRequest rir = arg1.getValue(); assertEquals("image1", rir.getImageId()); assertEquals("type1", rir.getInstanceType()); assertEquals("key_pair", rir.getKeyName()); assertEquals(1, rir.getMinCount().intValue()); assertEquals(1, rir.getMaxCount().intValue()); ArgumentCaptor<CreateTagsRequest> arg2 = ArgumentCaptor .forClass(CreateTagsRequest.class); verify(ec2).createTags(arg2.capture()); CreateTagsRequest ctr = arg2.getValue(); for (Tag t : ctr.getTags()) { if (t.getKey().equalsIgnoreCase("Name")) { assertEquals("name1", t.getValue()); } else if (t.getKey().equalsIgnoreCase("SubscriptionId")) { assertEquals("subId", t.getValue()); } else if (t.getKey().equalsIgnoreCase("OrganizationId")) { assertEquals("orgId", t.getValue()); } } parameters.put("USERDATA_URL", new Setting("USERDATA_URL", "userdata")); }
@Test(expected = APPlatformException.class) public void testCreateInstanceInvalid() throws Exception { // Missing instance id ec2mock.createRunInstancesResult(); ec2mock.createDescribeImagesResult("image1"); ec2mock.createDescribeSubnetsResult("subnet-a77430d0"); ec2mock.createDescribeSecurityGroupResult("subnet-a77430d0", "security_group1, security_group2"); Image image = ec2comm.resolveAMI("image1"); ec2comm.createInstance(image); }
@Test public void testCreateInstanceUserDataEmptyUrl() throws Exception { parameters.put(PropertyHandler.USERDATA_URL, new Setting( PropertyHandler.USERDATA_URL, "")); ec2mock.createRunInstancesResult("instance3"); ec2mock.createDescribeImagesResult("image1"); ec2mock.createDescribeSubnetsResult("subnet-a77430d0"); ec2mock.createDescribeSecurityGroupResult("subnet-a77430d0", "security_group1,security_group2"); ec2mock.createDescribeInstancesResult("instance1", "ok", "1.2.3.4"); Image image = ec2comm.resolveAMI("image1"); ec2comm.createInstance(image); String result = ph.getAWSInstanceId(); assertEquals("instance3", result); }
@Test public void testCreateInstanceSecurityGroups() throws Exception { parameters.put(PropertyHandler.SECURITY_GROUP_NAMES, new Setting( PropertyHandler.SECURITY_GROUP_NAMES, "security_group")); ec2mock.createRunInstancesResult("instance3"); ec2mock.createDescribeImagesResult("image1"); ec2mock.createDescribeSubnetsResult("subnet-a77430d0"); ec2mock.createDescribeSecurityGroupResult("subnet-a77430d0", "security_group"); ec2mock.createDescribeInstancesResult("instance1", "ok", "1.2.3.4"); Image image = ec2comm.resolveAMI("image1"); ec2comm.createInstance(image); String result = ph.getAWSInstanceId(); assertEquals("instance3", result); ArgumentCaptor<RunInstancesRequest> arg1 = ArgumentCaptor .forClass(RunInstancesRequest.class); verify(ec2).runInstances(arg1.capture()); RunInstancesRequest rir = arg1.getValue(); // Network interfaces and an instance-level security groups may not be // specified on the same request.. assertEquals(1, rir.getNetworkInterfaces().get(0).getGroups().size()); /* * assertEquals("security_group", * rir.getNetworkInterfaces().get(0).getGroups().get(0)); */ }
public void createDescribeImagesResult(String... imageIds) { Collection<Image> images = new ArrayList<Image>(); for (int i = 0; i < imageIds.length; i++) { images.add(new Image().withImageId(imageIds[i])); } DescribeImagesResult imagesResult = new DescribeImagesResult() .withImages(images); doReturn(imagesResult).when(ec2) .describeImages(any(DescribeImagesRequest.class)); }
private void pargeImages(AmazonEC2 ec2, Image image) { String imageId = image.getImageId(); ec2.deregisterImage(new DeregisterImageRequest(imageId)); for (BlockDeviceMapping block : image.getBlockDeviceMappings()) { String snapshotId = block.getEbs().getSnapshotId(); ec2.deleteSnapshot(new DeleteSnapshotRequest().withSnapshotId(snapshotId)); } }
/** * Just delegate to current partition. * * <p> * It is up to the {@link AWSImageEnumerationContext#loadAwsImages()} to load next * partition through {@link #withPartition(PaginatingIterator)}. */ @Override public List<Image> next() { List<Image> delegatedPage = this.partition.next(); this.pageNumber++; this.totalNumber += delegatedPage.size(); return delegatedPage; }
@Override protected DeferredResult<RemoteResourcesPage> getExternalResources(String nextPageLink) { // AWS does not support pagination of images so we internally partition // all results thus simulating paging return loadAwsImages().thenApply(imagesIterator -> { RemoteResourcesPage page = new RemoteResourcesPage(); if (imagesIterator.hasNext()) { final List<Image> awsImagesPage = imagesIterator.next(); for (Image awsImage : awsImagesPage) { page.resourcesPage.put(awsImage.getImageId(), awsImage); } } // Return a non-null nextPageLink to the parent so we are called back. if (imagesIterator.hasNext()) { page.nextPageLink = "awsImages_" + (imagesIterator.pageNumber() + 1); } else { this.service.logInfo("Enumerating AWS images: TOTAL number %s", imagesIterator.totalNumber()); } return page; }); }
private Optional<LocalDate> getExpirationDate(final Image image) { // current implementation parse creation date from name + add 60 days support period return Optional.ofNullable(image.getName()) .filter(name -> !name.isEmpty()) .map(TAUPAGE_NAME_SPLITTER::splitToList) .filter(list -> list.size() == 4) // "Taupage-AMI-20160201-123456" .map(parts -> parts.get(2)) .map(timestamp -> LocalDate.parse(timestamp, ofPattern("yyyyMMdd"))) .map(creationDate -> creationDate.plusDays(60)); }
private Optional<Image> getAmiFromEC2Api(final AmazonEC2Client ec2Client, final String imageId) { try { final DescribeImagesResult response = ec2Client.describeImages(new DescribeImagesRequest().withImageIds(imageId)); return ofNullable(response) .map(DescribeImagesResult::getImages) .map(List::stream) .flatMap(Stream::findFirst); } catch (final AmazonClientException e) { log.warn("Could not describe image " + imageId, e); return empty(); } }