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 2019/06/20 13:44:06 UTC
[camel-k] branch master updated: Service trait: confusing behavior
#753
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
The following commit(s) were added to refs/heads/master by this push:
new 2b47d49 Service trait: confusing behavior #753
2b47d49 is described below
commit 2b47d49d76518c8fb6c017a8f49c3725ff51f9f6
Author: lburgazzoli <lb...@gmail.com>
AuthorDate: Thu Jun 20 12:37:51 2019 +0200
Service trait: confusing behavior #753
---
docs/traits.adoc | 9 ++
pkg/trait/service.go | 24 ++++--
pkg/trait/service_test.go | 213 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 237 insertions(+), 9 deletions(-)
diff --git a/docs/traits.adoc b/docs/traits.adoc
index 6fe5929..72c5dce 100644
--- a/docs/traits.adoc
+++ b/docs/traits.adoc
@@ -191,8 +191,17 @@ More information can be found in the official Kubernetes documentation about htt
!===
! service.port
+! To configure a different port exposed by the service (default `80`).
+
+! service.port-name
+! To configure a different port name for the port exposed by the service (default `http`).
+
+! service.container-port
! To configure a different port exposed by the container (default `8080`).
+! service.container-port-name
+! To configure a different port name for the port exposed by the container (default `http`).
+
!===
| route
diff --git a/pkg/trait/service.go b/pkg/trait/service.go
index 408a05b..f852c2c 100644
--- a/pkg/trait/service.go
+++ b/pkg/trait/service.go
@@ -30,16 +30,22 @@ import (
type serviceTrait struct {
BaseTrait `property:",squash"`
- Auto *bool `property:"auto"`
- Port int `property:"port"`
+ Auto *bool `property:"auto"`
+ Port int `property:"port"`
+ PortName string `property:"port-name"`
+ ContainerPort int `property:"container-port"`
+ ContainerPortName string `property:"container-port-name"`
}
const httpPortName = "http"
func newServiceTrait() *serviceTrait {
return &serviceTrait{
- BaseTrait: newBaseTrait("service"),
- Port: 8080,
+ BaseTrait: newBaseTrait("service"),
+ Port: 80,
+ PortName: httpPortName,
+ ContainerPort: 8080,
+ ContainerPortName: httpPortName,
}
}
@@ -77,10 +83,10 @@ func (t *serviceTrait) Apply(e *Environment) (err error) {
e.Resources.Add(svc)
}
port := corev1.ServicePort{
- Name: httpPortName,
- Port: 80,
+ Name: t.PortName,
+ Port: int32(t.Port),
Protocol: corev1.ProtocolTCP,
- TargetPort: intstr.FromString(httpPortName),
+ TargetPort: intstr.FromString(t.ContainerPortName),
}
svc.Spec.Ports = append(svc.Spec.Ports, port)
@@ -97,8 +103,8 @@ func (t *serviceTrait) Apply(e *Environment) (err error) {
})
if container != nil {
container.Ports = append(container.Ports, corev1.ContainerPort{
- Name: httpPortName,
- ContainerPort: int32(t.Port),
+ Name: t.ContainerPortName,
+ ContainerPort: int32(t.ContainerPort),
Protocol: corev1.ProtocolTCP,
})
} else {
diff --git a/pkg/trait/service_test.go b/pkg/trait/service_test.go
new file mode 100644
index 0000000..7196c77
--- /dev/null
+++ b/pkg/trait/service_test.go
@@ -0,0 +1,213 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package trait
+
+import (
+ "context"
+ "testing"
+
+ "github.com/scylladb/go-set/strset"
+
+ "github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+ "github.com/apache/camel-k/pkg/util/kubernetes"
+ "github.com/apache/camel-k/pkg/util/test"
+
+ appsv1 "k8s.io/api/apps/v1"
+ corev1 "k8s.io/api/core/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestServiceWithDefaults(t *testing.T) {
+ catalog, err := test.DefaultCatalog()
+ assert.Nil(t, err)
+
+ traitCatalog := NewCatalog(context.TODO(), nil)
+
+ environment := Environment{
+ CamelCatalog: catalog,
+ Catalog: traitCatalog,
+ Integration: &v1alpha1.Integration{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "ns",
+ },
+ Status: v1alpha1.IntegrationStatus{
+ Phase: v1alpha1.IntegrationPhaseDeploying,
+ },
+ Spec: v1alpha1.IntegrationSpec{
+ Profile: v1alpha1.TraitProfileKubernetes,
+ Sources: []v1alpha1.SourceSpec{
+ {
+ DataSpec: v1alpha1.DataSpec{
+ Name: "routes.js",
+ Content: `from("undertow:test").log("hello")`,
+ Compression: true,
+ },
+ Language: v1alpha1.LanguageJavaScript,
+ },
+ },
+ Traits: map[string]v1alpha1.TraitSpec{
+ "service": {
+ Configuration: map[string]string{
+ "enabled": "true",
+ "auto": "false",
+ },
+ },
+ },
+ },
+ },
+ IntegrationKit: &v1alpha1.IntegrationKit{
+ Status: v1alpha1.IntegrationKitStatus{
+ Phase: v1alpha1.IntegrationKitPhaseReady,
+ },
+ },
+ Platform: &v1alpha1.IntegrationPlatform{
+ Spec: v1alpha1.IntegrationPlatformSpec{
+ Cluster: v1alpha1.IntegrationPlatformClusterOpenShift,
+ Build: v1alpha1.IntegrationPlatformBuildSpec{
+ PublishStrategy: v1alpha1.IntegrationPlatformBuildPublishStrategyS2I,
+ Registry: v1alpha1.IntegrationPlatformRegistrySpec{Address: "registry"},
+ },
+ },
+ },
+ EnvVars: make([]corev1.EnvVar, 0),
+ ExecutedTraits: make([]Trait, 0),
+ Resources: kubernetes.NewCollection(&appsv1.Deployment{}),
+ Classpath: strset.New(),
+ }
+
+ err = traitCatalog.apply(&environment)
+
+ assert.Nil(t, err)
+ assert.NotEmpty(t, environment.ExecutedTraits)
+ assert.NotNil(t, environment.GetTrait(ID("deployment")))
+ assert.NotNil(t, environment.GetTrait(ID("service")))
+
+ s := environment.Resources.GetService(func(service *corev1.Service) bool {
+ return service.Name == "test"
+ })
+ d := environment.Resources.GetDeployment(func(deployment *appsv1.Deployment) bool {
+ return deployment.Name == "test"
+ })
+
+ assert.NotNil(t, d)
+ assert.NotNil(t, s)
+
+ assert.Len(t, s.Spec.Ports, 1)
+ assert.Equal(t, int32(80), s.Spec.Ports[0].Port)
+ assert.Equal(t, "http", s.Spec.Ports[0].Name)
+ assert.Equal(t, "http", s.Spec.Ports[0].TargetPort.String())
+
+ assert.Len(t, d.Spec.Template.Spec.Containers, 1)
+ assert.Len(t, d.Spec.Template.Spec.Containers[0].Ports, 1)
+ assert.Equal(t, int32(8080), d.Spec.Template.Spec.Containers[0].Ports[0].ContainerPort)
+ assert.Equal(t, "http", d.Spec.Template.Spec.Containers[0].Ports[0].Name)
+}
+
+func TestService(t *testing.T) {
+ catalog, err := test.DefaultCatalog()
+ assert.Nil(t, err)
+
+ traitCatalog := NewCatalog(context.TODO(), nil)
+
+ environment := Environment{
+ CamelCatalog: catalog,
+ Catalog: traitCatalog,
+ Integration: &v1alpha1.Integration{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "ns",
+ },
+ Status: v1alpha1.IntegrationStatus{
+ Phase: v1alpha1.IntegrationPhaseDeploying,
+ },
+ Spec: v1alpha1.IntegrationSpec{
+ Profile: v1alpha1.TraitProfileKubernetes,
+ Sources: []v1alpha1.SourceSpec{
+ {
+ DataSpec: v1alpha1.DataSpec{
+ Name: "routes.js",
+ Content: `from("undertow:test").log("hello")`,
+ Compression: true,
+ },
+ Language: v1alpha1.LanguageJavaScript,
+ },
+ },
+ Traits: map[string]v1alpha1.TraitSpec{
+ "service": {
+ Configuration: map[string]string{
+ "enabled": "true",
+ "auto": "false",
+ "port": "81",
+ "port-name": "http-81",
+ "container-port": "8081",
+ "container-port-name": "http-8081",
+ },
+ },
+ },
+ },
+ },
+ IntegrationKit: &v1alpha1.IntegrationKit{
+ Status: v1alpha1.IntegrationKitStatus{
+ Phase: v1alpha1.IntegrationKitPhaseReady,
+ },
+ },
+ Platform: &v1alpha1.IntegrationPlatform{
+ Spec: v1alpha1.IntegrationPlatformSpec{
+ Cluster: v1alpha1.IntegrationPlatformClusterOpenShift,
+ Build: v1alpha1.IntegrationPlatformBuildSpec{
+ PublishStrategy: v1alpha1.IntegrationPlatformBuildPublishStrategyS2I,
+ Registry: v1alpha1.IntegrationPlatformRegistrySpec{Address: "registry"},
+ },
+ },
+ },
+ EnvVars: make([]corev1.EnvVar, 0),
+ ExecutedTraits: make([]Trait, 0),
+ Resources: kubernetes.NewCollection(&appsv1.Deployment{}),
+ Classpath: strset.New(),
+ }
+
+ err = traitCatalog.apply(&environment)
+
+ assert.Nil(t, err)
+ assert.NotEmpty(t, environment.ExecutedTraits)
+ assert.NotNil(t, environment.GetTrait(ID("deployment")))
+ assert.NotNil(t, environment.GetTrait(ID("service")))
+
+ s := environment.Resources.GetService(func(service *corev1.Service) bool {
+ return service.Name == "test"
+ })
+ d := environment.Resources.GetDeployment(func(deployment *appsv1.Deployment) bool {
+ return deployment.Name == "test"
+ })
+
+ assert.NotNil(t, d)
+ assert.NotNil(t, s)
+
+ assert.Len(t, s.Spec.Ports, 1)
+ assert.Equal(t, int32(81), s.Spec.Ports[0].Port)
+ assert.Equal(t, "http-81", s.Spec.Ports[0].Name)
+ assert.Equal(t, "http-8081", s.Spec.Ports[0].TargetPort.String())
+
+ assert.Len(t, d.Spec.Template.Spec.Containers, 1)
+ assert.Len(t, d.Spec.Template.Spec.Containers[0].Ports, 1)
+ assert.Equal(t, int32(8081), d.Spec.Template.Spec.Containers[0].Ports[0].ContainerPort)
+ assert.Equal(t, "http-8081", d.Spec.Template.Spec.Containers[0].Ports[0].Name)
+}