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/03/05 10:29:21 UTC
[camel-k] branch master updated: Adding Probes to Knative services
#511
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 660a190 Adding Probes to Knative services #511
660a190 is described below
commit 660a190a33aab902223ed0d2110c47ed69dfd301
Author: lburgazzoli <lb...@gmail.com>
AuthorDate: Fri Mar 1 01:09:05 2019 +0100
Adding Probes to Knative services #511
---
pkg/trait/probes.go | 93 +++++++++++++++++++++++++++++++
pkg/trait/probes_test.go | 134 +++++++++++++++++++++++++++++++++++++++++++++
pkg/trait/trait_catalog.go | 6 ++
3 files changed, 233 insertions(+)
diff --git a/pkg/trait/probes.go b/pkg/trait/probes.go
new file mode 100644
index 0000000..fbc0e33
--- /dev/null
+++ b/pkg/trait/probes.go
@@ -0,0 +1,93 @@
+/*
+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 (
+ "sort"
+
+ "github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+ "github.com/apache/camel-k/pkg/util"
+ "k8s.io/apimachinery/pkg/util/intstr"
+
+ serving "github.com/knative/serving/pkg/apis/serving/v1alpha1"
+ appsv1 "k8s.io/api/apps/v1"
+ corev1 "k8s.io/api/core/v1"
+)
+
+type probesTrait struct {
+ BaseTrait `property:",squash"`
+
+ BindHost string `property:"bind-host"`
+ BindPort int `property:"bind-port"`
+ Path string `property:"path"`
+}
+
+func newProbesTrait() *probesTrait {
+ return &probesTrait{
+ BaseTrait: newBaseTrait("probes"),
+ BindHost: "0.0.0.0",
+ BindPort: 8081,
+ Path: "/health",
+ }
+}
+
+func (t *probesTrait) Configure(e *Environment) (bool, error) {
+ if t.Enabled != nil && *t.Enabled {
+ return e.IntegrationInPhase(v1alpha1.IntegrationPhaseInitial) || e.IntegrationInPhase(v1alpha1.IntegrationPhaseDeploying), nil
+ }
+
+ return false, nil
+}
+
+func (t *probesTrait) Apply(e *Environment) error {
+ if e.IntegrationInPhase(v1alpha1.IntegrationPhaseInitial) {
+ util.StringSliceUniqueAdd(&e.Integration.Status.Dependencies, "runtime:health")
+
+ // sort the dependencies to get always the same list if they don't change
+ sort.Strings(e.Integration.Status.Dependencies)
+ }
+
+ if e.IntegrationInPhase(v1alpha1.IntegrationPhaseDeploying) {
+ e.Resources.VisitDeployment(func(deployment *appsv1.Deployment) {
+ if len(deployment.Spec.Template.Spec.Containers) != 1 {
+ return
+ }
+
+ deployment.Spec.Template.Spec.Containers[0].LivenessProbe = t.newProbe()
+ deployment.Spec.Template.Spec.Containers[0].ReadinessProbe = t.newProbe()
+ })
+
+ e.Resources.VisitKnativeService(func(service *serving.Service) {
+ service.Spec.RunLatest.Configuration.RevisionTemplate.Spec.Container.LivenessProbe = t.newProbe()
+ service.Spec.RunLatest.Configuration.RevisionTemplate.Spec.Container.ReadinessProbe = t.newProbe()
+ })
+ }
+
+ return nil
+}
+
+func (t *probesTrait) newProbe() *corev1.Probe {
+ return &corev1.Probe{
+ Handler: corev1.Handler{
+ HTTPGet: &corev1.HTTPGetAction{
+ Port: intstr.FromInt(t.BindPort),
+ Path: t.Path,
+ },
+ },
+ }
+}
diff --git a/pkg/trait/probes_test.go b/pkg/trait/probes_test.go
new file mode 100644
index 0000000..88a2a45
--- /dev/null
+++ b/pkg/trait/probes_test.go
@@ -0,0 +1,134 @@
+/*
+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 (
+ "testing"
+
+ "github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+ "github.com/apache/camel-k/pkg/util/kubernetes"
+
+ "github.com/stretchr/testify/assert"
+
+ serving "github.com/knative/serving/pkg/apis/serving/v1alpha1"
+ appsv1 "k8s.io/api/apps/v1"
+ corev1 "k8s.io/api/core/v1"
+)
+
+func TestProbesDeps(t *testing.T) {
+ e := Environment{
+ Integration: &v1alpha1.Integration{
+ Status: v1alpha1.IntegrationStatus{
+ Phase: v1alpha1.IntegrationPhaseInitial,
+ },
+ },
+ }
+
+ enabled := true
+
+ tr := newProbesTrait()
+ tr.Enabled = &enabled
+ tr.BindPort = 9191
+
+ ok, err := tr.Configure(&e)
+ assert.Nil(t, err)
+ assert.True(t, ok)
+
+ err = tr.Apply(&e)
+ assert.Nil(t, err)
+ assert.Contains(t, e.Integration.Status.Dependencies, "runtime:health")
+}
+
+func TestProbesOnDeployment(t *testing.T) {
+ target := appsv1.Deployment{
+ Spec: appsv1.DeploymentSpec{
+ Template: corev1.PodTemplateSpec{
+ Spec: corev1.PodSpec{
+ Containers: []corev1.Container{
+ {},
+ },
+ },
+ },
+ },
+ }
+
+ e := Environment{
+ Resources: kubernetes.NewCollection(&target),
+ Integration: &v1alpha1.Integration{
+ Status: v1alpha1.IntegrationStatus{
+ Phase: v1alpha1.IntegrationPhaseDeploying,
+ },
+ },
+ }
+
+ enabled := true
+
+ tr := newProbesTrait()
+ tr.Enabled = &enabled
+ tr.BindPort = 9191
+
+ ok, err := tr.Configure(&e)
+ assert.Nil(t, err)
+ assert.True(t, ok)
+
+ err = tr.Apply(&e)
+ assert.Nil(t, err)
+ //assert.Contains(t, e.Integration.Status.Dependencies, "runtime:health")
+ assert.Equal(t, "", target.Spec.Template.Spec.Containers[0].LivenessProbe.HTTPGet.Host)
+ assert.Equal(t, int32(9191), target.Spec.Template.Spec.Containers[0].LivenessProbe.HTTPGet.Port.IntVal)
+ assert.Equal(t, "/health", target.Spec.Template.Spec.Containers[0].LivenessProbe.HTTPGet.Path)
+ assert.Equal(t, "", target.Spec.Template.Spec.Containers[0].ReadinessProbe.HTTPGet.Host)
+ assert.Equal(t, int32(9191), target.Spec.Template.Spec.Containers[0].ReadinessProbe.HTTPGet.Port.IntVal)
+ assert.Equal(t, "/health", target.Spec.Template.Spec.Containers[0].ReadinessProbe.HTTPGet.Path)
+}
+
+func TestProbesOnKnativeService(t *testing.T) {
+ target := serving.Service{
+ Spec: serving.ServiceSpec{
+ RunLatest: &serving.RunLatestType{},
+ },
+ }
+
+ e := Environment{
+ Resources: kubernetes.NewCollection(&target),
+ Integration: &v1alpha1.Integration{
+ Status: v1alpha1.IntegrationStatus{
+ Phase: v1alpha1.IntegrationPhaseDeploying,
+ },
+ },
+ }
+
+ enabled := true
+
+ tr := newProbesTrait()
+ tr.Enabled = &enabled
+ tr.BindPort = 9191
+
+ ok, err := tr.Configure(&e)
+ assert.Nil(t, err)
+ assert.True(t, ok)
+
+ err = tr.Apply(&e)
+ assert.Nil(t, err)
+ assert.Equal(t, "", target.Spec.RunLatest.Configuration.RevisionTemplate.Spec.Container.LivenessProbe.HTTPGet.Host)
+ assert.Equal(t, int32(9191), target.Spec.RunLatest.Configuration.RevisionTemplate.Spec.Container.LivenessProbe.HTTPGet.Port.IntVal)
+ assert.Equal(t, "/health", target.Spec.RunLatest.Configuration.RevisionTemplate.Spec.Container.LivenessProbe.HTTPGet.Path)
+ assert.Equal(t, "", target.Spec.RunLatest.Configuration.RevisionTemplate.Spec.Container.ReadinessProbe.HTTPGet.Host)
+ assert.Equal(t, int32(9191), target.Spec.RunLatest.Configuration.RevisionTemplate.Spec.Container.ReadinessProbe.HTTPGet.Port.IntVal)
+ assert.Equal(t, "/health", target.Spec.RunLatest.Configuration.RevisionTemplate.Spec.Container.ReadinessProbe.HTTPGet.Path)
+}
diff --git a/pkg/trait/trait_catalog.go b/pkg/trait/trait_catalog.go
index 9c5c9c2..b2e2e60 100644
--- a/pkg/trait/trait_catalog.go
+++ b/pkg/trait/trait_catalog.go
@@ -52,6 +52,7 @@ type Catalog struct {
tEnvironment Trait
tClasspath Trait
tRestDsl Trait
+ tProbes Trait
}
// NewCatalog creates a new trait Catalog
@@ -79,6 +80,7 @@ func NewCatalog(ctx context.Context, c client.Client) *Catalog {
tIstio: newIstioTrait(),
tEnvironment: newEnvironmentTrait(),
tClasspath: newClasspathTrait(),
+ tProbes: newProbesTrait(),
}
for _, t := range catalog.allTraits() {
@@ -115,6 +117,7 @@ func (c *Catalog) allTraits() []Trait {
c.tIstio,
c.tEnvironment,
c.tClasspath,
+ c.tProbes,
}
}
@@ -138,6 +141,7 @@ func (c *Catalog) traitsFor(environment *Environment) []Trait {
c.tPrometheus,
c.tDeployer,
c.tDeployment,
+ c.tProbes,
c.tService,
c.tRoute,
c.tOwner,
@@ -158,6 +162,7 @@ func (c *Catalog) traitsFor(environment *Environment) []Trait {
c.tPrometheus,
c.tDeployer,
c.tDeployment,
+ c.tProbes,
c.tService,
c.tIngress,
c.tOwner,
@@ -178,6 +183,7 @@ func (c *Catalog) traitsFor(environment *Environment) []Trait {
c.tDeployer,
c.tDeployment,
c.tKnativeService,
+ c.tProbes,
c.tIstio,
c.tOwner,
}