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 58c4fdac8 fix(knative): enable service container port
58c4fdac8 is described below

commit 58c4fdac889eaccb938aa4b26b24116842d37ed6
Author: Pasquale Congiusti <pasquale.congiu...@gmail.com>
AuthorDate: Wed Mar 27 10:57:17 2024 +0100

    fix(knative): enable service container port
    
    The container port was skipped in case of a Knative service, as the Service 
resource is missing in such case.
---
 pkg/trait/container.go      | 100 +++++++++++++++-------------------
 pkg/trait/container_test.go | 127 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 169 insertions(+), 58 deletions(-)

diff --git a/pkg/trait/container.go b/pkg/trait/container.go
index b58842df1..7d32a06d6 100644
--- a/pkg/trait/container.go
+++ b/pkg/trait/container.go
@@ -176,57 +176,36 @@ func (t *containerTrait) configureContainer(e 
*Environment) error {
        if e.ApplicationProperties == nil {
                e.ApplicationProperties = make(map[string]string)
        }
-
        container := corev1.Container{
                Name:  t.Name,
                Image: e.Integration.Status.Image,
                Env:   make([]corev1.EnvVar, 0),
        }
-
        if t.ImagePullPolicy != "" {
                container.ImagePullPolicy = t.ImagePullPolicy
        }
-
        // combine Environment of integration with platform, kit, integration
        for _, env := range e.collectConfigurationPairs("env") {
                envvar.SetVal(&container.Env, env.Name, env.Value)
        }
-
        envvar.SetVal(&container.Env, digest.IntegrationDigestEnvVar, 
e.Integration.Status.Digest)
        envvar.SetVal(&container.Env, "CAMEL_K_CONF", 
filepath.Join(camel.BasePath, "application.properties"))
        envvar.SetVal(&container.Env, "CAMEL_K_CONF_D", camel.ConfDPath)
 
-       e.addSourcesProperties()
-       if props, err := e.computeApplicationProperties(); err != nil {
-               return err
-       } else if props != nil {
-               e.Resources.Add(props)
-       }
-
-       t.configureResources(&container)
-       if pointer.BoolDeref(t.Expose, false) {
-               t.configureService(e, &container)
-       }
-       t.configureCapabilities(e)
-
-       t.configureSecurityContext(e, &container)
-
        var containers *[]corev1.Container
        visited := false
-
+       knative := false
        // Deployment
        if err := e.Resources.VisitDeploymentE(func(deployment 
*appsv1.Deployment) error {
                for _, envVar := range e.EnvVars {
                        envvar.SetVar(&container.Env, envVar)
                }
-
                containers = &deployment.Spec.Template.Spec.Containers
                visited = true
                return nil
        }); err != nil {
                return err
        }
-
        // Knative Service
        if err := e.Resources.VisitKnativeServiceE(func(service 
*serving.Service) error {
                for _, env := range e.EnvVars {
@@ -236,34 +215,43 @@ func (t *containerTrait) configureContainer(e 
*Environment) error {
                        case env.ValueFrom.FieldRef != nil && 
env.ValueFrom.FieldRef.FieldPath == "metadata.namespace":
                                envvar.SetVar(&container.Env, 
corev1.EnvVar{Name: env.Name, Value: e.Integration.Namespace})
                        case env.ValueFrom.FieldRef != nil:
-                               t.L.Infof("Skipping environment variable %s 
(fieldRef)", env.Name)
+                               t.L.Debugf("Skipping environment variable %s 
(fieldRef)", env.Name)
                        case env.ValueFrom.ResourceFieldRef != nil:
-                               t.L.Infof("Skipping environment variable %s 
(resourceFieldRef)", env.Name)
+                               t.L.Debugf("Skipping environment variable %s 
(resourceFieldRef)", env.Name)
                        default:
                                envvar.SetVar(&container.Env, env)
                        }
                }
-
                containers = 
&service.Spec.ConfigurationSpec.Template.Spec.Containers
                visited = true
+               knative = true
                return nil
        }); err != nil {
                return err
        }
-
        // CronJob
        if err := e.Resources.VisitCronJobE(func(cron *batchv1.CronJob) error {
                for _, envVar := range e.EnvVars {
                        envvar.SetVar(&container.Env, envVar)
                }
-
                containers = 
&cron.Spec.JobTemplate.Spec.Template.Spec.Containers
                visited = true
                return nil
        }); err != nil {
                return err
        }
-
+       e.addSourcesProperties()
+       if props, err := e.computeApplicationProperties(); err != nil {
+               return err
+       } else if props != nil {
+               e.Resources.Add(props)
+       }
+       t.configureResources(&container)
+       if knative || pointer.BoolDeref(t.Expose, false) {
+               t.configureService(e, &container, knative)
+       }
+       t.configureCapabilities(e)
+       t.configureSecurityContext(e, &container)
        if visited {
                *containers = append(*containers, container)
        }
@@ -271,46 +259,42 @@ func (t *containerTrait) configureContainer(e 
*Environment) error {
        return nil
 }
 
-func (t *containerTrait) configureService(e *Environment, container 
*corev1.Container) {
-       service := e.Resources.GetServiceForIntegration(e.Integration)
-       if service == nil {
-               return
-       }
-
+func (t *containerTrait) configureService(e *Environment, container 
*corev1.Container, isKnative bool) {
        name := t.PortName
        if name == "" {
                name = defaultContainerPortName
        }
-
        containerPort := corev1.ContainerPort{
-               Name:          name,
                ContainerPort: int32(t.Port),
                Protocol:      corev1.ProtocolTCP,
        }
-
-       servicePort := corev1.ServicePort{
-               Name:       t.ServicePortName,
-               Port:       int32(t.ServicePort),
-               Protocol:   corev1.ProtocolTCP,
-               TargetPort: intstr.FromString(name),
+       if !isKnative {
+               // Knative does not want name=http
+               containerPort.Name = name
+               // The service is managed by Knative, so, we only take care of 
this when it's managed by us
+               service := e.Resources.GetServiceForIntegration(e.Integration)
+               if service != nil {
+                       servicePort := corev1.ServicePort{
+                               Name:       t.ServicePortName,
+                               Port:       int32(t.ServicePort),
+                               Protocol:   corev1.ProtocolTCP,
+                               TargetPort: intstr.FromString(name),
+                       }
+                       e.Integration.Status.SetCondition(
+                               v1.IntegrationConditionServiceAvailable,
+                               corev1.ConditionTrue,
+                               v1.IntegrationConditionServiceAvailableReason,
+                               // service -> container
+                               fmt.Sprintf("%s(%s/%d) -> %s(%s/%d)",
+                                       service.Name, servicePort.Name, 
servicePort.Port,
+                                       container.Name, containerPort.Name, 
containerPort.ContainerPort),
+                       )
+                       service.Spec.Ports = append(service.Spec.Ports, 
servicePort)
+                       // Mark the service as a user service
+                       service.Labels["camel.apache.org/service.type"] = 
v1.ServiceTypeUser
+               }
        }
-
-       e.Integration.Status.SetCondition(
-               v1.IntegrationConditionServiceAvailable,
-               corev1.ConditionTrue,
-               v1.IntegrationConditionServiceAvailableReason,
-
-               // service -> container
-               fmt.Sprintf("%s(%s/%d) -> %s(%s/%d)",
-                       service.Name, servicePort.Name, servicePort.Port,
-                       container.Name, containerPort.Name, 
containerPort.ContainerPort),
-       )
-
        container.Ports = append(container.Ports, containerPort)
-       service.Spec.Ports = append(service.Spec.Ports, servicePort)
-
-       // Mark the service as a user service
-       service.Labels["camel.apache.org/service.type"] = v1.ServiceTypeUser
 }
 
 func (t *containerTrait) configureResources(container *corev1.Container) {
diff --git a/pkg/trait/container_test.go b/pkg/trait/container_test.go
index 6d039cda8..176dd9794 100644
--- a/pkg/trait/container_test.go
+++ b/pkg/trait/container_test.go
@@ -528,3 +528,130 @@ func createEnvironment() *Environment {
 
        return environment
 }
+
+func TestDeploymentContainerPorts(t *testing.T) {
+       catalog, err := camel.DefaultCatalog()
+       require.NoError(t, err)
+
+       client, _ := test.NewFakeClient()
+       traitCatalog := NewCatalog(nil)
+
+       environment := Environment{
+               Ctx:          context.TODO(),
+               Client:       client,
+               CamelCatalog: catalog,
+               Catalog:      traitCatalog,
+               Integration: &v1.Integration{
+                       Spec: v1.IntegrationSpec{
+                               Profile: v1.TraitProfileKubernetes,
+                               Traits: v1.Traits{
+                                       Container: &traitv1.ContainerTrait{
+                                               Port:        8081,
+                                               ServicePort: 8081,
+                                       },
+                               },
+                               Sources: []v1.SourceSpec{
+                                       {
+                                               Language: v1.LanguageJavaSource,
+                                               DataSpec: v1.DataSpec{
+                                                       Name: "MyTest.java",
+                                                       Content: `
+                                                       public class 
MyRouteBuilder extends RouteBuilder {
+                                                               @Override
+                                                               public void 
configure() throws Exception {
+                                                                       
from("netty-http:http://0.0.0.0:8081/hello";).log("Received message: ${body}");
+                                                               }
+                                                       }
+                                                       `,
+                                               },
+                                       },
+                               },
+                       },
+               },
+               Platform: &v1.IntegrationPlatform{
+                       Spec: v1.IntegrationPlatformSpec{
+                               Build: v1.IntegrationPlatformBuildSpec{
+                                       RuntimeVersion: catalog.Runtime.Version,
+                               },
+                       },
+                       Status: v1.IntegrationPlatformStatus{
+                               Phase: v1.IntegrationPlatformPhaseReady,
+                       },
+               },
+               Resources: kubernetes.NewCollection(),
+       }
+       environment.Integration.Status.Phase = v1.IntegrationPhaseDeploying
+       environment.Platform.ResyncStatusFullConfig()
+
+       _, err = traitCatalog.apply(&environment)
+       require.NoError(t, err)
+       container := environment.GetIntegrationContainer()
+       assert.Len(t, container.Ports, 1)
+       assert.Equal(t, int32(8081), container.Ports[0].ContainerPort)
+       assert.Equal(t, "http", container.Ports[0].Name)
+       svc := 
environment.Resources.GetServiceForIntegration(environment.Integration)
+       assert.Len(t, svc.Spec.Ports, 1)
+       assert.Equal(t, int32(8081), svc.Spec.Ports[0].Port)
+}
+
+func TestKnativeServiceContainerPorts(t *testing.T) {
+       catalog, err := camel.DefaultCatalog()
+       require.NoError(t, err)
+
+       client, _ := test.NewFakeClient()
+       traitCatalog := NewCatalog(nil)
+
+       environment := Environment{
+               Ctx:          context.TODO(),
+               Client:       client,
+               CamelCatalog: catalog,
+               Catalog:      traitCatalog,
+               Integration: &v1.Integration{
+                       Spec: v1.IntegrationSpec{
+                               Profile: v1.TraitProfileKnative,
+                               Traits: v1.Traits{
+                                       Container: &traitv1.ContainerTrait{
+                                               Port:        8081,
+                                               ServicePort: 8081,
+                                       },
+                               },
+                               Sources: []v1.SourceSpec{
+                                       {
+                                               Language: v1.LanguageJavaSource,
+                                               DataSpec: v1.DataSpec{
+                                                       Name: "MyTest.java",
+                                                       Content: `
+                                                       public class 
MyRouteBuilder extends RouteBuilder {
+                                                               @Override
+                                                               public void 
configure() throws Exception {
+                                                                       
from("netty-http:http://0.0.0.0:8081/hello";).log("Received message: ${body}");
+                                                               }
+                                                       }
+                                                       `,
+                                               },
+                                       },
+                               },
+                       },
+               },
+               Platform: &v1.IntegrationPlatform{
+                       Spec: v1.IntegrationPlatformSpec{
+                               Build: v1.IntegrationPlatformBuildSpec{
+                                       RuntimeVersion: catalog.Runtime.Version,
+                               },
+                       },
+                       Status: v1.IntegrationPlatformStatus{
+                               Phase: v1.IntegrationPlatformPhaseReady,
+                       },
+               },
+               Resources: kubernetes.NewCollection(),
+       }
+       environment.Integration.Status.Phase = v1.IntegrationPhaseDeploying
+       environment.Platform.ResyncStatusFullConfig()
+
+       _, err = traitCatalog.apply(&environment)
+       require.NoError(t, err)
+       container := environment.GetIntegrationContainer()
+       assert.Len(t, container.Ports, 1)
+       assert.Equal(t, int32(8081), container.Ports[0].ContainerPort)
+       assert.Equal(t, "", container.Ports[0].Name)
+}

Reply via email to