This is an automated email from the ASF dual-hosted git repository. acosentino pushed a commit to branch secrets-vault-operation in repository https://gitbox.apache.org/repos/asf/camel.git
commit b595d1385ebf7bdb219f1240a2865c545e2950cb Author: Andrea Cosentino <[email protected]> AuthorDate: Tue Sep 3 12:10:55 2024 +0200 CAMEL-21142 - Kubernetes Secrets/Configmap: Trigger context reloading on update - Secrets implementation Signed-off-by: Andrea Cosentino <[email protected]> --- .../main/camel-main-configuration-metadata.json | 5 +- .../camel/periodic-task/kubernetes-secret-refresh | 2 + .../secrets/vault/SecretsReloadTriggerTask.java | 162 +++++++++++++++++++++ .../camel/vault/KubernetesVaultConfiguration.java | 52 +++++++ .../org/apache/camel/vault/VaultConfiguration.java | 19 +++ .../main/AwsVaultConfigurationConfigurer.java | 6 + .../AwsVaultConfigurationPropertiesConfigurer.java | 6 + .../main/AzureVaultConfigurationConfigurer.java | 6 + ...zureVaultConfigurationPropertiesConfigurer.java | 6 + .../main/GcpVaultConfigurationConfigurer.java | 6 + .../GcpVaultConfigurationPropertiesConfigurer.java | 6 + .../HashicorpVaultConfigurationConfigurer.java | 6 + ...corpVaultConfigurationPropertiesConfigurer.java | 6 + ...tesVaultConfigurationPropertiesConfigurer.java} | 35 +++-- .../camel-main-configuration-metadata.json | 5 +- ...mel.main.KubernetesVaultConfigurationProperties | 2 + core/camel-main/src/main/docs/main.adoc | 11 ++ .../org/apache/camel/main/BaseMainSupport.java | 3 + .../camel/main/DefaultConfigurationConfigurer.java | 29 +++- .../KubernetesVaultConfigurationProperties.java | 68 +++++++++ .../camel/main/VaultConfigurationProperties.java | 12 ++ .../java/org/apache/camel/main/MainVaultTest.java | 46 +++++- .../maven/packaging/PrepareCamelMainMojo.java | 16 ++ 23 files changed, 488 insertions(+), 27 deletions(-) diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json index a4e6e092707..71488c2c92c 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json @@ -12,6 +12,7 @@ { "name": "camel.vault.aws", "description": "Camel AWS Vault configurations", "sourceType": "org.apache.camel.vault.AwsVaultConfiguration" }, { "name": "camel.vault.gcp", "description": "Camel GCP Vault configurations", "sourceType": "org.apache.camel.vault.GcpVaultConfiguration" }, { "name": "camel.vault.azure", "description": "Camel Azure Key Vault configurations", "sourceType": "org.apache.camel.vault.AzureVaultConfiguration" }, + { "name": "camel.vault.kubernetes", "description": "Camel Kubernetes Vault configurations", "sourceType": "org.apache.camel.vault.KubernetesVaultConfiguration" }, { "name": "camel.opentelemetry", "description": "Camel OpenTelemetry configurations", "sourceType": "org.apache.camel.main.OtelConfigurationProperties" }, { "name": "camel.metrics", "description": "Camel Micrometer Metrics configurations", "sourceType": "org.apache.camel.main.MetricsConfigurationProperties" }, { "name": "camel.faulttolerance", "description": "Fault Tolerance EIP Circuit Breaker configurations", "sourceType": "org.apache.camel.main.FaultToleranceConfigurationProperties" }, @@ -349,6 +350,8 @@ { "name": "camel.vault.gcp.secrets", "description": "Specify the secret names (or pattern) to check for updates. Multiple secrets can be separated by comma.", "sourceType": "org.apache.camel.vault.GcpVaultConfiguration", "type": "string", "javaType": "java.lang.String" }, { "name": "camel.vault.gcp.serviceAccountKey", "description": "The Service Account Key location", "sourceType": "org.apache.camel.vault.GcpVaultConfiguration", "type": "string", "javaType": "java.lang.String" }, { "name": "camel.vault.gcp.subscriptionName", "description": "Define the Google Pubsub subscription Name to be used when checking for updates", "sourceType": "org.apache.camel.vault.GcpVaultConfiguration", "type": "string", "javaType": "java.lang.String" }, - { "name": "camel.vault.gcp.useDefaultInstance", "description": "Define if we want to use the GCP Client Default Instance or not", "sourceType": "org.apache.camel.vault.GcpVaultConfiguration", "type": "boolean", "javaType": "boolean", "defaultValue": "false" } + { "name": "camel.vault.gcp.useDefaultInstance", "description": "Define if we want to use the GCP Client Default Instance or not", "sourceType": "org.apache.camel.vault.GcpVaultConfiguration", "type": "boolean", "javaType": "boolean", "defaultValue": "false" }, + { "name": "camel.vault.kubernetes.refreshEnabled", "description": "Whether to automatically reload Camel upon secrets being updated in Kubernetes Cluster.", "sourceType": "org.apache.camel.vault.KubernetesVaultConfiguration", "type": "boolean", "javaType": "boolean", "defaultValue": "false" }, + { "name": "camel.vault.kubernetes.secrets", "description": "Specify the secret names (or pattern) to check for updates. Multiple secrets can be separated by comma.", "sourceType": "org.apache.camel.vault.KubernetesVaultConfiguration", "type": "string", "javaType": "java.lang.String" } ] } diff --git a/components/camel-kubernetes/src/generated/resources/META-INF/services/org/apache/camel/periodic-task/kubernetes-secret-refresh b/components/camel-kubernetes/src/generated/resources/META-INF/services/org/apache/camel/periodic-task/kubernetes-secret-refresh new file mode 100644 index 00000000000..62046aca12f --- /dev/null +++ b/components/camel-kubernetes/src/generated/resources/META-INF/services/org/apache/camel/periodic-task/kubernetes-secret-refresh @@ -0,0 +1,2 @@ +# Generated by camel build tools - do NOT edit this file! +class=org.apache.camel.component.kubernetes.secrets.vault.SecretsReloadTriggerTask diff --git a/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/secrets/vault/SecretsReloadTriggerTask.java b/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/secrets/vault/SecretsReloadTriggerTask.java new file mode 100644 index 00000000000..0efb6a009e5 --- /dev/null +++ b/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/secrets/vault/SecretsReloadTriggerTask.java @@ -0,0 +1,162 @@ +/* + * 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.kubernetes.secrets.vault; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.CountDownLatch; + +import io.fabric8.kubernetes.api.model.Secret; +import io.fabric8.kubernetes.client.*; +import org.apache.camel.CamelContext; +import org.apache.camel.CamelContextAware; +import org.apache.camel.component.kubernetes.properties.SecretPropertiesFunction; +import org.apache.camel.spi.ContextReloadStrategy; +import org.apache.camel.spi.PropertiesComponent; +import org.apache.camel.spi.PropertiesFunction; +import org.apache.camel.spi.annotations.PeriodicTask; +import org.apache.camel.support.PatternHelper; +import org.apache.camel.support.service.ServiceSupport; +import org.apache.camel.util.ObjectHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@PeriodicTask("kubernetes-secret-refresh") +public class SecretsReloadTriggerTask extends ServiceSupport implements CamelContextAware, Runnable { + + private CamelContext camelContext; + private boolean reloadEnabled = true; + private String secrets; + private KubernetesClient kubernetesClient; + private SecretPropertiesFunction propertiesFunction; + + private static final Logger LOG = LoggerFactory.getLogger(SecretsReloadTriggerTask.class); + + @Override + public CamelContext getCamelContext() { + return camelContext; + } + + @Override + public void setCamelContext(CamelContext camelContext) { + this.camelContext = camelContext; + } + + public boolean isReloadEnabled() { + return reloadEnabled; + } + + /** + * Whether Camel should be reloaded on Secrets updated + */ + public void setReloadEnabled(boolean reloadEnabled) { + this.reloadEnabled = reloadEnabled; + } + + @Override + protected void doStart() throws Exception { + super.doStart(); + + // auto-detect secrets in-use + PropertiesComponent pc = camelContext.getPropertiesComponent(); + PropertiesFunction pf = pc.getPropertiesFunction("secret"); + if (pf instanceof SecretPropertiesFunction) { + propertiesFunction = (SecretPropertiesFunction) pf; + LOG.debug("Auto-detecting secrets from properties-function: {}", pf.getName()); + } + // specific secrets + secrets = camelContext.getVaultConfiguration().kubernetes().getSecrets(); + if (ObjectHelper.isEmpty(secrets) && propertiesFunction == null) { + throw new IllegalArgumentException("Secrets must be configured on Kubernetes vault configuration"); + } + + kubernetesClient = propertiesFunction.getClient(); + } + + @Override + protected void doShutdown() throws Exception { + super.doShutdown(); + + if (kubernetesClient != null) { + try { + kubernetesClient.close(); + } catch (Exception e) { + // ignore + } + kubernetesClient = null; + } + } + + @Override + public void run() { + final CountDownLatch isWatchClosed = new CountDownLatch(1); + Watch watch = kubernetesClient.secrets().inNamespace(kubernetesClient.getNamespace()).watch(new Watcher<>() { + @Override + public void eventReceived(Action action, Secret secret) { + switch (action.name()) { + case "MODIFIED": + if (isReloadEnabled()) { + if (matchSecret(secret.getMetadata().getName())) { + LOG.info("Update for Kubernetes Secret: {} detected, triggering CamelContext reload", + secret.getMetadata().getName()); + ContextReloadStrategy reload = camelContext.hasService(ContextReloadStrategy.class); + if (reload != null) { + // trigger reload + reload.onReload(this); + } + } + } + break; + default: + LOG.debug("Not watched event {}", action.name()); + } + } + + @Override + public void onClose(WatcherException e) { + isWatchClosed.countDown(); + } + }); + + // Wait till watch gets closed + try { + isWatchClosed.await(); + } catch (InterruptedException e) { + LOG.error("Interrupted while waiting for the watch to close: {}", e.getMessage()); + Thread.currentThread().interrupt(); + } + watch.close(); + } + + protected boolean matchSecret(String name) { + Set<String> set = new HashSet<>(); + if (secrets != null) { + Collections.addAll(set, secrets.split(",")); + } + + for (String part : set) { + boolean result = name.contains(part) || PatternHelper.matchPattern(name, part); + LOG.trace("Matching secret id: {}={} -> {}", name, part, result); + if (result) { + return true; + } + } + + return false; + } +} diff --git a/core/camel-api/src/main/java/org/apache/camel/vault/KubernetesVaultConfiguration.java b/core/camel-api/src/main/java/org/apache/camel/vault/KubernetesVaultConfiguration.java new file mode 100644 index 00000000000..2183f8d5769 --- /dev/null +++ b/core/camel-api/src/main/java/org/apache/camel/vault/KubernetesVaultConfiguration.java @@ -0,0 +1,52 @@ +/* + * 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.vault; + +import org.apache.camel.spi.Metadata; + +/** + * Configuration for access to Kubernetes Secrets + */ +public class KubernetesVaultConfiguration extends VaultConfiguration { + + @Metadata + private boolean refreshEnabled; + @Metadata + private String secrets; + + public boolean isRefreshEnabled() { + return refreshEnabled; + } + + /** + * Whether to automatically reload Camel upon secrets being updated in Kubernetes Cluster. + */ + public void setRefreshEnabled(boolean refreshEnabled) { + this.refreshEnabled = refreshEnabled; + } + + public String getSecrets() { + return secrets; + } + + /** + * Specify the secret names (or pattern) to check for updates. Multiple secrets can be separated by comma. + */ + public void setSecrets(String secrets) { + this.secrets = secrets; + } +} diff --git a/core/camel-api/src/main/java/org/apache/camel/vault/VaultConfiguration.java b/core/camel-api/src/main/java/org/apache/camel/vault/VaultConfiguration.java index b7edeb927fe..9a111e82baf 100644 --- a/core/camel-api/src/main/java/org/apache/camel/vault/VaultConfiguration.java +++ b/core/camel-api/src/main/java/org/apache/camel/vault/VaultConfiguration.java @@ -25,6 +25,7 @@ public class VaultConfiguration { private GcpVaultConfiguration gcp; private AzureVaultConfiguration azure; private HashicorpVaultConfiguration hashicorp; + private KubernetesVaultConfiguration kubernetes; /** * AWS Vault Configuration @@ -66,6 +67,16 @@ public class VaultConfiguration { return hashicorp; } + /** + * Kubernetes Vault Configuration + */ + public KubernetesVaultConfiguration kubernetes() { + if (kubernetes == null) { + kubernetes = new KubernetesVaultConfiguration(); + } + return kubernetes; + } + public AwsVaultConfiguration getAwsVaultConfiguration() { return aws; } @@ -97,4 +108,12 @@ public class VaultConfiguration { public void setHashicorpVaultConfiguration(HashicorpVaultConfiguration hashicorp) { this.hashicorp = hashicorp; } + + public KubernetesVaultConfiguration getKubernetesVaultConfiguration() { + return kubernetes; + } + + public void setKubernetesVaultConfiguration(KubernetesVaultConfiguration kubernetes) { + this.kubernetes = kubernetes; + } } diff --git a/core/camel-main/src/generated/java/org/apache/camel/main/AwsVaultConfigurationConfigurer.java b/core/camel-main/src/generated/java/org/apache/camel/main/AwsVaultConfigurationConfigurer.java index 0ce5b71f0bd..50136343622 100644 --- a/core/camel-main/src/generated/java/org/apache/camel/main/AwsVaultConfigurationConfigurer.java +++ b/core/camel-main/src/generated/java/org/apache/camel/main/AwsVaultConfigurationConfigurer.java @@ -35,6 +35,8 @@ public class AwsVaultConfigurationConfigurer extends org.apache.camel.support.co case "gcpVaultConfiguration": target.setGcpVaultConfiguration(property(camelContext, org.apache.camel.vault.GcpVaultConfiguration.class, value)); return true; case "hashicorpvaultconfiguration": case "hashicorpVaultConfiguration": target.setHashicorpVaultConfiguration(property(camelContext, org.apache.camel.vault.HashicorpVaultConfiguration.class, value)); return true; + case "kubernetesvaultconfiguration": + case "kubernetesVaultConfiguration": target.setKubernetesVaultConfiguration(property(camelContext, org.apache.camel.vault.KubernetesVaultConfiguration.class, value)); return true; case "profilecredentialsprovider": case "profileCredentialsProvider": target.setProfileCredentialsProvider(property(camelContext, boolean.class, value)); return true; case "profilename": @@ -70,6 +72,8 @@ public class AwsVaultConfigurationConfigurer extends org.apache.camel.support.co case "gcpVaultConfiguration": return org.apache.camel.vault.GcpVaultConfiguration.class; case "hashicorpvaultconfiguration": case "hashicorpVaultConfiguration": return org.apache.camel.vault.HashicorpVaultConfiguration.class; + case "kubernetesvaultconfiguration": + case "kubernetesVaultConfiguration": return org.apache.camel.vault.KubernetesVaultConfiguration.class; case "profilecredentialsprovider": case "profileCredentialsProvider": return boolean.class; case "profilename": @@ -106,6 +110,8 @@ public class AwsVaultConfigurationConfigurer extends org.apache.camel.support.co case "gcpVaultConfiguration": return target.getGcpVaultConfiguration(); case "hashicorpvaultconfiguration": case "hashicorpVaultConfiguration": return target.getHashicorpVaultConfiguration(); + case "kubernetesvaultconfiguration": + case "kubernetesVaultConfiguration": return target.getKubernetesVaultConfiguration(); case "profilecredentialsprovider": case "profileCredentialsProvider": return target.isProfileCredentialsProvider(); case "profilename": diff --git a/core/camel-main/src/generated/java/org/apache/camel/main/AwsVaultConfigurationPropertiesConfigurer.java b/core/camel-main/src/generated/java/org/apache/camel/main/AwsVaultConfigurationPropertiesConfigurer.java index 01dca63e5c4..6c185838b30 100644 --- a/core/camel-main/src/generated/java/org/apache/camel/main/AwsVaultConfigurationPropertiesConfigurer.java +++ b/core/camel-main/src/generated/java/org/apache/camel/main/AwsVaultConfigurationPropertiesConfigurer.java @@ -35,6 +35,8 @@ public class AwsVaultConfigurationPropertiesConfigurer extends org.apache.camel. case "gcpVaultConfiguration": target.setGcpVaultConfiguration(property(camelContext, org.apache.camel.vault.GcpVaultConfiguration.class, value)); return true; case "hashicorpvaultconfiguration": case "hashicorpVaultConfiguration": target.setHashicorpVaultConfiguration(property(camelContext, org.apache.camel.vault.HashicorpVaultConfiguration.class, value)); return true; + case "kubernetesvaultconfiguration": + case "kubernetesVaultConfiguration": target.setKubernetesVaultConfiguration(property(camelContext, org.apache.camel.vault.KubernetesVaultConfiguration.class, value)); return true; case "profilecredentialsprovider": case "profileCredentialsProvider": target.setProfileCredentialsProvider(property(camelContext, boolean.class, value)); return true; case "profilename": @@ -70,6 +72,8 @@ public class AwsVaultConfigurationPropertiesConfigurer extends org.apache.camel. case "gcpVaultConfiguration": return org.apache.camel.vault.GcpVaultConfiguration.class; case "hashicorpvaultconfiguration": case "hashicorpVaultConfiguration": return org.apache.camel.vault.HashicorpVaultConfiguration.class; + case "kubernetesvaultconfiguration": + case "kubernetesVaultConfiguration": return org.apache.camel.vault.KubernetesVaultConfiguration.class; case "profilecredentialsprovider": case "profileCredentialsProvider": return boolean.class; case "profilename": @@ -106,6 +110,8 @@ public class AwsVaultConfigurationPropertiesConfigurer extends org.apache.camel. case "gcpVaultConfiguration": return target.getGcpVaultConfiguration(); case "hashicorpvaultconfiguration": case "hashicorpVaultConfiguration": return target.getHashicorpVaultConfiguration(); + case "kubernetesvaultconfiguration": + case "kubernetesVaultConfiguration": return target.getKubernetesVaultConfiguration(); case "profilecredentialsprovider": case "profileCredentialsProvider": return target.isProfileCredentialsProvider(); case "profilename": diff --git a/core/camel-main/src/generated/java/org/apache/camel/main/AzureVaultConfigurationConfigurer.java b/core/camel-main/src/generated/java/org/apache/camel/main/AzureVaultConfigurationConfigurer.java index 534014c212c..44d055274cd 100644 --- a/core/camel-main/src/generated/java/org/apache/camel/main/AzureVaultConfigurationConfigurer.java +++ b/core/camel-main/src/generated/java/org/apache/camel/main/AzureVaultConfigurationConfigurer.java @@ -45,6 +45,8 @@ public class AzureVaultConfigurationConfigurer extends org.apache.camel.support. case "gcpVaultConfiguration": target.setGcpVaultConfiguration(property(camelContext, org.apache.camel.vault.GcpVaultConfiguration.class, value)); return true; case "hashicorpvaultconfiguration": case "hashicorpVaultConfiguration": target.setHashicorpVaultConfiguration(property(camelContext, org.apache.camel.vault.HashicorpVaultConfiguration.class, value)); return true; + case "kubernetesvaultconfiguration": + case "kubernetesVaultConfiguration": target.setKubernetesVaultConfiguration(property(camelContext, org.apache.camel.vault.KubernetesVaultConfiguration.class, value)); return true; case "refreshenabled": case "refreshEnabled": target.setRefreshEnabled(property(camelContext, boolean.class, value)); return true; case "refreshperiod": @@ -83,6 +85,8 @@ public class AzureVaultConfigurationConfigurer extends org.apache.camel.support. case "gcpVaultConfiguration": return org.apache.camel.vault.GcpVaultConfiguration.class; case "hashicorpvaultconfiguration": case "hashicorpVaultConfiguration": return org.apache.camel.vault.HashicorpVaultConfiguration.class; + case "kubernetesvaultconfiguration": + case "kubernetesVaultConfiguration": return org.apache.camel.vault.KubernetesVaultConfiguration.class; case "refreshenabled": case "refreshEnabled": return boolean.class; case "refreshperiod": @@ -122,6 +126,8 @@ public class AzureVaultConfigurationConfigurer extends org.apache.camel.support. case "gcpVaultConfiguration": return target.getGcpVaultConfiguration(); case "hashicorpvaultconfiguration": case "hashicorpVaultConfiguration": return target.getHashicorpVaultConfiguration(); + case "kubernetesvaultconfiguration": + case "kubernetesVaultConfiguration": return target.getKubernetesVaultConfiguration(); case "refreshenabled": case "refreshEnabled": return target.isRefreshEnabled(); case "refreshperiod": diff --git a/core/camel-main/src/generated/java/org/apache/camel/main/AzureVaultConfigurationPropertiesConfigurer.java b/core/camel-main/src/generated/java/org/apache/camel/main/AzureVaultConfigurationPropertiesConfigurer.java index 4dbbd919010..f0165b5d13b 100644 --- a/core/camel-main/src/generated/java/org/apache/camel/main/AzureVaultConfigurationPropertiesConfigurer.java +++ b/core/camel-main/src/generated/java/org/apache/camel/main/AzureVaultConfigurationPropertiesConfigurer.java @@ -45,6 +45,8 @@ public class AzureVaultConfigurationPropertiesConfigurer extends org.apache.came case "gcpVaultConfiguration": target.setGcpVaultConfiguration(property(camelContext, org.apache.camel.vault.GcpVaultConfiguration.class, value)); return true; case "hashicorpvaultconfiguration": case "hashicorpVaultConfiguration": target.setHashicorpVaultConfiguration(property(camelContext, org.apache.camel.vault.HashicorpVaultConfiguration.class, value)); return true; + case "kubernetesvaultconfiguration": + case "kubernetesVaultConfiguration": target.setKubernetesVaultConfiguration(property(camelContext, org.apache.camel.vault.KubernetesVaultConfiguration.class, value)); return true; case "refreshenabled": case "refreshEnabled": target.setRefreshEnabled(property(camelContext, boolean.class, value)); return true; case "refreshperiod": @@ -83,6 +85,8 @@ public class AzureVaultConfigurationPropertiesConfigurer extends org.apache.came case "gcpVaultConfiguration": return org.apache.camel.vault.GcpVaultConfiguration.class; case "hashicorpvaultconfiguration": case "hashicorpVaultConfiguration": return org.apache.camel.vault.HashicorpVaultConfiguration.class; + case "kubernetesvaultconfiguration": + case "kubernetesVaultConfiguration": return org.apache.camel.vault.KubernetesVaultConfiguration.class; case "refreshenabled": case "refreshEnabled": return boolean.class; case "refreshperiod": @@ -122,6 +126,8 @@ public class AzureVaultConfigurationPropertiesConfigurer extends org.apache.came case "gcpVaultConfiguration": return target.getGcpVaultConfiguration(); case "hashicorpvaultconfiguration": case "hashicorpVaultConfiguration": return target.getHashicorpVaultConfiguration(); + case "kubernetesvaultconfiguration": + case "kubernetesVaultConfiguration": return target.getKubernetesVaultConfiguration(); case "refreshenabled": case "refreshEnabled": return target.isRefreshEnabled(); case "refreshperiod": diff --git a/core/camel-main/src/generated/java/org/apache/camel/main/GcpVaultConfigurationConfigurer.java b/core/camel-main/src/generated/java/org/apache/camel/main/GcpVaultConfigurationConfigurer.java index cadc0fbfe4e..5da7d981e03 100644 --- a/core/camel-main/src/generated/java/org/apache/camel/main/GcpVaultConfigurationConfigurer.java +++ b/core/camel-main/src/generated/java/org/apache/camel/main/GcpVaultConfigurationConfigurer.java @@ -31,6 +31,8 @@ public class GcpVaultConfigurationConfigurer extends org.apache.camel.support.co case "gcpVaultConfiguration": target.setGcpVaultConfiguration(property(camelContext, org.apache.camel.vault.GcpVaultConfiguration.class, value)); return true; case "hashicorpvaultconfiguration": case "hashicorpVaultConfiguration": target.setHashicorpVaultConfiguration(property(camelContext, org.apache.camel.vault.HashicorpVaultConfiguration.class, value)); return true; + case "kubernetesvaultconfiguration": + case "kubernetesVaultConfiguration": target.setKubernetesVaultConfiguration(property(camelContext, org.apache.camel.vault.KubernetesVaultConfiguration.class, value)); return true; case "projectid": case "projectId": target.setProjectId(property(camelContext, java.lang.String.class, value)); return true; case "refreshenabled": @@ -59,6 +61,8 @@ public class GcpVaultConfigurationConfigurer extends org.apache.camel.support.co case "gcpVaultConfiguration": return org.apache.camel.vault.GcpVaultConfiguration.class; case "hashicorpvaultconfiguration": case "hashicorpVaultConfiguration": return org.apache.camel.vault.HashicorpVaultConfiguration.class; + case "kubernetesvaultconfiguration": + case "kubernetesVaultConfiguration": return org.apache.camel.vault.KubernetesVaultConfiguration.class; case "projectid": case "projectId": return java.lang.String.class; case "refreshenabled": @@ -88,6 +92,8 @@ public class GcpVaultConfigurationConfigurer extends org.apache.camel.support.co case "gcpVaultConfiguration": return target.getGcpVaultConfiguration(); case "hashicorpvaultconfiguration": case "hashicorpVaultConfiguration": return target.getHashicorpVaultConfiguration(); + case "kubernetesvaultconfiguration": + case "kubernetesVaultConfiguration": return target.getKubernetesVaultConfiguration(); case "projectid": case "projectId": return target.getProjectId(); case "refreshenabled": diff --git a/core/camel-main/src/generated/java/org/apache/camel/main/GcpVaultConfigurationPropertiesConfigurer.java b/core/camel-main/src/generated/java/org/apache/camel/main/GcpVaultConfigurationPropertiesConfigurer.java index d3281fd8351..e63f1953e0e 100644 --- a/core/camel-main/src/generated/java/org/apache/camel/main/GcpVaultConfigurationPropertiesConfigurer.java +++ b/core/camel-main/src/generated/java/org/apache/camel/main/GcpVaultConfigurationPropertiesConfigurer.java @@ -31,6 +31,8 @@ public class GcpVaultConfigurationPropertiesConfigurer extends org.apache.camel. case "gcpVaultConfiguration": target.setGcpVaultConfiguration(property(camelContext, org.apache.camel.vault.GcpVaultConfiguration.class, value)); return true; case "hashicorpvaultconfiguration": case "hashicorpVaultConfiguration": target.setHashicorpVaultConfiguration(property(camelContext, org.apache.camel.vault.HashicorpVaultConfiguration.class, value)); return true; + case "kubernetesvaultconfiguration": + case "kubernetesVaultConfiguration": target.setKubernetesVaultConfiguration(property(camelContext, org.apache.camel.vault.KubernetesVaultConfiguration.class, value)); return true; case "projectid": case "projectId": target.setProjectId(property(camelContext, java.lang.String.class, value)); return true; case "refreshenabled": @@ -59,6 +61,8 @@ public class GcpVaultConfigurationPropertiesConfigurer extends org.apache.camel. case "gcpVaultConfiguration": return org.apache.camel.vault.GcpVaultConfiguration.class; case "hashicorpvaultconfiguration": case "hashicorpVaultConfiguration": return org.apache.camel.vault.HashicorpVaultConfiguration.class; + case "kubernetesvaultconfiguration": + case "kubernetesVaultConfiguration": return org.apache.camel.vault.KubernetesVaultConfiguration.class; case "projectid": case "projectId": return java.lang.String.class; case "refreshenabled": @@ -88,6 +92,8 @@ public class GcpVaultConfigurationPropertiesConfigurer extends org.apache.camel. case "gcpVaultConfiguration": return target.getGcpVaultConfiguration(); case "hashicorpvaultconfiguration": case "hashicorpVaultConfiguration": return target.getHashicorpVaultConfiguration(); + case "kubernetesvaultconfiguration": + case "kubernetesVaultConfiguration": return target.getKubernetesVaultConfiguration(); case "projectid": case "projectId": return target.getProjectId(); case "refreshenabled": diff --git a/core/camel-main/src/generated/java/org/apache/camel/main/HashicorpVaultConfigurationConfigurer.java b/core/camel-main/src/generated/java/org/apache/camel/main/HashicorpVaultConfigurationConfigurer.java index 7146b673c2c..7a5b962c37f 100644 --- a/core/camel-main/src/generated/java/org/apache/camel/main/HashicorpVaultConfigurationConfigurer.java +++ b/core/camel-main/src/generated/java/org/apache/camel/main/HashicorpVaultConfigurationConfigurer.java @@ -32,6 +32,8 @@ public class HashicorpVaultConfigurationConfigurer extends org.apache.camel.supp case "hashicorpvaultconfiguration": case "hashicorpVaultConfiguration": target.setHashicorpVaultConfiguration(property(camelContext, org.apache.camel.vault.HashicorpVaultConfiguration.class, value)); return true; case "host": target.setHost(property(camelContext, java.lang.String.class, value)); return true; + case "kubernetesvaultconfiguration": + case "kubernetesVaultConfiguration": target.setKubernetesVaultConfiguration(property(camelContext, org.apache.camel.vault.KubernetesVaultConfiguration.class, value)); return true; case "port": target.setPort(property(camelContext, java.lang.String.class, value)); return true; case "scheme": target.setScheme(property(camelContext, java.lang.String.class, value)); return true; case "token": target.setToken(property(camelContext, java.lang.String.class, value)); return true; @@ -51,6 +53,8 @@ public class HashicorpVaultConfigurationConfigurer extends org.apache.camel.supp case "hashicorpvaultconfiguration": case "hashicorpVaultConfiguration": return org.apache.camel.vault.HashicorpVaultConfiguration.class; case "host": return java.lang.String.class; + case "kubernetesvaultconfiguration": + case "kubernetesVaultConfiguration": return org.apache.camel.vault.KubernetesVaultConfiguration.class; case "port": return java.lang.String.class; case "scheme": return java.lang.String.class; case "token": return java.lang.String.class; @@ -71,6 +75,8 @@ public class HashicorpVaultConfigurationConfigurer extends org.apache.camel.supp case "hashicorpvaultconfiguration": case "hashicorpVaultConfiguration": return target.getHashicorpVaultConfiguration(); case "host": return target.getHost(); + case "kubernetesvaultconfiguration": + case "kubernetesVaultConfiguration": return target.getKubernetesVaultConfiguration(); case "port": return target.getPort(); case "scheme": return target.getScheme(); case "token": return target.getToken(); diff --git a/core/camel-main/src/generated/java/org/apache/camel/main/HashicorpVaultConfigurationPropertiesConfigurer.java b/core/camel-main/src/generated/java/org/apache/camel/main/HashicorpVaultConfigurationPropertiesConfigurer.java index 1a6a1553522..18ceb9a6fa6 100644 --- a/core/camel-main/src/generated/java/org/apache/camel/main/HashicorpVaultConfigurationPropertiesConfigurer.java +++ b/core/camel-main/src/generated/java/org/apache/camel/main/HashicorpVaultConfigurationPropertiesConfigurer.java @@ -32,6 +32,8 @@ public class HashicorpVaultConfigurationPropertiesConfigurer extends org.apache. case "hashicorpvaultconfiguration": case "hashicorpVaultConfiguration": target.setHashicorpVaultConfiguration(property(camelContext, org.apache.camel.vault.HashicorpVaultConfiguration.class, value)); return true; case "host": target.setHost(property(camelContext, java.lang.String.class, value)); return true; + case "kubernetesvaultconfiguration": + case "kubernetesVaultConfiguration": target.setKubernetesVaultConfiguration(property(camelContext, org.apache.camel.vault.KubernetesVaultConfiguration.class, value)); return true; case "port": target.setPort(property(camelContext, java.lang.String.class, value)); return true; case "scheme": target.setScheme(property(camelContext, java.lang.String.class, value)); return true; case "token": target.setToken(property(camelContext, java.lang.String.class, value)); return true; @@ -51,6 +53,8 @@ public class HashicorpVaultConfigurationPropertiesConfigurer extends org.apache. case "hashicorpvaultconfiguration": case "hashicorpVaultConfiguration": return org.apache.camel.vault.HashicorpVaultConfiguration.class; case "host": return java.lang.String.class; + case "kubernetesvaultconfiguration": + case "kubernetesVaultConfiguration": return org.apache.camel.vault.KubernetesVaultConfiguration.class; case "port": return java.lang.String.class; case "scheme": return java.lang.String.class; case "token": return java.lang.String.class; @@ -71,6 +75,8 @@ public class HashicorpVaultConfigurationPropertiesConfigurer extends org.apache. case "hashicorpvaultconfiguration": case "hashicorpVaultConfiguration": return target.getHashicorpVaultConfiguration(); case "host": return target.getHost(); + case "kubernetesvaultconfiguration": + case "kubernetesVaultConfiguration": return target.getKubernetesVaultConfiguration(); case "port": return target.getPort(); case "scheme": return target.getScheme(); case "token": return target.getToken(); diff --git a/core/camel-main/src/generated/java/org/apache/camel/main/HashicorpVaultConfigurationPropertiesConfigurer.java b/core/camel-main/src/generated/java/org/apache/camel/main/KubernetesVaultConfigurationPropertiesConfigurer.java similarity index 66% copy from core/camel-main/src/generated/java/org/apache/camel/main/HashicorpVaultConfigurationPropertiesConfigurer.java copy to core/camel-main/src/generated/java/org/apache/camel/main/KubernetesVaultConfigurationPropertiesConfigurer.java index 1a6a1553522..7037581608c 100644 --- a/core/camel-main/src/generated/java/org/apache/camel/main/HashicorpVaultConfigurationPropertiesConfigurer.java +++ b/core/camel-main/src/generated/java/org/apache/camel/main/KubernetesVaultConfigurationPropertiesConfigurer.java @@ -10,18 +10,18 @@ import org.apache.camel.spi.PropertyConfigurerGetter; import org.apache.camel.spi.ConfigurerStrategy; import org.apache.camel.spi.GeneratedPropertyConfigurer; import org.apache.camel.util.CaseInsensitiveMap; -import org.apache.camel.main.HashicorpVaultConfigurationProperties; +import org.apache.camel.main.KubernetesVaultConfigurationProperties; /** * Generated by camel build tools - do NOT edit this file! */ @Generated("org.apache.camel.maven.packaging.GenerateConfigurerMojo") @SuppressWarnings("unchecked") -public class HashicorpVaultConfigurationPropertiesConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter { +public class KubernetesVaultConfigurationPropertiesConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter { @Override public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) { - org.apache.camel.main.HashicorpVaultConfigurationProperties target = (org.apache.camel.main.HashicorpVaultConfigurationProperties) obj; + org.apache.camel.main.KubernetesVaultConfigurationProperties target = (org.apache.camel.main.KubernetesVaultConfigurationProperties) obj; switch (ignoreCase ? name.toLowerCase() : name) { case "awsvaultconfiguration": case "awsVaultConfiguration": target.setAwsVaultConfiguration(property(camelContext, org.apache.camel.vault.AwsVaultConfiguration.class, value)); return true; @@ -31,10 +31,11 @@ public class HashicorpVaultConfigurationPropertiesConfigurer extends org.apache. case "gcpVaultConfiguration": target.setGcpVaultConfiguration(property(camelContext, org.apache.camel.vault.GcpVaultConfiguration.class, value)); return true; case "hashicorpvaultconfiguration": case "hashicorpVaultConfiguration": target.setHashicorpVaultConfiguration(property(camelContext, org.apache.camel.vault.HashicorpVaultConfiguration.class, value)); return true; - case "host": target.setHost(property(camelContext, java.lang.String.class, value)); return true; - case "port": target.setPort(property(camelContext, java.lang.String.class, value)); return true; - case "scheme": target.setScheme(property(camelContext, java.lang.String.class, value)); return true; - case "token": target.setToken(property(camelContext, java.lang.String.class, value)); return true; + case "kubernetesvaultconfiguration": + case "kubernetesVaultConfiguration": target.setKubernetesVaultConfiguration(property(camelContext, org.apache.camel.vault.KubernetesVaultConfiguration.class, value)); return true; + case "refreshenabled": + case "refreshEnabled": target.setRefreshEnabled(property(camelContext, boolean.class, value)); return true; + case "secrets": target.setSecrets(property(camelContext, java.lang.String.class, value)); return true; default: return false; } } @@ -50,17 +51,18 @@ public class HashicorpVaultConfigurationPropertiesConfigurer extends org.apache. case "gcpVaultConfiguration": return org.apache.camel.vault.GcpVaultConfiguration.class; case "hashicorpvaultconfiguration": case "hashicorpVaultConfiguration": return org.apache.camel.vault.HashicorpVaultConfiguration.class; - case "host": return java.lang.String.class; - case "port": return java.lang.String.class; - case "scheme": return java.lang.String.class; - case "token": return java.lang.String.class; + case "kubernetesvaultconfiguration": + case "kubernetesVaultConfiguration": return org.apache.camel.vault.KubernetesVaultConfiguration.class; + case "refreshenabled": + case "refreshEnabled": return boolean.class; + case "secrets": return java.lang.String.class; default: return null; } } @Override public Object getOptionValue(Object obj, String name, boolean ignoreCase) { - org.apache.camel.main.HashicorpVaultConfigurationProperties target = (org.apache.camel.main.HashicorpVaultConfigurationProperties) obj; + org.apache.camel.main.KubernetesVaultConfigurationProperties target = (org.apache.camel.main.KubernetesVaultConfigurationProperties) obj; switch (ignoreCase ? name.toLowerCase() : name) { case "awsvaultconfiguration": case "awsVaultConfiguration": return target.getAwsVaultConfiguration(); @@ -70,10 +72,11 @@ public class HashicorpVaultConfigurationPropertiesConfigurer extends org.apache. case "gcpVaultConfiguration": return target.getGcpVaultConfiguration(); case "hashicorpvaultconfiguration": case "hashicorpVaultConfiguration": return target.getHashicorpVaultConfiguration(); - case "host": return target.getHost(); - case "port": return target.getPort(); - case "scheme": return target.getScheme(); - case "token": return target.getToken(); + case "kubernetesvaultconfiguration": + case "kubernetesVaultConfiguration": return target.getKubernetesVaultConfiguration(); + case "refreshenabled": + case "refreshEnabled": return target.isRefreshEnabled(); + case "secrets": return target.getSecrets(); default: return null; } } diff --git a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json index a4e6e092707..71488c2c92c 100644 --- a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json +++ b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json @@ -12,6 +12,7 @@ { "name": "camel.vault.aws", "description": "Camel AWS Vault configurations", "sourceType": "org.apache.camel.vault.AwsVaultConfiguration" }, { "name": "camel.vault.gcp", "description": "Camel GCP Vault configurations", "sourceType": "org.apache.camel.vault.GcpVaultConfiguration" }, { "name": "camel.vault.azure", "description": "Camel Azure Key Vault configurations", "sourceType": "org.apache.camel.vault.AzureVaultConfiguration" }, + { "name": "camel.vault.kubernetes", "description": "Camel Kubernetes Vault configurations", "sourceType": "org.apache.camel.vault.KubernetesVaultConfiguration" }, { "name": "camel.opentelemetry", "description": "Camel OpenTelemetry configurations", "sourceType": "org.apache.camel.main.OtelConfigurationProperties" }, { "name": "camel.metrics", "description": "Camel Micrometer Metrics configurations", "sourceType": "org.apache.camel.main.MetricsConfigurationProperties" }, { "name": "camel.faulttolerance", "description": "Fault Tolerance EIP Circuit Breaker configurations", "sourceType": "org.apache.camel.main.FaultToleranceConfigurationProperties" }, @@ -349,6 +350,8 @@ { "name": "camel.vault.gcp.secrets", "description": "Specify the secret names (or pattern) to check for updates. Multiple secrets can be separated by comma.", "sourceType": "org.apache.camel.vault.GcpVaultConfiguration", "type": "string", "javaType": "java.lang.String" }, { "name": "camel.vault.gcp.serviceAccountKey", "description": "The Service Account Key location", "sourceType": "org.apache.camel.vault.GcpVaultConfiguration", "type": "string", "javaType": "java.lang.String" }, { "name": "camel.vault.gcp.subscriptionName", "description": "Define the Google Pubsub subscription Name to be used when checking for updates", "sourceType": "org.apache.camel.vault.GcpVaultConfiguration", "type": "string", "javaType": "java.lang.String" }, - { "name": "camel.vault.gcp.useDefaultInstance", "description": "Define if we want to use the GCP Client Default Instance or not", "sourceType": "org.apache.camel.vault.GcpVaultConfiguration", "type": "boolean", "javaType": "boolean", "defaultValue": "false" } + { "name": "camel.vault.gcp.useDefaultInstance", "description": "Define if we want to use the GCP Client Default Instance or not", "sourceType": "org.apache.camel.vault.GcpVaultConfiguration", "type": "boolean", "javaType": "boolean", "defaultValue": "false" }, + { "name": "camel.vault.kubernetes.refreshEnabled", "description": "Whether to automatically reload Camel upon secrets being updated in Kubernetes Cluster.", "sourceType": "org.apache.camel.vault.KubernetesVaultConfiguration", "type": "boolean", "javaType": "boolean", "defaultValue": "false" }, + { "name": "camel.vault.kubernetes.secrets", "description": "Specify the secret names (or pattern) to check for updates. Multiple secrets can be separated by comma.", "sourceType": "org.apache.camel.vault.KubernetesVaultConfiguration", "type": "string", "javaType": "java.lang.String" } ] } diff --git a/core/camel-main/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.main.KubernetesVaultConfigurationProperties b/core/camel-main/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.main.KubernetesVaultConfigurationProperties new file mode 100644 index 00000000000..25608fddd04 --- /dev/null +++ b/core/camel-main/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.main.KubernetesVaultConfigurationProperties @@ -0,0 +1,2 @@ +# Generated by camel build tools - do NOT edit this file! +class=org.apache.camel.main.KubernetesVaultConfigurationPropertiesConfigurer diff --git a/core/camel-main/src/main/docs/main.adoc b/core/camel-main/src/main/docs/main.adoc index 84338b63325..93407afa5d1 100644 --- a/core/camel-main/src/main/docs/main.adoc +++ b/core/camel-main/src/main/docs/main.adoc @@ -404,6 +404,17 @@ The camel.vault.azure supports 12 options, which are listed below. |=== +=== Camel Kubernetes Vault configurations +The camel.vault.kubernetes supports 2 options, which are listed below. + +[width="100%",cols="2,5,^1,2",options="header"] +|=== +| Name | Description | Default | Type +| *camel.vault.kubernetes.refresh{zwsp}Enabled* | Whether to automatically reload Camel upon secrets being updated in Kubernetes Cluster. | false | boolean +| *camel.vault.kubernetes.secrets* | Specify the secret names (or pattern) to check for updates. Multiple secrets can be separated by comma. | | String +|=== + + === Camel OpenTelemetry configurations The camel.opentelemetry supports 5 options, which are listed below. diff --git a/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java b/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java index ee56ba4864f..e80b9e5ab0e 100644 --- a/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java +++ b/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java @@ -1638,6 +1638,9 @@ public abstract class BaseMainSupport extends BaseService { if ("hashicorp".equalsIgnoreCase(name)) { target = target.hashicorp(); } + if ("kubernetes".equalsIgnoreCase(name)) { + target = target.kubernetes(); + } // configure all the properties on the vault at once (to ensure they are configured in right order) OrderedLocationProperties config = MainHelper.extractProperties(properties, name + "."); setPropertiesOnTarget(camelContext, target, config, "camel.vault." + name + ".", failIfNotSet, true, diff --git a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java index 2317aad967a..7428fa7efac 100644 --- a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java +++ b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java @@ -99,11 +99,7 @@ import org.apache.camel.support.startup.BacklogStartupStepRecorder; import org.apache.camel.support.startup.LoggingStartupStepRecorder; import org.apache.camel.util.ObjectHelper; import org.apache.camel.util.TimeUtils; -import org.apache.camel.vault.AwsVaultConfiguration; -import org.apache.camel.vault.AzureVaultConfiguration; -import org.apache.camel.vault.GcpVaultConfiguration; -import org.apache.camel.vault.HashicorpVaultConfiguration; -import org.apache.camel.vault.VaultConfiguration; +import org.apache.camel.vault.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -614,6 +610,11 @@ public final class DefaultConfigurationConfigurer { VaultConfiguration vault = camelContext.getVaultConfiguration(); vault.setHashicorpVaultConfiguration(hashicorp); } + KubernetesVaultConfiguration kubernetes = getSingleBeanOfType(registry, KubernetesVaultConfiguration.class); + if (kubernetes != null) { + VaultConfiguration vault = camelContext.getVaultConfiguration(); + vault.setKubernetesVaultConfiguration(kubernetes); + } configureVault(camelContext); // apply custom configurations if any @@ -690,6 +691,24 @@ public final class DefaultConfigurationConfigurer { scheduler.schedulePeriodTask(r, period); } } + + if (vc.kubernetes().isRefreshEnabled()) { + Optional<Runnable> task = PluginHelper.getPeriodTaskResolver(camelContext) + .newInstance("kubernetes-secret-refresh", Runnable.class); + if (task.isPresent()) { + Runnable r = task.get(); + if (LOG.isDebugEnabled()) { + LOG.debug("Scheduling: {} ", r); + } + if (camelContext.hasService(ContextReloadStrategy.class) == null) { + // refresh is enabled then we need to automatically enable context-reload as well + ContextReloadStrategy reloader = new DefaultContextReloadStrategy(); + camelContext.addService(reloader); + } + PeriodTaskScheduler scheduler = PluginHelper.getPeriodTaskScheduler(camelContext); + scheduler.scheduledTask(r); + } + } } public static void afterPropertiesSet(final CamelContext camelContext) throws Exception { diff --git a/core/camel-main/src/main/java/org/apache/camel/main/KubernetesVaultConfigurationProperties.java b/core/camel-main/src/main/java/org/apache/camel/main/KubernetesVaultConfigurationProperties.java new file mode 100644 index 00000000000..4bf65f3e619 --- /dev/null +++ b/core/camel-main/src/main/java/org/apache/camel/main/KubernetesVaultConfigurationProperties.java @@ -0,0 +1,68 @@ +/* + * 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.main; + +import org.apache.camel.spi.BootstrapCloseable; +import org.apache.camel.spi.Configurer; +import org.apache.camel.vault.KubernetesVaultConfiguration; + +/** + * Configuration for access to AWS Secret. + */ +@Configurer(bootstrap = true) +public class KubernetesVaultConfigurationProperties extends KubernetesVaultConfiguration implements BootstrapCloseable { + + private MainConfigurationProperties parent; + + public KubernetesVaultConfigurationProperties(MainConfigurationProperties parent) { + this.parent = parent; + } + + public MainConfigurationProperties end() { + return parent; + } + + @Override + public void close() { + parent = null; + } + + // getter and setters + // -------------------------------------------------------------- + + // these are inherited from the parent class + + // fluent builders + // -------------------------------------------------------------- + + /** + * Whether to automatically reload Camel upon secrets being updated in Kubernetes Cluster. + */ + public KubernetesVaultConfigurationProperties withRefreshEnabled(boolean refreshEnabled) { + setRefreshEnabled(refreshEnabled); + return this; + } + + /** + * Specify the secret names (or pattern) to check for updates. Multiple secrets can be separated by comma. + */ + public KubernetesVaultConfigurationProperties withSecrets(String secrets) { + setSecrets(secrets); + return this; + } + +} diff --git a/core/camel-main/src/main/java/org/apache/camel/main/VaultConfigurationProperties.java b/core/camel-main/src/main/java/org/apache/camel/main/VaultConfigurationProperties.java index c01751f2f65..823a7635068 100644 --- a/core/camel-main/src/main/java/org/apache/camel/main/VaultConfigurationProperties.java +++ b/core/camel-main/src/main/java/org/apache/camel/main/VaultConfigurationProperties.java @@ -26,6 +26,7 @@ public class VaultConfigurationProperties extends VaultConfiguration implements private GcpVaultConfigurationProperties gcp; private AzureVaultConfigurationProperties azure; private HashicorpVaultConfigurationProperties hashicorp; + private KubernetesVaultConfigurationProperties kubernetes; public VaultConfigurationProperties(MainConfigurationProperties parent) { this.parent = parent; @@ -50,6 +51,9 @@ public class VaultConfigurationProperties extends VaultConfiguration implements if (hashicorp != null) { hashicorp.close(); } + if (kubernetes != null) { + kubernetes.close(); + } } // getter and setters @@ -91,4 +95,12 @@ public class VaultConfigurationProperties extends VaultConfiguration implements } return hashicorp; } + + @Override + public KubernetesVaultConfigurationProperties kubernetes() { + if (kubernetes == null) { + kubernetes = new KubernetesVaultConfigurationProperties(parent); + } + return kubernetes; + } } diff --git a/core/camel-main/src/test/java/org/apache/camel/main/MainVaultTest.java b/core/camel-main/src/test/java/org/apache/camel/main/MainVaultTest.java index 69b3cbafe0b..124ee478a77 100644 --- a/core/camel-main/src/test/java/org/apache/camel/main/MainVaultTest.java +++ b/core/camel-main/src/test/java/org/apache/camel/main/MainVaultTest.java @@ -17,10 +17,7 @@ package org.apache.camel.main; import org.apache.camel.CamelContext; -import org.apache.camel.vault.AwsVaultConfiguration; -import org.apache.camel.vault.AzureVaultConfiguration; -import org.apache.camel.vault.GcpVaultConfiguration; -import org.apache.camel.vault.HashicorpVaultConfiguration; +import org.apache.camel.vault.*; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -282,4 +279,45 @@ public class MainVaultTest { Assertions.assertEquals("https", cfg.getScheme()); main.stop(); } + + @Test + public void testMainKubernetes() { + Main main = new Main(); + + main.addInitialProperty("camel.vault.kubernetes.refreshEnabled", "true"); + main.addInitialProperty("camel.vault.kubernetes.secrets", "xxxx"); + + main.start(); + + CamelContext context = main.getCamelContext(); + assertNotNull(context); + + KubernetesVaultConfiguration cfg = context.getVaultConfiguration().kubernetes(); + assertNotNull(cfg); + + Assertions.assertTrue(cfg.isRefreshEnabled()); + Assertions.assertEquals("xxxx", cfg.getSecrets()); + main.stop(); + } + + @Test + public void testMainKubernetesFluent() { + Main main = new Main(); + main.configure().vault().kubernetes() + .withRefreshEnabled(true) + .withSecrets("xxxx") + .end(); + + main.start(); + + CamelContext context = main.getCamelContext(); + assertNotNull(context); + + KubernetesVaultConfiguration cfg = context.getVaultConfiguration().kubernetes(); + assertNotNull(cfg); + + Assertions.assertTrue(cfg.isRefreshEnabled()); + Assertions.assertEquals("xxxx", cfg.getSecrets()); + main.stop(); + } } diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCamelMainMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCamelMainMojo.java index 3565e44fc3d..29b6a228cad 100644 --- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCamelMainMojo.java +++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCamelMainMojo.java @@ -199,6 +199,8 @@ public class PrepareCamelMainMojo extends AbstractGeneratorMojo { prefix = "camel.vault.gcp."; } else if (file.getName().contains("AzureVault")) { prefix = "camel.vault.azure."; + } else if (file.getName().contains("KubernetesVault")) { + prefix = "camel.vault.kubernetes."; // TODO: add more vault providers here } else if (file.getName().contains("Health")) { prefix = "camel.health."; @@ -273,6 +275,16 @@ public class PrepareCamelMainMojo extends AbstractGeneratorMojo { throw new MojoFailureException("Error parsing file " + azureVaultConfig + " due " + e.getMessage(), e); } + File kubernetesVaultConfig + = new File(camelApiDir, "src/main/java/org/apache/camel/vault/KubernetesVaultConfiguration.java"); + try { + List<MainModel.MainOptionModel> model = parseConfigurationSource(kubernetesVaultConfig); + model.forEach(m -> m.setName("camel.vault.kubernetes." + m.getName())); + data.addAll(model); + } catch (Exception e) { + throw new MojoFailureException("Error parsing file " + kubernetesVaultConfig + " due " + e.getMessage(), e); + } + // lets sort so they are always ordered (but camel.main in top) data.sort((o1, o2) -> { if (o1.getName().startsWith("camel.main.") && !o2.getName().startsWith("camel.main.")) { @@ -331,6 +343,10 @@ public class PrepareCamelMainMojo extends AbstractGeneratorMojo { new MainGroupModel( "camel.vault.azure", "Camel Azure Key Vault configurations", "org.apache.camel.vault.AzureVaultConfiguration")); + model.getGroups().add( + new MainGroupModel( + "camel.vault.kubernetes", "Camel Kubernetes Vault configurations", + "org.apache.camel.vault.KubernetesVaultConfiguration")); // TODO: add more vault providers here model.getGroups().add(new MainGroupModel( "camel.opentelemetry", "Camel OpenTelemetry configurations",
