From 083586cf50d6477176dec571711b23e29107b154 Mon Sep 17 00:00:00 2001 From: Ivan Bodrov Date: Wed, 19 Jun 2024 08:56:22 -0400 Subject: [PATCH] aws: add a basic ecr describe-images wrapper (#154) --- pom.xml | 1 + tasks/aws/examples/ecr/concord.yml | 14 +++ tasks/aws/pom.xml | 98 +++++++++++++++++++ .../concord/plugins/aws/EcrTask.java | 95 ++++++++++++++++++ .../concord/plugins/aws/EcrTaskTest.java | 49 ++++++++++ tasks/aws/src/test/resources/logback.xml | 11 +++ 6 files changed, 268 insertions(+) create mode 100644 tasks/aws/examples/ecr/concord.yml create mode 100644 tasks/aws/pom.xml create mode 100644 tasks/aws/src/main/java/com/walmartlabs/concord/plugins/aws/EcrTask.java create mode 100644 tasks/aws/src/test/java/com/walmartlabs/concord/plugins/aws/EcrTaskTest.java create mode 100644 tasks/aws/src/test/resources/logback.xml diff --git a/pom.xml b/pom.xml index 90269ae8..3fc5b7af 100644 --- a/pom.xml +++ b/pom.xml @@ -37,6 +37,7 @@ tasks/akeyless tasks/argocd + tasks/aws tasks/confluence tasks/git tasks/gremlin diff --git a/tasks/aws/examples/ecr/concord.yml b/tasks/aws/examples/ecr/concord.yml new file mode 100644 index 00000000..553b238c --- /dev/null +++ b/tasks/aws/examples/ecr/concord.yml @@ -0,0 +1,14 @@ +configuration: + runtime: concord-v2 + dependencies: + - mvn://com.walmartlabs.concord.plugins:aws-tasks:2.3.0 + +flows: + default: + - task: awsEcr + in: + action: describe-images + region: us-east-1 + repositoryName: foo + out: result + - log: "Image Details: ${resource.prettyPrintJson(result.imageDetails)}" diff --git a/tasks/aws/pom.xml b/tasks/aws/pom.xml new file mode 100644 index 00000000..b578f8b3 --- /dev/null +++ b/tasks/aws/pom.xml @@ -0,0 +1,98 @@ + + + 4.0.0 + + + com.walmartlabs.concord.plugins + concord-plugins-parent + 2.2.1-SNAPSHOT + ../../pom.xml + + + aws-tasks + takari-jar + + + 2.26.4 + + + + + + software.amazon.awssdk + bom + ${aws.sdk.version} + pom + import + + + + + + + software.amazon.awssdk + ecr + + + software.amazon.awssdk + aws-core + + + software.amazon.awssdk + regions + + + software.amazon.awssdk + utils + + + com.walmartlabs.concord + concord-sdk + provided + + + com.walmartlabs.concord.runtime.v2 + concord-runtime-sdk-v2 + provided + + + javax.inject + javax.inject + provided + + + org.slf4j + slf4j-api + provided + + + com.fasterxml.jackson.core + jackson-databind + provided + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + + + org.junit.jupiter + junit-jupiter-api + test + + + ch.qos.logback + logback-classic + test + + + + + + + org.eclipse.sisu + sisu-maven-plugin + + + + diff --git a/tasks/aws/src/main/java/com/walmartlabs/concord/plugins/aws/EcrTask.java b/tasks/aws/src/main/java/com/walmartlabs/concord/plugins/aws/EcrTask.java new file mode 100644 index 00000000..5a95dc0d --- /dev/null +++ b/tasks/aws/src/main/java/com/walmartlabs/concord/plugins/aws/EcrTask.java @@ -0,0 +1,95 @@ +package com.walmartlabs.concord.plugins.aws; + +/*- + * ***** + * Concord + * ----- + * Copyright (C) 2017 - 2024 Walmart Inc., Concord Authors + * ----- + * 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. + * ===== + */ + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.walmartlabs.concord.runtime.v2.sdk.Task; +import com.walmartlabs.concord.runtime.v2.sdk.TaskResult; +import com.walmartlabs.concord.runtime.v2.sdk.Variables; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.ecr.EcrClient; + +import javax.inject.Inject; +import javax.inject.Named; +import java.util.Map; + +import static java.util.Objects.requireNonNull; + +@Named("awsEcr") +public class EcrTask implements Task { + + private static final Logger log = LoggerFactory.getLogger(EcrTask.class); + + private final ObjectMapper objectMapper; + + @Inject + public EcrTask(ObjectMapper objectMapper) { + this.objectMapper = requireNonNull(objectMapper).copy() + .registerModule(new JavaTimeModule()) + .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + } + + @Override + public TaskResult execute(Variables input) { + var action = input.assertString("action"); + if ("describe-images".equals(action)) { + return describeImages(input); + } + throw new IllegalArgumentException("Unsupported action: " + action); + } + + private TaskResult describeImages(Variables input) { + var region = assertRegion(input, "region"); + var repositoryName = input.assertString("repositoryName"); + var verbose = input.getBoolean("verbose", false); + + // create the client + if (verbose) { + log.info("Using region: {}", region); + } + var client = EcrClient.builder() + .region(region) + .build(); + + // describe-images + if (verbose) { + log.info("Describing images in repository '{}'", repositoryName); + } + var result = client.describeImages(r -> r.repositoryName(repositoryName)); + if (verbose) { + log.info("Done: {}", result.imageDetails().size()); + } + + // serialize result into POJOs + var data = objectMapper.convertValue(result.toBuilder(), Map.class); + //noinspection unchecked + return TaskResult.success().values(data); + } + + private static Region assertRegion(Variables input, String key) { + String region = input.assertString(key); + return Region.of(region); + } +} diff --git a/tasks/aws/src/test/java/com/walmartlabs/concord/plugins/aws/EcrTaskTest.java b/tasks/aws/src/test/java/com/walmartlabs/concord/plugins/aws/EcrTaskTest.java new file mode 100644 index 00000000..48d48053 --- /dev/null +++ b/tasks/aws/src/test/java/com/walmartlabs/concord/plugins/aws/EcrTaskTest.java @@ -0,0 +1,49 @@ +package com.walmartlabs.concord.plugins.aws; + +/*- + * ***** + * Concord + * ----- + * Copyright (C) 2017 - 2024 Walmart Inc., Concord Authors + * ----- + * 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. + * ===== + */ + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.walmartlabs.concord.runtime.v2.sdk.MapBackedVariables; +import com.walmartlabs.concord.runtime.v2.sdk.TaskResult; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +@Disabled("requires AWS credentials") +public class EcrTaskTest { + + @Test + public void testDescribeImages() { + var task = new EcrTask(new ObjectMapper()); + var input = new MapBackedVariables(Map.of( + "action", "describe-images", + "region", "us-east-1", + "repositoryName", "foo" + )); + var result = task.execute(input); + assertInstanceOf(TaskResult.SimpleResult.class, result); + assertNotNull(((TaskResult.SimpleResult) result).toMap().get("data")); + } +} diff --git a/tasks/aws/src/test/resources/logback.xml b/tasks/aws/src/test/resources/logback.xml new file mode 100644 index 00000000..271d50b9 --- /dev/null +++ b/tasks/aws/src/test/resources/logback.xml @@ -0,0 +1,11 @@ + + + + %d{HH:mm:ss.SSS} [%thread] [%-5level] %logger{36} - %msg%n + + + + + + +