You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2022/06/23 10:17:51 UTC
[camel] 03/03: CAMEL-18171: camel-kubernetes - Add secret property placeholder function
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch cmap
in repository https://gitbox.apache.org/repos/asf/camel.git
commit 396f644d6e2c6113129ef0be574008077d588d36
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu Jun 23 12:17:31 2022 +0200
CAMEL-18171: camel-kubernetes - Add secret property placeholder function
---
.../org/apache/camel/properties-function/secret | 2 +
...n.java => BaseConfigMapPropertiesFunction.java} | 47 +-----------
.../properties/ConfigMapPropertiesFunction.java | 39 +---------
...Function.java => SecretPropertiesFunction.java} | 57 +++------------
.../SecretPropertiesFunctionRouteTest.java | 85 ++++++++++++++++++++++
.../properties/SecretPropertiesFunctionTest.java | 68 +++++++++++++++++
6 files changed, 170 insertions(+), 128 deletions(-)
diff --git a/components/camel-kubernetes/src/generated/resources/META-INF/services/org/apache/camel/properties-function/secret b/components/camel-kubernetes/src/generated/resources/META-INF/services/org/apache/camel/properties-function/secret
new file mode 100644
index 00000000000..ff86576daa6
--- /dev/null
+++ b/components/camel-kubernetes/src/generated/resources/META-INF/services/org/apache/camel/properties-function/secret
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.kubernetes.properties.SecretPropertiesFunction
diff --git a/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/properties/ConfigMapPropertiesFunction.java b/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/properties/BaseConfigMapPropertiesFunction.java
similarity index 55%
copy from components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/properties/ConfigMapPropertiesFunction.java
copy to components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/properties/BaseConfigMapPropertiesFunction.java
index d6bcb117730..8a3c49e813b 100644
--- a/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/properties/ConfigMapPropertiesFunction.java
+++ b/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/properties/BaseConfigMapPropertiesFunction.java
@@ -16,9 +16,6 @@
*/
package org.apache.camel.component.kubernetes.properties;
-import java.util.Base64;
-
-import io.fabric8.kubernetes.api.model.ConfigMap;
import io.fabric8.kubernetes.client.KubernetesClient;
import org.apache.camel.CamelContext;
import org.apache.camel.CamelContextAware;
@@ -26,13 +23,11 @@ import org.apache.camel.spi.PropertiesFunction;
import org.apache.camel.support.CamelContextHelper;
import org.apache.camel.support.service.ServiceSupport;
import org.apache.camel.util.ObjectHelper;
-import org.apache.camel.util.StringHelper;
/**
- * A {@link PropertiesFunction} that can lookup from Kubernetes configmaps.
+ * Base for kubernetes {@link PropertiesFunction}.
*/
-@org.apache.camel.spi.annotations.PropertiesFunction("configmap")
-public class ConfigMapPropertiesFunction extends ServiceSupport implements PropertiesFunction, CamelContextAware {
+abstract class BaseConfigMapPropertiesFunction extends ServiceSupport implements PropertiesFunction, CamelContextAware {
private CamelContext camelContext;
private KubernetesClient client;
@@ -45,11 +40,6 @@ public class ConfigMapPropertiesFunction extends ServiceSupport implements Prope
ObjectHelper.notNull(client, "KubernetesClient must be configured");
}
- @Override
- public String getName() {
- return "configmap";
- }
-
@Override
public CamelContext getCamelContext() {
return camelContext;
@@ -68,37 +58,4 @@ public class ConfigMapPropertiesFunction extends ServiceSupport implements Prope
this.client = client;
}
- @Override
- public String apply(String remainder) {
- String defaultValue = StringHelper.after(remainder, ":");
-
- String name = StringHelper.before(remainder, "/");
- String key = StringHelper.after(remainder, "/");
-
- if (name == null || key == null) {
- return defaultValue;
- }
-
- String answer = null;
- ConfigMap cm = client.configMaps().withName(name).get();
- if (cm != null) {
- answer = cm.getData() != null ? cm.getData().get(key) : null;
- if (answer == null) {
- // maybe a binary data
- answer = cm.getBinaryData() != null ? cm.getBinaryData().get(key) : null;
- if (answer != null) {
- // need to decode base64
- byte[] data = Base64.getDecoder().decode(answer);
- if (data != null) {
- answer = new String(data);
- }
- }
- }
- }
- if (answer == null) {
- return defaultValue;
- }
-
- return answer;
- }
}
diff --git a/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/properties/ConfigMapPropertiesFunction.java b/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/properties/ConfigMapPropertiesFunction.java
index d6bcb117730..b888d01c147 100644
--- a/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/properties/ConfigMapPropertiesFunction.java
+++ b/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/properties/ConfigMapPropertiesFunction.java
@@ -19,55 +19,20 @@ package org.apache.camel.component.kubernetes.properties;
import java.util.Base64;
import io.fabric8.kubernetes.api.model.ConfigMap;
-import io.fabric8.kubernetes.client.KubernetesClient;
-import org.apache.camel.CamelContext;
-import org.apache.camel.CamelContextAware;
import org.apache.camel.spi.PropertiesFunction;
-import org.apache.camel.support.CamelContextHelper;
-import org.apache.camel.support.service.ServiceSupport;
-import org.apache.camel.util.ObjectHelper;
import org.apache.camel.util.StringHelper;
/**
* A {@link PropertiesFunction} that can lookup from Kubernetes configmaps.
*/
@org.apache.camel.spi.annotations.PropertiesFunction("configmap")
-public class ConfigMapPropertiesFunction extends ServiceSupport implements PropertiesFunction, CamelContextAware {
-
- private CamelContext camelContext;
- private KubernetesClient client;
-
- @Override
- protected void doInit() throws Exception {
- if (client == null) {
- client = CamelContextHelper.findSingleByType(camelContext, KubernetesClient.class);
- }
- ObjectHelper.notNull(client, "KubernetesClient must be configured");
- }
+public class ConfigMapPropertiesFunction extends BaseConfigMapPropertiesFunction {
@Override
public String getName() {
return "configmap";
}
- @Override
- public CamelContext getCamelContext() {
- return camelContext;
- }
-
- @Override
- public void setCamelContext(CamelContext camelContext) {
- this.camelContext = camelContext;
- }
-
- public KubernetesClient getClient() {
- return client;
- }
-
- public void setClient(KubernetesClient client) {
- this.client = client;
- }
-
@Override
public String apply(String remainder) {
String defaultValue = StringHelper.after(remainder, ":");
@@ -80,7 +45,7 @@ public class ConfigMapPropertiesFunction extends ServiceSupport implements Prope
}
String answer = null;
- ConfigMap cm = client.configMaps().withName(name).get();
+ ConfigMap cm = getClient().configMaps().withName(name).get();
if (cm != null) {
answer = cm.getData() != null ? cm.getData().get(key) : null;
if (answer == null) {
diff --git a/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/properties/ConfigMapPropertiesFunction.java b/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/properties/SecretPropertiesFunction.java
similarity index 53%
copy from components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/properties/ConfigMapPropertiesFunction.java
copy to components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/properties/SecretPropertiesFunction.java
index d6bcb117730..70c49df0b55 100644
--- a/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/properties/ConfigMapPropertiesFunction.java
+++ b/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/properties/SecretPropertiesFunction.java
@@ -18,54 +18,19 @@ package org.apache.camel.component.kubernetes.properties;
import java.util.Base64;
-import io.fabric8.kubernetes.api.model.ConfigMap;
-import io.fabric8.kubernetes.client.KubernetesClient;
-import org.apache.camel.CamelContext;
-import org.apache.camel.CamelContextAware;
+import io.fabric8.kubernetes.api.model.Secret;
import org.apache.camel.spi.PropertiesFunction;
-import org.apache.camel.support.CamelContextHelper;
-import org.apache.camel.support.service.ServiceSupport;
-import org.apache.camel.util.ObjectHelper;
import org.apache.camel.util.StringHelper;
/**
- * A {@link PropertiesFunction} that can lookup from Kubernetes configmaps.
+ * A {@link PropertiesFunction} that can lookup from Kubernetes secret.
*/
-@org.apache.camel.spi.annotations.PropertiesFunction("configmap")
-public class ConfigMapPropertiesFunction extends ServiceSupport implements PropertiesFunction, CamelContextAware {
-
- private CamelContext camelContext;
- private KubernetesClient client;
-
- @Override
- protected void doInit() throws Exception {
- if (client == null) {
- client = CamelContextHelper.findSingleByType(camelContext, KubernetesClient.class);
- }
- ObjectHelper.notNull(client, "KubernetesClient must be configured");
- }
+@org.apache.camel.spi.annotations.PropertiesFunction("secret")
+public class SecretPropertiesFunction extends BaseConfigMapPropertiesFunction {
@Override
public String getName() {
- return "configmap";
- }
-
- @Override
- public CamelContext getCamelContext() {
- return camelContext;
- }
-
- @Override
- public void setCamelContext(CamelContext camelContext) {
- this.camelContext = camelContext;
- }
-
- public KubernetesClient getClient() {
- return client;
- }
-
- public void setClient(KubernetesClient client) {
- this.client = client;
+ return "secret";
}
@Override
@@ -80,14 +45,14 @@ public class ConfigMapPropertiesFunction extends ServiceSupport implements Prope
}
String answer = null;
- ConfigMap cm = client.configMaps().withName(name).get();
- if (cm != null) {
- answer = cm.getData() != null ? cm.getData().get(key) : null;
+ Secret sec = getClient().secrets().withName(name).get();
+ if (sec != null) {
+ // string data can be used as-is
+ answer = sec.getStringData() != null ? sec.getStringData().get(key) : null;
if (answer == null) {
- // maybe a binary data
- answer = cm.getBinaryData() != null ? cm.getBinaryData().get(key) : null;
+ // need to base64 decode from data
+ answer = sec.getData() != null ? sec.getData().get(key) : null;
if (answer != null) {
- // need to decode base64
byte[] data = Base64.getDecoder().decode(answer);
if (data != null) {
answer = new String(data);
diff --git a/components/camel-kubernetes/src/test/java/org/apache/camel/component/kubernetes/properties/SecretPropertiesFunctionRouteTest.java b/components/camel-kubernetes/src/test/java/org/apache/camel/component/kubernetes/properties/SecretPropertiesFunctionRouteTest.java
new file mode 100644
index 00000000000..5dfef3fbc29
--- /dev/null
+++ b/components/camel-kubernetes/src/test/java/org/apache/camel/component/kubernetes/properties/SecretPropertiesFunctionRouteTest.java
@@ -0,0 +1,85 @@
+package org.apache.camel.component.kubernetes.properties;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
+import java.util.Map;
+
+import io.fabric8.kubernetes.api.model.Secret;
+import io.fabric8.kubernetes.api.model.SecretBuilder;
+import io.fabric8.kubernetes.client.ConfigBuilder;
+import io.fabric8.kubernetes.client.DefaultKubernetesClient;
+import io.fabric8.kubernetes.client.KubernetesClient;
+import org.apache.camel.CamelContext;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.kubernetes.KubernetesTestSupport;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Order;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.jupiter.api.condition.EnabledIfSystemProperties;
+import org.junit.jupiter.api.condition.EnabledIfSystemProperty;
+
+@EnabledIfSystemProperties({
+ @EnabledIfSystemProperty(named = "kubernetes.test.auth", matches = ".*", disabledReason = "Requires kubernetes"),
+ @EnabledIfSystemProperty(named = "kubernetes.test.host", matches = ".*", disabledReason = "Requires kubernetes"),
+ @EnabledIfSystemProperty(named = "kubernetes.test.host.k8s", matches = "true", disabledReason = "Requires kubernetes"),
+})
+@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
+public class SecretPropertiesFunctionRouteTest extends KubernetesTestSupport {
+
+ private KubernetesClient client;
+ private Secret sec;
+
+ @Override
+ protected RoutesBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ from("direct:start")
+ .transform().simple("Connect with {{secret:mysecret/myuser}}:{{secret:mysecret/mypass}}");
+ }
+ };
+ }
+
+ @Override
+ protected CamelContext createCamelContext() throws Exception {
+ CamelContext context = super.createCamelContext();
+
+ ConfigBuilder builder = new ConfigBuilder();
+ builder.withOauthToken(authToken);
+ builder.withMasterUrl(host);
+ client = new DefaultKubernetesClient(builder.build());
+ context.getRegistry().bind("KubernetesClient", client);
+
+ Map<String, String> data
+ = Map.of("myuser", Base64.getEncoder().encodeToString("scott".getBytes(StandardCharsets.UTF_8)),
+ "mypass", Base64.getEncoder().encodeToString("tiger".getBytes(StandardCharsets.UTF_8)));
+ Secret sec = new SecretBuilder().editOrNewMetadata().withName("mysecret").endMetadata().withData(data).build();
+ client.secrets().createOrReplace(sec);
+
+ return context;
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ if (client != null && sec != null) {
+ try {
+ client.secrets().delete(sec);
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+
+ super.tearDown();
+ }
+
+ @Test
+ @Order(1)
+ public void secretPropertiesFunction() throws Exception {
+ String out = template.requestBody("direct:start", null, String.class);
+ Assertions.assertEquals("Connect with scott:tiger", out);
+ }
+
+}
diff --git a/components/camel-kubernetes/src/test/java/org/apache/camel/component/kubernetes/properties/SecretPropertiesFunctionTest.java b/components/camel-kubernetes/src/test/java/org/apache/camel/component/kubernetes/properties/SecretPropertiesFunctionTest.java
new file mode 100644
index 00000000000..5d7339f7c85
--- /dev/null
+++ b/components/camel-kubernetes/src/test/java/org/apache/camel/component/kubernetes/properties/SecretPropertiesFunctionTest.java
@@ -0,0 +1,68 @@
+package org.apache.camel.component.kubernetes.properties;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
+import java.util.Map;
+
+import io.fabric8.kubernetes.api.model.Secret;
+import io.fabric8.kubernetes.api.model.SecretBuilder;
+import io.fabric8.kubernetes.client.ConfigBuilder;
+import io.fabric8.kubernetes.client.DefaultKubernetesClient;
+import io.fabric8.kubernetes.client.KubernetesClient;
+import org.apache.camel.component.kubernetes.KubernetesTestSupport;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Order;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.jupiter.api.condition.EnabledIfSystemProperties;
+import org.junit.jupiter.api.condition.EnabledIfSystemProperty;
+
+@EnabledIfSystemProperties({
+ @EnabledIfSystemProperty(named = "kubernetes.test.auth", matches = ".*", disabledReason = "Requires kubernetes"),
+ @EnabledIfSystemProperty(named = "kubernetes.test.host", matches = ".*", disabledReason = "Requires kubernetes"),
+ @EnabledIfSystemProperty(named = "kubernetes.test.host.k8s", matches = "true", disabledReason = "Requires kubernetes"),
+})
+@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
+public class SecretPropertiesFunctionTest extends KubernetesTestSupport {
+
+ @Test
+ @Order(1)
+ public void secretPropertiesFunction() throws Exception {
+ ConfigBuilder builder = new ConfigBuilder();
+ builder.withOauthToken(authToken);
+ builder.withMasterUrl(host);
+
+ KubernetesClient client = new DefaultKubernetesClient(builder.build());
+
+ Map<String, String> data
+ = Map.of("myuser", Base64.getEncoder().encodeToString("scott".getBytes(StandardCharsets.UTF_8)),
+ "mypass", Base64.getEncoder().encodeToString("tiger".getBytes(StandardCharsets.UTF_8)));
+ Secret sec = new SecretBuilder().editOrNewMetadata().withName("mysecret").endMetadata().withData(data).build();
+ client.secrets().createOrReplace(sec);
+
+ try {
+ SecretPropertiesFunction cmf = new SecretPropertiesFunction();
+ cmf.setClient(client);
+ cmf.setCamelContext(context);
+ cmf.start();
+
+ String out = cmf.apply("mysecret/myuser");
+ Assertions.assertEquals("scott", out);
+
+ out = cmf.apply("mysecret/unknown");
+ Assertions.assertNull(out);
+
+ out = cmf.apply("mysecret/unknown:444");
+ Assertions.assertEquals("444", out);
+
+ out = cmf.apply("mysecret/mypass");
+ Assertions.assertEquals("tiger", out);
+
+ cmf.stop();
+ } finally {
+ client.secrets().delete(sec);
+ }
+ }
+
+}