From 18d11fd41ec015a33e47192317f4a91a77161613 Mon Sep 17 00:00:00 2001 From: jonkipu Date: Thu, 17 Mar 2022 11:29:17 +0200 Subject: [PATCH] support for s3 object lambda for downloading artifacts --- .../java/hudson/plugins/s3/Destination.java | 17 ++++++++++------- src/main/java/hudson/plugins/s3/Entry.java | 9 ++++++--- .../hudson/plugins/s3/FingerprintRecord.java | 8 +++++--- src/main/java/hudson/plugins/s3/S3Artifact.java | 11 +++++++++-- .../hudson/plugins/s3/S3BucketPublisher.java | 3 ++- src/main/java/hudson/plugins/s3/S3Profile.java | 13 +++++++------ 6 files changed, 39 insertions(+), 22 deletions(-) diff --git a/src/main/java/hudson/plugins/s3/Destination.java b/src/main/java/hudson/plugins/s3/Destination.java index 42bcb881..559c5e61 100644 --- a/src/main/java/hudson/plugins/s3/Destination.java +++ b/src/main/java/hudson/plugins/s3/Destination.java @@ -18,8 +18,9 @@ public class Destination implements Serializable { private static final long serialVersionUID = 1L; public final String bucketName; public final String objectName; + public final String s3ObjectLambda; - public Destination(final String userBucketName, final String fileName) { + public Destination(final String userBucketName, final String fileName, String s3ObjectLambda) { if (userBucketName == null || fileName == null) throw new IllegalArgumentException("Not defined for null parameters: "+userBucketName+","+fileName); @@ -34,6 +35,8 @@ public Destination(final String userBucketName, final String fileName) { } else { objectName = s3CompatibleFileName; } + + this.s3ObjectLambda = s3ObjectLambda; } private String replaceWindowsBackslashes(String fileName) { @@ -46,7 +49,7 @@ public String toString() { } - public static Destination newFromRun(Run run, String bucketName, String fileName, boolean enableFullpath) + public static Destination newFromRun(Run run, String bucketName, String fileName, boolean enableFullpath, String s3ObjectLambda) { final String projectName; @@ -58,23 +61,23 @@ public static Destination newFromRun(Run run, String bucketName, String fileName } int buildID = run.getNumber(); - return new Destination(bucketName, "jobs/" + projectName + "/" + buildID + "/" + fileName); + return new Destination(bucketName, "jobs/" + projectName + "/" + buildID + "/" + fileName, s3ObjectLambda); } public static Destination newFromRun(Run run, S3Artifact artifact) { - return newFromRun(run, artifact.getBucket(), artifact.getName(), artifact.useFullProjectName()); + return newFromRun(run, artifact.getBucket(), artifact.getName(), artifact.useFullProjectName(), artifact.getObjectLambda()); } - public static Destination newFromRunDetails(RunDetails runDetails, String bucketName, String fileName, boolean enableFullpath) { + public static Destination newFromRunDetails(RunDetails runDetails, String bucketName, String fileName, boolean enableFullpath, String s3ObjectLambda) { final String projectName = runDetails.getProjectName(enableFullpath); int buildID = runDetails.getBuildId(); - return new Destination(bucketName, "jobs/" + projectName + "/" + buildID + "/" + fileName); + return new Destination(bucketName, "jobs/" + projectName + "/" + buildID + "/" + fileName, s3ObjectLambda); } public static Destination newFromRunDetails(RunDetails runDetails, S3Artifact artifact) { - return newFromRunDetails(runDetails, artifact.getBucket(), artifact.getName(), artifact.useFullProjectName()); + return newFromRunDetails(runDetails, artifact.getBucket(), artifact.getName(), artifact.useFullProjectName(), artifact.getObjectLambda()); } } diff --git a/src/main/java/hudson/plugins/s3/Entry.java b/src/main/java/hudson/plugins/s3/Entry.java index 63f95cc6..41a04ebb 100644 --- a/src/main/java/hudson/plugins/s3/Entry.java +++ b/src/main/java/hudson/plugins/s3/Entry.java @@ -43,7 +43,7 @@ public final class Entry implements Describable { * Stores the Region Value */ public String selectedRegion; - + /** * Do not publish the artifacts when build fails */ @@ -58,7 +58,7 @@ public final class Entry implements Describable { * Let Jenkins manage the S3 uploaded artifacts */ public boolean managedArtifacts; - + /** * Use S3 server side encryption when uploading the artifacts */ @@ -90,11 +90,13 @@ public final class Entry implements Describable { */ public List userMetadata; + public String s3ObjectLambda; + @DataBoundConstructor public Entry(String bucket, String sourceFile, String excludedFile, String storageClass, String selectedRegion, boolean noUploadOnFailure, boolean uploadFromSlave, boolean managedArtifacts, boolean useServerSideEncryption, boolean flatten, boolean gzipFiles, boolean keepForever, - boolean showDirectlyInBrowser, List userMetadata) { + boolean showDirectlyInBrowser, List userMetadata, String s3ObjectLambda) { this.bucket = bucket; this.sourceFile = sourceFile; this.excludedFile = excludedFile; @@ -109,6 +111,7 @@ public Entry(String bucket, String sourceFile, String excludedFile, String stora this.keepForever = keepForever; this.userMetadata = userMetadata; this.showDirectlyInBrowser = showDirectlyInBrowser; + this.s3ObjectLambda = s3ObjectLambda; } @Override diff --git a/src/main/java/hudson/plugins/s3/FingerprintRecord.java b/src/main/java/hudson/plugins/s3/FingerprintRecord.java index 51bac187..78fc2221 100644 --- a/src/main/java/hudson/plugins/s3/FingerprintRecord.java +++ b/src/main/java/hudson/plugins/s3/FingerprintRecord.java @@ -42,15 +42,17 @@ public class FingerprintRecord implements Serializable { private boolean showDirectlyInBrowser; private final S3Profile profile; private final RunDetails runDetails; + private final String s3ObjectLambda; - public FingerprintRecord(boolean produced, String bucket, String name, String region, String md5sum, RunDetails runDetails, S3Profile profile) { + public FingerprintRecord(boolean produced, String bucket, String name, String region, String md5sum, RunDetails runDetails, S3Profile profile, String s3ObjectLambda) { this.produced = produced; - this.artifact = new S3Artifact(region, bucket, name); + this.artifact = new S3Artifact(region, bucket, name, s3ObjectLambda); this.md5sum = md5sum; this.showDirectlyInBrowser = false; this.keepForever = false; this.runDetails = runDetails; this.profile = profile; + this.s3ObjectLambda = s3ObjectLambda; } Fingerprint addRecord(Run run) throws IOException { @@ -105,7 +107,7 @@ public S3Artifact getArtifact() { private String getDownloadURL(AmazonS3Client client, int signedUrlExpirySeconds, RunDetails runDetails, FingerprintRecord record) { final Destination dest = Destination.newFromRunDetails(runDetails, record.getArtifact()); - final GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(dest.bucketName, dest.objectName); + final GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(dest.s3ObjectLambda, dest.objectName); request.setExpiration(new Date(System.currentTimeMillis() + signedUrlExpirySeconds*1000)); if (!record.isShowDirectlyInBrowser()) { diff --git a/src/main/java/hudson/plugins/s3/S3Artifact.java b/src/main/java/hudson/plugins/s3/S3Artifact.java index 04cc4fec..6d1ec0a4 100644 --- a/src/main/java/hudson/plugins/s3/S3Artifact.java +++ b/src/main/java/hudson/plugins/s3/S3Artifact.java @@ -14,12 +14,14 @@ public final class S3Artifact implements Serializable { private final String name; private final String region; private /*almost final*/ Boolean useFullProjectName; + private final String s3ObjectLambda; - public S3Artifact(String region, String bucket, String name) { + public S3Artifact(String region, String bucket, String name, String s3ObjectLambda) { this.bucket = bucket.intern(); this.name = name.intern(); this.region = region.intern(); this.useFullProjectName = true; + this.s3ObjectLambda = s3ObjectLambda; } /* Old version of this plugin used short name, @@ -46,10 +48,15 @@ public String getRegion() { return region; } + @Exported + public String getObjectLambda() { + return s3ObjectLambda; + } + public Boolean useFullProjectName() { if (useFullProjectName == null) return false; return useFullProjectName; } -} \ No newline at end of file +} diff --git a/src/main/java/hudson/plugins/s3/S3BucketPublisher.java b/src/main/java/hudson/plugins/s3/S3BucketPublisher.java index dc6e5a05..b8f1d45f 100644 --- a/src/main/java/hudson/plugins/s3/S3BucketPublisher.java +++ b/src/main/java/hudson/plugins/s3/S3BucketPublisher.java @@ -265,6 +265,7 @@ public void perform(@Nonnull Run run, @Nonnull FilePath ws, @Nonnull Launc final String bucket = Util.replaceMacro(entry.bucket, envVars); final String storageClass = Util.replaceMacro(entry.storageClass, envVars); + final String s3ObjectLambda = Util.replaceMacro(entry.s3ObjectLambda, envVars); final String selRegion = entry.selectedRegion; final List paths = new ArrayList<>(); @@ -294,7 +295,7 @@ public void perform(@Nonnull Run run, @Nonnull FilePath ws, @Nonnull Launc final Map escapedMetadata = buildMetadata(envVars, entry); final List records = Lists.newArrayList(); - final List fingerprints = profile.upload(run, bucket, paths, filenames, escapedMetadata, storageClass, selRegion, entry.uploadFromSlave, entry.managedArtifacts, entry.useServerSideEncryption, entry.gzipFiles); + final List fingerprints = profile.upload(run, bucket, paths, filenames, escapedMetadata, storageClass, selRegion, entry.uploadFromSlave, entry.managedArtifacts, entry.useServerSideEncryption, entry.gzipFiles, s3ObjectLambda); for (FingerprintRecord fingerprintRecord : fingerprints) { records.add(fingerprintRecord); diff --git a/src/main/java/hudson/plugins/s3/S3Profile.java b/src/main/java/hudson/plugins/s3/S3Profile.java index 64b60d86..d6befbc9 100644 --- a/src/main/java/hudson/plugins/s3/S3Profile.java +++ b/src/main/java/hudson/plugins/s3/S3Profile.java @@ -132,7 +132,8 @@ public List upload(Run run, final boolean uploadFromSlave, final boolean managedArtifacts, final boolean useServerSideEncryption, - final boolean gzipFiles) throws IOException, InterruptedException { + final boolean gzipFiles, + final String s3ObjectLambda) throws IOException, InterruptedException { final List fingerprints = new ArrayList<>(fileNames.size()); try { @@ -143,10 +144,10 @@ public List upload(Run run, final Destination dest; final boolean produced; if (managedArtifacts) { - dest = Destination.newFromRun(run, bucketName, fileName, true); + dest = Destination.newFromRun(run, bucketName, fileName, true, s3ObjectLambda); produced = run.getTimeInMillis() <= filePath.lastModified() + 2000; } else { - dest = new Destination(bucketName, fileName); + dest = new Destination(bucketName, fileName, s3ObjectLambda); produced = false; } @@ -164,7 +165,7 @@ public List upload(Run run, @Override public FingerprintRecord call() throws IOException, InterruptedException { final String md5 = invoke(uploadFromSlave, filePath, upload); - return new FingerprintRecord(produced, bucketName, fileName, selregion, md5, new RunDetails(run), profile); + return new FingerprintRecord(produced, bucketName, fileName, selregion, md5, new RunDetails(run), profile, s3ObjectLambda); } }); @@ -209,7 +210,7 @@ public List list(Run build, String bucket) { final String buildName = build.getDisplayName(); final int buildID = build.getNumber(); - final Destination dest = new Destination(bucket, "jobs/" + buildName + '/' + buildID + '/' + name); + final Destination dest = new Destination(bucket, "jobs/" + buildName + '/' + buildID + '/' + name, bucket); final ListObjectsRequest listObjectsRequest = new ListObjectsRequest() .withBucketName(dest.bucketName) @@ -252,7 +253,7 @@ public List downloadAll(Run build, @Override public FingerprintRecord call() throws IOException, InterruptedException { final String md5 = target.act(new S3DownloadCallable(accessKey, secretKey, useRole, dest, artifact.getRegion(), getProxy())); - return new FingerprintRecord(true, dest.bucketName, target.getName(), artifact.getRegion(), md5, new RunDetails(build), profile); + return new FingerprintRecord(true, dest.bucketName, target.getName(), artifact.getRegion(), md5, new RunDetails(build), profile, artifact.getObjectLambda()); } })); }