Skip to content

Commit

Permalink
[JENKINS-73640] Use AWS SDK for Java 2.x
Browse files Browse the repository at this point in the history
Co-authored-by: Denis Blanchette <[email protected]>
  • Loading branch information
basil and dblanchette committed Dec 17, 2024
1 parent 4d2067f commit 5a119b1
Show file tree
Hide file tree
Showing 58 changed files with 1,831 additions and 1,349 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ console](https://wiki.jenkins.io/display/JENKINS/Jenkins+Script+Console),
example:

```groovy
import com.amazonaws.services.ec2.model.InstanceType
import software.amazon.awssdk.services.ec2.model.InstanceType
import com.cloudbees.jenkins.plugins.awscredentials.AWSCredentialsImpl
import com.cloudbees.plugins.credentials.*
import com.cloudbees.plugins.credentials.domains.Domain
Expand Down
24 changes: 14 additions & 10 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@ THE SOFTWARE.
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- TODO until in BOM -->
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>aws-credentials</artifactId>
<version>238.v8fb_588a_2b_e67</version>
</dependency>
</dependencies>
</dependencyManagement>

Expand All @@ -108,6 +114,14 @@ THE SOFTWARE.
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.jenkins.plugins.aws-java-sdk2</groupId>
<artifactId>aws-java-sdk2-ec2</artifactId>
</dependency>
<dependency>
<groupId>io.jenkins.plugins.aws-java-sdk2</groupId>
<artifactId>aws-java-sdk2-sts</artifactId>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>apache-httpcomponents-client-4-api</artifactId>
Expand Down Expand Up @@ -141,16 +155,6 @@ THE SOFTWARE.
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>trilead-api</artifactId>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.aws-java-sdk</groupId>
<artifactId>aws-java-sdk-ec2</artifactId>
<version>1.12.696-451.v0651a_da_9ca_ec</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.aws-java-sdk</groupId>
<artifactId>aws-java-sdk-minimal</artifactId>
<version>1.12.767-467.vb_e93f0c614b_6</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-step-api</artifactId>
Expand Down
22 changes: 11 additions & 11 deletions src/main/java/hudson/plugins/ec2/AmazonEC2Cloud.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,6 @@
*/
package hudson.plugins.ec2;

import com.amazonaws.SdkClientException;
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;
import edu.umd.cs.findbugs.annotations.Nullable;
import hudson.Extension;
import hudson.Util;
Expand All @@ -51,6 +46,11 @@
import org.kohsuke.stapler.QueryParameter;
import org.kohsuke.stapler.interceptor.RequirePOST;
import org.kohsuke.stapler.verb.POST;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.core.exception.SdkClientException;
import software.amazon.awssdk.services.ec2.Ec2Client;
import software.amazon.awssdk.services.ec2.model.DescribeRegionsResponse;
import software.amazon.awssdk.services.ec2.model.Region;

/**
* The original implementation of {@link EC2Cloud}.
Expand Down Expand Up @@ -178,7 +178,7 @@ public void setAltEC2Endpoint(String altEC2Endpoint) {
}

@Override
protected AWSCredentialsProvider createCredentialsProvider() {
protected AwsCredentialsProvider createCredentialsProvider() {
return createCredentialsProvider(
isUseInstanceProfileForCredentials(),
getCredentialsId(),
Expand Down Expand Up @@ -229,14 +229,14 @@ public ListBoxModel doFillRegionItems(
ListBoxModel model = new ListBoxModel();
if (Jenkins.get().hasPermission(Jenkins.ADMINISTER)) {
try {
AWSCredentialsProvider credentialsProvider =
AwsCredentialsProvider credentialsProvider =
createCredentialsProvider(useInstanceProfileForCredentials, credentialsId);
AmazonEC2 client = AmazonEC2Factory.getInstance()
Ec2Client client = AmazonEC2Factory.getInstance()
.connect(credentialsProvider, determineEC2EndpointURL(altEC2Endpoint));
DescribeRegionsResult regions = client.describeRegions();
List<Region> regionList = regions.getRegions();
DescribeRegionsResponse regions = client.describeRegions();
List<Region> regionList = regions.regions();
for (Region r : regionList) {
String name = r.getRegionName();
String name = r.regionName();
model.add(name, name);
}
} catch (SdkClientException ex) {
Expand Down
65 changes: 33 additions & 32 deletions src/main/java/hudson/plugins/ec2/CloudHelper.java
Original file line number Diff line number Diff line change
@@ -1,36 +1,36 @@
package hudson.plugins.ec2;

import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.model.AvailabilityZone;
import com.amazonaws.services.ec2.model.DescribeAvailabilityZonesResult;
import com.amazonaws.services.ec2.model.DescribeImagesRequest;
import com.amazonaws.services.ec2.model.DescribeInstancesRequest;
import com.amazonaws.services.ec2.model.Image;
import com.amazonaws.services.ec2.model.Instance;
import com.amazonaws.services.ec2.model.Reservation;
import edu.umd.cs.findbugs.annotations.CheckForNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Logger;
import org.apache.commons.lang.StringUtils;
import software.amazon.awssdk.awscore.exception.AwsServiceException;
import software.amazon.awssdk.core.exception.SdkException;
import software.amazon.awssdk.services.ec2.Ec2Client;
import software.amazon.awssdk.services.ec2.model.AvailabilityZone;
import software.amazon.awssdk.services.ec2.model.DescribeAvailabilityZonesResponse;
import software.amazon.awssdk.services.ec2.model.DescribeImagesRequest;
import software.amazon.awssdk.services.ec2.model.DescribeInstancesRequest;
import software.amazon.awssdk.services.ec2.model.Image;
import software.amazon.awssdk.services.ec2.model.Instance;
import software.amazon.awssdk.services.ec2.model.Reservation;

final class CloudHelper {
private static final Logger LOGGER = Logger.getLogger(CloudHelper.class.getName());

static Instance getInstanceWithRetry(String instanceId, EC2Cloud cloud)
throws AmazonClientException, InterruptedException {
static Instance getInstanceWithRetry(String instanceId, EC2Cloud cloud) throws SdkException, InterruptedException {
// Sometimes even after a successful RunInstances, DescribeInstances
// returns an error for a few seconds. We do a few retries instead of
// failing instantly. See [JENKINS-15319].
for (int i = 0; i < 5; i++) {
try {
return getInstance(instanceId, cloud);
} catch (AmazonServiceException e) {
if (e.getErrorCode().equals("InvalidInstanceID.NotFound")
|| EC2Cloud.EC2_REQUEST_EXPIRED_ERROR_CODE.equals(e.getErrorCode())) {
} catch (AwsServiceException e) {
if (e.awsErrorDetails().errorCode().equals("InvalidInstanceID.NotFound")
|| EC2Cloud.EC2_REQUEST_EXPIRED_ERROR_CODE.equals(
e.awsErrorDetails().errorCode())) {
// retry in 5 seconds.
Thread.sleep(5000);
continue;
Expand All @@ -43,50 +43,51 @@ static Instance getInstanceWithRetry(String instanceId, EC2Cloud cloud)
}

@CheckForNull
static Instance getInstance(String instanceId, EC2Cloud cloud) throws AmazonClientException {
static Instance getInstance(String instanceId, EC2Cloud cloud) throws SdkException {
if (StringUtils.isEmpty(instanceId) || cloud == null) {
return null;
}

DescribeInstancesRequest request = new DescribeInstancesRequest();
request.setInstanceIds(Collections.singletonList(instanceId));
DescribeInstancesRequest request = DescribeInstancesRequest.builder()
.instanceIds(Collections.singletonList(instanceId))
.build();

List<Reservation> reservations =
cloud.connect().describeInstances(request).getReservations();
cloud.connect().describeInstances(request).reservations();
if (reservations.size() != 1) {
String message = "Unexpected number of reservations reported by EC2 for instance id '" + instanceId
+ "', expected 1 result, found " + reservations + ".";
if (reservations.isEmpty()) {
message += " Instance seems to be dead.";
}
LOGGER.info(message);
throw new AmazonClientException(message);
throw SdkException.builder().message(message).build();
}
Reservation reservation = reservations.get(0);

List<Instance> instances = reservation.getInstances();
List<Instance> instances = reservation.instances();
if (instances.size() != 1) {
String message = "Unexpected number of instances reported by EC2 for instance id '" + instanceId
+ "', expected 1 result, found " + instances + ".";
if (instances.isEmpty()) {
message += " Instance seems to be dead.";
}
LOGGER.info(message);
throw new AmazonClientException(message);
throw SdkException.builder().message(message).build();
}
return instances.get(0);
}

@CheckForNull
static Image getAmiImage(AmazonEC2 ec2, String ami) {
static Image getAmiImage(Ec2Client ec2, String ami) {
List<String> images = Collections.singletonList(ami);
List<String> owners = Collections.emptyList();
List<String> users = Collections.emptyList();
DescribeImagesRequest request = new DescribeImagesRequest();
request.setImageIds(images);
request.setOwners(owners);
request.setExecutableUsers(users);
List<Image> img = ec2.describeImages(request).getImages();
DescribeImagesRequest.Builder requestBuilder = DescribeImagesRequest.builder();
requestBuilder.imageIds(images);
requestBuilder.owners(owners);
requestBuilder.executableUsers(users);
List<Image> img = ec2.describeImages(requestBuilder.build()).images();
if (img == null || img.isEmpty()) {
// de-registered AMI causes an empty list to be
// returned. so be defensive
Expand All @@ -98,14 +99,14 @@ static Image getAmiImage(AmazonEC2 ec2, String ami) {
}

// Retrieve the availability zones for the region connected on
static ArrayList<String> getAvailabilityZones(AmazonEC2 ec2) {
static ArrayList<String> getAvailabilityZones(Ec2Client ec2) {
ArrayList<String> availabilityZones = new ArrayList<>();

DescribeAvailabilityZonesResult zones = ec2.describeAvailabilityZones();
List<AvailabilityZone> zoneList = zones.getAvailabilityZones();
DescribeAvailabilityZonesResponse zones = ec2.describeAvailabilityZones();
List<AvailabilityZone> zoneList = zones.availabilityZones();

for (AvailabilityZone z : zoneList) {
availabilityZones.add(z.getZoneName());
availabilityZones.add(z.zoneName());
}

return availabilityZones;
Expand Down
Loading

0 comments on commit 5a119b1

Please sign in to comment.