/* * The MIT License * * Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package hudson.plugins.ec2; import hudson.Extension; import hudson.Util; import hudson.model.Failure; import hudson.slaves.Cloud; import hudson.util.FormValidation; import hudson.util.ListBoxModel; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.List; import java.util.Locale; import javax.servlet.ServletException; import jenkins.model.Jenkins; import org.apache.commons.lang.StringUtils; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerResponse; import com.amazonaws.auth.AWSCredentialsProvider; import com.amazonaws.services.ec2.AmazonEC2; import com.amazonaws.services.ec2.model.DescribeRegionsResult; import com.amazonaws.services.ec2.model.Region; /** * The original implementation of {@link EC2Cloud}. * * @author Kohsuke Kawaguchi */ public class AmazonEC2Cloud extends EC2Cloud { /** * Represents the region. Can be null for backward compatibility reasons. */ private String region; public static final String CLOUD_ID_PREFIX = "ec2-"; // Used when running unit tests public static boolean testMode; @DataBoundConstructor public AmazonEC2Cloud(String cloudName, boolean useInstanceProfileForCredentials, String credentialsId, String region, String privateKey, String instanceCapStr, List<? extends SlaveTemplate> templates) { super(createCloudId(cloudName), useInstanceProfileForCredentials, credentialsId, privateKey, instanceCapStr, templates); this.region = region; } public String getCloudName() { return this.name.substring(CLOUD_ID_PREFIX.length()); } @Override public String getDisplayName() { return getCloudName(); } private static String createCloudId(String cloudName) { return CLOUD_ID_PREFIX + cloudName.trim(); } public String getRegion() { if (region == null) region = DEFAULT_EC2_HOST; // Backward compatibility // Handles pre 1.14 region names that used the old AwsRegion enum, note we don't change // the region here to keep the meta-data compatible in the case of a downgrade (is that right?) if (region.indexOf('_') > 0) return region.replace('_', '-').toLowerCase(Locale.ENGLISH); return region; } public static URL getEc2EndpointUrl(String region) { try { return new URL("https://ec2." + region + "." + AWS_URL_HOST + "/"); } catch (MalformedURLException e) { throw new Error(e); // Impossible } } @Override public URL getEc2EndpointUrl() { return getEc2EndpointUrl(getRegion()); } @Override public URL getS3EndpointUrl() { try { return new URL("https://" + getRegion() + ".s3.amazonaws.com/"); } catch (MalformedURLException e) { throw new Error(e); // Impossible } } @Extension public static class DescriptorImpl extends EC2Cloud.DescriptorImpl { @Override public String getDisplayName() { return "Amazon EC2"; } public FormValidation doCheckCloudName(@QueryParameter String value) { try { Jenkins.checkGoodName(value); } catch (Failure e) { return FormValidation.error(e.getMessage()); } String cloudId = createCloudId(value); int found = 0; for (Cloud c : Jenkins.getInstance().clouds) { if (c.name.equals(cloudId)) { found++; } } if (found > 1) { return FormValidation.error(Messages.AmazonEC2Cloud_NonUniqName()); } return FormValidation.ok(); } public ListBoxModel doFillRegionItems(@QueryParameter boolean useInstanceProfileForCredentials, @QueryParameter String credentialsId) throws IOException, ServletException { ListBoxModel model = new ListBoxModel(); if (testMode) { model.add(DEFAULT_EC2_HOST); return model; } AWSCredentialsProvider credentialsProvider = createCredentialsProvider(useInstanceProfileForCredentials, credentialsId); AmazonEC2 client = connect(credentialsProvider, new URL("http://ec2.amazonaws.com")); DescribeRegionsResult regions = client.describeRegions(); List<Region> regionList = regions.getRegions(); for (Region r : regionList) { String name = r.getRegionName(); model.add(name, name); } return model; } public FormValidation doTestConnection(@QueryParameter String region, @QueryParameter boolean useInstanceProfileForCredentials, @QueryParameter String credentialsId, @QueryParameter String privateKey) throws IOException, ServletException { if (Util.fixEmpty(region) == null) { region = DEFAULT_EC2_HOST; } return super.doTestConnection(getEc2EndpointUrl(region), useInstanceProfileForCredentials, credentialsId, privateKey); } public FormValidation doGenerateKey(StaplerResponse rsp, @QueryParameter String region, @QueryParameter boolean useInstanceProfileForCredentials, @QueryParameter String credentialsId) throws IOException, ServletException { return super.doGenerateKey(rsp, getEc2EndpointUrl(region), useInstanceProfileForCredentials, credentialsId); } } }