diff --git a/kork-artifacts/src/main/java/com/netflix/spinnaker/kork/artifacts/artifactstore/s3/S3ArtifactStore.java b/kork-artifacts/src/main/java/com/netflix/spinnaker/kork/artifacts/artifactstore/s3/S3ArtifactStore.java index 88532c0fe..307c0038a 100644 --- a/kork-artifacts/src/main/java/com/netflix/spinnaker/kork/artifacts/artifactstore/s3/S3ArtifactStore.java +++ b/kork-artifacts/src/main/java/com/netflix/spinnaker/kork/artifacts/artifactstore/s3/S3ArtifactStore.java @@ -88,7 +88,19 @@ public Artifact store(Artifact artifact) { if (applicationsRegex != null && !Pattern.matches(applicationsRegex, application)) { return artifact; } - + byte[] referenceBytes; + try { + referenceBytes = getReferenceAsBytes(artifact); + } catch (IllegalArgumentException e) { + // When this occurs, that means we've run into an embedded/base64 artifact + // that does not contain base64 in its reference. This can happen a couple + // of ways with using SpEL within an artifact, manipulating the pipeline + // JSON directly, etc. So instead of trying to evaluate SpEL here or + // failing, we will just return the raw artifact, and not store this + // particular one. + log.warn("Artifact cannot be stored due to reference not being base64 encoded"); + return artifact; + } String ref = uriBuilder.buildArtifactURI(application, artifact); Artifact remoteArtifact = artifact.toBuilder().type(ArtifactTypes.REMOTE_BASE64.getMimeType()).reference(ref).build(); @@ -108,7 +120,7 @@ public Artifact store(Artifact artifact) { .tagging(Tagging.builder().tagSet(accountTag).build()) .build(); - s3Client.putObject(request, RequestBody.fromBytes(getReferenceAsBytes(artifact))); + s3Client.putObject(request, RequestBody.fromBytes(referenceBytes)); return remoteArtifact; } diff --git a/kork-artifacts/src/test/java/com/netflix/spinnaker/kork/artifacts/artifactstore/s3/S3ArtifactStorerTest.java b/kork-artifacts/src/test/java/com/netflix/spinnaker/kork/artifacts/artifactstore/s3/S3ArtifactStorerTest.java new file mode 100644 index 000000000..17072804d --- /dev/null +++ b/kork-artifacts/src/test/java/com/netflix/spinnaker/kork/artifacts/artifactstore/s3/S3ArtifactStorerTest.java @@ -0,0 +1,46 @@ +/* + * Copyright 2023 Apple Inc. + * + * 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.kork.artifacts.artifactstore.s3; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; + +import com.netflix.spinnaker.kork.artifacts.ArtifactTypes; +import com.netflix.spinnaker.kork.artifacts.artifactstore.ArtifactStoreURISHA256Builder; +import com.netflix.spinnaker.kork.artifacts.model.Artifact; +import com.netflix.spinnaker.security.AuthenticatedRequest; +import org.junit.jupiter.api.Test; +import software.amazon.awssdk.services.s3.S3Client; + +public class S3ArtifactStorerTest { + @Test + public void testInvalidEmbeddedBase64StillSucceeds() { + S3Client client = mock(S3Client.class); + AuthenticatedRequest.setApplication("my-application"); + S3ArtifactStore artifactStore = + new S3ArtifactStore(client, null, "my-bucket", new ArtifactStoreURISHA256Builder(), null); + String expectedReference = "${ #nonbase64spel() }"; + Artifact artifact = + artifactStore.store( + Artifact.builder() + .type(ArtifactTypes.EMBEDDED_BASE64.getMimeType()) + .reference(expectedReference) + .build()); + assertEquals(expectedReference, artifact.getReference()); + assertEquals(ArtifactTypes.EMBEDDED_BASE64.getMimeType(), artifact.getType()); + } +}