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

squakez 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 25479a76d Fix #6663: skip auto-inferred trait defaults in 
.status.traits (#6667)
25479a76d is described below

commit 25479a76d3002677d616ba5ac75002f8c46fd6b4
Author: Davy <[email protected]>
AuthorDate: Wed Jun 10 23:05:29 2026 -0700

    Fix #6663: skip auto-inferred trait defaults in .status.traits (#6667)
    
    * fix(trait): stop auto-inferred defaults from leaking into .status.traits
    
    Fixes #6663
---
 pkg/trait/container.go             | 17 +++++--
 pkg/trait/container_test.go        |  2 +-
 pkg/trait/mount_test.go            |  2 +-
 pkg/trait/route_test.go            |  4 +-
 pkg/trait/security_context_test.go |  2 +-
 pkg/trait/service.go               |  5 +-
 pkg/trait/service_test.go          |  5 +-
 pkg/trait/trait_test.go            | 96 ++++++++++++++++++++++++++++++++++++++
 8 files changed, 119 insertions(+), 14 deletions(-)

diff --git a/pkg/trait/container.go b/pkg/trait/container.go
index 77fa58fdf..db817188e 100644
--- a/pkg/trait/container.go
+++ b/pkg/trait/container.go
@@ -66,6 +66,7 @@ type containerTrait struct {
        traitv1.ContainerTrait `property:",squash"`
 
        containerPorts []containerPort
+       expose         *bool
 }
 
 // containerPort is supporting port parsing.
@@ -93,7 +94,7 @@ func (t *containerTrait) Configure(e *Environment) (bool, 
*TraitCondition, error
        if ptr.Deref(t.Auto, true) {
                if t.Expose == nil {
                        if e.Resources.GetServiceForIntegration(e.Integration) 
!= nil {
-                               t.Expose = new(true)
+                               t.expose = new(true)
                        }
                }
        }
@@ -214,7 +215,7 @@ func (t *containerTrait) configureContainer(e *Environment) 
error {
                // Knative does not like anybody touching the container ports
                t.configurePorts(&container)
        }
-       if knative || ptr.Deref(t.Expose, false) {
+       if knative || t.isExpose() {
                t.configureService(e, &container, knative)
        }
        t.configureCapabilities(e)
@@ -356,9 +357,7 @@ func (t *containerTrait) setSecurityContext(e *Environment, 
container *corev1.Co
                return err
        }
 
-       t.RunAsUser = runAsUser
-
-       sc.RunAsUser = t.RunAsUser
+       sc.RunAsUser = runAsUser
        container.SecurityContext = &sc
 
        return nil
@@ -386,6 +385,14 @@ func (t *containerTrait) getUser(e *Environment) (*int64, 
error) {
        return runAsUser, nil
 }
 
+func (t *containerTrait) isExpose() bool {
+       if t.Expose != nil {
+               return *t.Expose
+       }
+
+       return ptr.Deref(t.expose, false)
+}
+
 func (t *containerTrait) getPort() int32 {
        if t.Port == 0 {
                return defaultContainerPort
diff --git a/pkg/trait/container_test.go b/pkg/trait/container_test.go
index 7a5465ced..c90db6c6d 100644
--- a/pkg/trait/container_test.go
+++ b/pkg/trait/container_test.go
@@ -144,7 +144,7 @@ func TestContainerWithOpenshift(t *testing.T) {
        conditions, traits, err := traitCatalog.apply(&environment)
 
        require.NoError(t, err)
-       assert.NotEmpty(t, traits)
+       assert.Empty(t, traits)
        assert.NotEmpty(t, conditions)
        assert.NotEmpty(t, environment.ExecutedTraits)
        assert.NotNil(t, environment.GetTrait("deployment"))
diff --git a/pkg/trait/mount_test.go b/pkg/trait/mount_test.go
index 55bc076b9..7753fd544 100644
--- a/pkg/trait/mount_test.go
+++ b/pkg/trait/mount_test.go
@@ -47,7 +47,7 @@ func TestMountVolumesEmpty(t *testing.T) {
        conditions, traits, err := traitCatalog.apply(environment)
 
        require.NoError(t, err)
-       assert.NotEmpty(t, traits)
+       assert.Empty(t, traits)
        assert.NotEmpty(t, conditions)
        assert.NotEmpty(t, environment.ExecutedTraits)
        assert.NotNil(t, environment.GetTrait("mount"))
diff --git a/pkg/trait/route_test.go b/pkg/trait/route_test.go
index 26590b9e3..4be9d133c 100644
--- a/pkg/trait/route_test.go
+++ b/pkg/trait/route_test.go
@@ -198,7 +198,7 @@ func TestRoute_Default(t *testing.T) {
 
        conditions, traits, err := traitsCatalog.apply(environment)
        require.NoError(t, err)
-       assert.NotEmpty(t, traits)
+       assert.Empty(t, traits)
        assert.NotEmpty(t, conditions)
        assert.NotEmpty(t, environment.ExecutedTraits)
        assert.NotNil(t, environment.GetTrait("container"))
@@ -235,7 +235,7 @@ func TestRoute_Disabled(t *testing.T) {
        traitsCatalog := environment.Catalog
        conditions, traits, err := traitsCatalog.apply(environment)
        require.NoError(t, err)
-       assert.NotEmpty(t, traits)
+       assert.Empty(t, traits)
        assert.Contains(t, conditions, expectedCondition)
        assert.NotEmpty(t, environment.ExecutedTraits)
        assert.Nil(t, environment.GetTrait("route"))
diff --git a/pkg/trait/security_context_test.go 
b/pkg/trait/security_context_test.go
index bc3331d06..c70130be2 100644
--- a/pkg/trait/security_context_test.go
+++ b/pkg/trait/security_context_test.go
@@ -78,7 +78,7 @@ func TestDefaultPodOpenshiftSecurityContext(t *testing.T) {
        conditions, traits, err := traitCatalog.apply(environment)
 
        require.NoError(t, err)
-       assert.NotEmpty(t, traits)
+       assert.Empty(t, traits)
        assert.NotEmpty(t, conditions)
        assert.NotEmpty(t, environment.ExecutedTraits)
        assert.NotNil(t, environment.GetTrait("deployment"))
diff --git a/pkg/trait/service.go b/pkg/trait/service.go
index 6de61b7dc..336d5b957 100644
--- a/pkg/trait/service.go
+++ b/pkg/trait/service.go
@@ -86,6 +86,7 @@ func (t *serviceTrait) Configure(e *Environment) (bool, 
*TraitCondition, error)
                return false, nil, nil
        }
 
+       enabled := ptr.Deref(t.Enabled, false)
        if ptr.Deref(t.Auto, true) {
                exposeHTTPServices, err := e.ConsumeMeta(false, func(meta 
metadata.IntegrationMetadata) bool {
                        return meta.ExposesHTTPServices
@@ -103,7 +104,7 @@ func (t *serviceTrait) Configure(e *Environment) (bool, 
*TraitCondition, error)
                        return false, condition, err
                }
 
-               t.Enabled = new(exposeHTTPServices)
+               enabled = exposeHTTPServices
        }
 
        servicePorts, err := t.parseServicePorts()
@@ -112,7 +113,7 @@ func (t *serviceTrait) Configure(e *Environment) (bool, 
*TraitCondition, error)
        }
        t.servicePorts = servicePorts
 
-       return ptr.Deref(t.Enabled, false) || len(t.servicePorts) > 0, nil, nil
+       return enabled || len(t.servicePorts) > 0, nil, nil
 }
 
 func (t *serviceTrait) Apply(e *Environment) error {
diff --git a/pkg/trait/service_test.go b/pkg/trait/service_test.go
index 5afd3625b..74ad9b5e0 100644
--- a/pkg/trait/service_test.go
+++ b/pkg/trait/service_test.go
@@ -578,11 +578,11 @@ func 
TestServiceWithKnativeServiceDisabledInIntegrationPlatform(t *testing.T) {
        conditions, traits, err := traitCatalog.apply(&environment)
 
        require.NoError(t, err)
-       assert.NotEmpty(t, traits)
        assert.Contains(t, conditions, expectedCondition)
        assert.NotEmpty(t, environment.ExecutedTraits)
        assert.NotNil(t, environment.GetTrait(serviceTraitID))
        assert.Nil(t, environment.GetTrait(knativeServiceTraitID))
+       assert.Nil(t, traits.Service)
 }
 
 func TestServiceAutoConfiguration(t *testing.T) {
@@ -633,7 +633,8 @@ func TestServiceAutoConfiguration(t *testing.T) {
        }
        _, traits, err := traitCatalog.apply(&environment)
        require.NoError(t, err)
-       assert.Equal(t, ptr.To(true), traits.Service.Enabled)
+       assert.NotNil(t, environment.GetTrait(serviceTraitID))
+       assert.Nil(t, traits.Service)
 }
 
 func TestServiceAnnotationsAndLables(t *testing.T) {
diff --git a/pkg/trait/trait_test.go b/pkg/trait/trait_test.go
index 9fb4f7598..550f06f59 100644
--- a/pkg/trait/trait_test.go
+++ b/pkg/trait/trait_test.go
@@ -345,6 +345,102 @@ func TestDefaultIntegrationErrorTraitsSetting(t 
*testing.T) {
        testDefaultIntegrationPhaseTraitsSetting(t, v1.IntegrationPhaseError)
 }
 
+func TestAutoInferredServiceTraitsDoNotLeakIntoStatus(t *testing.T) {
+       it := &v1.Integration{
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:      "my-it",
+                       Namespace: "ns",
+               },
+               Spec: v1.IntegrationSpec{
+                       Sources: []v1.SourceSpec{
+                               {
+                                       DataSpec: v1.DataSpec{
+                                               Name:    "file.java",
+                                               Content: 
`from("servlet:http").to("log:info")`,
+                                       },
+                                       Language: v1.LanguageJavaSource,
+                               },
+                       },
+               },
+               Status: v1.IntegrationStatus{
+                       Phase: v1.IntegrationPhaseRunning,
+                       Conditions: []v1.IntegrationCondition{
+                               {
+                                       Type:   
v1.IntegrationConditionDeploymentAvailable,
+                                       Status: corev1.ConditionTrue,
+                               },
+                       },
+               },
+       }
+       // Load the default catalog
+       camelCatalogData, err := 
resources.Resource(fmt.Sprintf("/resources/camel-catalog-%s.yaml", 
defaults.CamelKRuntimeCatalogVersion))
+       require.NoError(t, err)
+       var cat v1.CamelCatalog
+       err = yaml.Unmarshal(camelCatalogData, &cat)
+       require.NoError(t, err)
+       cat.Namespace = "default"
+       platform.SingletonPlatform.CatalogNamespace = cat.Namespace
+
+       client, err := internal.NewFakeClient(&cat)
+       require.NoError(t, err)
+       env, err := Apply(context.Background(), client, it, nil)
+       require.NoError(t, err)
+       require.NotNil(t, env.Resources.GetServiceForIntegration(it))
+       assert.Equal(t, &v1.Traits{}, env.Integration.Status.Traits)
+}
+
+func TestUserSpecifiedTraitValuesStillAppearInStatus(t *testing.T) {
+       it := &v1.Integration{
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:      "my-it",
+                       Namespace: "ns",
+               },
+               Spec: v1.IntegrationSpec{
+                       Sources: []v1.SourceSpec{
+                               {
+                                       DataSpec: v1.DataSpec{
+                                               Name:    "file.java",
+                                               Content: 
`from("servlet:http").to("log:info")`,
+                                       },
+                                       Language: v1.LanguageJavaSource,
+                               },
+                       },
+                       Traits: v1.Traits{
+                               Container: &traitv1.ContainerTrait{
+                                       Port: 9090,
+                               },
+                       },
+               },
+               Status: v1.IntegrationStatus{
+                       Phase: v1.IntegrationPhaseRunning,
+                       Conditions: []v1.IntegrationCondition{
+                               {
+                                       Type:   
v1.IntegrationConditionDeploymentAvailable,
+                                       Status: corev1.ConditionTrue,
+                               },
+                       },
+               },
+       }
+       camelCatalogData, err := 
resources.Resource(fmt.Sprintf("/resources/camel-catalog-%s.yaml", 
defaults.CamelKRuntimeCatalogVersion))
+       require.NoError(t, err)
+       var cat v1.CamelCatalog
+       err = yaml.Unmarshal(camelCatalogData, &cat)
+       require.NoError(t, err)
+       cat.Namespace = "default"
+       platform.SingletonPlatform.CatalogNamespace = cat.Namespace
+
+       client, err := internal.NewFakeClient(&cat)
+       require.NoError(t, err)
+       env, err := Apply(context.Background(), client, it, nil)
+       require.NoError(t, err)
+       require.NotNil(t, env.Resources.GetServiceForIntegration(it))
+       assert.Equal(t, &v1.Traits{
+               Container: &traitv1.ContainerTrait{
+                       Port: 9090,
+               },
+       }, env.Integration.Status.Traits)
+}
+
 func TestIntegrationTraitsSetting(t *testing.T) {
        it := &v1.Integration{
                ObjectMeta: metav1.ObjectMeta{

Reply via email to