Skip to content

Commit

Permalink
fix(aws/lambda): Support Artifact as Lambda payload (#5062)
Browse files Browse the repository at this point in the history
* fix(aws/lambda): Support Artifact as Lambda payload

* fix(lambda): include tmp directory clean up

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
  • Loading branch information
Jason Coffman and mergify[bot] committed Nov 6, 2020
1 parent ac02c2e commit f24c3a9
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 1 deletion.
4 changes: 4 additions & 0 deletions clouddriver-lambda/clouddriver-lambda.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
dependencies {
implementation project(":cats:cats-core")
implementation project(":clouddriver-api")
implementation project(":clouddriver-artifacts")
implementation project(":clouddriver-aws")
implementation project(":clouddriver-core")
implementation project(":clouddriver-security")
Expand All @@ -11,12 +12,15 @@ dependencies {
annotationProcessor "org.projectlombok:lombok"
testAnnotationProcessor "org.projectlombok:lombok"

implementation "commons-io:commons-io"
implementation "com.amazonaws:aws-java-sdk"
implementation "com.github.ben-manes.caffeine:guava"
implementation "com.netflix.awsobjectmapper:awsobjectmapper"
implementation "com.netflix.spinnaker.kork:kork-artifacts"
implementation "org.apache.commons:commons-lang3"
implementation "org.apache.httpcomponents:httpclient"
implementation "org.apache.httpcomponents:httpcore"
implementation "org.apache.commons:commons-compress:1.20"
implementation "org.codehaus.groovy:groovy-all"
implementation "org.springframework.boot:spring-boot-starter-web"
implementation "com.squareup.okhttp:okhttp"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.netflix.spinnaker.clouddriver.lambda.deploy.description;

import com.netflix.spinnaker.kork.artifacts.model.Artifact;
import lombok.Data;
import lombok.EqualsAndHashCode;

Expand All @@ -26,4 +27,5 @@ public class InvokeLambdaFunctionDescription extends AbstractLambdaFunctionDescr
String qualifier;

String payload;
Artifact payloadArtifact;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright 2020 Amazon.com, Inc. or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.netflix.spinnaker.clouddriver.lambda.deploy.exception;

public class LambdaOperationException extends RuntimeException {
public LambdaOperationException(String message) {
super(message);
}

public LambdaOperationException(String message, Throwable cause) {
super(message, cause);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,31 +20,53 @@
import com.amazonaws.services.lambda.model.InvokeRequest;
import com.amazonaws.services.lambda.model.InvokeResult;
import com.amazonaws.services.lambda.model.LogType;
import com.netflix.spinnaker.clouddriver.artifacts.ArtifactDownloader;
import com.netflix.spinnaker.clouddriver.lambda.deploy.description.InvokeLambdaFunctionDescription;
import com.netflix.spinnaker.clouddriver.lambda.deploy.description.InvokeLambdaFunctionOutputDescription;
import com.netflix.spinnaker.clouddriver.lambda.deploy.exception.LambdaOperationException;
import com.netflix.spinnaker.clouddriver.orchestration.AtomicOperation;
import com.netflix.spinnaker.kork.artifacts.model.Artifact;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;

public class InvokeLambdaAtomicOperation
extends AbstractLambdaAtomicOperation<
InvokeLambdaFunctionDescription, InvokeLambdaFunctionOutputDescription>
implements AtomicOperation<InvokeLambdaFunctionOutputDescription> {

@Autowired private ArtifactDownloader artifactDownloader;

public InvokeLambdaAtomicOperation(InvokeLambdaFunctionDescription description) {
super(description, "INVOKE_LAMBDA_FUNCTION");
}

@Override
public InvokeLambdaFunctionOutputDescription operate(List priorOutputs) {
updateTaskStatus("Initializing Invoking AWS Lambda Function Operation...");
return invokeFunction(description.getFunctionName(), description.getPayload());

if (description.getPayloadArtifact() != null) {
String payload = getPayloadFromArtifact(description.getPayloadArtifact());
return invokeFunction(description.getFunctionName(), payload);
} else if (description.getPayload() != null) {
return invokeFunction(description.getFunctionName(), description.getPayload());
}

return null;
}

private InvokeLambdaFunctionOutputDescription invokeFunction(
String functionName, String payload) {
AWSLambda client = getLambdaClient();

InvokeRequest req =
new InvokeRequest()
.withFunctionName(functionName)
Expand Down Expand Up @@ -78,4 +100,50 @@ public static String byteBuffer2String(ByteBuffer buf, Charset charset) {
}
return new String(bytes, charset);
}

private String getPayloadFromArtifact(Artifact artifact) {
Path directory = createEmptyDirectory();
File payloadFile = downloadFileToDirectory(artifact, directory);
String payloadString;

try {
payloadString = FileUtils.readFileToString(payloadFile, "UTF8");
} catch (IOException e) {
throw new LambdaOperationException("Unable to read Artifact file to string.");
} finally {
try {
FileUtils.cleanDirectory(directory.toFile());
FileUtils.forceDelete(directory.toFile());
} catch (Exception e) {
throw new LambdaOperationException("Unable to clean up and delete directory.");
}
}

return payloadString;
}

private Path createEmptyDirectory() {
Path path;
try {
path = Files.createTempDirectory("awslambdainvoke-");
FileUtils.cleanDirectory(path.toFile());
} catch (IOException ex) {
throw new LambdaOperationException(
"Unable to create empty directory for AWS Lambda Invocation.");
}
return path;
}

private File downloadFileToDirectory(Artifact artifact, Path directory) {
File targetFile;
try {
InputStream inStream = artifactDownloader.download(artifact);
targetFile = new File(directory + "/ARTIFACT.yaml");
FileUtils.copyInputStreamToFile(inStream, targetFile);
IOUtils.closeQuietly(inStream);
} catch (IOException e) {
throw new LambdaOperationException("Failed to load payload Artifact.");
}
return targetFile;
}
}

0 comments on commit f24c3a9

Please sign in to comment.