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 09dd6b0d8 feat(cmd): bind .spec.traits instead of annotations
09dd6b0d8 is described below
commit 09dd6b0d810203ed524e88450b9920f864fc5cd7
Author: Pasquale Congiusti <[email protected]>
AuthorDate: Sat Nov 29 09:32:58 2025 +0100
feat(cmd): bind .spec.traits instead of annotations
Closes #6327
---
docs/modules/ROOT/pages/pipes/bind-cli.adoc | 4 +-
docs/modules/ROOT/pages/pipes/pipes.adoc | 18 +--
docs/modules/ROOT/pages/pipes/promoting.adoc | 10 +-
pkg/apis/camel/v1/common_types.go | 1 +
pkg/apis/camel/v1/pipe_types_support.go | 26 +---
pkg/apis/camel/v1/pipe_types_support_test.go | 25 ++--
pkg/cmd/bind.go | 31 +----
pkg/cmd/bind_test.go | 11 +-
pkg/cmd/promote.go | 109 ++++++----------
pkg/cmd/promote_test.go | 179 +++++++++++++++++++--------
10 files changed, 215 insertions(+), 199 deletions(-)
diff --git a/docs/modules/ROOT/pages/pipes/bind-cli.adoc
b/docs/modules/ROOT/pages/pipes/bind-cli.adoc
index d783dbf68..5133b22a6 100644
--- a/docs/modules/ROOT/pages/pipes/bind-cli.adoc
+++ b/docs/modules/ROOT/pages/pipes/bind-cli.adoc
@@ -67,7 +67,6 @@ kind: Pipe
metadata:
annotations:
camel.apache.org/operator.id: camel-k
- trait.camel.apache.org/camel.runtime-version: 3.6.0
name: timer-source-to-log-sink
namespace: camel-k
spec:
@@ -85,5 +84,8 @@ spec:
kind: Kamelet
name: timer-source
namespace: camel-k
+ traits:
+ camel:
+ runtime-version: 3.6.0
status: {}
----
diff --git a/docs/modules/ROOT/pages/pipes/pipes.adoc
b/docs/modules/ROOT/pages/pipes/pipes.adoc
index f11d0b46b..25d145f1b 100644
--- a/docs/modules/ROOT/pages/pipes/pipes.adoc
+++ b/docs/modules/ROOT/pages/pipes/pipes.adoc
@@ -67,31 +67,31 @@ In the example above we're making sure to call an
intermediate resource in order
=== Traits configuration
-Although this should not be necessarily required (the operator do all the
required configuration for you), you can tune your `Pipe` with
xref:traits:traits.adoc[traits] configuration adding `.metadata.annotations`.
Let's have a look at the following example:
+Although this should not be necessarily required (the operator do all the
required configuration for you), you can tune your `Pipe` with
xref:traits:traits.adoc[traits] configuration adding `.spec.traits` as you are
used to do with Integration. Let's have a look at the following example:
-.timer-2-log-annotation.yaml
+.timer-2-log.yaml
[source,yaml,subs="attributes+"]
----
apiVersion: camel.apache.org/v1
kind: Pipe
metadata:
- name: timer-2-log-annotation
- annotations: # <1>
- trait.camel.apache.org/logging.level: DEBUG
- trait.camel.apache.org/logging.color: "false"
+ name: timer-2-log
spec:
source:
uri: timer:foo
sink:
uri: log:bar
+ traits:
+ mount:
+ configs:
+ - configmap:my-cm
----
-<1> Include `.metadata.annotations` to specify the list of traits we want to
configure
-In this example, we've set the `logging` trait to specify certain
configuration we want to apply. You can do the same with all the traits
available, just by setting `trait.camel.apache.org/trait-name.trait-property`
with the expected value.
+In this example, we've set the `mount` trait to add a given Configmap at
runtime. You can do the same with all the traits available.
[NOTE]
====
-If you need to specify an array of values, the syntax will be
`trait.camel.apache.org/trait.conf: "[\"opt1\", \"opt2\", ...]"`
+You can use `kamel bind -t` as well.
====
== Using Kamel CLI
diff --git a/docs/modules/ROOT/pages/pipes/promoting.adoc
b/docs/modules/ROOT/pages/pipes/promoting.adoc
index 4e31ba68b..c7bde9367 100644
--- a/docs/modules/ROOT/pages/pipes/promoting.adoc
+++ b/docs/modules/ROOT/pages/pipes/promoting.adoc
@@ -32,9 +32,6 @@ kind: Pipe
metadata:
annotations:
camel.apache.org/kamelet.icon:
data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gU3ZnIFZlY3RvciBJY29ucyA6IGh0dHA6Ly93d3cub25saW5ld2ViZm9udHMuY29tL2ljb24gLS0...
- trait.camel.apache.org/camel.runtime-version: 3.8.1
- trait.camel.apache.org/container.image:
10.100.107.57/camel-k/camel-k-kit-crbhu56n5tgc73cb1ts0@sha256:e3f66b61148e77ceda8531632847b455219300d95c9e640f4924b7e69419c2b9
- trait.camel.apache.org/jvm.classpath:
dependencies/*:dependencies/app/*:dependencies/lib/boot/*:dependencies/lib/main/*:dependencies/quarkus/*
name: timer-source-to-log-sink
namespace: prod
spec:
@@ -52,6 +49,13 @@ spec:
kind: Kamelet
name: timer-source
namespace: prod
+ traits:
+ camel:
+ runtime-version: 3.8.1
+ container:
+ image:
10.100.107.57/camel-k/camel-k-kit-crbhu56n5tgc73cb1ts0@sha256:e3f66b61148e77ceda8531632847b455219300d95c9e640f4924b7e69419c2b9
+ jvm:
+ classpath:
dependencies/*:dependencies/app/*:dependencies/lib/boot/*:dependencies/lib/main/*:dependencies/quarkus/*
status: {}
----
diff --git a/pkg/apis/camel/v1/common_types.go
b/pkg/apis/camel/v1/common_types.go
index 39d7fe9c5..f70e0f5b5 100644
--- a/pkg/apis/camel/v1/common_types.go
+++ b/pkg/apis/camel/v1/common_types.go
@@ -25,6 +25,7 @@ import (
const (
// TraitAnnotationPrefix represents the prefix used for traits
annotations.
+ // Deprecated: use .spec.traits instead.
TraitAnnotationPrefix = "trait.camel.apache.org/"
// OperatorIDAnnotation operator id annotation label.
OperatorIDAnnotation = "camel.apache.org/operator.id"
diff --git a/pkg/apis/camel/v1/pipe_types_support.go
b/pkg/apis/camel/v1/pipe_types_support.go
index eee0ff853..173f74d9f 100644
--- a/pkg/apis/camel/v1/pipe_types_support.go
+++ b/pkg/apis/camel/v1/pipe_types_support.go
@@ -22,7 +22,6 @@ import (
"encoding/json"
"fmt"
- scase "github.com/stoewer/go-strcase"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
@@ -72,28 +71,9 @@ func (in *Pipe) SetOperatorID(operatorID string) {
SetAnnotation(&in.ObjectMeta, OperatorIDAnnotation, operatorID)
}
-// SetTrait converts a trait into the related annotation.
-func (in *Pipe) SetTraits(traits *Traits) error {
- var mappedTraits map[string]map[string]interface{}
- data, err := json.Marshal(traits)
- if err != nil {
- return err
- }
- err = json.Unmarshal(data, &mappedTraits)
- if err != nil {
- return err
- }
-
- if in.Annotations == nil && (len(mappedTraits) > 0) {
- in.Annotations = make(map[string]string)
- }
- for id, trait := range mappedTraits {
- for k, v := range trait {
- in.Annotations[fmt.Sprintf("%s%s.%s",
TraitAnnotationPrefix, id, scase.KebabCase(k))] = fmt.Sprintf("%v", v)
- }
- }
-
- return nil
+// SetTrait add the Trait specification to the Pipe.
+func (in *Pipe) SetTraits(traits *Traits) {
+ in.Spec.Traits = traits
}
// GetCondition returns the condition with the provided type.
diff --git a/pkg/apis/camel/v1/pipe_types_support_test.go
b/pkg/apis/camel/v1/pipe_types_support_test.go
index 312515fc5..dfa71e2a5 100644
--- a/pkg/apis/camel/v1/pipe_types_support_test.go
+++ b/pkg/apis/camel/v1/pipe_types_support_test.go
@@ -67,15 +67,22 @@ func TestSetTraits(t *testing.T) {
},
}
- expectedAnnotations := map[string]string(map[string]string{
- "trait.camel.apache.org/affinity.enabled": "true",
- "trait.camel.apache.org/affinity.pod-affinity": "true",
- "trait.camel.apache.org/knative.channel-sources": "[channel-a
channel-b]",
- "trait.camel.apache.org/knative.enabled": "true",
- })
+ expectedTraits := &Traits{
+ Affinity: &trait.AffinityTrait{
+ Trait: trait.Trait{
+ Enabled: ptr.To(true),
+ },
+ PodAffinity: ptr.To(true),
+ },
+ Knative: &trait.KnativeTrait{
+ Trait: trait.Trait{
+ Enabled: ptr.To(true),
+ },
+ ChannelSources: []string{"channel-a", "channel-b"},
+ },
+ }
pipe := NewPipe("my-pipe", "my-ns")
- err := pipe.SetTraits(&traits)
- assert.NoError(t, err)
- assert.Equal(t, expectedAnnotations, pipe.Annotations)
+ pipe.SetTraits(&traits)
+ assert.Equal(t, expectedTraits, pipe.Spec.Traits)
}
diff --git a/pkg/cmd/bind.go b/pkg/cmd/bind.go
index ed37e9e09..9d417ae34 100644
--- a/pkg/cmd/bind.go
+++ b/pkg/cmd/bind.go
@@ -232,17 +232,9 @@ func (o *bindCmdOptions) run(cmd *cobra.Command, args
[]string) error {
}
if len(o.Traits) > 0 {
- if pipe.Annotations == nil {
- pipe.Annotations = make(map[string]string)
- }
-
- for _, t := range o.Traits {
- kv := strings.SplitN(t, "=", 2)
- if len(kv) != 2 {
- return fmt.Errorf("could not parse trait
configuration %s, expected format 'trait.property=value'", t)
- }
- value :=
maybeBuildArrayNotation(pipe.Annotations[v1.TraitAnnotationPrefix+kv[0]], kv[1])
- pipe.Annotations[v1.TraitAnnotationPrefix+kv[0]] = value
+ catalog := trait.NewCatalog(client)
+ if err := trait.ConfigureTraits(o.Traits, &pipe.Spec.Traits,
catalog); err != nil {
+ return err
}
}
@@ -278,23 +270,6 @@ func (o *bindCmdOptions) run(cmd *cobra.Command, args
[]string) error {
return nil
}
-// buildArrayNotation is used to build an array annotation to support traits
array configuration
-// for example, `-t camel.properties=a=1 -t camel.properties=b=2` would
convert into annotation
-// `camel.properties=[a=1,b=2]“.
-func maybeBuildArrayNotation(array, value string) string {
- if array == "" {
- return value
- }
- // append
- if strings.HasPrefix(array, "[") && strings.HasSuffix(array, "]") {
- content := array[1:len(array)-1] + "," + value
-
- return "[" + content + "]"
- }
- // init the array notation
- return "[" + array + "," + value + "]"
-}
-
func showPipeOutput(cmd *cobra.Command, binding *v1.Pipe, outputFormat string,
scheme runtime.ObjectTyper) error {
printer := printers.NewTypeSetter(scheme)
printer.Delegate = &kubernetes.CLIPrinter{
diff --git a/pkg/cmd/bind_test.go b/pkg/cmd/bind_test.go
index 1a90437e9..956d54fa9 100644
--- a/pkg/cmd/bind_test.go
+++ b/pkg/cmd/bind_test.go
@@ -181,13 +181,16 @@ kind: Pipe
metadata:
annotations:
camel.apache.org/operator.id: camel-k
- trait.camel.apache.org/mount.configs: configmap:my-cm
name: my-to-my
spec:
sink:
uri: my:dst
source:
uri: my:src
+ traits:
+ mount:
+ configs:
+ - configmap:my-cm
status: {}
`, output)
}
@@ -204,13 +207,17 @@ kind: Pipe
metadata:
annotations:
camel.apache.org/operator.id: camel-k
- trait.camel.apache.org/camel.properties: '[a=1,b=2]'
name: my-to-my
spec:
sink:
uri: my:dst
source:
uri: my:src
+ traits:
+ camel:
+ properties:
+ - a=1
+ - b=2
status: {}
`, output)
}
diff --git a/pkg/cmd/promote.go b/pkg/cmd/promote.go
index b9d1e5abe..e7990a081 100644
--- a/pkg/cmd/promote.go
+++ b/pkg/cmd/promote.go
@@ -142,10 +142,7 @@ func (o *promoteCmdOptions) run(cmd *cobra.Command, args
[]string) error {
// Pipe promotion
if promotePipe {
- destPipe, err := o.editPipe(sourcePipe, sourceIntegration,
sourceKit)
- if err != nil {
- return err
- }
+ destPipe := o.editPipe(sourcePipe, sourceIntegration, sourceKit)
if o.OutputFormat != "" {
return showPipeOutput(cmd, destPipe, o.OutputFormat,
c.GetScheme())
}
@@ -265,7 +262,7 @@ func (o *promoteCmdOptions) editIntegration(it
*v1.Integration, kit *v1.Integrat
dstIt.Spec.Traits.JVM = &traitv1.JVMTrait{}
}
jvmTrait := dstIt.Spec.Traits.JVM
- mergedClasspath := getClasspath(kit, jvmTrait.Classpath)
+ mergedClasspath := getClasspath(kit, jvmTrait)
jvmTrait.Classpath = mergedClasspath
// We must also set the runtime version so we pin it to the
given catalog on which
// the container image was built
@@ -279,7 +276,11 @@ func (o *promoteCmdOptions) editIntegration(it
*v1.Integration, kit *v1.Integrat
}
// getClasspath merges the classpath required by the kit with any value
provided in the trait.
-func getClasspath(kit *v1.IntegrationKit, jvmTraitClasspath string) string {
+func getClasspath(kit *v1.IntegrationKit, jvmTraitSpec *traitv1.JVMTrait)
string {
+ jvmTraitClasspath := ""
+ if jvmTraitSpec != nil {
+ jvmTraitClasspath = jvmTraitSpec.Classpath
+ }
kitClasspathSet := kit.Status.GetDependenciesPaths()
if !kitClasspathSet.IsEmpty() {
if jvmTraitClasspath != "" {
@@ -335,7 +336,7 @@ func cloneLabels(lbs map[string]string) map[string]string {
return newMap
}
-func (o *promoteCmdOptions) editPipe(kb *v1.Pipe, it *v1.Integration, kit
*v1.IntegrationKit) (*v1.Pipe, error) {
+func (o *promoteCmdOptions) editPipe(kb *v1.Pipe, it *v1.Integration, kit
*v1.IntegrationKit) *v1.Pipe {
contImage := it.Status.Image
// Pipe
dst := v1.NewPipe(o.To, kb.Name)
@@ -354,11 +355,12 @@ func (o *promoteCmdOptions) editPipe(kb *v1.Pipe, it
*v1.Integration, kit *v1.In
// We must provide the classpath expected for the
IntegrationKit. This is calculated dynamically and
// would get lost when creating the non managed build
Integration. For this reason
// we must report it in the promoted Integration.
- mergedClasspath := getClasspath(kit,
dst.Annotations[v1.TraitAnnotationPrefix+"jvm.classpath"])
if traits.JVM == nil {
traits.JVM = &traitv1.JVMTrait{}
}
- traits.JVM.Classpath = mergedClasspath
+ jvmTrait := traits.JVM
+ mergedClasspath := getClasspath(kit, jvmTrait)
+ jvmTrait.Classpath = mergedClasspath
// We must also set the runtime version so we pin it to the
given catalog on which
// the container image was built
if traits.Camel == nil {
@@ -366,9 +368,8 @@ func (o *promoteCmdOptions) editPipe(kb *v1.Pipe, it
*v1.Integration, kit *v1.In
}
traits.Camel.RuntimeVersion = kit.Status.RuntimeVersion
}
- if err := dst.SetTraits(traits); err != nil {
- return nil, err
- }
+ dst.SetTraits(traits)
+
if dst.Spec.Source.Ref != nil {
dst.Spec.Source.Ref.Namespace = o.To
}
@@ -383,7 +384,7 @@ func (o *promoteCmdOptions) editPipe(kb *v1.Pipe, it
*v1.Integration, kit *v1.In
}
}
- return &dst, nil
+ return &dst
}
func (o *promoteCmdOptions) replaceResource(res k8sclient.Object) (bool,
error) {
@@ -481,10 +482,32 @@ patches:
// getIntegrationPatch will filter those traits/configuration we want to
include in the Integration patch.
func getIntegrationPatch(baseIt *v1.Integration) *v1.Integration {
+ patchedTraits := patchTraits(baseIt.Spec.Traits)
+
+ patchedIt := v1.NewIntegration("", baseIt.Name)
+ patchedIt.Spec = v1.IntegrationSpec{
+ Traits: patchedTraits,
+ }
+
+ return &patchedIt
+}
+
+// getPipePatch will filter those traits/configuration we want to include in
the Pipe patch.
+func getPipePatch(basePipe *v1.Pipe) *v1.Pipe {
+ patchedTraits := patchTraits(*basePipe.Spec.Traits)
+
+ patchedPipe := v1.NewPipe("", basePipe.Name)
+ patchedPipe.Spec = v1.PipeSpec{
+ Traits: &patchedTraits,
+ }
+
+ return &patchedPipe
+}
+
+func patchTraits(baseTraits v1.Traits) v1.Traits {
patchedTraits := v1.Traits{}
- baseTraits := baseIt.Spec.Traits
if baseTraits.Affinity != nil {
- patchedTraits.Affinity = baseIt.Spec.Traits.Affinity
+ patchedTraits.Affinity = baseTraits.Affinity
}
if baseTraits.Camel != nil && baseTraits.Camel.Properties != nil {
patchedTraits.Camel = &traitv1.CamelTrait{
@@ -520,15 +543,10 @@ func getIntegrationPatch(baseIt *v1.Integration)
*v1.Integration {
}
}
if baseTraits.Toleration != nil {
- patchedTraits.Toleration = baseIt.Spec.Traits.Toleration
+ patchedTraits.Toleration = baseTraits.Toleration
}
- patchedIt := v1.NewIntegration("", baseIt.Name)
- patchedIt.Spec = v1.IntegrationSpec{
- Traits: patchedTraits,
- }
-
- return &patchedIt
+ return patchedTraits
}
// appendKustomizePipe creates a Kustomize GitOps based directory structure
for the chosen Pipe.
@@ -593,50 +611,3 @@ patches:
return err
}
-
-// getPipePatch will filter those traits/configuration we want to include in
the Pipe patch.
-func getPipePatch(basePipe *v1.Pipe) *v1.Pipe {
- patchedPipe := v1.NewPipe("", basePipe.Name)
- patchedPipe.Annotations = basePipe.Annotations
- // Only keep those traits we want to include in the patch
- for kAnn := range basePipe.Annotations {
- if strings.HasPrefix(kAnn, v1.TraitAnnotationPrefix) {
- if !isPipeTraitPatch(kAnn) {
- delete(basePipe.Annotations, kAnn)
- }
- }
- }
-
- return &patchedPipe
-}
-
-// isPipeTraitPatch returns true if it belongs to the list of the opinionated
traits we want to keep in the patch.
-func isPipeTraitPatch(keyAnnotation string) bool {
- if strings.HasPrefix(keyAnnotation,
v1.TraitAnnotationPrefix+"affinity") {
- return true
- }
- if keyAnnotation == v1.TraitAnnotationPrefix+"camel.properties" {
- return true
- }
- if strings.HasPrefix(keyAnnotation,
v1.TraitAnnotationPrefix+"container.request") ||
- strings.HasPrefix(keyAnnotation,
v1.TraitAnnotationPrefix+"container.limit") {
- return true
- }
- if keyAnnotation == v1.TraitAnnotationPrefix+"environment.vars" {
- return true
- }
- if keyAnnotation == v1.TraitAnnotationPrefix+"jvm.options" {
- return true
- }
- if strings.HasPrefix(keyAnnotation,
v1.TraitAnnotationPrefix+"mount.configs") ||
- strings.HasPrefix(keyAnnotation,
v1.TraitAnnotationPrefix+"mount.resources") ||
- strings.HasPrefix(keyAnnotation,
v1.TraitAnnotationPrefix+"mount.volumes") ||
- strings.HasPrefix(keyAnnotation,
v1.TraitAnnotationPrefix+"mount.empty-dirs") {
- return true
- }
- if strings.HasPrefix(keyAnnotation,
v1.TraitAnnotationPrefix+"toleration") {
- return true
- }
-
- return false
-}
diff --git a/pkg/cmd/promote_test.go b/pkg/cmd/promote_test.go
index fbbb44e7c..4c55880db 100644
--- a/pkg/cmd/promote_test.go
+++ b/pkg/cmd/promote_test.go
@@ -154,15 +154,18 @@ func TestPipeDryRun(t *testing.T) {
assert.Equal(t, `apiVersion: camel.apache.org/v1
kind: Pipe
metadata:
- annotations:
- trait.camel.apache.org/camel.runtime-version: 1.2.3
- trait.camel.apache.org/container.image: my-special-image
- trait.camel.apache.org/jvm.classpath:
/path/to/artifact-1/*:/path/to/artifact-2/*
name: my-pipe-test
namespace: prod-namespace
spec:
sink: {}
source: {}
+ traits:
+ camel:
+ runtimeVersion: 1.2.3
+ container:
+ image: my-special-image
+ jvm:
+ classpath: /path/to/artifact-1/*:/path/to/artifact-2/*
status: {}
`, output)
}
@@ -254,9 +257,6 @@ kind: Pipe
metadata:
annotations:
my-annotation: my-value
- trait.camel.apache.org/camel.runtime-version: 1.2.3
- trait.camel.apache.org/container.image: my-special-image
- trait.camel.apache.org/jvm.classpath:
/path/to/artifact-1/*:/path/to/artifact-2/*
labels:
my-label: my-value
name: my-pipe-test
@@ -264,6 +264,13 @@ metadata:
spec:
sink: {}
source: {}
+ traits:
+ camel:
+ runtimeVersion: 1.2.3
+ container:
+ image: my-special-image
+ jvm:
+ classpath: /path/to/artifact-1/*:/path/to/artifact-2/*
status: {}
`, output)
}
@@ -442,9 +449,6 @@ kind: Pipe
metadata:
annotations:
my-annotation: my-value
- trait.camel.apache.org/camel.runtime-version: 1.2.3
- trait.camel.apache.org/container.image: my-special-image
- trait.camel.apache.org/jvm.classpath:
/path/to/artifact-1/*:/path/to/artifact-2/*
labels:
my-label: my-value
name: my-pipe-test
@@ -452,6 +456,13 @@ metadata:
spec:
sink: {}
source: {}
+ traits:
+ camel:
+ runtimeVersion: 1.2.3
+ container:
+ image: my-special-image
+ jvm:
+ classpath: /path/to/artifact-1/*:/path/to/artifact-2/*
status: {}
`, output)
}
@@ -605,50 +616,83 @@ kind: Pipe
metadata:
annotations:
my-annotation: my-value
- trait.camel.apache.org/affinity.node-affinity-labels: '[node1,node2]'
- trait.camel.apache.org/camel.properties: '[a=1]'
- trait.camel.apache.org/camel.runtime-version: 1.2.3
- trait.camel.apache.org/container.image: my-special-image
- trait.camel.apache.org/container.image-pull-policy: Always
- trait.camel.apache.org/container.limit-cpu: "2"
- trait.camel.apache.org/container.limit-memory: 1024Mi
- trait.camel.apache.org/container.request-cpu: "1"
- trait.camel.apache.org/container.request-memory: 2048Mi
- trait.camel.apache.org/environment.vars: '[MYVAR=1]'
- trait.camel.apache.org/jvm.classpath:
/path/to/artifact-1/*:/path/to/artifact-2/*
- trait.camel.apache.org/jvm.jar: my.jar
- trait.camel.apache.org/jvm.options: '[-XMX 123]'
- trait.camel.apache.org/mount.resources:
'[configmap:my-cm,secret:my-sec/my-key@/tmp/file.txt]'
- trait.camel.apache.org/service.auto: "false"
- trait.camel.apache.org/toleration.taints: '[mytaints:true]'
labels:
my-label: my-value
name: my-pipe-test
spec:
sink: {}
source: {}
+ traits:
+ affinity:
+ nodeAffinityLabels:
+ - my-node
+ camel:
+ properties:
+ - my.property=val
+ runtimeVersion: 1.2.3
+ container:
+ image: my-special-image
+ imagePullPolicy: Always
+ limitCPU: "1"
+ limitMemory: 1024Mi
+ port: 2000
+ requestCPU: "0.5"
+ requestMemory: 512Mi
+ environment:
+ vars:
+ - MY_VAR=val
+ jvm:
+ classpath: /path/to/artifact-1/*:/path/to/artifact-2/*
+ jar: my.jar
+ options:
+ - -XMX 123
+ mount:
+ configs:
+ - configmap:my-cm
+ - secret:my-sec
+ service:
+ annotations:
+ my-annotation: "123"
+ auto: false
+ enabled: true
+ toleration:
+ taints:
+ - taint1:true
status: {}
`
const expectedGitOpsPipePatch = `apiVersion: camel.apache.org/v1
kind: Pipe
metadata:
- annotations:
- my-annotation: my-value
- trait.camel.apache.org/affinity.node-affinity-labels: '[node1,node2]'
- trait.camel.apache.org/camel.properties: '[a=1]'
- trait.camel.apache.org/container.limit-cpu: "2"
- trait.camel.apache.org/container.limit-memory: 1024Mi
- trait.camel.apache.org/container.request-cpu: "1"
- trait.camel.apache.org/container.request-memory: 2048Mi
- trait.camel.apache.org/environment.vars: '[MYVAR=1]'
- trait.camel.apache.org/jvm.options: '[-XMX 123]'
- trait.camel.apache.org/mount.resources:
'[configmap:my-cm,secret:my-sec/my-key@/tmp/file.txt]'
- trait.camel.apache.org/toleration.taints: '[mytaints:true]'
name: my-pipe-test
spec:
sink: {}
source: {}
+ traits:
+ affinity:
+ nodeAffinityLabels:
+ - my-node
+ camel:
+ properties:
+ - my.property=val
+ container:
+ limitCPU: "1"
+ limitMemory: 1024Mi
+ requestCPU: "0.5"
+ requestMemory: 512Mi
+ environment:
+ vars:
+ - MY_VAR=val
+ jvm:
+ options:
+ - -XMX 123
+ mount:
+ configs:
+ - configmap:my-cm
+ - secret:my-sec
+ toleration:
+ taints:
+ - taint1:true
status: {}
`
@@ -661,34 +705,59 @@ func TestPipeGitOps(t *testing.T) {
dstPlatform.Status.Version = defaults.Version
dstPlatform.Status.Build.RuntimeVersion = defaults.DefaultRuntimeVersion
dstPlatform.Status.Phase = v1.IntegrationPlatformPhaseReady
- defaultKB := nominalPipe("my-pipe-test")
- defaultKB.Annotations = map[string]string{
+ defaultPipe := nominalPipe("my-pipe-test")
+ defaultPipe.Annotations = map[string]string{
"camel.apache.org/operator.id": "camel-k",
"my-annotation": "my-value",
- v1.TraitAnnotationPrefix + "affinity.node-affinity-labels":
"[node1,node2]",
- v1.TraitAnnotationPrefix + "camel.properties":
"[a=1]",
- v1.TraitAnnotationPrefix + "container.limit-cpu": "2",
- v1.TraitAnnotationPrefix + "container.limit-memory":
"1024Mi",
- v1.TraitAnnotationPrefix + "container.request-cpu": "1",
- v1.TraitAnnotationPrefix + "container.request-memory":
"2048Mi",
- v1.TraitAnnotationPrefix + "container.image-pull-policy":
"Always",
- v1.TraitAnnotationPrefix + "environment.vars":
"[MYVAR=1]",
- v1.TraitAnnotationPrefix + "jvm.options":
"[-XMX 123]",
- v1.TraitAnnotationPrefix + "jvm.jar":
"my.jar",
- v1.TraitAnnotationPrefix + "mount.resources":
"[configmap:my-cm,secret:my-sec/my-key@/tmp/file.txt]",
- v1.TraitAnnotationPrefix + "service.auto":
"false",
- v1.TraitAnnotationPrefix + "toleration.taints":
"[mytaints:true]",
}
- defaultKB.Labels = map[string]string{
+ defaultPipe.Labels = map[string]string{
"my-label": "my-value",
}
defaultIntegration, defaultKit := nominalIntegration("my-pipe-test")
+ defaultIntegration.Status.Traits = &v1.Traits{
+ Affinity: &trait.AffinityTrait{
+ NodeAffinityLabels: []string{"my-node"},
+ },
+ Camel: &trait.CamelTrait{
+ Properties: []string{"my.property=val"},
+ },
+ Container: &trait.ContainerTrait{
+ LimitCPU: "1",
+ LimitMemory: "1024Mi",
+ RequestCPU: "0.5",
+ RequestMemory: "512Mi",
+ Port: 2000,
+ ImagePullPolicy: corev1.PullAlways,
+ },
+ Environment: &trait.EnvironmentTrait{
+ Vars: []string{"MY_VAR=val"},
+ },
+ JVM: &trait.JVMTrait{
+ Jar: "my.jar",
+ Options: []string{"-XMX 123"},
+ },
+ Mount: &trait.MountTrait{
+ Configs: []string{"configmap:my-cm", "secret:my-sec"},
+ },
+ Service: &trait.ServiceTrait{
+ Trait: trait.Trait{
+ Enabled: ptr.To(true),
+ },
+ Auto: ptr.To(false),
+ Annotations: map[string]string{
+ "my-annotation": "123",
+ },
+ },
+ Toleration: &trait.TolerationTrait{
+ Taints: []string{"taint1:true"},
+ },
+ }
srcCatalog := createTestCamelCatalog(srcPlatform)
dstCatalog := createTestCamelCatalog(dstPlatform)
tmpDir := t.TempDir()
- _, promoteCmd, _ := initializePromoteCmdOptions(t, &srcPlatform,
&dstPlatform, &defaultKB, &defaultIntegration, &defaultKit, &srcCatalog,
&dstCatalog)
+ _, promoteCmd, _ := initializePromoteCmdOptions(t, &srcPlatform,
&dstPlatform, &defaultPipe, &defaultIntegration, &defaultKit, &srcCatalog,
&dstCatalog)
output, err := ExecuteCommand(promoteCmd, cmdPromote, "my-pipe-test",
"--to", "prod-namespace", "--export-gitops-dir", tmpDir, "-n", "default")
require.NoError(t, err)
assert.Contains(t, output, `Exported a Kustomize based Gitops
directory`)