This is an automated email from the ASF dual-hosted git repository. pcongiusti pushed a commit to branch release-1.10.x in repository https://gitbox.apache.org/repos/asf/camel-k.git
The following commit(s) were added to refs/heads/release-1.10.x by this push: new 0dafa9b9c fix(#4961): Improve cross-namespace check for Kamelet refs 0dafa9b9c is described below commit 0dafa9b9cc1f32179ef3c20b997c14a8b5e1383a Author: Christoph Deppisch <cdeppi...@redhat.com> AuthorDate: Tue Dec 5 16:10:36 2023 +0100 fix(#4961): Improve cross-namespace check for Kamelet refs - Allow explicit references to default Kamelets in operator namespace - Keep check on cross-namespace reference for other resources (e.g. Knative Broker) - Keep raising cross-namespace check errors for Kamelet references to other user namespaces --- pkg/util/bindings/catalog.go | 9 +- pkg/util/bindings/catalog_test.go | 198 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 206 insertions(+), 1 deletion(-) diff --git a/pkg/util/bindings/catalog.go b/pkg/util/bindings/catalog.go index dd2e87fc6..fa32fa0b9 100644 --- a/pkg/util/bindings/catalog.go +++ b/pkg/util/bindings/catalog.go @@ -22,10 +22,12 @@ import ( "sort" "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" + "github.com/apache/camel-k/pkg/platform" ) var bindingProviders []BindingProvider +// RegisterBindingProvider --. func RegisterBindingProvider(bp BindingProvider) { bindingProviders = append(bindingProviders, bp) sort.Slice(bindingProviders, func(i, j int) bool { @@ -58,7 +60,12 @@ func validateEndpoint(ctx BindingContext, e v1alpha1.Endpoint) error { return errors.New("cannot use both ref and URI to specify an endpoint: only one of them should be used") } if e.Ref != nil && e.Ref.Namespace != "" && e.Ref.Namespace != ctx.Namespace { - return errors.New("cross-namespace references are not allowed in kamelet binding") + // referencing default Kamelets in operator namespace is allowed + if e.Ref.Kind == v1alpha1.KameletKind && e.Ref.Namespace == platform.GetOperatorNamespace() { + return nil + } + + return errors.New("cross-namespace references are not allowed in KameletBinding") } return nil } diff --git a/pkg/util/bindings/catalog_test.go b/pkg/util/bindings/catalog_test.go new file mode 100644 index 000000000..e2f97f8f2 --- /dev/null +++ b/pkg/util/bindings/catalog_test.go @@ -0,0 +1,198 @@ +/* +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 bindings + +import ( + "context" + "fmt" + "testing" + + v1 "github.com/apache/camel-k/pkg/apis/camel/v1" + "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" + corev1 "k8s.io/api/core/v1" + eventing "knative.dev/eventing/pkg/apis/eventing/v1" + + "github.com/apache/camel-k/pkg/util/test" + "github.com/stretchr/testify/assert" +) + +func TestValidateEndpoint(t *testing.T) { + testcases := []struct { + name string + namespace string + operatorNamespace string + endpoint v1alpha1.Endpoint + }{ + { + name: "kamelet-ref", + namespace: "test", + endpoint: v1alpha1.Endpoint{ + Ref: &corev1.ObjectReference{ + Kind: v1alpha1.KameletKind, + APIVersion: v1.SchemeGroupVersion.String(), + Name: "foo-kamelet", + }, + }, + }, + { + name: "kamelet-ref-in-namespace", + namespace: "test", + endpoint: v1alpha1.Endpoint{ + Ref: &corev1.ObjectReference{ + Kind: v1alpha1.KameletKind, + Namespace: "test", + APIVersion: v1.SchemeGroupVersion.String(), + Name: "foo-kamelet", + }, + }, + }, + { + name: "kamelet-ref-in-operator-namespace", + namespace: "test", + operatorNamespace: "global", + endpoint: v1alpha1.Endpoint{ + Ref: &corev1.ObjectReference{ + Kind: v1alpha1.KameletKind, + Namespace: "global", + APIVersion: v1.SchemeGroupVersion.String(), + Name: "foo-kamelet", + }, + }, + }, + { + name: "knative-broker-ref", + namespace: "test", + endpoint: v1alpha1.Endpoint{ + Ref: &corev1.ObjectReference{ + Kind: "Broker", + APIVersion: eventing.SchemeGroupVersion.String(), + Name: "foo-broker", + }, + }, + }, + { + name: "knative-broker-ref-in-namespace", + namespace: "test", + endpoint: v1alpha1.Endpoint{ + Ref: &corev1.ObjectReference{ + Kind: "Broker", + Namespace: "test", + APIVersion: eventing.SchemeGroupVersion.String(), + Name: "foo-broker", + }, + }, + }, + } + + for i, tc := range testcases { + t.Run(fmt.Sprintf("test-%d-%s", i, tc.name), func(t *testing.T) { + if tc.operatorNamespace != "" { + t.Setenv("NAMESPACE", tc.operatorNamespace) + } + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + client, err := test.NewFakeClient() + assert.NoError(t, err) + + bindingContext := BindingContext{ + Ctx: ctx, + Client: client, + Namespace: tc.namespace, + Profile: v1.DefaultTraitProfile, + } + + err = validateEndpoint(bindingContext, tc.endpoint) + assert.NoError(t, err) + }) + } +} + +func TestValidateEndpointError(t *testing.T) { + uri := "log:info" + + testcases := []struct { + name string + namespace string + operatorNamespace string + endpoint v1alpha1.Endpoint + }{ + { + name: "kamelet-ref-and-uri", + namespace: "test", + endpoint: v1alpha1.Endpoint{ + URI: &uri, + Ref: &corev1.ObjectReference{ + Kind: v1alpha1.KameletKind, + APIVersion: v1.SchemeGroupVersion.String(), + Name: "foo-kamelet", + }, + }, + }, + { + name: "kamelet-ref-cross-namespace", + namespace: "test", + endpoint: v1alpha1.Endpoint{ + Ref: &corev1.ObjectReference{ + Kind: v1alpha1.KameletKind, + Namespace: "other", + APIVersion: v1.SchemeGroupVersion.String(), + Name: "foo-kamelet", + }, + }, + }, + { + name: "knative-broker-ref-in-operator-namespace", + namespace: "test", + operatorNamespace: "global", + endpoint: v1alpha1.Endpoint{ + Ref: &corev1.ObjectReference{ + Kind: "Broker", + Namespace: "global", + APIVersion: eventing.SchemeGroupVersion.String(), + Name: "foo-broker", + }, + }, + }, + } + + for i, tc := range testcases { + t.Run(fmt.Sprintf("test-%d-%s", i, tc.name), func(t *testing.T) { + if tc.operatorNamespace != "" { + t.Setenv("NAMESPACE", tc.operatorNamespace) + } + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + client, err := test.NewFakeClient() + assert.NoError(t, err) + + bindingContext := BindingContext{ + Ctx: ctx, + Client: client, + Namespace: tc.namespace, + Profile: v1.DefaultTraitProfile, + } + + err = validateEndpoint(bindingContext, tc.endpoint) + assert.Error(t, err, "cross-namespace references are not allowed in Pipe") + }) + } +}