You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by as...@apache.org on 2022/01/21 08:34:17 UTC

[camel-k] branch release-1.6.x updated: feat(trait): environment variables

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

astefanutti pushed a commit to branch release-1.6.x
in repository https://gitbox.apache.org/repos/asf/camel-k.git


The following commit(s) were added to refs/heads/release-1.6.x by this push:
     new 3727af7  feat(trait): environment variables
3727af7 is described below

commit 3727af79d1054c269f8d42b8916b190831a27422
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Mon Sep 20 14:33:22 2021 +0200

    feat(trait): environment variables
    
    Moved the logic to process environment variable to trait. It will simplify setting via annotations
    
    Closes #2512
---
 deploy/traits.yaml                                 |   4 +
 docs/modules/traits/pages/environment.adoc         |   4 +
 examples/README.md                                 |   5 +-
 examples/basic/Env.java                            |  31 ++++
 examples/basic/README.md                           |   3 +
 ...annotation.yaml => env-var-writer.kamelet.yaml} |  20 +--
 examples/kamelets/kameletbindings/kb-env-vars.yaml |  22 ++-
 ...nnotation.yaml => kb-log-trait-annotation.yaml} |   0
 pkg/cmd/run.go                                     |   2 +-
 pkg/trait/environment.go                           |  10 ++
 pkg/trait/environment_test.go                      | 169 ++++++++++-----------
 11 files changed, 158 insertions(+), 112 deletions(-)

diff --git a/deploy/traits.yaml b/deploy/traits.yaml
index 92500da..7888a19 100755
--- a/deploy/traits.yaml
+++ b/deploy/traits.yaml
@@ -287,6 +287,10 @@ traits:
     type: bool
     description: Enables injection of `NAMESPACE` and `POD_NAME` environment variables
       (default `true`)
+  - name: vars
+    type: '[]string'
+    description: A list of variables to be created on the Pod. Must have KEY=VALUE
+      syntax (ie, MY_VAR="my value").
 - name: error-handler
   platform: true
   profiles:
diff --git a/docs/modules/traits/pages/environment.adoc b/docs/modules/traits/pages/environment.adoc
index 896d369..f3d9c0e 100755
--- a/docs/modules/traits/pages/environment.adoc
+++ b/docs/modules/traits/pages/environment.adoc
@@ -32,6 +32,10 @@ The following configuration options are available:
 | bool
 | Enables injection of `NAMESPACE` and `POD_NAME` environment variables (default `true`)
 
+| environment.vars
+| []string
+| A list of variables to be created on the Pod. Must have KEY=VALUE syntax (ie, MY_VAR="my value").
+
 |===
 
 // End of autogenerated code - DO NOT EDIT! (configuration)
diff --git a/examples/README.md b/examples/README.md
index 03b605f..04b29b5 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -9,6 +9,7 @@ In this section you will find the most basic examples. Useful to start learning
 | Type  |  Description | Link  |
 |---|---|---|
 | Languages | Simple integrations developed in various supported languages | [see examples](./languages/)|
+| Basic | Simple integrations with basic configuration | [see examples](./basic/)|
 | Cron | How to create a `cront` integration | [see examples](./cron/)|
 | User Config | Explore how to include a `property`, `secret`, `configmap` or file `resource` in your integration | [see examples](./user-config/)|
 | Processor | Show how to include `Processor`s logic | [see examples](./processor/)|
@@ -20,7 +21,6 @@ In this section you will find the most basic examples. Useful to start learning
 
 In this section you can find a few examples of certain [`Camel` components](https://camel.apache.org/components/latest/index.html). This is a limited number of the wide variety of components supported by Apache Camel. You can also find useful examples [in this repository](https://github.com/apache/camel-k-examples).
 
-
 | Type  |  Description | Link  |
 |---|---|---|
 | AMQP | Component usage | [see examples](./amqp/)|
@@ -50,4 +50,5 @@ Traits configuration will be very helpful to fine tune your `Integration`. Here
 
 | Type  |  Description | Link  |
 |---|---|---|
-| JVM | How to use `JVM` trait| [see examples](./traits/jvm/)|
\ No newline at end of file
+| Container | How to customize with `container` trait| [see examples](./traits/container/)|
+| JVM | How to use `jvm` trait| [see examples](./traits/jvm/)|
\ No newline at end of file
diff --git a/examples/basic/Env.java b/examples/basic/Env.java
new file mode 100644
index 0000000..988da15
--- /dev/null
+++ b/examples/basic/Env.java
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+// To run this integrations use:
+//
+// kamel run --env MY_ENV_VAR="hello world" Env.java --dev
+//
+
+import org.apache.camel.builder.RouteBuilder;
+
+public class Env extends RouteBuilder {
+  @Override
+  public void configure() throws Exception {
+	  from("timer:tick")
+        .log("${env:MY_ENV_VAR}");
+  }
+}
\ No newline at end of file
diff --git a/examples/basic/README.md b/examples/basic/README.md
new file mode 100644
index 0000000..9bdef5c
--- /dev/null
+++ b/examples/basic/README.md
@@ -0,0 +1,3 @@
+# Camel K basic examples
+
+Find useful examples about how to run an integration in Camel K.
\ No newline at end of file
diff --git a/examples/kamelets/kameletbindings/kb-trait-annotation.yaml b/examples/kamelets/kameletbindings/env-var-writer.kamelet.yaml
similarity index 80%
copy from examples/kamelets/kameletbindings/kb-trait-annotation.yaml
copy to examples/kamelets/kameletbindings/env-var-writer.kamelet.yaml
index 73a5d6a..840e9fe 100644
--- a/examples/kamelets/kameletbindings/kb-trait-annotation.yaml
+++ b/examples/kamelets/kameletbindings/env-var-writer.kamelet.yaml
@@ -16,14 +16,16 @@
 # ---------------------------------------------------------------------------
 
 apiVersion: camel.apache.org/v1alpha1
-kind: KameletBinding
+kind: Kamelet
 metadata:
-  name: timer-2-log-annotation
-  annotations:
-    trait.camel.apache.org/logging.level: DEBUG
-    trait.camel.apache.org/logging.color: "false"
+  name: env-var-writer
 spec:
-  source:
-    uri: timer:foo
-  sink:
-    uri: log:bar
\ No newline at end of file
+  definition:
+    title: "Log some env vars"   
+  flow:
+    from:
+      uri: kamelet:source
+      steps:
+      - set-body:
+          simple: "${env:MY_ENV_VAR1} / ${env:MY_ENV_VAR2}"
+      - to: "log:bar"  
diff --git a/examples/kamelets/kameletbindings/kb-env-vars.yaml b/examples/kamelets/kameletbindings/kb-env-vars.yaml
index 7e42760..4ce9e5a 100644
--- a/examples/kamelets/kameletbindings/kb-env-vars.yaml
+++ b/examples/kamelets/kameletbindings/kb-env-vars.yaml
@@ -15,17 +15,23 @@
 # limitations under the License.
 # ---------------------------------------------------------------------------
 
+# Apply kamelet used in this binding
+# kubectl apply -f env-var-writer.kamelet.yaml
+#
+# Apply kamelet binding
+# kubect apply -f kb-env-vars.yaml
+# 
 apiVersion: camel.apache.org/v1alpha1
 kind: KameletBinding
 metadata:
   name: timer-to-log
-  namespace: default
+  annotations: 
+    trait.camel.apache.org/environment.vars: "[\"MY_ENV_VAR1 = value1\", \"MY_ENV_VAR2 = value2\"]"
 spec:
-  integration:
-    configuration:
-    - type: env
-      value: X=hello world!
-  sink:
-    uri: log:bar
   source:
-    uri: timer:foo
\ No newline at end of file
+    uri: timer:foo
+  sink:
+    ref:
+      kind: Kamelet
+      apiVersion: camel.apache.org/v1alpha1
+      name: env-var-writer
diff --git a/examples/kamelets/kameletbindings/kb-trait-annotation.yaml b/examples/kamelets/kameletbindings/kb-log-trait-annotation.yaml
similarity index 100%
rename from examples/kamelets/kameletbindings/kb-trait-annotation.yaml
rename to examples/kamelets/kameletbindings/kb-log-trait-annotation.yaml
diff --git a/pkg/cmd/run.go b/pkg/cmd/run.go
index 8cb1ebf..2b8faac 100644
--- a/pkg/cmd/run.go
+++ b/pkg/cmd/run.go
@@ -621,7 +621,7 @@ func (o *runCmdOptions) createOrUpdateIntegration(cmd *cobra.Command, c client.C
 		integration.Spec.AddConfiguration("volume", item)
 	}
 	for _, item := range o.EnvVars {
-		integration.Spec.AddConfiguration("env", item)
+		o.Traits = append(o.Traits, fmt.Sprintf("environment.vars=%s", item))
 	}
 
 	if err := o.configureTraits(integration, o.Traits, catalog); err != nil {
diff --git a/pkg/trait/environment.go b/pkg/trait/environment.go
index ed5ee41..b4ebfa8 100644
--- a/pkg/trait/environment.go
+++ b/pkg/trait/environment.go
@@ -20,6 +20,7 @@ package trait
 import (
 	"github.com/apache/camel-k/pkg/util/defaults"
 	"github.com/apache/camel-k/pkg/util/envvar"
+	"github.com/apache/camel-k/pkg/util/property"
 )
 
 // The environment trait is used internally to inject standard environment variables in the integration container,
@@ -30,6 +31,8 @@ type environmentTrait struct {
 	BaseTrait `property:",squash"`
 	// Enables injection of `NAMESPACE` and `POD_NAME` environment variables (default `true`)
 	ContainerMeta *bool `property:"container-meta" json:"containerMeta,omitempty"`
+	// A list of variables to be created on the Pod. Must have KEY=VALUE syntax (ie, MY_VAR="my value").
+	Vars []string `property:"vars" json:"vars,omitempty"`
 }
 
 const (
@@ -78,6 +81,13 @@ func (t *environmentTrait) Apply(e *Environment) error {
 		envvar.SetValFrom(&e.EnvVars, envVarPodName, "metadata.name")
 	}
 
+	if t.Vars != nil {
+		for _, env := range t.Vars {
+			k, v := property.SplitPropertyFileEntry(env)
+			envvar.SetVal(&e.EnvVars, k, v)
+		}
+	}
+
 	return nil
 }
 
diff --git a/pkg/trait/environment_test.go b/pkg/trait/environment_test.go
index ad0d3be..13cb070 100644
--- a/pkg/trait/environment_test.go
+++ b/pkg/trait/environment_test.go
@@ -37,34 +37,7 @@ func TestDefaultEnvironment(t *testing.T) {
 	catalog, err := camel.DefaultCatalog()
 	assert.Nil(t, err)
 
-	env := Environment{
-		CamelCatalog: catalog,
-		Catalog:      NewCatalog(context.TODO(), nil),
-		Integration: &v1.Integration{
-			Status: v1.IntegrationStatus{
-				Phase: v1.IntegrationPhaseDeploying,
-			},
-			Spec: v1.IntegrationSpec{
-				Profile: v1.TraitProfileOpenShift,
-			},
-		},
-		IntegrationKit: &v1.IntegrationKit{
-			Status: v1.IntegrationKitStatus{
-				Phase: v1.IntegrationKitPhaseReady,
-			},
-		},
-		Platform: &v1.IntegrationPlatform{
-			ObjectMeta: metav1.ObjectMeta{
-				Namespace: "ns",
-			},
-			Spec: v1.IntegrationPlatformSpec{
-				Cluster: v1.IntegrationPlatformClusterOpenShift,
-			},
-		},
-		EnvVars:        make([]corev1.EnvVar, 0),
-		ExecutedTraits: make([]Trait, 0),
-		Resources:      kubernetes.NewCollection(),
-	}
+	env := mockEnvironment(catalog)
 	env.Platform.ResyncStatusFullConfig()
 
 	err = NewEnvironmentTestCatalog().apply(&env)
@@ -108,38 +81,11 @@ func TestEnabledContainerMetaDataEnvVars(t *testing.T) {
 	c, err := camel.DefaultCatalog()
 	assert.Nil(t, err)
 
-	env := Environment{
-		CamelCatalog: c,
-		Catalog:      NewCatalog(context.TODO(), nil),
-		Integration: &v1.Integration{
-			Status: v1.IntegrationStatus{
-				Phase: v1.IntegrationPhaseDeploying,
-			},
-			Spec: v1.IntegrationSpec{
-				Profile: v1.TraitProfileOpenShift,
-				Traits: map[string]v1.TraitSpec{
-					"environment": test.TraitSpecFromMap(t, map[string]interface{}{
-						"containerMeta": true,
-					}),
-				},
-			},
-		},
-		IntegrationKit: &v1.IntegrationKit{
-			Status: v1.IntegrationKitStatus{
-				Phase: v1.IntegrationKitPhaseReady,
-			},
-		},
-		Platform: &v1.IntegrationPlatform{
-			ObjectMeta: metav1.ObjectMeta{
-				Namespace: "ns",
-			},
-			Spec: v1.IntegrationPlatformSpec{
-				Cluster: v1.IntegrationPlatformClusterOpenShift,
-			},
-		},
-		EnvVars:        make([]corev1.EnvVar, 0),
-		ExecutedTraits: make([]Trait, 0),
-		Resources:      kubernetes.NewCollection(),
+	env := mockEnvironment(c)
+	env.Integration.Spec.Traits = map[string]v1.TraitSpec{
+		"environment": test.TraitSpecFromMap(t, map[string]interface{}{
+			"containerMeta": true,
+		}),
 	}
 	env.Platform.ResyncStatusFullConfig()
 
@@ -174,39 +120,13 @@ func TestDisabledContainerMetaDataEnvVars(t *testing.T) {
 	c, err := camel.DefaultCatalog()
 	assert.Nil(t, err)
 
-	env := Environment{
-		CamelCatalog: c,
-		Catalog:      NewCatalog(context.TODO(), nil),
-		Integration: &v1.Integration{
-			Status: v1.IntegrationStatus{
-				Phase: v1.IntegrationPhaseDeploying,
-			},
-			Spec: v1.IntegrationSpec{
-				Profile: v1.TraitProfileOpenShift,
-				Traits: map[string]v1.TraitSpec{
-					"environment": test.TraitSpecFromMap(t, map[string]interface{}{
-						"containerMeta": false,
-					}),
-				},
-			},
-		},
-		IntegrationKit: &v1.IntegrationKit{
-			Status: v1.IntegrationKitStatus{
-				Phase: v1.IntegrationKitPhaseReady,
-			},
-		},
-		Platform: &v1.IntegrationPlatform{
-			ObjectMeta: metav1.ObjectMeta{
-				Namespace: "ns",
-			},
-			Spec: v1.IntegrationPlatformSpec{
-				Cluster: v1.IntegrationPlatformClusterOpenShift,
-			},
-		},
-		EnvVars:        make([]corev1.EnvVar, 0),
-		ExecutedTraits: make([]Trait, 0),
-		Resources:      kubernetes.NewCollection(),
+	env := mockEnvironment(c)
+	env.Integration.Spec.Traits = map[string]v1.TraitSpec{
+		"environment": test.TraitSpecFromMap(t, map[string]interface{}{
+			"containerMeta": false,
+		}),
 	}
+
 	env.Platform.ResyncStatusFullConfig()
 
 	err = NewEnvironmentTestCatalog().apply(&env)
@@ -236,6 +156,71 @@ func TestDisabledContainerMetaDataEnvVars(t *testing.T) {
 	assert.True(t, ck)
 }
 
+func TestCustomEnvVars(t *testing.T) {
+	c, err := camel.DefaultCatalog()
+	assert.Nil(t, err)
+
+	env := mockEnvironment(c)
+	env.Integration.Spec.Traits = map[string]v1.TraitSpec{
+		"environment": test.TraitSpecFromMap(t, map[string]interface{}{
+			"vars": []string{"key1=val1", "key2 = val2"},
+		}),
+	}
+	env.Platform.ResyncStatusFullConfig()
+
+	err = NewEnvironmentTestCatalog().apply(&env)
+
+	assert.Nil(t, err)
+
+	userK1 := false
+	userK2 := false
+
+	env.Resources.VisitDeployment(func(deployment *appsv1.Deployment) {
+		for _, e := range deployment.Spec.Template.Spec.Containers[0].Env {
+			if e.Name == "key1" {
+				userK1 = e.Value == "val1"
+			}
+			if e.Name == "key2" {
+				userK2 = e.Value == "val2"
+			}
+		}
+	})
+
+	assert.True(t, userK1)
+	assert.True(t, userK2)
+}
+
 func NewEnvironmentTestCatalog() *Catalog {
 	return NewCatalog(context.TODO(), nil)
 }
+
+func mockEnvironment(catalog *camel.RuntimeCatalog) Environment {
+	return Environment{
+		CamelCatalog: catalog,
+		Catalog:      NewCatalog(context.TODO(), nil),
+		Integration: &v1.Integration{
+			Status: v1.IntegrationStatus{
+				Phase: v1.IntegrationPhaseDeploying,
+			},
+			Spec: v1.IntegrationSpec{
+				Profile: v1.TraitProfileOpenShift,
+			},
+		},
+		IntegrationKit: &v1.IntegrationKit{
+			Status: v1.IntegrationKitStatus{
+				Phase: v1.IntegrationKitPhaseReady,
+			},
+		},
+		Platform: &v1.IntegrationPlatform{
+			ObjectMeta: metav1.ObjectMeta{
+				Namespace: "ns",
+			},
+			Spec: v1.IntegrationPlatformSpec{
+				Cluster: v1.IntegrationPlatformClusterOpenShift,
+			},
+		},
+		EnvVars:        make([]corev1.EnvVar, 0),
+		ExecutedTraits: make([]Trait, 0),
+		Resources:      kubernetes.NewCollection(),
+	}
+}