/** * Check that the AMI requested is available in the cloud and can be used. */ public FormValidation doValidateAmi( @QueryParameter boolean useInstanceProfileForCredentials, @QueryParameter String credentialsId, @QueryParameter String ec2endpoint, @QueryParameter String region, final @QueryParameter String ami) throws IOException { AWSCredentialsProvider credentialsProvider = EC2Cloud.createCredentialsProvider(useInstanceProfileForCredentials, credentialsId); AmazonEC2 ec2; if (region != null) { ec2 = EC2Cloud.connect(credentialsProvider, AmazonEC2Cloud.getEc2EndpointUrl(region)); } else { ec2 = EC2Cloud.connect(credentialsProvider, new URL(ec2endpoint)); } if (ec2 != null) { try { List<String> images = new LinkedList<String>(); images.add(ami); List<String> owners = new LinkedList<String>(); List<String> users = new LinkedList<String>(); DescribeImagesRequest request = new DescribeImagesRequest(); request.setImageIds(images); request.setOwners(owners); request.setExecutableUsers(users); List<Image> img = ec2.describeImages(request).getImages(); if (img == null || img.isEmpty()) { // de-registered AMI causes an empty list to be // returned. so be defensive // against other possibilities return FormValidation.error("No such AMI, or not usable with this accessId: " + ami); } String ownerAlias = img.get(0).getImageOwnerAlias(); return FormValidation.ok( img.get(0).getImageLocation() + (ownerAlias != null ? " by " + ownerAlias : "")); } catch (AmazonClientException e) { return FormValidation.error(e.getMessage()); } } else return FormValidation.ok(); // can't test }
/* * Check the current Spot price of the selected instance type for the selected region */ public FormValidation doCurrentSpotPrice( @QueryParameter boolean useInstanceProfileForCredentials, @QueryParameter String credentialsId, @QueryParameter String region, @QueryParameter String type, @QueryParameter String zone) throws IOException, ServletException { String cp = ""; String zoneStr = ""; // Connect to the EC2 cloud with the access id, secret key, and // region queried from the created cloud AWSCredentialsProvider credentialsProvider = EC2Cloud.createCredentialsProvider(useInstanceProfileForCredentials, credentialsId); AmazonEC2 ec2 = EC2Cloud.connect(credentialsProvider, AmazonEC2Cloud.getEc2EndpointUrl(region)); if (ec2 != null) { try { // Build a new price history request with the currently // selected type DescribeSpotPriceHistoryRequest request = new DescribeSpotPriceHistoryRequest(); // If a zone is specified, set the availability zone in the // request // Else, proceed with no availability zone which will result // with the cheapest Spot price if (getAvailabilityZones(ec2).contains(zone)) { request.setAvailabilityZone(zone); zoneStr = zone + " availability zone"; } else { zoneStr = region + " region"; } /* * Iterate through the AWS instance types to see if can find a match for the databound String type. * This is necessary because the AWS API needs the instance type string formatted a particular way * to retrieve prices and the form gives us the strings in a different format. For example "T1Micro" * vs "t1.micro". */ InstanceType ec2Type = null; for (InstanceType it : InstanceType.values()) { if (it.name().equals(type)) { ec2Type = it; break; } } /* * If the type string cannot be matched with an instance type, throw a Form error */ if (ec2Type == null) { return FormValidation.error("Could not resolve instance type: " + type); } Collection<String> instanceType = new ArrayList<String>(); instanceType.add(ec2Type.toString()); request.setInstanceTypes(instanceType); request.setStartTime(new Date()); // Retrieve the price history request result and store the // current price DescribeSpotPriceHistoryResult result = ec2.describeSpotPriceHistory(request); if (!result.getSpotPriceHistory().isEmpty()) { SpotPrice currentPrice = result.getSpotPriceHistory().get(0); cp = currentPrice.getSpotPrice(); } } catch (AmazonServiceException e) { return FormValidation.error(e.getMessage()); } } /* * If we could not return the current price of the instance display an error Else, remove the additional * zeros from the current price and return it to the interface in the form of a message */ if (cp.isEmpty()) { return FormValidation.error("Could not retrieve current Spot price"); } else { cp = cp.substring(0, cp.length() - 3); return FormValidation.ok( "The current Spot price for a " + type + " in the " + zoneStr + " is $" + cp); } }