This is an automated email from the ASF dual-hosted git repository. claudio4j 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 67f98a92e fix(knative): Integration in error state when knative SinkBinding mode=inclusion #4119 (#4133) 67f98a92e is described below commit 67f98a92e009feba865c9abac9be5200775ca8a0 Author: Claudio Miranda <clau...@claudius.com.br> AuthorDate: Tue Mar 14 22:49:46 2023 -0300 fix(knative): Integration in error state when knative SinkBinding mode=inclusion #4119 (#4133) https://github.com/apache/camel-k/issues/4119 --- config/rbac/operator-role-knative.yaml | 7 ++ .../knative-sinkbinding-http/Rest2Channel.java | 26 ++++++++ .../knative-sinkbinding-http/messages-channel.yaml | 58 +---------------- .../knative-sinkbinding-http/sinkbinding.feature | 9 +++ .../knative-sinkbinding-http/yaks-config.yaml | 74 ++++++---------------- pkg/apis/camel/v1/trait/knative.go | 4 ++ pkg/resources/resources.go | 4 +- pkg/trait/knative.go | 10 +++ pkg/util/knative/knative.go | 34 ++++++++++ 9 files changed, 113 insertions(+), 113 deletions(-) diff --git a/config/rbac/operator-role-knative.yaml b/config/rbac/operator-role-knative.yaml index 8ef0f42b6..3cba80931 100644 --- a/config/rbac/operator-role-knative.yaml +++ b/config/rbac/operator-role-knative.yaml @@ -71,3 +71,10 @@ rules: - list - patch - update +- apiGroups: + - "" + resources: + - namespaces + verbs: + - get + - patch diff --git a/e2e/yaks/common/knative-sinkbinding-http/Rest2Channel.java b/e2e/yaks/common/knative-sinkbinding-http/Rest2Channel.java new file mode 100644 index 000000000..5eb905e57 --- /dev/null +++ b/e2e/yaks/common/knative-sinkbinding-http/Rest2Channel.java @@ -0,0 +1,26 @@ +/* + * 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. + */ + +import org.apache.camel.builder.RouteBuilder; + +public class Rest2Channel extends RouteBuilder { + public void configure() throws Exception { + rest("/") + .put("/foo/new") + .to("knative:channel/messages"); + } +} \ No newline at end of file diff --git a/config/rbac/operator-role-knative.yaml b/e2e/yaks/common/knative-sinkbinding-http/messages-channel.yaml similarity index 56% copy from config/rbac/operator-role-knative.yaml copy to e2e/yaks/common/knative-sinkbinding-http/messages-channel.yaml index 8ef0f42b6..c67517d92 100644 --- a/config/rbac/operator-role-knative.yaml +++ b/e2e/yaks/common/knative-sinkbinding-http/messages-channel.yaml @@ -15,59 +15,7 @@ # limitations under the License. # --------------------------------------------------------------------------- -kind: Role -apiVersion: rbac.authorization.k8s.io/v1 +apiVersion: messaging.knative.dev/v1 +kind: InMemoryChannel metadata: - name: camel-k-operator-knative - labels: - app: "camel-k" -rules: -- apiGroups: - - serving.knative.dev - resources: - - services - - routes - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - eventing.knative.dev - resources: - - triggers - - brokers - verbs: - - create - - delete - - get - - list - - patch - - update -- apiGroups: - - messaging.knative.dev - resources: - - subscriptions - - channels - - inmemorychannels - verbs: - - create - - delete - - get - - list - - patch - - update -- apiGroups: - - sources.knative.dev - resources: - - sinkbindings - verbs: - - create - - delete - - get - - list - - patch - - update + name: messages diff --git a/e2e/yaks/common/knative-sinkbinding-http/sinkbinding.feature b/e2e/yaks/common/knative-sinkbinding-http/sinkbinding.feature new file mode 100644 index 000000000..e5503b57b --- /dev/null +++ b/e2e/yaks/common/knative-sinkbinding-http/sinkbinding.feature @@ -0,0 +1,9 @@ +Feature: Camel K can run source HTTP endpoint in sinkbinding mode + + Background: + Given Kubernetes resource polling configuration + | maxAttempts | 1 | + | delayBetweenAttempts | 500 | + + Scenario: Integration knative-service starts with no errors + Given wait for condition=Ready on Kubernetes custom resource integration/rest2channel in integration.camel.apache.org/v1 diff --git a/config/rbac/operator-role-knative.yaml b/e2e/yaks/common/knative-sinkbinding-http/yaks-config.yaml similarity index 55% copy from config/rbac/operator-role-knative.yaml copy to e2e/yaks/common/knative-sinkbinding-http/yaks-config.yaml index 8ef0f42b6..e50bd2be4 100644 --- a/config/rbac/operator-role-knative.yaml +++ b/e2e/yaks/common/knative-sinkbinding-http/yaks-config.yaml @@ -15,59 +15,21 @@ # limitations under the License. # --------------------------------------------------------------------------- -kind: Role -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: camel-k-operator-knative - labels: - app: "camel-k" -rules: -- apiGroups: - - serving.knative.dev - resources: - - services - - routes - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - eventing.knative.dev - resources: - - triggers - - brokers - verbs: - - create - - delete - - get - - list - - patch - - update -- apiGroups: - - messaging.knative.dev - resources: - - subscriptions - - channels - - inmemorychannels - verbs: - - create - - delete - - get - - list - - patch - - update -- apiGroups: - - sources.knative.dev - resources: - - sinkbindings - verbs: - - create - - delete - - get - - list - - patch - - update +config: + namespace: + temporary: true +pre: +- name: installation + run: | + kubectl -n knative-eventing set env deployments eventing-webhook --containers="eventing-webhook" SINK_BINDING_SELECTION_MODE=inclusion + sleep 5s + + kubectl apply -n $YAKS_NAMESPACE -f messages-channel.yaml + + kamel run Rest2Channel.java -w -n $YAKS_NAMESPACE + + kubectl wait integration --all --for=condition=Ready --timeout=10m -n $YAKS_NAMESPACE +post: + - name: print dump + if: env:CI=true && failure() + run: yaks dump --includes app=camel-k diff --git a/pkg/apis/camel/v1/trait/knative.go b/pkg/apis/camel/v1/trait/knative.go index 666953b08..4495c6a48 100644 --- a/pkg/apis/camel/v1/trait/knative.go +++ b/pkg/apis/camel/v1/trait/knative.go @@ -57,4 +57,8 @@ type KnativeTrait struct { SinkBinding *bool `property:"sink-binding" json:"sinkBinding,omitempty"` // Enable automatic discovery of all trait properties. Auto *bool `property:"auto" json:"auto,omitempty"` + // Enables the camel-k-operator to set the "bindings.knative.dev/include=true" label to the namespace + // As Knative requires this label to perform injection of K_SINK URL into the service. + // If this is false, the integration pod may start and fail, read the SinkBinding Knative documentation. (default: true) + NamespaceLabel *bool `property:"namespace-label" json:"namespaceLabel,omitempty"` } diff --git a/pkg/resources/resources.go b/pkg/resources/resources.go index 98e8285a5..6e51234f3 100644 --- a/pkg/resources/resources.go +++ b/pkg/resources/resources.go @@ -392,9 +392,9 @@ var assets = func() http.FileSystem { "/rbac/operator-role-knative.yaml": &vfsgen۰CompressedFileInfo{ name: "operator-role-knative.yaml", modTime: time.Time{}, - uncompressedSize: 1677, + uncompressedSize: 1752, - compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x94\x41\x8f\xdb\x46\x0c\x85\xef\xf3\x2b\x1e\xac\x4b\x02\xac\xb5\x6d\x4f\x85\x7b\x72\x37\xbb\xad\xd1\xc0\x06\x56\x4e\x83\x1c\x29\x89\x96\x08\x4b\x33\x53\xce\xc8\x8a\xfb\xeb\x0b\x8d\xe5\xc6\xc1\x1e\xf6\xb2\xd1\xc5\x1c\xf9\x0d\xf9\x91\x8f\x76\x86\xe5\xdb\x3d\x26\xc3\x47\xa9\xd8\x06\xae\x11\x1d\x62\xcb\x58\x7b\xaa\x5a\x46\xe1\x0e\x71\x24\x65\x3c\xb9\xc1\xd6\x14\xc5\x59\xbc\x5b\x17\x4f\xef\x31\xd8\x9a\x15\xce\x32\x9c\x [...] + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x94\x41\x8f\xdb\x46\x0c\x85\xef\xfa\x15\x0f\xd6\x25\x01\xd6\x72\xdb\x53\xe1\x9e\xdc\xcd\x6e\x6b\x34\xb0\x81\x95\xd3\x20\x47\x4a\xa2\x25\xc2\xd2\xcc\x94\x33\xb2\xe2\xfe\xfa\x42\x23\xb9\x71\xb2\x87\xbd\xec\xea\x62\x8e\xcc\x21\x3f\xf2\x3d\x3b\xc5\xf2\xf5\x9e\x24\xc5\x47\x29\xd9\x78\xae\x10\x2c\x42\xc3\xd8\x38\x2a\x1b\x46\x6e\x8f\x61\x20\x65\x3c\xda\xde\x54\x14\xc4\x1a\xbc\xdb\xe4\x8f\xef\xd1\x9b\x8a\x15\xd6\x30\xac\x [...] }, "/rbac/operator-role-leases.yaml": &vfsgen۰CompressedFileInfo{ name: "operator-role-leases.yaml", diff --git a/pkg/trait/knative.go b/pkg/trait/knative.go index 935e0d03f..e53bb4cf7 100644 --- a/pkg/trait/knative.go +++ b/pkg/trait/knative.go @@ -469,6 +469,16 @@ func (t *knativeTrait) configureSinkBinding(e *Environment, env *knativeapi.Came APIVersion: ref.APIVersion, } + if pointer.BoolDeref(t.NamespaceLabel, true) { + // set the namespace label to allow automatic sinkbinding injection + enabled, err := knativeutil.EnableKnativeBindInNamespace(e.Ctx, e.Client, e.Integration.Namespace) + if err != nil { + t.L.Errorf(err, "Error setting label 'bindings.knative.dev/include=true' in namespace: %s", e.Integration.Namespace) + } else if enabled { + t.L.Infof("Label 'bindings.knative.dev/include=true' set in namespace: %s", e.Integration.Namespace) + } + } + // Add the SinkBinding in first position, to make sure it is created // before the reference source, so that the SinkBinding webhook has // all the information to perform injection. diff --git a/pkg/util/knative/knative.go b/pkg/util/knative/knative.go index 9a1d225b5..eae9b1c80 100644 --- a/pkg/util/knative/knative.go +++ b/pkg/util/knative/knative.go @@ -19,6 +19,7 @@ package knative import ( "context" + "encoding/json" "fmt" "net/url" @@ -27,6 +28,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" "knative.dev/pkg/apis" ctrl "sigs.k8s.io/controller-runtime/pkg/client" @@ -206,3 +208,35 @@ func getSinkURI(ctx context.Context, c client.Client, sink *corev1.ObjectReferen } return addressURL.String(), nil } + +// EnableKnativeBindInNamespace sets the "bindings.knative.dev/include=true" label to the namespace, only +// if there aren't any of these labels bindings.knative.dev/include bindings.knative.dev/exclude in the namespace +// Returns true if the label was set in the namespace +// https://knative.dev/docs/eventing/custom-event-source/sinkbinding/create-a-sinkbinding +func EnableKnativeBindInNamespace(ctx context.Context, client client.Client, namespace string) (bool, error) { + ns, err := client.CoreV1().Namespaces().Get(ctx, namespace, metav1.GetOptions{}) + if err != nil { + return false, err + } + + // if there are sinkbinding labels in the namespace, camel-k-operator respects it and doesn't proceed + sinkbindingLabelsExists := ns.Labels["bindings.knative.dev/include"] != "" || ns.Labels["bindings.knative.dev/exclude"] != "" + if sinkbindingLabelsExists { + return false, nil + } + + var jsonLabelPatch = map[string]interface{}{ + "metadata": map[string]interface{}{ + "labels": map[string]string{"bindings.knative.dev/include": "true"}, + }, + } + patch, err := json.Marshal(jsonLabelPatch) + if err != nil { + return false, err + } + _, err = client.CoreV1().Namespaces().Patch(ctx, namespace, types.MergePatchType, patch, metav1.PatchOptions{}) + if err != nil { + return false, err + } + return true, nil +}