You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by pc...@apache.org on 2024/03/27 14:16:28 UTC
(camel-k) branch main updated: fix(knative): enable service container port
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 <pa...@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)
+}