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 7dfac6456 fix(trait): service binding
7dfac6456 is described below
commit 7dfac64564a85c5f375924e67901a13fbfd1ce30
Author: Pasquale Congiusti <[email protected]>
AuthorDate: Thu Feb 8 09:56:45 2024 +0100
fix(trait): service binding
---
e2e/common/config/config_test.go | 1 -
pkg/trait/mount.go | 10 +++++
pkg/trait/service_binding.go | 42 ++++++++++++--------
pkg/trait/service_binding_test.go | 83 +++++++++++++++++++++++++++++++++++++++
pkg/trait/trait_types.go | 12 ------
pkg/util/kubernetes/collection.go | 20 ++++++++++
pkg/util/test/client.go | 2 +-
7 files changed, 139 insertions(+), 31 deletions(-)
diff --git a/e2e/common/config/config_test.go b/e2e/common/config/config_test.go
index ab7094b13..ef178e3c9 100644
--- a/e2e/common/config/config_test.go
+++ b/e2e/common/config/config_test.go
@@ -328,7 +328,6 @@ func TestRunConfigExamples(t *testing.T) {
Expect(DeleteConfigmap(ns, "my-cm-test-build-properties")).To(Succeed())
Expect(DeleteConfigmap(ns, "my-cm-test-property")).To(Succeed())
Expect(DeleteConfigmap(ns, "my-cm-test-properties")).To(Succeed())
- Expect(DeleteSecret(ns, "my-sec-inlined")).To(Succeed())
Expect(DeleteSecret(ns, "my-sec-test-build-property")).To(Succeed())
Expect(DeleteSecret(ns, "my-sec-test-build-properties")).To(Succeed())
Expect(DeleteSecret(ns, "my-sec-test-property")).To(Succeed())
diff --git a/pkg/trait/mount.go b/pkg/trait/mount.go
index 75aa96faa..5c00185f5 100644
--- a/pkg/trait/mount.go
+++ b/pkg/trait/mount.go
@@ -49,6 +49,8 @@ func (t *mountTrait) Configure(e *Environment) (bool,
*TraitCondition, error) {
if e.Integration == nil || !e.IntegrationInRunningPhases() {
return false, nil, nil
}
+ // Look for secrets which may have been created by service binding trait
+ t.addServiceBindingSecret(e)
// Validate resources and pvcs
for _, c := range t.Configs {
@@ -166,3 +168,11 @@ func (t *mountTrait) mountResource(vols *[]corev1.Volume,
mnts *[]corev1.VolumeM
*vols = append(*vols, *vol)
*mnts = append(*mnts, *mnt)
}
+
+func (t *mountTrait) addServiceBindingSecret(e *Environment) {
+ e.Resources.VisitSecret(func(secret *corev1.Secret) {
+ if secret.Labels[serviceBindingLabel] == "true" {
+ t.Configs = append(t.Configs, "secret:"+secret.Name)
+ }
+ })
+}
diff --git a/pkg/trait/service_binding.go b/pkg/trait/service_binding.go
index dabea7481..2bb1758ee 100644
--- a/pkg/trait/service_binding.go
+++ b/pkg/trait/service_binding.go
@@ -37,6 +37,21 @@ import (
"github.com/apache/camel-k/v2/pkg/util/reference"
)
+const (
+ serviceBindingMountPointAnnotation =
"camel.apache.org/serviceBinding.mount-point"
+ serviceBindingLabel = "camel.apache.org/serviceBinding"
+)
+
+var handlers = []pipeline.Handler{
+ pipeline.HandlerFunc(collect.PreFlight),
+ pipeline.HandlerFunc(collect.ProvisionedService),
+ pipeline.HandlerFunc(collect.BindingDefinitions),
+ pipeline.HandlerFunc(collect.BindingItems),
+ pipeline.HandlerFunc(collect.OwnedResources),
+ pipeline.HandlerFunc(mapping.Handle),
+ pipeline.HandlerFunc(naming.Handle),
+}
+
type serviceBindingTrait struct {
BaseTrait
traitv1.ServiceBindingTrait `property:",squash"`
@@ -68,17 +83,15 @@ func (t *serviceBindingTrait) Apply(e *Environment) error {
return err
}
// let the SBO retry policy be controlled by Camel-k
- err = process(ctx, getHandlers())
+ err = process(ctx, handlers)
if err != nil {
return err
}
- secret := createSecret(ctx, e.Integration.Namespace)
+ secret := createSecret(ctx, e.Integration.Namespace, e.Integration.Name)
if secret != nil {
e.Resources.Add(secret)
e.ApplicationProperties["quarkus.kubernetes-service-binding.enabled"] = "true"
- e.ApplicationProperties["SERVICE_BINDING_ROOT"] =
camel.ServiceBindingsMountPath
- e.ServiceBindingSecret = secret.GetName()
}
return nil
}
@@ -164,19 +177,7 @@ func createServiceBinding(e *Environment, services
[]sb.Service, name string) *s
}
}
-func getHandlers() []pipeline.Handler {
- return []pipeline.Handler{
- pipeline.HandlerFunc(collect.PreFlight),
- pipeline.HandlerFunc(collect.ProvisionedService),
- pipeline.HandlerFunc(collect.BindingDefinitions),
- pipeline.HandlerFunc(collect.BindingItems),
- pipeline.HandlerFunc(collect.OwnedResources),
- pipeline.HandlerFunc(mapping.Handle),
- pipeline.HandlerFunc(naming.Handle),
- }
-}
-
-func createSecret(ctx pipeline.Context, ns string) *corev1.Secret {
+func createSecret(ctx pipeline.Context, ns, integrationName string)
*corev1.Secret {
name := ctx.BindingSecretName()
items := ctx.BindingItems()
data := items.AsMap()
@@ -191,6 +192,13 @@ func createSecret(ctx pipeline.Context, ns string)
*corev1.Secret {
ObjectMeta: metav1.ObjectMeta{
Namespace: ns,
Name: name,
+ Labels: map[string]string{
+ v1.IntegrationLabel: integrationName,
+ serviceBindingLabel: "true",
+ },
+ Annotations: map[string]string{
+ serviceBindingMountPointAnnotation:
camel.ServiceBindingsMountPath,
+ },
},
StringData: data,
}
diff --git a/pkg/trait/service_binding_test.go
b/pkg/trait/service_binding_test.go
new file mode 100644
index 000000000..c80f22b5b
--- /dev/null
+++ b/pkg/trait/service_binding_test.go
@@ -0,0 +1,83 @@
+/*
+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/redhat-developer/service-binding-operator/pkg/reconcile/pipeline"
+ "github.com/stretchr/testify/assert"
+
+ v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
+ "github.com/apache/camel-k/v2/pkg/util/camel"
+ "github.com/apache/camel-k/v2/pkg/util/test"
+)
+
+func TestServiceBinding(t *testing.T) {
+ sbTrait, environment := createNominalServiceBindingTest()
+ sbTrait.Services = []string{
+ "ConfigMap:default/my-service-name",
+ }
+ configured, condition, err := sbTrait.Configure(environment)
+
+ assert.True(t, configured)
+ assert.Nil(t, err)
+ assert.Nil(t, condition)
+
+ // Required for local testing purposes only
+ handlers = []pipeline.Handler{}
+ err = sbTrait.Apply(environment)
+ assert.Nil(t, err)
+ // TODO we should make the service binding trait to easily work with
fake client
+ // and test the apply result in the environment accordingly.
+}
+
+func createNominalServiceBindingTest() (*serviceBindingTrait, *Environment) {
+ trait, _ := newServiceBindingTrait().(*serviceBindingTrait)
+ client, _ := test.NewFakeClient()
+
+ environment := &Environment{
+ Client: client,
+ Catalog: NewCatalog(client),
+ CamelCatalog: &camel.RuntimeCatalog{},
+ Integration: &v1.Integration{
+ Spec: v1.IntegrationSpec{
+ Sources: []v1.SourceSpec{
+ {
+ Language: v1.LanguageJavaSource,
+ },
+ },
+ },
+ Status: v1.IntegrationStatus{
+ Phase: v1.IntegrationPhaseInitialization,
+ },
+ },
+ IntegrationKit: &v1.IntegrationKit{},
+ Pipeline: []v1.Task{
+ {
+ Builder: &v1.BuilderTask{},
+ },
+ {
+ Package: &v1.BuilderTask{},
+ },
+ },
+ Platform: &v1.IntegrationPlatform{},
+ }
+
+ return trait, environment
+}
diff --git a/pkg/trait/trait_types.go b/pkg/trait/trait_types.go
index 602e59c72..e991d0c5a 100644
--- a/pkg/trait/trait_types.go
+++ b/pkg/trait/trait_types.go
@@ -224,7 +224,6 @@ type Environment struct {
EnvVars []corev1.EnvVar
ApplicationProperties map[string]string
Interceptors []string
- ServiceBindingSecret string
}
// ControllerStrategy is used to determine the kind of controller that needs
to be created for the integration.
@@ -571,17 +570,6 @@ func (e *Environment) configureVolumesAndMounts(vols
*[]corev1.Volume, mnts *[]c
*vols = append(*vols, *vol)
*mnts = append(*mnts, *mnt)
}
- // append Service Binding secrets
- if len(e.ServiceBindingSecret) > 0 {
- secret := e.ServiceBindingSecret
- refName := kubernetes.SanitizeLabel(secret)
- mountPath := filepath.Join(camel.ServiceBindingsMountPath,
strings.ToLower(secret))
- vol := getVolume(refName, "secret", secret, "", "")
- mnt := getMount(refName, mountPath, "", true)
-
- *vols = append(*vols, *vol)
- *mnts = append(*mnts, *mnt)
- }
// Deprecated - should use mount trait
// User provided volumes
for _, volumeConfig := range e.collectConfigurationValues("volume") {
diff --git a/pkg/util/kubernetes/collection.go
b/pkg/util/kubernetes/collection.go
index c318fce48..dd3fcaf1a 100644
--- a/pkg/util/kubernetes/collection.go
+++ b/pkg/util/kubernetes/collection.go
@@ -204,6 +204,26 @@ func (c *Collection) RemoveConfigMap(filter
func(*corev1.ConfigMap) bool) *corev
return cm
}
+// VisitSecret executes the visitor function on all Secrets resources.
+func (c *Collection) VisitSecret(visitor func(*corev1.Secret)) {
+ c.Visit(func(res runtime.Object) {
+ if conv, ok := res.(*corev1.Secret); ok {
+ visitor(conv)
+ }
+ })
+}
+
+// GetSecret returns a Secret that matches the given function.
+func (c *Collection) GetSecret(filter func(*corev1.Secret) bool)
*corev1.Secret {
+ var retValue *corev1.Secret
+ c.VisitSecret(func(re *corev1.Secret) {
+ if filter(re) {
+ retValue = re
+ }
+ })
+ return retValue
+}
+
// VisitService executes the visitor function on all Service resources.
func (c *Collection) VisitService(visitor func(*corev1.Service)) {
c.Visit(func(res runtime.Object) {
diff --git a/pkg/util/test/client.go b/pkg/util/test/client.go
index 82657df94..6c45fc0e1 100644
--- a/pkg/util/test/client.go
+++ b/pkg/util/test/client.go
@@ -160,7 +160,7 @@ func (c *FakeClient) GetScheme() *runtime.Scheme {
}
func (c *FakeClient) GetConfig() *rest.Config {
- return nil
+ return &rest.Config{}
}
func (c *FakeClient) GetCurrentNamespace(kubeConfig string) (string, error) {