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

pcongiusti 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 963b1eb01 feat(trait): set env as configmaps/secrets
963b1eb01 is described below

commit 963b1eb01a564b4d33b9cdc7a8d6c8d84664f44a
Author: Pasquale Congiusti <[email protected]>
AuthorDate: Thu Aug 8 14:43:39 2024 +0200

    feat(trait): set env as configmaps/secrets
    
    Closes #5522
---
 addons/vault/aws/aws_secrets_manager.go            |  6 ++--
 addons/vault/azure/azure_key_vault.go              |  9 ++---
 addons/vault/hashicorp/hashicorp_vault.go          |  5 +--
 docs/modules/ROOT/partials/apis/camel-k-crds.adoc  |  5 +--
 docs/modules/traits/pages/environment.adoc         |  5 +--
 pkg/apis/camel/v1/common_types_support.go          |  5 +--
 pkg/apis/camel/v1/trait/environment.go             |  5 +--
 .../camel.apache.org_integrationplatforms.yaml     | 10 +++---
 .../camel.apache.org_integrationprofiles.yaml      | 10 +++---
 .../crd/bases/camel.apache.org_integrations.yaml   |  5 +--
 .../bases/camel.apache.org_kameletbindings.yaml    |  5 +--
 .../config/crd/bases/camel.apache.org_pipes.yaml   |  5 +--
 pkg/trait/environment.go                           | 12 ++++++-
 pkg/trait/environment_test.go                      | 40 ++++++++++++++++++++++
 pkg/util/envvar/envvar.go                          | 29 +++++++++++++++-
 15 files changed, 117 insertions(+), 39 deletions(-)

diff --git a/addons/vault/aws/aws_secrets_manager.go 
b/addons/vault/aws/aws_secrets_manager.go
index 6e57e4a8c..af7a1709a 100644
--- a/addons/vault/aws/aws_secrets_manager.go
+++ b/addons/vault/aws/aws_secrets_manager.go
@@ -18,7 +18,6 @@ limitations under the License.
 package aws
 
 import (
-       "regexp"
        "strconv"
 
        "github.com/apache/camel-k/v2/pkg/util/kubernetes"
@@ -105,7 +104,6 @@ func (t *awsSecretsManagerTrait) Configure(environment 
*trait.Environment) (bool
 }
 
 func (t *awsSecretsManagerTrait) 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.CapabilityAwsSecretsManager)
        }
@@ -114,7 +112,7 @@ func (t *awsSecretsManagerTrait) Apply(environment 
*trait.Environment) error {
                return nil
        }
 
-       hits := rex.FindAllStringSubmatch(t.AccessKey, -1)
+       hits := v1.PlainConfigSecretRegexp.FindAllStringSubmatch(t.AccessKey, 
-1)
        if len(hits) >= 1 {
                var res, _ = v1.DecodeValueSource(t.AccessKey, 
"aws-access-key", "The access Key provided is not valid")
                if secretValue, err := 
kubernetes.ResolveValueSource(environment.Ctx, environment.Client, 
environment.Platform.Namespace, &res); err != nil {
@@ -125,7 +123,7 @@ func (t *awsSecretsManagerTrait) Apply(environment 
*trait.Environment) error {
        } else {
                environment.ApplicationProperties["camel.vault.aws.accessKey"] 
= t.AccessKey
        }
-       hits = rex.FindAllStringSubmatch(t.SecretKey, -1)
+       hits = v1.PlainConfigSecretRegexp.FindAllStringSubmatch(t.SecretKey, -1)
        if len(hits) >= 1 {
                var res, _ = v1.DecodeValueSource(t.SecretKey, 
"aws-secret-key", "The secret Key provided is not valid")
                if secretValue, err := 
kubernetes.ResolveValueSource(environment.Ctx, environment.Client, 
environment.Platform.Namespace, &res); err != nil {
diff --git a/addons/vault/azure/azure_key_vault.go 
b/addons/vault/azure/azure_key_vault.go
index 0dcdfc5b8..44b283f78 100644
--- a/addons/vault/azure/azure_key_vault.go
+++ b/addons/vault/azure/azure_key_vault.go
@@ -18,7 +18,6 @@ limitations under the License.
 package azure
 
 import (
-       "regexp"
        "strconv"
 
        "github.com/apache/camel-k/v2/pkg/util/kubernetes"
@@ -81,10 +80,6 @@ type Trait struct {
        BlobContainerName string `property:"blob-container-name" 
json:"blobContainerName,omitempty"`
 }
 
-var (
-       azureKeyValueRex = 
regexp.MustCompile(`^(configmap|secret):([a-zA-Z0-9][a-zA-Z0-9-]*)(/([a-zA-Z0-9].*))?$`)
-)
-
 type azureKeyVaultTrait struct {
        trait.BaseTrait
        Trait `property:",squash"`
@@ -130,7 +125,7 @@ func (t *azureKeyVaultTrait) Apply(environment 
*trait.Environment) error {
                return nil
        }
 
-       hits := azureKeyValueRex.FindAllStringSubmatch(t.ClientSecret, -1)
+       hits := 
v1.PlainConfigSecretRegexp.FindAllStringSubmatch(t.ClientSecret, -1)
        if len(hits) >= 1 {
                var res, _ = v1.DecodeValueSource(t.ClientSecret, 
"azure-key-vault-client-secret", "The Azure Key Vault Client Secret provided is 
not valid")
                if secretValue, err := 
kubernetes.ResolveValueSource(environment.Ctx, environment.Client, 
environment.Platform.Namespace, &res); err != nil {
@@ -141,7 +136,7 @@ func (t *azureKeyVaultTrait) Apply(environment 
*trait.Environment) error {
        } else {
                
environment.ApplicationProperties["camel.vault.azure.clientSecret"] = 
t.ClientSecret
        }
-       hits = azureKeyValueRex.FindAllStringSubmatch(t.BlobAccessKey, -1)
+       hits = 
v1.PlainConfigSecretRegexp.FindAllStringSubmatch(t.BlobAccessKey, -1)
        if len(hits) >= 1 {
                var res, _ = v1.DecodeValueSource(t.BlobAccessKey, 
"azure-storage-blob-access-key", "The Azure Storage Blob Access Key provided is 
not valid")
                if secretValue, err := 
kubernetes.ResolveValueSource(environment.Ctx, environment.Client, 
environment.Platform.Namespace, &res); err != nil {
diff --git a/addons/vault/hashicorp/hashicorp_vault.go 
b/addons/vault/hashicorp/hashicorp_vault.go
index d8aeb00fd..399d912f0 100644
--- a/addons/vault/hashicorp/hashicorp_vault.go
+++ b/addons/vault/hashicorp/hashicorp_vault.go
@@ -18,8 +18,6 @@ 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"
@@ -81,7 +79,6 @@ func (t *hashicorpVaultTrait) Configure(environment 
*trait.Environment) (bool, *
 }
 
 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)
        }
@@ -90,7 +87,7 @@ func (t *hashicorpVaultTrait) Apply(environment 
*trait.Environment) error {
                return nil
        }
 
-       hits := rex.FindAllStringSubmatch(t.Token, -1)
+       hits := v1.PlainConfigSecretRegexp.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")
 
diff --git a/docs/modules/ROOT/partials/apis/camel-k-crds.adoc 
b/docs/modules/ROOT/partials/apis/camel-k-crds.adoc
index fd9da8052..c827f5d9c 100644
--- a/docs/modules/ROOT/partials/apis/camel-k-crds.adoc
+++ b/docs/modules/ROOT/partials/apis/camel-k-crds.adoc
@@ -6906,8 +6906,9 @@ Propagates the `HTTP_PROXY`, `HTTPS_PROXY` and `NO_PROXY` 
environment variables
 
 
 A list of environment variables to be added to the integration container.
-The syntax is KEY=VALUE, e.g., `MY_VAR="my value"`.
-These take precedence over the previously defined environment variables.
+The syntax is either VAR=VALUE or VAR=[configmap{vbar}secret]:name/key, where 
name represents the resource name,
+and key represents the resource key to be mapped as and environment variable.
+These take precedence over any previously defined environment variables.
 
 
 |===
diff --git a/docs/modules/traits/pages/environment.adoc 
b/docs/modules/traits/pages/environment.adoc
index d40ab6a5a..e399da352 100755
--- a/docs/modules/traits/pages/environment.adoc
+++ b/docs/modules/traits/pages/environment.adoc
@@ -41,8 +41,9 @@ The following configuration options are available:
 | environment.vars
 | []string
 | A list of environment variables to be added to the integration container.
-The syntax is KEY=VALUE, e.g., `MY_VAR="my value"`.
-These take precedence over the previously defined environment variables.
+The syntax is either VAR=VALUE or VAR=[configmap\|secret]:name/key, where name 
represents the resource name,
+and key represents the resource key to be mapped as and environment variable.
+These take precedence over any previously defined environment variables.
 
 |===
 
diff --git a/pkg/apis/camel/v1/common_types_support.go 
b/pkg/apis/camel/v1/common_types_support.go
index b3b68ea45..8f01f71f1 100644
--- a/pkg/apis/camel/v1/common_types_support.go
+++ b/pkg/apis/camel/v1/common_types_support.go
@@ -30,6 +30,8 @@ import (
        "github.com/imdario/mergo"
 )
 
+var PlainConfigSecretRegexp = 
regexp.MustCompile(`^(configmap|secret):([a-zA-Z0-9][a-zA-Z0-9-]*)(/([a-zA-Z0-9].*))?$`)
+
 func (in *Artifact) String() string {
        return in.ID
 }
@@ -224,8 +226,7 @@ func (bc *BuildConfiguration) IsEmpty() bool {
 // DecodeValueSource returns a ValueSource object from an input that respects 
the format configmap|secret:resource-name[/path].
 func DecodeValueSource(input string, defaultKey string, errorMessage string) 
(ValueSource, error) {
        sub := make([]string, 0)
-       rex := 
regexp.MustCompile(`^(configmap|secret):([a-zA-Z0-9][a-zA-Z0-9-]*)(/([a-zA-Z0-9].*))?$`)
-       hits := rex.FindAllStringSubmatch(input, -1)
+       hits := PlainConfigSecretRegexp.FindAllStringSubmatch(input, -1)
 
        for _, hit := range hits {
                if len(hit) > 1 {
diff --git a/pkg/apis/camel/v1/trait/environment.go 
b/pkg/apis/camel/v1/trait/environment.go
index da3c423e5..70f3e8a43 100644
--- a/pkg/apis/camel/v1/trait/environment.go
+++ b/pkg/apis/camel/v1/trait/environment.go
@@ -28,7 +28,8 @@ type EnvironmentTrait struct {
        // Propagates the `HTTP_PROXY`, `HTTPS_PROXY` and `NO_PROXY` 
environment variables (default `true`)
        HTTPProxy *bool `property:"http-proxy" json:"httpProxy,omitempty"`
        // A list of environment variables to be added to the integration 
container.
-       // The syntax is KEY=VALUE, e.g., `MY_VAR="my value"`.
-       // These take precedence over the previously defined environment 
variables.
+       // The syntax is either VAR=VALUE or VAR=[configmap|secret]:name/key, 
where name represents the resource name,
+       // and key represents the resource key to be mapped as and environment 
variable.
+       // These take precedence over any previously defined environment 
variables.
        Vars []string `property:"vars" json:"vars,omitempty"`
 }
diff --git 
a/pkg/resources/config/crd/bases/camel.apache.org_integrationplatforms.yaml 
b/pkg/resources/config/crd/bases/camel.apache.org_integrationplatforms.yaml
index c21fdca75..2eeba0a8c 100644
--- a/pkg/resources/config/crd/bases/camel.apache.org_integrationplatforms.yaml
+++ b/pkg/resources/config/crd/bases/camel.apache.org_integrationplatforms.yaml
@@ -993,8 +993,9 @@ spec:
                       vars:
                         description: |-
                           A list of environment variables to be added to the 
integration container.
-                          The syntax is KEY=VALUE, e.g., `MY_VAR="my value"`.
-                          These take precedence over the previously defined 
environment variables.
+                          The syntax is either VAR=VALUE or 
VAR=[configmap|secret]:name/key, where name represents the resource name,
+                          and key represents the resource key to be mapped as 
and environment variable.
+                          These take precedence over any previously defined 
environment variables.
                         items:
                           type: string
                         type: array
@@ -3091,8 +3092,9 @@ spec:
                       vars:
                         description: |-
                           A list of environment variables to be added to the 
integration container.
-                          The syntax is KEY=VALUE, e.g., `MY_VAR="my value"`.
-                          These take precedence over the previously defined 
environment variables.
+                          The syntax is either VAR=VALUE or 
VAR=[configmap|secret]:name/key, where name represents the resource name,
+                          and key represents the resource key to be mapped as 
and environment variable.
+                          These take precedence over any previously defined 
environment variables.
                         items:
                           type: string
                         type: array
diff --git 
a/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml 
b/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml
index d96df69f0..6d80e7742 100644
--- a/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml
+++ b/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml
@@ -868,8 +868,9 @@ spec:
                       vars:
                         description: |-
                           A list of environment variables to be added to the 
integration container.
-                          The syntax is KEY=VALUE, e.g., `MY_VAR="my value"`.
-                          These take precedence over the previously defined 
environment variables.
+                          The syntax is either VAR=VALUE or 
VAR=[configmap|secret]:name/key, where name represents the resource name,
+                          and key represents the resource key to be mapped as 
and environment variable.
+                          These take precedence over any previously defined 
environment variables.
                         items:
                           type: string
                         type: array
@@ -2848,8 +2849,9 @@ spec:
                       vars:
                         description: |-
                           A list of environment variables to be added to the 
integration container.
-                          The syntax is KEY=VALUE, e.g., `MY_VAR="my value"`.
-                          These take precedence over the previously defined 
environment variables.
+                          The syntax is either VAR=VALUE or 
VAR=[configmap|secret]:name/key, where name represents the resource name,
+                          and key represents the resource key to be mapped as 
and environment variable.
+                          These take precedence over any previously defined 
environment variables.
                         items:
                           type: string
                         type: array
diff --git a/pkg/resources/config/crd/bases/camel.apache.org_integrations.yaml 
b/pkg/resources/config/crd/bases/camel.apache.org_integrations.yaml
index 7f99d90d6..a8d5d3c21 100644
--- a/pkg/resources/config/crd/bases/camel.apache.org_integrations.yaml
+++ b/pkg/resources/config/crd/bases/camel.apache.org_integrations.yaml
@@ -6884,8 +6884,9 @@ spec:
                       vars:
                         description: |-
                           A list of environment variables to be added to the 
integration container.
-                          The syntax is KEY=VALUE, e.g., `MY_VAR="my value"`.
-                          These take precedence over the previously defined 
environment variables.
+                          The syntax is either VAR=VALUE or 
VAR=[configmap|secret]:name/key, where name represents the resource name,
+                          and key represents the resource key to be mapped as 
and environment variable.
+                          These take precedence over any previously defined 
environment variables.
                         items:
                           type: string
                         type: array
diff --git 
a/pkg/resources/config/crd/bases/camel.apache.org_kameletbindings.yaml 
b/pkg/resources/config/crd/bases/camel.apache.org_kameletbindings.yaml
index 2805a4bc9..508d07818 100644
--- a/pkg/resources/config/crd/bases/camel.apache.org_kameletbindings.yaml
+++ b/pkg/resources/config/crd/bases/camel.apache.org_kameletbindings.yaml
@@ -6955,8 +6955,9 @@ spec:
                           vars:
                             description: |-
                               A list of environment variables to be added to 
the integration container.
-                              The syntax is KEY=VALUE, e.g., `MY_VAR="my 
value"`.
-                              These take precedence over the previously 
defined environment variables.
+                              The syntax is either VAR=VALUE or 
VAR=[configmap|secret]:name/key, where name represents the resource name,
+                              and key represents the resource key to be mapped 
as and environment variable.
+                              These take precedence over any previously 
defined environment variables.
                             items:
                               type: string
                             type: array
diff --git a/pkg/resources/config/crd/bases/camel.apache.org_pipes.yaml 
b/pkg/resources/config/crd/bases/camel.apache.org_pipes.yaml
index 77aa04e8e..25008359f 100644
--- a/pkg/resources/config/crd/bases/camel.apache.org_pipes.yaml
+++ b/pkg/resources/config/crd/bases/camel.apache.org_pipes.yaml
@@ -6953,8 +6953,9 @@ spec:
                           vars:
                             description: |-
                               A list of environment variables to be added to 
the integration container.
-                              The syntax is KEY=VALUE, e.g., `MY_VAR="my 
value"`.
-                              These take precedence over the previously 
defined environment variables.
+                              The syntax is either VAR=VALUE or 
VAR=[configmap|secret]:name/key, where name represents the resource name,
+                              and key represents the resource key to be mapped 
as and environment variable.
+                              These take precedence over any previously 
defined environment variables.
                             items:
                               type: string
                             type: array
diff --git a/pkg/trait/environment.go b/pkg/trait/environment.go
index 3609ff7b9..c1db2aec8 100644
--- a/pkg/trait/environment.go
+++ b/pkg/trait/environment.go
@@ -22,6 +22,7 @@ import (
 
        "k8s.io/utils/ptr"
 
+       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/util/camel"
        "github.com/apache/camel-k/v2/pkg/util/defaults"
@@ -102,7 +103,16 @@ func (t *environmentTrait) Apply(e *Environment) error {
        if t.Vars != nil {
                for _, env := range t.Vars {
                        k, v := property.SplitPropertyFileEntry(env)
-                       envvar.SetVal(&e.EnvVars, k, v)
+                       confs := 
v1.PlainConfigSecretRegexp.FindAllStringSubmatch(v, -1)
+                       if len(confs) > 0 {
+                               var res, err = v1.DecodeValueSource(v, "", 
"Invalid configuration "+v)
+                               if err != nil {
+                                       return err
+                               }
+                               envvar.SetValFromValueSource(&e.EnvVars, k, res)
+                       } else {
+                               envvar.SetVal(&e.EnvVars, k, v)
+                       }
                }
        }
 
diff --git a/pkg/trait/environment_test.go b/pkg/trait/environment_test.go
index fb19d54c6..05bf6cd8e 100644
--- a/pkg/trait/environment_test.go
+++ b/pkg/trait/environment_test.go
@@ -18,6 +18,7 @@ limitations under the License.
 package trait
 
 import (
+       "fmt"
        "testing"
 
        "github.com/stretchr/testify/assert"
@@ -192,6 +193,45 @@ func TestCustomEnvVars(t *testing.T) {
        assert.True(t, userK2)
 }
 
+func TestValueSourceEnvVars(t *testing.T) {
+       c, err := camel.DefaultCatalog()
+       require.NoError(t, err)
+
+       env := mockEnvironment(c)
+       env.Integration.Spec.Traits = v1.Traits{
+               Environment: &traitv1.EnvironmentTrait{
+                       Vars: []string{"MY_VAR_1=secret:my-sec/my-sec-value", 
"MY_VAR_2=configmap:my-cm/my-cm-value"},
+               },
+       }
+       env.Platform.ResyncStatusFullConfig()
+
+       conditions, err := NewEnvironmentTestCatalog().apply(&env)
+       require.NoError(t, err)
+       assert.NotEmpty(t, conditions)
+
+       userK1 := false
+       userK2 := false
+
+       env.Resources.VisitDeployment(func(deployment *appsv1.Deployment) {
+               fmt.Println(deployment.Spec.Template.Spec.Containers[0].Env)
+               for _, e := range 
deployment.Spec.Template.Spec.Containers[0].Env {
+                       if e.Name == "MY_VAR_1" {
+                               userK1 = e.Value == "" &&
+                                       e.ValueFrom.SecretKeyRef.Name == 
"my-sec" &&
+                                       e.ValueFrom.SecretKeyRef.Key == 
"my-sec-value"
+                       }
+                       if e.Name == "MY_VAR_2" {
+                               userK2 = e.Value == "" &&
+                                       e.ValueFrom.ConfigMapKeyRef.Name == 
"my-cm" &&
+                                       e.ValueFrom.ConfigMapKeyRef.Key == 
"my-cm-value"
+                       }
+               }
+       })
+
+       assert.True(t, userK1)
+       assert.True(t, userK2)
+}
+
 func NewEnvironmentTestCatalog() *Catalog {
        return NewCatalog(nil)
 }
diff --git a/pkg/util/envvar/envvar.go b/pkg/util/envvar/envvar.go
index 0d017d391..f6b668e85 100644
--- a/pkg/util/envvar/envvar.go
+++ b/pkg/util/envvar/envvar.go
@@ -17,7 +17,10 @@ limitations under the License.
 
 package envvar
 
-import corev1 "k8s.io/api/core/v1"
+import (
+       v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
+       corev1 "k8s.io/api/core/v1"
+)
 
 // Get --.
 func Get(vars []corev1.EnvVar, name string) *corev1.EnvVar {
@@ -92,3 +95,27 @@ func SetValFrom(vars *[]corev1.EnvVar, name string, path 
string) {
                })
        }
 }
+
+// SetValFromValueSource --.
+func SetValFromValueSource(vars *[]corev1.EnvVar, name string, vs 
v1.ValueSource) {
+       var envVarSource *corev1.EnvVarSource
+       if vs.SecretKeyRef != nil {
+               envVarSource = &corev1.EnvVarSource{
+                       SecretKeyRef: vs.SecretKeyRef,
+               }
+       } else if vs.ConfigMapKeyRef != nil {
+               envVarSource = &corev1.EnvVarSource{
+                       ConfigMapKeyRef: vs.ConfigMapKeyRef,
+               }
+       }
+
+       if envVar := Get(*vars, name); envVar != nil {
+               envVar.Value = ""
+               envVar.ValueFrom = envVarSource
+       } else {
+               *vars = append(*vars, corev1.EnvVar{
+                       Name:      name,
+                       ValueFrom: envVarSource,
+               })
+       }
+}

Reply via email to