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 <[email protected]>
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.