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-k.git


The following commit(s) were added to refs/heads/main by this push:
     new f5c86b79d Kamelet - Inject secret in Vaults - Hashicorp Vault (#4799)
f5c86b79d is described below

commit f5c86b79d320ea719b645545d4923c1c9e43c6f5
Author: Andrea Cosentino <anco...@gmail.com>
AuthorDate: Thu Oct 5 17:04:29 2023 +0200

    Kamelet - Inject secret in Vaults - Hashicorp Vault (#4799)
    
    Signed-off-by: Andrea Cosentino <anco...@gmail.com>
---
 addons/vault/hashicorp/hashicorp_vault.go      | 20 +++++-
 addons/vault/hashicorp/hashicorp_vault_test.go | 84 +++++++++++++++++++++++++-
 docs/modules/traits/pages/hashicorp-vault.adoc |  4 +-
 resources/traits.yaml                          |  6 +-
 4 files changed, 108 insertions(+), 6 deletions(-)

diff --git a/addons/vault/hashicorp/hashicorp_vault.go 
b/addons/vault/hashicorp/hashicorp_vault.go
index e3eefed8e..058b18cc9 100644
--- a/addons/vault/hashicorp/hashicorp_vault.go
+++ b/addons/vault/hashicorp/hashicorp_vault.go
@@ -18,10 +18,13 @@ limitations under the License.
 package hashicorp
 
 import (
+       "regexp"
+
        v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
        traitv1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1/trait"
        "github.com/apache/camel-k/v2/pkg/trait"
        "github.com/apache/camel-k/v2/pkg/util"
+       "github.com/apache/camel-k/v2/pkg/util/kubernetes"
        "k8s.io/utils/pointer"
 )
 
@@ -46,7 +49,9 @@ type Trait struct {
        Port string `property:"port" json:"port,omitempty"`
        // The Hashicorp engine to use
        Engine string `property:"engine" json:"engine,omitempty"`
-       // The token to access Hashicorp Vault
+       // The token to access Hashicorp Vault. This could be a plain text or a 
configmap/secret
+       // The content of the hashicorp vault token is expected to be a text 
containing a valid Hashicorp Vault Token.
+       // Syntax: [configmap|secret]:name[/key], where name represents the 
resource name, key optionally represents the resource key to be filtered 
(default key value = hashicorp-vault-token).
        Token string `property:"token" json:"token,omitempty"`
        // The scheme to access Hashicorp Vault
        Scheme string `property:"scheme" json:"scheme,omitempty"`
@@ -76,6 +81,7 @@ func (t *hashicorpVaultTrait) Configure(environment 
*trait.Environment) (bool, e
 }
 
 func (t *hashicorpVaultTrait) Apply(environment *trait.Environment) error {
+       rex := 
regexp.MustCompile(`^(configmap|secret):([a-zA-Z0-9][a-zA-Z0-9-]*)(/([a-zA-Z0-9].*))?$`)
        if environment.IntegrationInPhase(v1.IntegrationPhaseInitialization) {
                
util.StringSliceUniqueAdd(&environment.Integration.Status.Capabilities, 
v1.CapabilityHashicorpVault)
                // Deprecated
@@ -84,7 +90,17 @@ func (t *hashicorpVaultTrait) Apply(environment 
*trait.Environment) error {
        }
 
        if environment.IntegrationInRunningPhases() {
-               
environment.ApplicationProperties["camel.vault.hashicorp.token"] = t.Token
+               hits := rex.FindAllStringSubmatch(t.Token, -1)
+               if len(hits) >= 1 {
+                       var res, _ = v1.DecodeValueSource(t.Token, 
"hashicorp-vault-token", "The Hashicorp Vault Token provided is not valid")
+                       if secretValue, err := 
kubernetes.ResolveValueSource(environment.Ctx, environment.Client, 
environment.Platform.Namespace, &res); err != nil {
+                               return err
+                       } else if secretValue != "" {
+                               
environment.ApplicationProperties["camel.vault.hashicorp.token"] = 
string([]byte(secretValue))
+                       }
+               } else {
+                       
environment.ApplicationProperties["camel.vault.hashicorp.token"] = t.Token
+               }
                environment.ApplicationProperties["camel.vault.hashicorp.host"] 
= t.Host
                environment.ApplicationProperties["camel.vault.hashicorp.port"] 
= t.Port
                
environment.ApplicationProperties["camel.vault.hashicorp.engine"] = t.Engine
diff --git a/addons/vault/hashicorp/hashicorp_vault_test.go 
b/addons/vault/hashicorp/hashicorp_vault_test.go
index 7333dffe1..86cb70229 100644
--- a/addons/vault/hashicorp/hashicorp_vault_test.go
+++ b/addons/vault/hashicorp/hashicorp_vault_test.go
@@ -20,6 +20,9 @@ package hashicorp
 import (
        "testing"
 
+       "github.com/apache/camel-k/v2/pkg/util/test"
+       corev1 "k8s.io/api/core/v1"
+
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
        "k8s.io/utils/pointer"
 
@@ -28,6 +31,7 @@ import (
        "github.com/apache/camel-k/v2/pkg/util/camel"
 
        "github.com/stretchr/testify/assert"
+       "k8s.io/apimachinery/pkg/runtime"
 )
 
 func TestHashicorpVaultTraitApply(t *testing.T) {
@@ -55,25 +59,101 @@ func TestHashicorpVaultTraitApply(t *testing.T) {
        assert.Equal(t, "http", 
e.ApplicationProperties["camel.vault.hashicorp.scheme"])
 }
 
-func createEnvironment(t *testing.T, catalogGen func() (*camel.RuntimeCatalog, 
error)) *trait.Environment {
+func TestHashicorpVaultTraitWithSecretApply(t *testing.T) {
+       e := createEnvironment(t, camel.QuarkusCatalog, &corev1.Secret{
+               ObjectMeta: metav1.ObjectMeta{
+                       Namespace: "test",
+                       Name:      "my-secret1",
+               },
+               Data: map[string][]byte{
+                       "hashicorp-vault-token": 
[]byte("my-hashicorp-vault-token"),
+               },
+       })
+       hashicorp := NewHashicorpVaultTrait()
+       secrets, _ := hashicorp.(*hashicorpVaultTrait)
+       secrets.Enabled = pointer.Bool(true)
+       secrets.Engine = "test"
+       secrets.Token = "secret:my-secret1/hashicorp-vault-token"
+       secrets.Host = "localhost"
+       secrets.Port = "9091"
+       secrets.Scheme = "http"
+       ok, err := secrets.Configure(e)
+       assert.Nil(t, err)
+       assert.True(t, ok)
+
+       err = secrets.Apply(e)
+       assert.Nil(t, err)
+
+       assert.Empty(t, e.ApplicationProperties["quarkus.jaeger.enabled"])
+       assert.Equal(t, "test", 
e.ApplicationProperties["camel.vault.hashicorp.engine"])
+       assert.Equal(t, "my-hashicorp-vault-token", 
e.ApplicationProperties["camel.vault.hashicorp.token"])
+       assert.Equal(t, "localhost", 
e.ApplicationProperties["camel.vault.hashicorp.host"])
+       assert.Equal(t, "9091", 
e.ApplicationProperties["camel.vault.hashicorp.port"])
+       assert.Equal(t, "http", 
e.ApplicationProperties["camel.vault.hashicorp.scheme"])
+}
+
+func TestHashicorpVaultTraitWithConfigMapApply(t *testing.T) {
+       e := createEnvironment(t, camel.QuarkusCatalog, &corev1.ConfigMap{
+               ObjectMeta: metav1.ObjectMeta{
+                       Namespace: "test",
+                       Name:      "my-configmap1",
+               },
+               Data: map[string]string{
+                       "hashicorp-vault-token": "my-hashicorp-vault-token",
+               },
+       })
+       hashicorp := NewHashicorpVaultTrait()
+       secrets, _ := hashicorp.(*hashicorpVaultTrait)
+       secrets.Enabled = pointer.Bool(true)
+       secrets.Engine = "test"
+       secrets.Token = "configmap:my-configmap1/hashicorp-vault-token"
+       secrets.Host = "localhost"
+       secrets.Port = "9091"
+       secrets.Scheme = "http"
+       ok, err := secrets.Configure(e)
+       assert.Nil(t, err)
+       assert.True(t, ok)
+
+       err = secrets.Apply(e)
+       assert.Nil(t, err)
+
+       assert.Empty(t, e.ApplicationProperties["quarkus.jaeger.enabled"])
+       assert.Equal(t, "test", 
e.ApplicationProperties["camel.vault.hashicorp.engine"])
+       assert.Equal(t, "my-hashicorp-vault-token", 
e.ApplicationProperties["camel.vault.hashicorp.token"])
+       assert.Equal(t, "localhost", 
e.ApplicationProperties["camel.vault.hashicorp.host"])
+       assert.Equal(t, "9091", 
e.ApplicationProperties["camel.vault.hashicorp.port"])
+       assert.Equal(t, "http", 
e.ApplicationProperties["camel.vault.hashicorp.scheme"])
+}
+
+func createEnvironment(t *testing.T, catalogGen func() (*camel.RuntimeCatalog, 
error), objects ...runtime.Object) *trait.Environment {
        t.Helper()
 
        catalog, err := catalogGen()
+       client, _ := test.NewFakeClient(objects...)
        assert.Nil(t, err)
 
        e := trait.Environment{
                CamelCatalog:          catalog,
                ApplicationProperties: make(map[string]string),
+               Client:                client,
        }
 
        it := v1.Integration{
                ObjectMeta: metav1.ObjectMeta{
-                       Name: "test",
+                       Namespace: "test",
+                       Name:      "test",
                },
                Status: v1.IntegrationStatus{
                        Phase: v1.IntegrationPhaseDeploying,
                },
        }
+       platform := v1.IntegrationPlatform{
+               ObjectMeta: metav1.ObjectMeta{
+                       Namespace: "test",
+                       Name:      "test",
+               },
+       }
        e.Integration = &it
+       e.Platform = &platform
        return &e
 }
diff --git a/docs/modules/traits/pages/hashicorp-vault.adoc 
b/docs/modules/traits/pages/hashicorp-vault.adoc
index ea64b34e8..10c0cb89d 100644
--- a/docs/modules/traits/pages/hashicorp-vault.adoc
+++ b/docs/modules/traits/pages/hashicorp-vault.adoc
@@ -51,7 +51,9 @@ The following configuration options are available:
 
 | hashicorp-vault.token
 | string
-| The token to access Hashicorp Vault
+| The token to access Hashicorp Vault. This could be a plain text or a 
configmap/secret
+The content of the hashicorp vault token is expected to be a text containing a 
valid Hashicorp Vault Token.
+Syntax: [configmap\|secret]:name[/key], where name represents the resource 
name, key optionally represents the resource key to be filtered (default key 
value = hashicorp-vault-token).
 
 | hashicorp-vault.scheme
 | string
diff --git a/resources/traits.yaml b/resources/traits.yaml
index 5fdd4f75e..7484e147e 100755
--- a/resources/traits.yaml
+++ b/resources/traits.yaml
@@ -650,7 +650,11 @@ traits:
     description: The Hashicorp engine to use
   - name: token
     type: string
-    description: The token to access Hashicorp Vault
+    description: 'The token to access Hashicorp Vault. This could be a plain 
text
+      or a configmap/secret The content of the hashicorp vault token is 
expected to
+      be a text containing a valid Hashicorp Vault Token. Syntax: 
[configmap|secret]:name[/key],
+      where name represents the resource name, key optionally represents the 
resource
+      key to be filtered (default key value = hashicorp-vault-token).'
   - name: scheme
     type: string
     description: The scheme to access Hashicorp Vault

Reply via email to