You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ac...@apache.org on 2023/10/05 13:24:17 UTC
[camel-k] branch 4743-hashicorp-vault created (now 15083c455)
This is an automated email from the ASF dual-hosted git repository.
acosentino pushed a change to branch 4743-hashicorp-vault
in repository https://gitbox.apache.org/repos/asf/camel-k.git
at 15083c455 Kamelet - Inject secret in Vaults - Hashicorp Vault
This branch includes the following new commits:
new 15083c455 Kamelet - Inject secret in Vaults - Hashicorp Vault
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
[camel-k] 01/01: Kamelet - Inject secret in Vaults - Hashicorp Vault
Posted by ac...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
acosentino pushed a commit to branch 4743-hashicorp-vault
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 15083c45564efbbda85637a263de240bb6f0b69a
Author: Andrea Cosentino <an...@gmail.com>
AuthorDate: Thu Oct 5 15:23:09 2023 +0200
Kamelet - Inject secret in Vaults - Hashicorp Vault
Signed-off-by: Andrea Cosentino <an...@gmail.com>
---
addons/vault/hashicorp/hashicorp_vault.go | 20 +++++-
addons/vault/hashicorp/hashicorp_vault_test.go | 84 +++++++++++++++++++++-
docs/modules/traits/pages/aws-secrets-manager.adoc | 4 +-
docs/modules/traits/pages/hashicorp-vault.adoc | 4 +-
resources/traits.yaml | 16 +++--
5 files changed, 115 insertions(+), 13 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/aws-secrets-manager.adoc b/docs/modules/traits/pages/aws-secrets-manager.adoc
index 4a67be3c1..d221f8280 100644
--- a/docs/modules/traits/pages/aws-secrets-manager.adoc
+++ b/docs/modules/traits/pages/aws-secrets-manager.adoc
@@ -50,8 +50,8 @@ Syntax: [configmap\|secret]:name[/key], where name represents the resource name,
| aws-secrets-manager.secret-key
| string
| The AWS Secret Key to use. This could be a plain text or a configmap/secret
- // The content of the aws secret key is expected to be a text containing a valid AWS secret key.
- // Syntax: [configmap\|secret]:name[/key], where name represents the resource name, key optionally represents the resource key to be filtered (default key value = aws-secret-key).
+The content of the aws secret key is expected to be a text containing a valid AWS secret key.
+Syntax: [configmap\|secret]:name[/key], where name represents the resource name, key optionally represents the resource key to be filtered (default key value = aws-secret-key).
| aws-secrets-manager.region
| string
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 826996269..887545196 100755
--- a/resources/traits.yaml
+++ b/resources/traits.yaml
@@ -116,11 +116,11 @@ traits:
(default key value = aws-access-key).'
- name: secret-key
type: string
- description: "The AWS Secret Key to use. This could be a plain text or a configmap/secret
- \t// The content of the aws secret key is expected to be a text containing a
- valid AWS secret key. \t// Syntax: [configmap|secret]:name[/key], where name
- represents the resource name, key optionally represents the resource key to
- be filtered (default key value = aws-secret-key)."
+ description: 'The AWS Secret Key to use. This could be a plain text or a configmap/secret
+ The content of the aws secret key is expected to be a text containing a valid
+ AWS secret key. Syntax: [configmap|secret]:name[/key], where name represents
+ the resource name, key optionally represents the resource key to be filtered
+ (default key value = aws-secret-key).'
- name: region
type: string
description: The AWS Region to use
@@ -641,7 +641,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