This is an automated email from the ASF dual-hosted git repository.

gfournier pushed a commit to branch release-2.5.x
in repository https://gitbox.apache.org/repos/asf/camel-k.git


The following commit(s) were added to refs/heads/release-2.5.x by this push:
     new 93954e181 fix(binding): don't panic if no binding available
93954e181 is described below

commit 93954e181c69d12530adb81df391a6947a7904b0
Author: Pasquale Congiusti <pasquale.congiu...@gmail.com>
AuthorDate: Sat Nov 23 09:12:31 2024 +0100

    fix(binding): don't panic if no binding available
    
    Closes #5953
---
 pkg/controller/kameletbinding/initialize_test.go | 96 ++++++++++++++++++++++++
 pkg/controller/kameletbinding/integration.go     |  6 +-
 pkg/util/bindings/catalog.go                     | 19 ++++-
 3 files changed, 116 insertions(+), 5 deletions(-)

diff --git a/pkg/controller/kameletbinding/initialize_test.go 
b/pkg/controller/kameletbinding/initialize_test.go
new file mode 100644
index 000000000..d8b8a3935
--- /dev/null
+++ b/pkg/controller/kameletbinding/initialize_test.go
@@ -0,0 +1,96 @@
+/*
+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 kameletbinding
+
+import (
+       "context"
+       "testing"
+
+       corev1 "k8s.io/api/core/v1"
+       metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+       "k8s.io/utils/ptr"
+
+       v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
+       "github.com/apache/camel-k/v2/pkg/apis/camel/v1alpha1"
+
+       "github.com/apache/camel-k/v2/pkg/util/log"
+       "github.com/apache/camel-k/v2/pkg/util/test"
+
+       "github.com/stretchr/testify/assert"
+       "github.com/stretchr/testify/require"
+)
+
+func TestNewKLBUnsupportedRef(t *testing.T) {
+       svc := &corev1.Service{
+               TypeMeta: metav1.TypeMeta{
+                       Kind:       "Service",
+                       APIVersion: "v1",
+               },
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:      "my-svc",
+                       Namespace: "ns",
+               },
+               Spec: corev1.ServiceSpec{
+                       Ports: []corev1.ServicePort{},
+                       Selector: map[string]string{
+                               v1.IntegrationLabel: "my-klb",
+                       },
+               },
+       }
+       klb := &v1alpha1.KameletBinding{
+               TypeMeta: metav1.TypeMeta{
+                       APIVersion: v1alpha1.SchemeGroupVersion.String(),
+                       Kind:       v1alpha1.KameletBindingKind,
+               },
+               ObjectMeta: metav1.ObjectMeta{
+                       Namespace: "ns",
+                       Name:      "my-klb",
+               },
+               Spec: v1alpha1.KameletBindingSpec{
+                       Source: v1alpha1.Endpoint{
+                               URI: ptr.To("timer:tick"),
+                       },
+                       Sink: v1alpha1.Endpoint{
+                               Ref: &corev1.ObjectReference{
+                                       APIVersion: svc.APIVersion,
+                                       Kind:       svc.Kind,
+                                       Namespace:  svc.Namespace,
+                                       Name:       svc.Name,
+                               },
+                       },
+               },
+       }
+       c, err := test.NewFakeClient(klb)
+       require.NoError(t, err)
+
+       a := NewInitializeAction()
+       a.InjectLogger(log.Log)
+       a.InjectClient(c)
+       assert.Equal(t, "initialize", a.Name())
+       assert.True(t, a.CanHandle(klb))
+       handledKlb, err := a.Handle(context.TODO(), klb)
+       require.Error(t, err)
+       assert.Equal(t, "could not find any suitable binding provider for 
v1/Service my-svc in namespace ns. "+
+               "Bindings available: [\"kamelet\" \"knative-uri\" \"strimzi\" 
\"camel-uri\" \"knative-ref\"]", err.Error())
+       assert.Equal(t, v1alpha1.KameletBindingPhaseError, 
handledKlb.Status.Phase)
+       cond := 
handledKlb.Status.GetCondition(v1alpha1.KameletBindingIntegrationConditionError)
+       assert.NotNil(t, cond)
+       assert.Equal(t, corev1.ConditionFalse, cond.Status)
+       assert.Equal(t, "could not find any suitable binding provider for 
v1/Service my-svc in namespace ns. "+
+               "Bindings available: [\"kamelet\" \"knative-uri\" \"strimzi\" 
\"camel-uri\" \"knative-ref\"]", cond.Message)
+}
diff --git a/pkg/controller/kameletbinding/integration.go 
b/pkg/controller/kameletbinding/integration.go
index b28780de8..f0ebc37ca 100644
--- a/pkg/controller/kameletbinding/integration.go
+++ b/pkg/controller/kameletbinding/integration.go
@@ -105,16 +105,16 @@ func CreateIntegrationFor(ctx context.Context, c 
client.Client, binding *v1alpha
 
        from, err := bindings.TranslateV1alpha1(bindingContext, 
endpointTypeSourceContext, binding.Spec.Source)
        if err != nil {
-               return nil, fmt.Errorf("could not determine source URI: %w", 
err)
+               return nil, err
        }
        to, err := bindings.TranslateV1alpha1(bindingContext, 
endpointTypeSinkContext, binding.Spec.Sink)
        if err != nil {
-               return nil, fmt.Errorf("could not determine sink URI: %w", err)
+               return nil, err
        }
        // error handler is optional
        errorHandler, err := maybeErrorHandler(binding.Spec.ErrorHandler, 
bindingContext)
        if err != nil {
-               return nil, fmt.Errorf("could not determine error handler: %w", 
err)
+               return nil, err
        }
 
        steps := make([]*bindings.Binding, 0, len(binding.Spec.Steps))
diff --git a/pkg/util/bindings/catalog.go b/pkg/util/bindings/catalog.go
index 18bcb2483..ff61e9600 100644
--- a/pkg/util/bindings/catalog.go
+++ b/pkg/util/bindings/catalog.go
@@ -57,6 +57,8 @@ func V1alpha1RegisterBindingProvider(bp 
V1alpha1BindingProvider) {
 }
 
 // Translate execute all chained binding providers, returning the first 
success or the first error.
+//
+//nolint:dupl
 func Translate(ctx BindingContext, endpointCtx EndpointContext, endpoint 
v1.Endpoint) (*Binding, error) {
        availableBindings := make([]string, len(bindingProviders))
        if err := validateEndpoint(ctx, endpoint); err != nil {
@@ -101,18 +103,31 @@ func validateEndpoint(ctx BindingContext, e v1.Endpoint) 
error {
 
 // TranslateV1alpha1 execute all chained binding providers, returning the 
first success or the first error.
 // Deprecated.
+//
+//nolint:dupl
 func TranslateV1alpha1(ctx V1alpha1BindingContext, endpointCtx 
V1alpha1EndpointContext, endpoint v1alpha1.Endpoint) (*Binding, error) {
+       availableBindings := make([]string, len(v1alpha1BindingProviders))
        if err := validateEndpointV1alpha1(ctx, endpoint); err != nil {
                return nil, err
        }
 
-       for _, bp := range v1alpha1BindingProviders {
+       for i, bp := range v1alpha1BindingProviders {
+               availableBindings[i] = bp.ID()
                b, err := bp.Translate(ctx, endpointCtx, endpoint)
                if b != nil || err != nil {
                        return b, err
                }
        }
-       return nil, nil
+
+       // If no success we return an error with the actual list of available 
binding providers
+       var errorMessage string
+       if endpoint.Ref != nil {
+               errorMessage = fmt.Sprintf("could not find any suitable binding 
provider for %s/%s %s in namespace %s. Bindings available: %q",
+                       endpoint.Ref.APIVersion, endpoint.Ref.Kind, 
endpoint.Ref.Name, endpoint.Ref.Namespace, availableBindings)
+       } else if ptr.Deref(endpoint.URI, "") != "" {
+               errorMessage = fmt.Sprintf("could not find any suitable binding 
provider for %s", *endpoint.URI)
+       }
+       return nil, fmt.Errorf(errorMessage)
 }
 
 // Deprecated.

Reply via email to