From 41eb77ed4faace1dd92263142f1d29478900b4b9 Mon Sep 17 00:00:00 2001 From: Vladimir Orany Date: Wed, 4 Aug 2021 16:08:33 +0200 Subject: [PATCH] added support for AWS SecretManager --- README.md | 13 +++ build.gradle | 1 + ...mazonSecretsManagerGetSecretValueTask.java | 84 +++++++++++++++++++ .../AmazonSecretsManagerPlugin.java | 32 +++++++ .../AmazonSecretsManagerPluginExtension.java | 56 +++++++++++++ ...ethod.aws.reboot.secretsmanager.properties | 17 ++++ 6 files changed, 203 insertions(+) create mode 100644 src/main/java/jp/classmethod/aws/reboot/gradle/secretsmanager/AmazonSecretsManagerGetSecretValueTask.java create mode 100644 src/main/java/jp/classmethod/aws/reboot/gradle/secretsmanager/AmazonSecretsManagerPlugin.java create mode 100644 src/main/java/jp/classmethod/aws/reboot/gradle/secretsmanager/AmazonSecretsManagerPluginExtension.java create mode 100644 src/main/resources/META-INF/gradle-plugins/jp.classmethod.aws.reboot.secretsmanager.properties diff --git a/README.md b/README.md index 7cbfe88..1dc7f22 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,8 @@ Current Features / Supported AWS Products * Attach role policy * ELB * (TBD) +* Secrets Manager + * Get secret value * SQS * Send messages * Delete messages @@ -412,6 +414,17 @@ task publishJsonMessage(type: AmazonSNSPublishMessageTask) { ``` Look at [SNS example](samples/10-sns) for more information. +### Secrets Manager + +```groovy +apply plugin: "jp.classmethod.aws.secretsmanager" + +task retrieveSecrets(type: AmazonSecretsManagerGetSecretValueTask) { + secretName 'my-app-secrets' + destination file('application-secrets.json') +} +``` + License ------- Copyright (C) 2013-2018 [Classmethod, Inc.](http://classmethod.jp/) diff --git a/build.gradle b/build.gradle index 4dd71c1..7e256e1 100644 --- a/build.gradle +++ b/build.gradle @@ -218,6 +218,7 @@ dependencies { implementation "com.amazonaws:aws-java-sdk-cloudformation:$awsJavaSdkVersion" implementation "com.amazonaws:aws-java-sdk-lambda:$awsJavaSdkVersion" implementation "com.amazonaws:aws-java-sdk-iam:$awsJavaSdkVersion" + implementation "com.amazonaws:aws-java-sdk-secretsmanager:$awsJavaSdkVersion" implementation "com.amazonaws:aws-java-sdk-sqs:$awsJavaSdkVersion" implementation "com.amazonaws:aws-java-sdk-sns:$awsJavaSdkVersion" implementation "com.amazonaws:aws-java-sdk-ecr:$awsJavaSdkVersion" diff --git a/src/main/java/jp/classmethod/aws/reboot/gradle/secretsmanager/AmazonSecretsManagerGetSecretValueTask.java b/src/main/java/jp/classmethod/aws/reboot/gradle/secretsmanager/AmazonSecretsManagerGetSecretValueTask.java new file mode 100644 index 0000000..8897395 --- /dev/null +++ b/src/main/java/jp/classmethod/aws/reboot/gradle/secretsmanager/AmazonSecretsManagerGetSecretValueTask.java @@ -0,0 +1,84 @@ +/* + * Copyright 2015-2016 the original author or 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. + */ +package jp.classmethod.aws.reboot.gradle.secretsmanager; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; + +import lombok.Getter; +import lombok.Setter; + +import org.gradle.api.GradleException; +import org.gradle.api.internal.ConventionTask; +import org.gradle.api.tasks.Input; +import org.gradle.api.tasks.OutputFile; +import org.gradle.api.tasks.TaskAction; + +import com.amazonaws.services.secretsmanager.AWSSecretsManager; +import com.amazonaws.services.secretsmanager.model.GetSecretValueRequest; +import com.amazonaws.services.secretsmanager.model.GetSecretValueResult; + +public class AmazonSecretsManagerGetSecretValueTask extends ConventionTask { + + @Getter(onMethod = @__(@OutputFile)) + @Setter + private File destination; + + @Getter(onMethod = @__(@Input)) + @Setter + private String secretName; + + + public AmazonSecretsManagerGetSecretValueTask() { + setDescription("Retrieve secret value into a file"); + setGroup("AWS"); + } + + @TaskAction + public void retrieveSecretValue() { + getLogger().trace("Retrieving secrets from {} into {}", secretName, destination); + + File destination = getDestination(); + String secretName = getSecretName(); + + if (secretName == null) { + throw new GradleException("Must specify secret name"); + } + if (destination == null) { + throw new GradleException("Must provide the destination file"); + } + + AmazonSecretsManagerPluginExtension ext = getProject() + .getExtensions() + .getByType(AmazonSecretsManagerPluginExtension.class); + + AWSSecretsManager sm = ext.getClient(); + + GetSecretValueRequest request = new GetSecretValueRequest().withSecretId(secretName); + + GetSecretValueResult result = sm.getSecretValue(request); + + try { + Files.write(destination.toPath(), result.getSecretString().getBytes(StandardCharsets.UTF_8)); + getLogger().info("Secrets from {} has been written into {}", secretName, destination); + } catch (IOException e) { + getLogger().error("Exception writing the secrets file", e); + } + } + +} diff --git a/src/main/java/jp/classmethod/aws/reboot/gradle/secretsmanager/AmazonSecretsManagerPlugin.java b/src/main/java/jp/classmethod/aws/reboot/gradle/secretsmanager/AmazonSecretsManagerPlugin.java new file mode 100644 index 0000000..632982a --- /dev/null +++ b/src/main/java/jp/classmethod/aws/reboot/gradle/secretsmanager/AmazonSecretsManagerPlugin.java @@ -0,0 +1,32 @@ +/* + * Copyright 2015-2016 the original author or 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. + */ +package jp.classmethod.aws.reboot.gradle.secretsmanager; + +import org.gradle.api.Plugin; +import org.gradle.api.Project; + +import jp.classmethod.aws.reboot.gradle.AwsPlugin; + +public class AmazonSecretsManagerPlugin implements Plugin { + + public void apply(Project project) { + project.getPluginManager().apply(AwsPlugin.class); + project.getExtensions().create( + AmazonSecretsManagerPluginExtension.NAME, + AmazonSecretsManagerPluginExtension.class, + project); + } +} diff --git a/src/main/java/jp/classmethod/aws/reboot/gradle/secretsmanager/AmazonSecretsManagerPluginExtension.java b/src/main/java/jp/classmethod/aws/reboot/gradle/secretsmanager/AmazonSecretsManagerPluginExtension.java new file mode 100644 index 0000000..d470297 --- /dev/null +++ b/src/main/java/jp/classmethod/aws/reboot/gradle/secretsmanager/AmazonSecretsManagerPluginExtension.java @@ -0,0 +1,56 @@ +/* + * Copyright 2015-2016 the original author or 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. + */ +package jp.classmethod.aws.reboot.gradle.secretsmanager; + +import org.gradle.api.Project; + +import com.amazonaws.services.secretsmanager.AWSSecretsManagerClient; +import com.amazonaws.services.secretsmanager.AWSSecretsManagerClientBuilder; + +import jp.classmethod.aws.reboot.gradle.AwsPluginExtension; +import jp.classmethod.aws.reboot.gradle.common.BaseRegionAwarePluginExtension; + +public class AmazonSecretsManagerPluginExtension extends BaseRegionAwarePluginExtension { + + public static final String NAME = "secretsmanager"; + + + public AmazonSecretsManagerPluginExtension(Project project) { + super(project, AWSSecretsManagerClient.class); + } + + @Override + protected AWSSecretsManagerClient initClient() { + AWSSecretsManagerClientBuilder builder = AWSSecretsManagerClient.builder(); + + AwsPluginExtension aws = getProject().getExtensions().getByType(AwsPluginExtension.class); + String profile = aws.getProfileName() == null ? System.getenv("AWS_PROFILE") : aws.getProfileName(); + + getProject().getLogger().info("Using profile {} for authorization", profile); + + builder.withCredentials(aws.newCredentialsProvider(profile)); + + if (getRegion() != null) { + getProject().getLogger().info("Using region {} from the Secrets Manager extension", getRegion()); + builder.withRegion(getRegion()); + } else if (aws.getRegion() != null) { + getProject().getLogger().info("Using region {} from the AWS extension", getRegion()); + builder.withRegion(aws.getRegion()); + } + + return (AWSSecretsManagerClient) builder.build(); + } +} diff --git a/src/main/resources/META-INF/gradle-plugins/jp.classmethod.aws.reboot.secretsmanager.properties b/src/main/resources/META-INF/gradle-plugins/jp.classmethod.aws.reboot.secretsmanager.properties new file mode 100644 index 0000000..5251f23 --- /dev/null +++ b/src/main/resources/META-INF/gradle-plugins/jp.classmethod.aws.reboot.secretsmanager.properties @@ -0,0 +1,17 @@ +# +# Copyright 2013-2016 Classmethod, 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. +# + +implementation-class=jp.classmethod.aws.reboot.gradle.secretsmanager.AmazonSecretsManagerPlugin