This is an automated email from the ASF dual-hosted git repository.

acosentino pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git

commit d705425347f8b6be276918c642e4ae8008bef141
Author: Andrea Cosentino <[email protected]>
AuthorDate: Mon Feb 14 14:42:46 2022 +0100

    CAMEL-17644 - Support ability to load properties from Vault/Secrets cloud 
services - AWS Secrets Manager
---
 core/camel-base/pom.xml                            |   8 ++
 .../AWSSecretsManagerPropertiesFunction.java       | 103 +++++++++++++++++++++
 .../component/properties/PropertiesComponent.java  |   1 +
 core/camel-core/pom.xml                            |   6 ++
 4 files changed, 118 insertions(+)

diff --git a/core/camel-base/pom.xml b/core/camel-base/pom.xml
index faeea8b..4410cc5 100644
--- a/core/camel-base/pom.xml
+++ b/core/camel-base/pom.xml
@@ -56,6 +56,14 @@
             <artifactId>camel-util</artifactId>
         </dependency>
 
+        <!-- required dependencies for AWS Secrets Manager -->
+        <dependency>
+            <groupId>software.amazon.awssdk</groupId>
+            <artifactId>secretsmanager</artifactId>
+            <version>${aws-java-sdk2-version}</version>
+            <scope>provided</scope>
+        </dependency>
+
         <!-- required logging api dependency by camel-base -->
         <dependency>
             <groupId>org.slf4j</groupId>
diff --git 
a/core/camel-base/src/main/java/org/apache/camel/component/properties/AWSSecretsManagerPropertiesFunction.java
 
b/core/camel-base/src/main/java/org/apache/camel/component/properties/AWSSecretsManagerPropertiesFunction.java
new file mode 100644
index 0000000..636d72c
--- /dev/null
+++ 
b/core/camel-base/src/main/java/org/apache/camel/component/properties/AWSSecretsManagerPropertiesFunction.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.camel.component.properties;
+
+import java.util.Base64;
+
+import org.apache.camel.spi.PropertiesFunction;
+import org.apache.camel.util.StringHelper;
+import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
+import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
+import software.amazon.awssdk.regions.Region;
+import software.amazon.awssdk.services.secretsmanager.SecretsManagerClient;
+import 
software.amazon.awssdk.services.secretsmanager.SecretsManagerClientBuilder;
+import 
software.amazon.awssdk.services.secretsmanager.model.GetSecretValueRequest;
+import 
software.amazon.awssdk.services.secretsmanager.model.GetSecretValueResponse;
+
+/**
+ * A {@link PropertiesFunction} that lookup the property value from AWS 
Secrets Manager service.
+ * <p/>
+ * The credentials to access Secrets Manager is defined using three 
environment variables representing the static credentials:
+ * <ul>
+ * <li><tt>AWS_ACCESS_KEY</tt></li>
+ * <li><tt>AWS_SECRET_KEY</tt></li>
+ * <li><tt>AWS_REGION</tt></li>
+ * </ul>
+ * <p/>
+ * This implementation is to return the secret value associated with a key.
+ * The properties related to this kind of Properties Function are all prefixed 
with <tt>aws:</tt>.
+ * For example asking for <tt>aws:token</tt>, will return the secret value 
associated the secret named token on AWS Secrets Manager
+ */
+public class AWSSecretsManagerPropertiesFunction implements PropertiesFunction 
{
+
+    private static final String ACCESS_KEY = "AWS_ACCESS_KEY";
+    private static final String SECRET_KEY = "AWS_SECRET_KEY";
+    private static final String REGION = "AWS_REGION";
+
+    @Override
+    public String getName() {
+        return "aws";
+    }
+
+    @Override
+    public String apply(String remainder) {
+        String key = remainder;
+        String returnValue = null;
+
+        SecretsManagerClient client = null;
+        SecretsManagerClientBuilder clientBuilder = 
SecretsManagerClient.builder();
+
+        if (remainder.contains(":")) {
+            key = StringHelper.before(remainder, ":");
+        }
+
+        // make sure to use upper case
+        if (key != null) {
+            // a service should have both the host and port defined
+            String accessKey = System.getenv(ACCESS_KEY);
+            String secretKey = System.getenv(SECRET_KEY);
+            String region = System.getenv(REGION);
+            returnValue = getSecretFromSource(key, returnValue, clientBuilder, 
accessKey, secretKey, region);
+        }
+
+        return returnValue;
+    }
+
+    private String getSecretFromSource(
+            String key, String returnValue, SecretsManagerClientBuilder 
clientBuilder, String accessKey, String secretKey,
+            String region) {
+        GetSecretValueRequest request;
+        SecretsManagerClient client;
+        if (accessKey != null && secretKey != null && region != null) {
+            AwsBasicCredentials cred = AwsBasicCredentials.create(accessKey, 
secretKey);
+            clientBuilder = 
clientBuilder.credentialsProvider(StaticCredentialsProvider.create(cred));
+            clientBuilder.region(Region.of(region));
+            client = clientBuilder.build();
+            GetSecretValueRequest.Builder builder = 
GetSecretValueRequest.builder();
+            builder.secretId(key);
+            request = builder.build();
+            GetSecretValueResponse secret = client.getSecretValue(request);
+            returnValue = secret.secretString();
+            if (secret.secretString() != null) {
+                returnValue = secret.secretString();
+            } else {
+                returnValue = new 
String(Base64.getDecoder().decode(secret.secretBinary().asByteBuffer()).array());
+            }
+        }
+        return returnValue;
+    }
+}
diff --git 
a/core/camel-base/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java
 
b/core/camel-base/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java
index e70500e..79b31af 100644
--- 
a/core/camel-base/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java
+++ 
b/core/camel-base/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java
@@ -127,6 +127,7 @@ public class PropertiesComponent extends ServiceSupport
         addPropertiesFunction(new ServicePropertiesFunction());
         addPropertiesFunction(new ServiceHostPropertiesFunction());
         addPropertiesFunction(new ServicePortPropertiesFunction());
+        addPropertiesFunction(new AWSSecretsManagerPropertiesFunction());
     }
 
     /**
diff --git a/core/camel-core/pom.xml b/core/camel-core/pom.xml
index 233c333..6901478 100644
--- a/core/camel-core/pom.xml
+++ b/core/camel-core/pom.xml
@@ -238,6 +238,12 @@
             <artifactId>junit-jupiter-engine</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>software.amazon.awssdk</groupId>
+            <artifactId>secretsmanager</artifactId>
+            <version>${aws-java-sdk2-version}</version>
+            <scope>test</scope>
+        </dependency>
 
     </dependencies>
 

Reply via email to