You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by nf...@apache.org on 2020/09/17 09:10:07 UTC

[camel-k] 12/21: Fix #1574: implement changes in source loading

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

nferraro pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit 4bea9af710a7d05869e6c0e1baa660b62ad34bb4
Author: nicolaferraro <ni...@gmail.com>
AuthorDate: Tue Aug 11 16:37:23 2020 +0200

    Fix #1574: implement changes in source loading
---
 deploy/resources.go                              |  12 +-
 deploy/traits.yaml                               |  17 +++
 docs/modules/ROOT/nav.adoc                       |   1 +
 docs/modules/traits/pages/kamelets.adoc          |  39 +++++
 pkg/apis/camel/v1/integration_types.go           |   6 +-
 pkg/apis/camel/v1/zz_generated.deepcopy.go       |   5 +
 pkg/apis/camel/v1alpha1/jsonschema_types.go      |   8 +-
 pkg/apis/camel/v1alpha1/kamelet_types.go         |  14 +-
 pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go |  51 ++++++-
 pkg/controller/kamelet/common.go                 |  48 ++++++
 pkg/controller/kamelet/initialize.go             |   4 +-
 pkg/controller/kamelet/monitor.go                |   3 +-
 pkg/trait/container.go                           |   9 +-
 pkg/trait/kamelets.go                            |  44 ++++--
 pkg/trait/kamelets_test.go                       |  14 +-
 pkg/trait/knative_service_test.go                |  10 +-
 pkg/trait/trait_test.go                          |   8 +-
 pkg/trait/trait_types.go                         | 183 ++++++-----------------
 18 files changed, 284 insertions(+), 192 deletions(-)

diff --git a/deploy/resources.go b/deploy/resources.go
index 0741e84..673756d 100644
--- a/deploy/resources.go
+++ b/deploy/resources.go
@@ -144,6 +144,13 @@ var assets = func() http.FileSystem {
 
 			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x3a\x4f\x8f\xe2\x38\xf6\xf7\x7c\x8a\xa7\xe2\xd0\x33\x52\x01\xbf\x9e\xb9\xfc\xc4\x9e\x58\xba\x4b\xcb\x76\x37\x55\x02\x7a\x46\x73\x34\xce\x23\x78\xcb\xb1\xb3\xb6\x03\x5d\xbb\xda\xef\xbe\x7a\x76\x12\x92\x90\x50\x14\xd5\xad\x95\x46\x95\x1b\xf1\xfb\xff\xdf\x2f\x0c\x60\xf8\xfd\x9e\x68\x00\x9f\x05\x47\x65\x31\x06\xa7\xc1\xed\x10\xa6\x19\xe3\x3b\x84\x95\xde\xba\x03\x33\x08\x77\x3a\x57\x31\x73\x42\x2b\xf8\x69\xba\xba\xfb\x [...]
 		},
+		"/crd-kamelet.yaml": &vfsgen۰CompressedFileInfo{
+			name:             "crd-kamelet.yaml",
+			modTime:          time.Time{},
+			uncompressedSize: 1498,
+
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x54\xc1\x6e\xe3\x36\x10\xbd\xeb\x2b\x1e\xac\xcb\x2e\x10\xcb\x4d\x4f\x85\x7a\x72\xbd\x09\xea\x26\x90\x83\xc8\xdb\xc5\x1e\xc7\xd2\x58\x1a\x98\x22\x59\x92\xb2\x63\x14\xfd\xf7\x82\x92\x1c\x3b\x68\x8f\xab\x93\xfd\x66\x38\xf3\xde\xbc\x21\x53\xcc\x7f\xdc\x97\xa4\x78\x96\x8a\xb5\xe7\x1a\xc1\x20\xb4\x8c\xa5\xa5\xaa\x65\x94\x66\x1f\x4e\xe4\x18\x8f\xa6\xd7\x35\x05\x31\x1a\x9f\x96\xe5\xe3\x67\xf4\xba\x66\x07\xa3\x19\xc6\xa1\x [...]
+		},
 		"/operator-deployment.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "operator-deployment.yaml",
 			modTime:          time.Time{},
@@ -354,9 +361,9 @@ var assets = func() http.FileSystem {
 		"/traits.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "traits.yaml",
 			modTime:          time.Time{},
-			uncompressedSize: 32177,
+			uncompressedSize: 32786,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x7d\x6d\x73\x1b\x37\x92\xf0\xf7\xfc\x0a\x94\x9e\xa7\x4a\xa2\x8a\x1c\xc9\xd9\xca\x26\xab\xbb\x5c\x4a\xeb\x38\xbb\x72\x62\x5b\x67\x39\xc9\x5d\xe5\xb6\x96\xe0\x4c\x93\x84\x85\x01\x66\x01\x0c\x65\xe6\xea\xfe\xfb\x55\x37\x5e\x06\x33\x1c\x49\x94\x63\xa5\xb4\x55\x57\xf9\x10\x93\x9a\x69\x34\x1a\xfd\xfe\x02\x3a\xc3\x85\xb3\x67\x9f\xcd\x98\xe2\x35\x9c\x31\xbe\x5c\x0a\x25\xdc\xf6\x33\xc6\x1a\xc9\xdd\x52\x9b\xfa\x8c\x2d\xb9\x [...]
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x7d\x6d\x73\x1b\x37\x92\xf0\xf7\xfc\x0a\x94\x9e\xa7\x4a\xa2\x8a\x1c\xc9\xd9\xca\x26\xab\xbb\x5c\x4a\xeb\x38\xbb\x72\x62\x5b\x67\x39\xc9\x5d\xe5\xb6\x96\xe0\x4c\x93\x84\x85\x01\x66\x01\x0c\x65\xe6\xea\xfe\xfb\x55\x37\x5e\x06\x33\x1c\x49\x94\x63\xa5\xb4\x55\x57\xf9\x10\x93\x9a\x69\x34\x1a\xfd\xfe\x02\x3a\xc3\x85\xb3\x67\x9f\xcd\x98\xe2\x35\x9c\x31\xbe\x5c\x0a\x25\xdc\xf6\x33\xc6\x1a\xc9\xdd\x52\x9b\xfa\x8c\x2d\xb9\x [...]
 		},
 		"/user-cluster-role.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "user-cluster-role.yaml",
@@ -380,6 +387,7 @@ var assets = func() http.FileSystem {
 		fs["/crd-integration-kit.yaml"].(os.FileInfo),
 		fs["/crd-integration-platform.yaml"].(os.FileInfo),
 		fs["/crd-integration.yaml"].(os.FileInfo),
+		fs["/crd-kamelet.yaml"].(os.FileInfo),
 		fs["/operator-deployment.yaml"].(os.FileInfo),
 		fs["/operator-role-binding-events.yaml"].(os.FileInfo),
 		fs["/operator-role-binding-knative.yaml"].(os.FileInfo),
diff --git a/deploy/traits.yaml b/deploy/traits.yaml
index 070d61c..c2d85f0 100755
--- a/deploy/traits.yaml
+++ b/deploy/traits.yaml
@@ -319,6 +319,23 @@ traits:
   - name: options
     type: '[]string'
     description: A list of JVM options
+- name: kamelets
+  platform: true
+  profiles:
+  - Kubernetes
+  - Knative
+  - OpenShift
+  description: The kamelets trait is a platform trait used to inject Kamelets into the integration runtime.
+  properties:
+  - name: enabled
+    type: bool
+    description: Can be used to enable or disable a trait. All traits share this common property.
+  - name: auto
+    type: bool
+    description: Automatically inject all referenced Kamelets and their default configuration (enabled by default)
+  - name: list
+    type: string
+    description: Comma separated list of Kamelet names to load into the current integration
 - name: knative-service
   platform: false
   profiles:
diff --git a/docs/modules/ROOT/nav.adoc b/docs/modules/ROOT/nav.adoc
index 039d5c3..7c00b89 100644
--- a/docs/modules/ROOT/nav.adoc
+++ b/docs/modules/ROOT/nav.adoc
@@ -37,6 +37,7 @@
 ** xref:traits:istio.adoc[Istio]
 ** xref:traits:jolokia.adoc[Jolokia]
 ** xref:traits:jvm.adoc[Jvm]
+** xref:traits:kamelets.adoc[Kamelets]
 ** xref:traits:knative-service.adoc[Knative Service]
 ** xref:traits:knative.adoc[Knative]
 ** xref:traits:master.adoc[Master]
diff --git a/docs/modules/traits/pages/kamelets.adoc b/docs/modules/traits/pages/kamelets.adoc
new file mode 100755
index 0000000..7409709
--- /dev/null
+++ b/docs/modules/traits/pages/kamelets.adoc
@@ -0,0 +1,39 @@
+= Kamelets Trait
+
+// Start of autogenerated code - DO NOT EDIT! (description)
+The kamelets trait is a platform trait used to inject Kamelets into the integration runtime.
+
+
+This trait is available in the following profiles: **Kubernetes, Knative, OpenShift**.
+
+WARNING: The kamelets trait is a *platform trait*: disabling it may compromise the platform functionality.
+
+// End of autogenerated code - DO NOT EDIT! (description)
+// Start of autogenerated code - DO NOT EDIT! (configuration)
+== Configuration
+
+Trait properties can be specified when running any integration with the CLI:
+```
+kamel run --trait kamelets.[key]=[value] --trait kamelets.[key2]=[value2] integration.groovy
+```
+The following configuration options are available:
+
+[cols="2,1,5a"]
+|===
+|Property | Type | Description
+
+| kamelets.enabled
+| bool
+| Can be used to enable or disable a trait. All traits share this common property.
+
+| kamelets.auto
+| bool
+| Automatically inject all referenced Kamelets and their default configuration (enabled by default)
+
+| kamelets.list
+| string
+| Comma separated list of Kamelet names to load into the current integration
+
+|===
+
+// End of autogenerated code - DO NOT EDIT! (configuration)
diff --git a/pkg/apis/camel/v1/integration_types.go b/pkg/apis/camel/v1/integration_types.go
index 7e985a2..47aeb44 100644
--- a/pkg/apis/camel/v1/integration_types.go
+++ b/pkg/apis/camel/v1/integration_types.go
@@ -127,13 +127,15 @@ type SourceSpec struct {
 	Interceptors []string `json:"interceptors,omitempty"`
 	// Type defines the kind of source described by this object
 	Type SourceType `json:"type,omitempty"`
+	// List of property names defined in the source (e.g. if type is "template")
+	PropertyNames []string `json:"property-names,omitempty"`
 }
 
 type SourceType string
 
 const (
-	SourceTypeDefault SourceType = ""
-	SourceTypeKamelet SourceType = "kamelet"
+	SourceTypeDefault  SourceType = ""
+	SourceTypeTemplate SourceType = "template"
 )
 
 // Language --
diff --git a/pkg/apis/camel/v1/zz_generated.deepcopy.go b/pkg/apis/camel/v1/zz_generated.deepcopy.go
index d48aa41..534a75d 100644
--- a/pkg/apis/camel/v1/zz_generated.deepcopy.go
+++ b/pkg/apis/camel/v1/zz_generated.deepcopy.go
@@ -1312,6 +1312,11 @@ func (in *SourceSpec) DeepCopyInto(out *SourceSpec) {
 		*out = make([]string, len(*in))
 		copy(*out, *in)
 	}
+	if in.PropertyNames != nil {
+		in, out := &in.PropertyNames, &out.PropertyNames
+		*out = make([]string, len(*in))
+		copy(*out, *in)
+	}
 	return
 }
 
diff --git a/pkg/apis/camel/v1alpha1/jsonschema_types.go b/pkg/apis/camel/v1alpha1/jsonschema_types.go
index 6ebdf1e..a66b131 100644
--- a/pkg/apis/camel/v1alpha1/jsonschema_types.go
+++ b/pkg/apis/camel/v1alpha1/jsonschema_types.go
@@ -19,6 +19,8 @@ limitations under the License.
 
 package v1alpha1
 
+import "encoding/json"
+
 // JSONSchemaProps is a JSON-Schema following Specification Draft 4 (http://json-schema.org/).
 type JSONSchemaProps struct {
 	ID          string        `json:"id,omitempty" protobuf:"bytes,1,opt,name=id"`
@@ -59,7 +61,7 @@ type JSONSchemaProps struct {
 	// default is a default value for undefined object fields.
 	// Defaulting is a beta feature under the CustomResourceDefaulting feature gate.
 	// Defaulting requires spec.preserveUnknownFields to be false.
-	Default              *JSON                      `json:"default,omitempty" protobuf:"bytes,8,opt,name=default"`
+	Default              *json.RawMessage           `json:"default,omitempty" protobuf:"bytes,8,opt,name=default"`
 	Maximum              *float64                   `json:"maximum,omitempty" protobuf:"bytes,9,opt,name=maximum"`
 	ExclusiveMaximum     bool                       `json:"exclusiveMaximum,omitempty" protobuf:"bytes,10,opt,name=exclusiveMaximum"`
 	Minimum              *float64                   `json:"minimum,omitempty" protobuf:"bytes,11,opt,name=minimum"`
@@ -71,7 +73,7 @@ type JSONSchemaProps struct {
 	MinItems             *int64                     `json:"minItems,omitempty" protobuf:"bytes,17,opt,name=minItems"`
 	UniqueItems          bool                       `json:"uniqueItems,omitempty" protobuf:"bytes,18,opt,name=uniqueItems"`
 	MultipleOf           *float64                   `json:"multipleOf,omitempty" protobuf:"bytes,19,opt,name=multipleOf"`
-	Enum                 []JSON                     `json:"enum,omitempty" protobuf:"bytes,20,rep,name=enum"`
+	Enum                 []*json.RawMessage         `json:"enum,omitempty" protobuf:"bytes,20,rep,name=enum"`
 	MaxProperties        *int64                     `json:"maxProperties,omitempty" protobuf:"bytes,21,opt,name=maxProperties"`
 	MinProperties        *int64                     `json:"minProperties,omitempty" protobuf:"bytes,22,opt,name=minProperties"`
 	Required             []string                   `json:"required,omitempty" protobuf:"bytes,23,rep,name=required"`
@@ -87,7 +89,7 @@ type JSONSchemaProps struct {
 	AdditionalItems      *JSONSchemaPropsOrBool     `json:"additionalItems,omitempty" protobuf:"bytes,33,opt,name=additionalItems"`
 	Definitions          JSONSchemaDefinitions      `json:"definitions,omitempty" protobuf:"bytes,34,opt,name=definitions"`
 	ExternalDocs         *ExternalDocumentation     `json:"externalDocs,omitempty" protobuf:"bytes,35,opt,name=externalDocs"`
-	Example              *JSON                      `json:"example,omitempty" protobuf:"bytes,36,opt,name=example"`
+	Example              *json.RawMessage           `json:"example,omitempty" protobuf:"bytes,36,opt,name=example"`
 	Nullable             bool                       `json:"nullable,omitempty" protobuf:"bytes,37,opt,name=nullable"`
 
 	// x-kubernetes-preserve-unknown-fields stops the API server
diff --git a/pkg/apis/camel/v1alpha1/kamelet_types.go b/pkg/apis/camel/v1alpha1/kamelet_types.go
index 34594b2..81557a1 100644
--- a/pkg/apis/camel/v1alpha1/kamelet_types.go
+++ b/pkg/apis/camel/v1alpha1/kamelet_types.go
@@ -58,6 +58,12 @@ type AuthorizationSpec struct {
 type KameletStatus struct {
 	Phase      KameletPhase       `json:"phase,omitempty"`
 	Conditions []KameletCondition `json:"conditions,omitempty"`
+	Properties []KameletProperty  `json:"properties,omitempty"`
+}
+
+type KameletProperty struct {
+	Name    string `json:"name,omitempty"`
+	Default string `json:"default,omitempty"`
 }
 
 // KameletCondition describes the state of a resource at a certain point.
@@ -95,11 +101,13 @@ const (
 	KameletPhaseReady KameletPhase = "Ready"
 )
 
-// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
-
 // Kamelet is the Schema for the kamelets API
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+// +k8s:openapi-gen=true
+// +genclient
+// +kubebuilder:resource:path=kamelets,scope=Namespaced,shortName=kl,categories=kamel;camel
 // +kubebuilder:subresource:status
-// +kubebuilder:resource:path=kamelets,scope=Namespaced
+// +kubebuilder:printcolumn:name="Phase",type=string,JSONPath=`.status.phase`,description="The Kamelet phase"
 type Kamelet struct {
 	metav1.TypeMeta   `json:",inline"`
 	metav1.ObjectMeta `json:"metadata,omitempty"`
diff --git a/pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go
index e6c991c..2014759 100644
--- a/pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go
+++ b/pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go
@@ -5,6 +5,8 @@
 package v1alpha1
 
 import (
+	json "encoding/json"
+
 	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
 	runtime "k8s.io/apimachinery/pkg/runtime"
 )
@@ -137,8 +139,12 @@ func (in *JSONSchemaProps) DeepCopyInto(out *JSONSchemaProps) {
 	}
 	if in.Default != nil {
 		in, out := &in.Default, &out.Default
-		*out = new(JSON)
-		(*in).DeepCopyInto(*out)
+		*out = new(json.RawMessage)
+		if **in != nil {
+			in, out := *in, *out
+			*out = make([]byte, len(*in))
+			copy(*out, *in)
+		}
 	}
 	if in.Maximum != nil {
 		in, out := &in.Maximum, &out.Maximum
@@ -177,9 +183,17 @@ func (in *JSONSchemaProps) DeepCopyInto(out *JSONSchemaProps) {
 	}
 	if in.Enum != nil {
 		in, out := &in.Enum, &out.Enum
-		*out = make([]JSON, len(*in))
+		*out = make([]*json.RawMessage, len(*in))
 		for i := range *in {
-			(*in)[i].DeepCopyInto(&(*out)[i])
+			if (*in)[i] != nil {
+				in, out := &(*in)[i], &(*out)[i]
+				*out = new(json.RawMessage)
+				if **in != nil {
+					in, out := *in, *out
+					*out = make([]byte, len(*in))
+					copy(*out, *in)
+				}
+			}
 		}
 	}
 	if in.MaxProperties != nil {
@@ -273,8 +287,12 @@ func (in *JSONSchemaProps) DeepCopyInto(out *JSONSchemaProps) {
 	}
 	if in.Example != nil {
 		in, out := &in.Example, &out.Example
-		*out = new(JSON)
-		(*in).DeepCopyInto(*out)
+		*out = new(json.RawMessage)
+		if **in != nil {
+			in, out := *in, *out
+			*out = make([]byte, len(*in))
+			copy(*out, *in)
+		}
 	}
 	if in.XPreserveUnknownFields != nil {
 		in, out := &in.XPreserveUnknownFields, &out.XPreserveUnknownFields
@@ -464,6 +482,22 @@ func (in *KameletList) DeepCopyObject() runtime.Object {
 }
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *KameletProperty) DeepCopyInto(out *KameletProperty) {
+	*out = *in
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KameletProperty.
+func (in *KameletProperty) DeepCopy() *KameletProperty {
+	if in == nil {
+		return nil
+	}
+	out := new(KameletProperty)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *KameletSpec) DeepCopyInto(out *KameletSpec) {
 	*out = *in
 	in.Definition.DeepCopyInto(&out.Definition)
@@ -515,6 +549,11 @@ func (in *KameletStatus) DeepCopyInto(out *KameletStatus) {
 			(*in)[i].DeepCopyInto(&(*out)[i])
 		}
 	}
+	if in.Properties != nil {
+		in, out := &in.Properties, &out.Properties
+		*out = make([]KameletProperty, len(*in))
+		copy(*out, *in)
+	}
 	return
 }
 
diff --git a/pkg/controller/kamelet/common.go b/pkg/controller/kamelet/common.go
new file mode 100644
index 0000000..d95b27a
--- /dev/null
+++ b/pkg/controller/kamelet/common.go
@@ -0,0 +1,48 @@
+package kamelet
+
+import (
+	"encoding/json"
+	"fmt"
+	"sort"
+
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+	"github.com/pkg/errors"
+)
+
+func updateStatus(kamelet *v1alpha1.Kamelet) (*v1alpha1.Kamelet, error) {
+	target := kamelet.DeepCopy()
+	target.Status.Phase = v1alpha1.KameletPhaseReady
+	if err := recomputeProperties(target); err != nil {
+		return nil, err
+	}
+	return target, nil
+}
+
+func recomputeProperties(kamelet *v1alpha1.Kamelet) error {
+	kamelet.Status.Properties = make([]v1alpha1.KameletProperty, 0, len(kamelet.Spec.Definition.Properties))
+	propSet := make(map[string]bool)
+	for k, v := range kamelet.Spec.Definition.Properties {
+		if propSet[k] {
+			continue
+		}
+		propSet[k] = true
+		defValue := ""
+		if v.Default != nil {
+			var val interface{}
+			if err := json.Unmarshal(*v.Default, &val); err != nil {
+				return errors.Wrapf(err, "cannot decode default value for property %q", k)
+			}
+			defValue = fmt.Sprintf("%v", val)
+		}
+		kamelet.Status.Properties = append(kamelet.Status.Properties, v1alpha1.KameletProperty{
+			Name:    k,
+			Default: defValue,
+		})
+	}
+	sort.SliceStable(kamelet.Status.Properties, func(i, j int) bool {
+		pi := kamelet.Status.Properties[i].Name
+		pj := kamelet.Status.Properties[j].Name
+		return pi < pj
+	})
+	return nil
+}
diff --git a/pkg/controller/kamelet/initialize.go b/pkg/controller/kamelet/initialize.go
index 0b3f0aa..eeae301 100644
--- a/pkg/controller/kamelet/initialize.go
+++ b/pkg/controller/kamelet/initialize.go
@@ -41,7 +41,5 @@ func (action *initializeAction) CanHandle(kamelet *v1alpha1.Kamelet) bool {
 }
 
 func (action *initializeAction) Handle(ctx context.Context, kamelet *v1alpha1.Kamelet) (*v1alpha1.Kamelet, error) {
-	target := kamelet.DeepCopy()
-	target.Status.Phase = v1alpha1.KameletPhaseReady
-	return target, nil
+	return updateStatus(kamelet)
 }
diff --git a/pkg/controller/kamelet/monitor.go b/pkg/controller/kamelet/monitor.go
index 49935d2..99e5224 100644
--- a/pkg/controller/kamelet/monitor.go
+++ b/pkg/controller/kamelet/monitor.go
@@ -41,6 +41,5 @@ func (action *monitorAction) CanHandle(kamelet *v1alpha1.Kamelet) bool {
 }
 
 func (action *monitorAction) Handle(ctx context.Context, kamelet *v1alpha1.Kamelet) (*v1alpha1.Kamelet, error) {
-	// Doing nothing for now
-	return kamelet, nil
+	return updateStatus(kamelet)
 }
diff --git a/pkg/trait/container.go b/pkg/trait/container.go
index 9c19e5e..485b302 100644
--- a/pkg/trait/container.go
+++ b/pkg/trait/container.go
@@ -21,19 +21,16 @@ import (
 	"fmt"
 	"sort"
 	"strconv"
-	"strings"
 
+	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
 	"github.com/apache/camel-k/pkg/util"
+	"github.com/apache/camel-k/pkg/util/envvar"
 	appsv1 "k8s.io/api/apps/v1"
 	"k8s.io/api/batch/v1beta1"
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/api/resource"
 	"k8s.io/apimachinery/pkg/util/intstr"
-
 	serving "knative.dev/serving/pkg/apis/serving/v1"
-
-	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
-	"github.com/apache/camel-k/pkg/util/envvar"
 )
 
 const (
@@ -195,8 +192,6 @@ func (t *containerTrait) configureContainer(e *Environment) error {
 	envvar.SetVal(&container.Env, "CAMEL_K_CONF", "/etc/camel/conf/application.properties")
 	envvar.SetVal(&container.Env, "CAMEL_K_CONF_D", "/etc/camel/conf.d")
 
-	// Configure sources
-	envvar.SetVal(&container.Env, "CAMEL_K_ROUTES", strings.Join(e.ComputeSourcesURI(), ","))
 	e.AddSourcesProperties()
 
 	t.configureResources(e, &container)
diff --git a/pkg/trait/kamelets.go b/pkg/trait/kamelets.go
index d1b3bef..05f734f 100644
--- a/pkg/trait/kamelets.go
+++ b/pkg/trait/kamelets.go
@@ -88,7 +88,7 @@ func (t *kameletsTrait) Configure(e *Environment) (bool, error) {
 		return false, nil
 	}
 
-	if !e.IntegrationInPhase(v1.IntegrationPhaseInitialization) {
+	if !e.IntegrationInPhase(v1.IntegrationPhaseInitialization, v1.IntegrationPhaseDeploying, v1.IntegrationPhaseRunning) {
 		return false, nil
 	}
 
@@ -114,11 +114,16 @@ func (t *kameletsTrait) Configure(e *Environment) (bool, error) {
 }
 
 func (t *kameletsTrait) Apply(e *Environment) error {
-	if err := t.addKamelets(e); err != nil {
-		return err
-	}
-	if err := t.addConfigurationSecrets(e); err != nil {
-		return err
+
+	if e.IntegrationInPhase(v1.IntegrationPhaseInitialization) {
+		if err := t.addKamelets(e); err != nil {
+			return err
+		}
+		if err := t.addConfigurationSecrets(e); err != nil {
+			return err
+		}
+	} else if e.IntegrationInPhase(v1.IntegrationPhaseDeploying, v1.IntegrationPhaseRunning) {
+		return t.configureApplicationProperties(e)
 	}
 	return nil
 }
@@ -150,6 +155,27 @@ func (t *kameletsTrait) addKamelets(e *Environment) error {
 	return nil
 }
 
+func (t *kameletsTrait) configureApplicationProperties(e *Environment) error {
+	for _, k := range t.getKameletKeys() {
+		var kamelet v1alpha1.Kamelet
+		key := client.ObjectKey{
+			Namespace: e.Integration.Namespace,
+			Name:      k,
+		}
+		if err := t.Client.Get(t.Ctx, key, &kamelet); err != nil {
+			return err
+		}
+
+		// Configuring defaults from Kamelet
+		for _, prop := range kamelet.Status.Properties {
+			if prop.Default != "" {
+				e.ApplicationProperties[fmt.Sprintf("camel.kamelet.%s.%s", kamelet.Name, prop.Name)] = prop.Default
+			}
+		}
+	}
+	return nil
+}
+
 func (t *kameletsTrait) addKameletAsSource(e *Environment, kamelet v1alpha1.Kamelet) error {
 	sources := make([]v1.SourceSpec, 0)
 
@@ -165,7 +191,7 @@ func (t *kameletsTrait) addKameletAsSource(e *Environment, kamelet v1alpha1.Kame
 				Content: string(flowData),
 			},
 			Language: v1.LanguageYaml,
-			Type:     v1.SourceTypeKamelet,
+			Type:     v1.SourceTypeTemplate,
 		}
 		flowSource, err = integrationSourceFromKameletSource(e, kamelet, flowSource, fmt.Sprintf("%s-kamelet-%s-flow", e.Integration.Name, kamelet.Name))
 		if err != nil {
@@ -184,7 +210,7 @@ func (t *kameletsTrait) addKameletAsSource(e *Environment, kamelet v1alpha1.Kame
 
 	kameletCounter := 0
 	for _, source := range sources {
-		if source.Type == v1.SourceTypeKamelet {
+		if source.Type == v1.SourceTypeTemplate {
 			kameletCounter++
 		}
 		replaced := false
@@ -279,7 +305,7 @@ func (t *kameletsTrait) getConfigurationKeys() []configurationKey {
 }
 
 func integrationSourceFromKameletSource(e *Environment, kamelet v1alpha1.Kamelet, source v1.SourceSpec, name string) (v1.SourceSpec, error) {
-	if source.Type == v1.SourceTypeKamelet {
+	if source.Type == v1.SourceTypeTemplate {
 		// Kamelets must be named "<kamelet-name>.extension"
 		language := source.InferLanguage()
 		source.Name = fmt.Sprintf("%s.%s", kamelet.Name, string(language))
diff --git a/pkg/trait/kamelets_test.go b/pkg/trait/kamelets_test.go
index 4f37b1d..e72ad78 100644
--- a/pkg/trait/kamelets_test.go
+++ b/pkg/trait/kamelets_test.go
@@ -115,7 +115,7 @@ func TestKameletLookup(t *testing.T) {
 	assert.Len(t, environment.Integration.Status.GeneratedSources, 1)
 	source := environment.Integration.Status.GeneratedSources[0]
 	assert.Equal(t, "timer.yaml", source.Name)
-	assert.Equal(t, "kamelet", string(source.Type))
+	assert.Equal(t, "template", string(source.Type))
 
 	assert.Equal(t, []string{"camel:log", "camel:timer"}, environment.Integration.Status.Dependencies)
 }
@@ -165,7 +165,7 @@ func TestKameletSecondarySourcesLookup(t *testing.T) {
 
 	flowSource := environment.Integration.Status.GeneratedSources[0]
 	assert.Equal(t, "timer.yaml", flowSource.Name)
-	assert.Equal(t, "kamelet", string(flowSource.Type))
+	assert.Equal(t, "template", string(flowSource.Type))
 	assert.Equal(t, "it-kamelet-timer-flow", flowSource.ContentRef)
 	assert.Equal(t, "content", flowSource.ContentKey)
 
@@ -194,7 +194,7 @@ func TestNonYAMLKameletLookup(t *testing.T) {
 						Name:    "mykamelet.groovy",
 						Content: `from("timer").to("log:info")`,
 					},
-					Type: v1.SourceTypeKamelet,
+					Type: v1.SourceTypeTemplate,
 				},
 			},
 		},
@@ -215,7 +215,7 @@ func TestNonYAMLKameletLookup(t *testing.T) {
 	assert.Len(t, environment.Integration.Status.GeneratedSources, 1)
 	source := environment.Integration.Status.GeneratedSources[0]
 	assert.Equal(t, "timer.groovy", source.Name)
-	assert.Equal(t, "kamelet", string(source.Type))
+	assert.Equal(t, "template", string(source.Type))
 }
 
 func TestErrorMultipleKameletSources(t *testing.T) {
@@ -236,7 +236,7 @@ func TestErrorMultipleKameletSources(t *testing.T) {
 						Name:    "mykamelet.groovy",
 						Content: `from("timer").to("log:info")`,
 					},
-					Type: v1.SourceTypeKamelet,
+					Type: v1.SourceTypeTemplate,
 				},
 			},
 			Flow: marshalOrFail(map[string]interface{}{
@@ -333,13 +333,13 @@ func TestMultipleKamelets(t *testing.T) {
 
 	flowSource2 := environment.Integration.Status.GeneratedSources[0]
 	assert.Equal(t, "logger.yaml", flowSource2.Name)
-	assert.Equal(t, "kamelet", string(flowSource2.Type))
+	assert.Equal(t, "template", string(flowSource2.Type))
 	assert.Equal(t, "it-kamelet-logger-flow", flowSource2.ContentRef)
 	assert.Equal(t, "content", flowSource2.ContentKey)
 
 	flowSource := environment.Integration.Status.GeneratedSources[1]
 	assert.Equal(t, "timer.yaml", flowSource.Name)
-	assert.Equal(t, "kamelet", string(flowSource.Type))
+	assert.Equal(t, "template", string(flowSource.Type))
 	assert.Equal(t, "it-kamelet-timer-flow", flowSource.ContentRef)
 	assert.Equal(t, "content", flowSource.ContentKey)
 
diff --git a/pkg/trait/knative_service_test.go b/pkg/trait/knative_service_test.go
index 9406d32..731eec9 100644
--- a/pkg/trait/knative_service_test.go
+++ b/pkg/trait/knative_service_test.go
@@ -118,7 +118,7 @@ func TestKnativeService(t *testing.T) {
 	assert.NotEmpty(t, environment.ExecutedTraits)
 	assert.NotNil(t, environment.GetTrait("knative"))
 	assert.NotNil(t, envvar.Get(environment.EnvVars, "CAMEL_KNATIVE_CONFIGURATION"))
-	assert.Equal(t, 4, environment.Resources.Size())
+	assert.Equal(t, 5, environment.Resources.Size())
 
 	s := environment.Resources.GetKnativeService(func(service *serving.Service) bool {
 		return service.Name == KnativeServiceTestName
@@ -128,8 +128,8 @@ func TestKnativeService(t *testing.T) {
 
 	spec := s.Spec.ConfigurationSpec.Template.Spec
 
-	assert.Len(t, spec.Containers[0].VolumeMounts, 5)
-	assert.Len(t, spec.Volumes, 5)
+	assert.Len(t, spec.Containers[0].VolumeMounts, 6)
+	assert.Len(t, spec.Volumes, 6)
 
 	assert.Condition(t, func() bool {
 		for _, v := range spec.Containers[0].VolumeMounts {
@@ -172,7 +172,9 @@ func TestKnativeService(t *testing.T) {
 		}
 	})
 
-	test.EnvVarHasValue(t, spec.Containers[0].Env, "CAMEL_K_ROUTES", "file:/etc/camel/sources/i-source-000/routes.js?language=js&compression=true")
+	assert.Equal(t, "file:/etc/camel/sources/i-source-000/routes.js", environment.ApplicationProperties["camel.k.sources[0].location"])
+	assert.Equal(t, "js", environment.ApplicationProperties["camel.k.sources[0].language"])
+	assert.Equal(t, "true", environment.ApplicationProperties["camel.k.sources[0].compression"])
 	test.EnvVarHasValue(t, spec.Containers[0].Env, "CAMEL_K_CONF", "/etc/camel/conf/application.properties")
 	test.EnvVarHasValue(t, spec.Containers[0].Env, "CAMEL_K_CONF_D", "/etc/camel/conf.d")
 }
diff --git a/pkg/trait/trait_test.go b/pkg/trait/trait_test.go
index bcf3519..d936c56 100644
--- a/pkg/trait/trait_test.go
+++ b/pkg/trait/trait_test.go
@@ -49,7 +49,7 @@ func TestOpenShiftTraits(t *testing.T) {
 	assert.Nil(t, env.GetTrait("service"))
 	assert.Nil(t, env.GetTrait("route"))
 	assert.NotNil(t, env.GetTrait("owner"))
-	assert.Nil(t, res.GetConfigMap(func(cm *corev1.ConfigMap) bool {
+	assert.NotNil(t, res.GetConfigMap(func(cm *corev1.ConfigMap) bool {
 		return cm.Labels["camel.apache.org/properties.type"] != ""
 	}))
 	assert.NotNil(t, res.GetDeployment(func(deployment *appsv1.Deployment) bool {
@@ -64,7 +64,7 @@ func TestOpenShiftTraitsWithWeb(t *testing.T) {
 	assert.NotNil(t, env.GetTrait("service"))
 	assert.NotNil(t, env.GetTrait("route"))
 	assert.NotNil(t, env.GetTrait("owner"))
-	assert.Nil(t, res.GetConfigMap(func(cm *corev1.ConfigMap) bool {
+	assert.NotNil(t, res.GetConfigMap(func(cm *corev1.ConfigMap) bool {
 		return cm.Labels["camel.apache.org/properties.type"] != ""
 	}))
 	assert.NotNil(t, res.GetDeployment(func(deployment *appsv1.Deployment) bool {
@@ -114,7 +114,7 @@ func TestKubernetesTraits(t *testing.T) {
 	assert.Nil(t, env.GetTrait("service"))
 	assert.Nil(t, env.GetTrait("route"))
 	assert.NotNil(t, env.GetTrait("owner"))
-	assert.Nil(t, res.GetConfigMap(func(cm *corev1.ConfigMap) bool {
+	assert.NotNil(t, res.GetConfigMap(func(cm *corev1.ConfigMap) bool {
 		return cm.Labels["camel.apache.org/properties.type"] != ""
 	}))
 	assert.NotNil(t, res.GetDeployment(func(deployment *appsv1.Deployment) bool {
@@ -129,7 +129,7 @@ func TestKubernetesTraitsWithWeb(t *testing.T) {
 	assert.NotNil(t, env.GetTrait("service"))
 	assert.Nil(t, env.GetTrait("route"))
 	assert.NotNil(t, env.GetTrait("owner"))
-	assert.Nil(t, res.GetConfigMap(func(cm *corev1.ConfigMap) bool {
+	assert.NotNil(t, res.GetConfigMap(func(cm *corev1.ConfigMap) bool {
 		return cm.Labels["camel.apache.org/properties.type"] != ""
 	}))
 	assert.NotNil(t, res.GetDeployment(func(deployment *appsv1.Deployment) bool {
diff --git a/pkg/trait/trait_types.go b/pkg/trait/trait_types.go
index c397c2f..3d38531 100644
--- a/pkg/trait/trait_types.go
+++ b/pkg/trait/trait_types.go
@@ -54,9 +54,6 @@ var (
 	// SourcesMountPath --
 	SourcesMountPath = path.Join(BasePath, "sources")
 
-	// KameletsMountPath --
-	KameletsMountPath = path.Join(BasePath, "kamelets.d")
-
 	// ResourcesMountPath --
 	ResourcesMountPath = path.Join(BasePath, "resources")
 
@@ -478,34 +475,43 @@ func (e *Environment) ComputeConfigMaps() []runtime.Object {
 	return maps
 }
 
-// ComputeSourcesURI --
-func (e *Environment) ComputeSourcesURI() []string {
-	sources := e.Integration.Sources()
-	paths := make([]string, 0, len(sources))
-
-	for i, s := range sources {
-		if s.Type == v1.SourceTypeKamelet {
-			// Kamelet information is added to application.properties
-			continue
-		}
+// AddSourcesProperties --
+func (e *Environment) AddSourcesProperties() {
+	if e.ApplicationProperties == nil {
+		e.ApplicationProperties = make(map[string]string)
+	}
+	for i, s := range e.Integration.Sources() {
 		root := path.Join(SourcesMountPath, fmt.Sprintf("i-source-%03d", i))
 
 		srcName := strings.TrimPrefix(s.Name, "/")
 		src := path.Join(root, srcName)
 		src = "file:" + src
-		interceptors := make([]string, 0, len(s.Interceptors))
+		e.ApplicationProperties[fmt.Sprintf("camel.k.sources[%d].location", i)] = src
 
-		params := make([]string, 0)
+		simpleName := srcName
+		if strings.Contains(srcName, ".") {
+			simpleName = srcName[0:strings.Index(srcName, ".")]
+		}
+		e.ApplicationProperties[fmt.Sprintf("camel.k.sources[%d].name", i)] = simpleName
+
+		for pid, p := range s.PropertyNames {
+			e.ApplicationProperties[fmt.Sprintf("camel.k.sources[%d].property-names[%d]", i, pid)] = p
+		}
+
+		if s.Type != "" {
+			e.ApplicationProperties[fmt.Sprintf("camel.k.sources[%d].type", i)] = string(s.Type)
+		}
 		if s.InferLanguage() != "" {
-			params = append(params, "language="+string(s.InferLanguage()))
+			e.ApplicationProperties[fmt.Sprintf("camel.k.sources[%d].language", i)] = string(s.InferLanguage())
 		}
 		if s.Loader != "" {
-			params = append(params, "loader="+s.Loader)
+			e.ApplicationProperties[fmt.Sprintf("camel.k.sources[%d].loader", i)] = string(s.Loader)
 		}
 		if s.Compression {
-			params = append(params, "compression=true")
+			e.ApplicationProperties[fmt.Sprintf("camel.k.sources[%d].compression", i)] = "true"
 		}
 
+		interceptors := make([]string, 0, len(s.Interceptors))
 		if s.Interceptors != nil {
 			interceptors = append(interceptors, s.Interceptors...)
 		}
@@ -513,73 +519,7 @@ func (e *Environment) ComputeSourcesURI() []string {
 			interceptors = append(interceptors, e.Interceptors...)
 		}
 		if len(interceptors) > 0 {
-			params = append(params, "interceptors="+strings.Join(interceptors, ","))
-		}
-
-		if len(params) > 0 {
-			src = fmt.Sprintf("%s?%s", src, strings.Join(params, "&"))
-		}
-
-		paths = append(paths, src)
-	}
-
-	return paths
-}
-
-// AddSourcesProperties --
-func (e *Environment) AddSourcesProperties() {
-	sources := e.Integration.Sources()
-	properties := make(map[string]string)
-
-	for _, s := range sources {
-		if s.Type == v1.SourceTypeKamelet {
-			// We compute properties only for Kamelets
-			// TODO move other sources types to this format instead of ENV_VAR
-
-			srcName := strings.TrimPrefix(s.Name, "/")
-			kameletName := srcName
-			if strings.Contains(kameletName, ".") {
-				kameletName = kameletName[0:strings.LastIndex(kameletName, ".")]
-			}
-			root := path.Join(KameletsMountPath, kameletName)
-
-			src := path.Join(root, srcName)
-			src = "file:" + src
-			properties[fmt.Sprintf("camel.k.kamelets[%s].location", kameletName)] = src
-
-			schemaName := path.Join(root, fmt.Sprintf("%s-schema.json", kameletName))
-			properties[fmt.Sprintf("camel.k.kamelets[%s].schema", kameletName)] = schemaName
-
-			if s.InferLanguage() != "" {
-				properties[fmt.Sprintf("camel.k.kamelets[%s].language", kameletName)] = string(s.InferLanguage())
-			}
-			if s.Loader != "" {
-				properties[fmt.Sprintf("camel.k.kamelets[%s].loader", kameletName)] = s.Loader
-			}
-			if s.Compression {
-				properties[fmt.Sprintf("camel.k.kamelets[%s].compression", kameletName)] = True
-			}
-
-			interceptors := make([]string, 0, len(s.Interceptors))
-			if s.Interceptors != nil {
-				interceptors = append(interceptors, s.Interceptors...)
-			}
-			if e.Interceptors != nil {
-				interceptors = append(interceptors, e.Interceptors...)
-			}
-			for i, interceptor := range interceptors {
-				properties[fmt.Sprintf("camel.k.kamelets[%s].interceptors[%d]", kameletName, i)] = interceptor
-			}
-		}
-	}
-
-	if len(properties) > 0 {
-		if e.ApplicationProperties == nil {
-			e.ApplicationProperties = properties
-		} else {
-			for k, v := range properties {
-				e.ApplicationProperties[k] = v
-			}
+			e.ApplicationProperties[fmt.Sprintf("camel.k.sources[%d].interceptors", i)] = strings.Join(interceptors, ",")
 		}
 	}
 }
@@ -596,67 +536,30 @@ func (e *Environment) ConfigureVolumesAndMounts(vols *[]corev1.Volume, mnts *[]c
 			cmName = s.ContentRef
 		}
 		resName := strings.TrimPrefix(s.Name, "/")
+		refName := fmt.Sprintf("i-source-%03d", i)
+		resPath := path.Join(SourcesMountPath, refName)
 
-		if s.Type == v1.SourceTypeKamelet {
-			kameletName := resName
-			if strings.Contains(kameletName, ".") {
-				kameletName = kameletName[0:strings.LastIndex(kameletName, ".")]
-			}
-			refName := fmt.Sprintf("i-kamelet-source-%03d", i)
-			resPath := path.Join(KameletsMountPath, kameletName)
-			schemaResName := fmt.Sprintf("%s-schema.json", kameletName)
-
-			*vols = append(*vols, corev1.Volume{
-				Name: refName,
-				VolumeSource: corev1.VolumeSource{
-					ConfigMap: &corev1.ConfigMapVolumeSource{
-						LocalObjectReference: corev1.LocalObjectReference{
-							Name: cmName,
-						},
-						Items: []corev1.KeyToPath{
-							{
-								Key:  "content",
-								Path: resName,
-							},
-							{
-								Key:  "schema",
-								Path: schemaResName,
-							},
-						},
+		*vols = append(*vols, corev1.Volume{
+			Name: refName,
+			VolumeSource: corev1.VolumeSource{
+				ConfigMap: &corev1.ConfigMapVolumeSource{
+					LocalObjectReference: corev1.LocalObjectReference{
+						Name: cmName,
 					},
-				},
-			})
-
-			*mnts = append(*mnts, corev1.VolumeMount{
-				Name:      refName,
-				MountPath: resPath,
-			})
-		} else {
-			refName := fmt.Sprintf("i-source-%03d", i)
-			resPath := path.Join(SourcesMountPath, refName)
-
-			*vols = append(*vols, corev1.Volume{
-				Name: refName,
-				VolumeSource: corev1.VolumeSource{
-					ConfigMap: &corev1.ConfigMapVolumeSource{
-						LocalObjectReference: corev1.LocalObjectReference{
-							Name: cmName,
-						},
-						Items: []corev1.KeyToPath{
-							{
-								Key:  "content",
-								Path: resName,
-							},
+					Items: []corev1.KeyToPath{
+						{
+							Key:  "content",
+							Path: resName,
 						},
 					},
 				},
-			})
+			},
+		})
 
-			*mnts = append(*mnts, corev1.VolumeMount{
-				Name:      refName,
-				MountPath: resPath,
-			})
-		}
+		*mnts = append(*mnts, corev1.VolumeMount{
+			Name:      refName,
+			MountPath: resPath,
+		})
 	}
 
 	for i, r := range e.Integration.Resources() {