You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by nf...@apache.org on 2020/10/06 12:21:48 UTC

[camel-k] 01/02: Fix #1686: add support for strimzi in kamelet binding

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

nferraro pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit 1a009eb225081a287ff06851f734d2d33c6a748e
Author: nicolaferraro <ni...@gmail.com>
AuthorDate: Fri Oct 2 15:46:17 2020 +0200

    Fix #1686: add support for strimzi in kamelet binding
---
 addons/register_strimzi.go                         |  27 ++++
 addons/strimzi/addtoscheme_strimzi_duck_v1beta1.go |  28 ++++
 .../v1beta1/client/internalclientset/clientset.go  |  98 +++++++++++++
 .../duck/v1beta1/client/internalclientset/doc.go   |  21 +++
 .../internalclientset/fake/clientset_generated.go  |  83 +++++++++++
 .../v1beta1/client/internalclientset/fake/doc.go   |  21 +++
 .../client/internalclientset/fake/register.go      |  57 ++++++++
 .../v1beta1/client/internalclientset/scheme/doc.go |  21 +++
 .../client/internalclientset/scheme/register.go    |  57 ++++++++
 .../internalclientset/typed/duck/v1beta1/doc.go    |  21 +++
 .../typed/duck/v1beta1/duck_client.go              |  95 ++++++++++++
 .../typed/duck/v1beta1/fake/doc.go                 |  21 +++
 .../typed/duck/v1beta1/fake/fake_duck_client.go    |  45 ++++++
 .../typed/duck/v1beta1/fake/fake_kafka.go          |  79 ++++++++++
 .../typed/duck/v1beta1/fake/fake_kafkatopic.go     |  79 ++++++++++
 .../typed/duck/v1beta1/generated_expansion.go      |  24 ++++
 .../internalclientset/typed/duck/v1beta1/kafka.go  | 103 +++++++++++++
 .../typed/duck/v1beta1/kafkatopic.go               | 103 +++++++++++++
 addons/strimzi/duck/v1beta1/doc.go                 |  21 +++
 addons/strimzi/duck/v1beta1/duck_types.go          |  83 +++++++++++
 addons/strimzi/duck/v1beta1/register.go            |  52 +++++++
 .../strimzi/duck/v1beta1/zz_generated.deepcopy.go  | 159 +++++++++++++++++++++
 addons/strimzi/strimzi.go                          | 119 +++++++++++++++
 addons/strimzi/strimzi_test.go                     | 113 +++++++++++++++
 ...el-k.v1.2.0-snapshot.clusterserviceversion.yaml |   9 ++
 deploy/operator-role-binding-strimzi.yaml          |  30 ++++
 deploy/operator-role-olm.yaml                      |   9 ++
 deploy/operator-role-strimzi.yaml                  |  33 +++++
 deploy/resources.go                                |  20 ++-
 helm/camel-k/templates/operator-role.yaml          |   9 ++
 pkg/controller/kameletbinding/initialize.go        |  10 +-
 pkg/install/operator.go                            |  14 ++
 pkg/util/bindings/api.go                           |  10 +-
 pkg/util/bindings/bindings_test.go                 |  16 ++-
 pkg/util/bindings/camel_uri.go                     |   2 +-
 pkg/util/bindings/catalog.go                       |  11 +-
 pkg/util/bindings/kamelet.go                       |   2 +-
 pkg/util/bindings/knative_ref.go                   |   2 +-
 pkg/util/bindings/knative_uri.go                   |   2 +-
 script/Makefile                                    |   8 +-
 script/gen_client_strimzi.sh                       |  39 +++++
 41 files changed, 1740 insertions(+), 16 deletions(-)

diff --git a/addons/register_strimzi.go b/addons/register_strimzi.go
new file mode 100644
index 0000000..9eac795
--- /dev/null
+++ b/addons/register_strimzi.go
@@ -0,0 +1,27 @@
+/*
+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 addons
+
+import (
+	"github.com/apache/camel-k/addons/strimzi"
+	"github.com/apache/camel-k/pkg/util/bindings"
+)
+
+func init() {
+	bindings.RegisterBindingProvider(strimzi.StrimziBindingProvider{})
+}
diff --git a/addons/strimzi/addtoscheme_strimzi_duck_v1beta1.go b/addons/strimzi/addtoscheme_strimzi_duck_v1beta1.go
new file mode 100644
index 0000000..d4af282
--- /dev/null
+++ b/addons/strimzi/addtoscheme_strimzi_duck_v1beta1.go
@@ -0,0 +1,28 @@
+/*
+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 strimzi
+
+import (
+	"github.com/apache/camel-k/addons/strimzi/duck/v1beta1"
+	"github.com/apache/camel-k/pkg/apis"
+)
+
+func init() {
+	// Register the types with the Scheme so the components can map objects to GroupVersionKinds and back
+	apis.AddToSchemes = append(apis.AddToSchemes, v1beta1.SchemeBuilder.AddToScheme)
+}
diff --git a/addons/strimzi/duck/v1beta1/client/internalclientset/clientset.go b/addons/strimzi/duck/v1beta1/client/internalclientset/clientset.go
new file mode 100644
index 0000000..e372c75
--- /dev/null
+++ b/addons/strimzi/duck/v1beta1/client/internalclientset/clientset.go
@@ -0,0 +1,98 @@
+/*
+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.
+*/
+
+// Code generated by client-gen. DO NOT EDIT.
+
+package internalclientset
+
+import (
+	"fmt"
+
+	kafkav1beta1 "github.com/apache/camel-k/addons/strimzi/duck/v1beta1/client/internalclientset/typed/duck/v1beta1"
+	discovery "k8s.io/client-go/discovery"
+	rest "k8s.io/client-go/rest"
+	flowcontrol "k8s.io/client-go/util/flowcontrol"
+)
+
+type Interface interface {
+	Discovery() discovery.DiscoveryInterface
+	KafkaV1beta1() kafkav1beta1.KafkaV1beta1Interface
+}
+
+// Clientset contains the clients for groups. Each group has exactly one
+// version included in a Clientset.
+type Clientset struct {
+	*discovery.DiscoveryClient
+	kafkaV1beta1 *kafkav1beta1.KafkaV1beta1Client
+}
+
+// KafkaV1beta1 retrieves the KafkaV1beta1Client
+func (c *Clientset) KafkaV1beta1() kafkav1beta1.KafkaV1beta1Interface {
+	return c.kafkaV1beta1
+}
+
+// Discovery retrieves the DiscoveryClient
+func (c *Clientset) Discovery() discovery.DiscoveryInterface {
+	if c == nil {
+		return nil
+	}
+	return c.DiscoveryClient
+}
+
+// NewForConfig creates a new Clientset for the given config.
+// If config's RateLimiter is not set and QPS and Burst are acceptable,
+// NewForConfig will generate a rate-limiter in configShallowCopy.
+func NewForConfig(c *rest.Config) (*Clientset, error) {
+	configShallowCopy := *c
+	if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 {
+		if configShallowCopy.Burst <= 0 {
+			return nil, fmt.Errorf("Burst is required to be greater than 0 when RateLimiter is not set and QPS is set to greater than 0")
+		}
+		configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst)
+	}
+	var cs Clientset
+	var err error
+	cs.kafkaV1beta1, err = kafkav1beta1.NewForConfig(&configShallowCopy)
+	if err != nil {
+		return nil, err
+	}
+
+	cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy)
+	if err != nil {
+		return nil, err
+	}
+	return &cs, nil
+}
+
+// NewForConfigOrDie creates a new Clientset for the given config and
+// panics if there is an error in the config.
+func NewForConfigOrDie(c *rest.Config) *Clientset {
+	var cs Clientset
+	cs.kafkaV1beta1 = kafkav1beta1.NewForConfigOrDie(c)
+
+	cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c)
+	return &cs
+}
+
+// New creates a new Clientset for the given RESTClient.
+func New(c rest.Interface) *Clientset {
+	var cs Clientset
+	cs.kafkaV1beta1 = kafkav1beta1.New(c)
+
+	cs.DiscoveryClient = discovery.NewDiscoveryClient(c)
+	return &cs
+}
diff --git a/addons/strimzi/duck/v1beta1/client/internalclientset/doc.go b/addons/strimzi/duck/v1beta1/client/internalclientset/doc.go
new file mode 100644
index 0000000..0eb96b7
--- /dev/null
+++ b/addons/strimzi/duck/v1beta1/client/internalclientset/doc.go
@@ -0,0 +1,21 @@
+/*
+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.
+*/
+
+// Code generated by client-gen. DO NOT EDIT.
+
+// This package has the automatically generated clientset.
+package internalclientset
diff --git a/addons/strimzi/duck/v1beta1/client/internalclientset/fake/clientset_generated.go b/addons/strimzi/duck/v1beta1/client/internalclientset/fake/clientset_generated.go
new file mode 100644
index 0000000..de14238
--- /dev/null
+++ b/addons/strimzi/duck/v1beta1/client/internalclientset/fake/clientset_generated.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.
+*/
+
+// Code generated by client-gen. DO NOT EDIT.
+
+package fake
+
+import (
+	clientset "github.com/apache/camel-k/addons/strimzi/duck/v1beta1/client/internalclientset"
+	kafkav1beta1 "github.com/apache/camel-k/addons/strimzi/duck/v1beta1/client/internalclientset/typed/duck/v1beta1"
+	fakekafkav1beta1 "github.com/apache/camel-k/addons/strimzi/duck/v1beta1/client/internalclientset/typed/duck/v1beta1/fake"
+	"k8s.io/apimachinery/pkg/runtime"
+	"k8s.io/apimachinery/pkg/watch"
+	"k8s.io/client-go/discovery"
+	fakediscovery "k8s.io/client-go/discovery/fake"
+	"k8s.io/client-go/testing"
+)
+
+// NewSimpleClientset returns a clientset that will respond with the provided objects.
+// It's backed by a very simple object tracker that processes creates, updates and deletions as-is,
+// without applying any validations and/or defaults. It shouldn't be considered a replacement
+// for a real clientset and is mostly useful in simple unit tests.
+func NewSimpleClientset(objects ...runtime.Object) *Clientset {
+	o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder())
+	for _, obj := range objects {
+		if err := o.Add(obj); err != nil {
+			panic(err)
+		}
+	}
+
+	cs := &Clientset{tracker: o}
+	cs.discovery = &fakediscovery.FakeDiscovery{Fake: &cs.Fake}
+	cs.AddReactor("*", "*", testing.ObjectReaction(o))
+	cs.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) {
+		gvr := action.GetResource()
+		ns := action.GetNamespace()
+		watch, err := o.Watch(gvr, ns)
+		if err != nil {
+			return false, nil, err
+		}
+		return true, watch, nil
+	})
+
+	return cs
+}
+
+// Clientset implements clientset.Interface. Meant to be embedded into a
+// struct to get a default implementation. This makes faking out just the method
+// you want to test easier.
+type Clientset struct {
+	testing.Fake
+	discovery *fakediscovery.FakeDiscovery
+	tracker   testing.ObjectTracker
+}
+
+func (c *Clientset) Discovery() discovery.DiscoveryInterface {
+	return c.discovery
+}
+
+func (c *Clientset) Tracker() testing.ObjectTracker {
+	return c.tracker
+}
+
+var _ clientset.Interface = &Clientset{}
+
+// KafkaV1beta1 retrieves the KafkaV1beta1Client
+func (c *Clientset) KafkaV1beta1() kafkav1beta1.KafkaV1beta1Interface {
+	return &fakekafkav1beta1.FakeKafkaV1beta1{Fake: &c.Fake}
+}
diff --git a/addons/strimzi/duck/v1beta1/client/internalclientset/fake/doc.go b/addons/strimzi/duck/v1beta1/client/internalclientset/fake/doc.go
new file mode 100644
index 0000000..9c6a5fa
--- /dev/null
+++ b/addons/strimzi/duck/v1beta1/client/internalclientset/fake/doc.go
@@ -0,0 +1,21 @@
+/*
+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.
+*/
+
+// Code generated by client-gen. DO NOT EDIT.
+
+// This package has the automatically generated fake clientset.
+package fake
diff --git a/addons/strimzi/duck/v1beta1/client/internalclientset/fake/register.go b/addons/strimzi/duck/v1beta1/client/internalclientset/fake/register.go
new file mode 100644
index 0000000..7c48520
--- /dev/null
+++ b/addons/strimzi/duck/v1beta1/client/internalclientset/fake/register.go
@@ -0,0 +1,57 @@
+/*
+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.
+*/
+
+// Code generated by client-gen. DO NOT EDIT.
+
+package fake
+
+import (
+	kafkav1beta1 "github.com/apache/camel-k/addons/strimzi/duck/v1beta1"
+	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	runtime "k8s.io/apimachinery/pkg/runtime"
+	schema "k8s.io/apimachinery/pkg/runtime/schema"
+	serializer "k8s.io/apimachinery/pkg/runtime/serializer"
+	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
+)
+
+var scheme = runtime.NewScheme()
+var codecs = serializer.NewCodecFactory(scheme)
+var parameterCodec = runtime.NewParameterCodec(scheme)
+var localSchemeBuilder = runtime.SchemeBuilder{
+	kafkav1beta1.AddToScheme,
+}
+
+// AddToScheme adds all types of this clientset into the given scheme. This allows composition
+// of clientsets, like in:
+//
+//   import (
+//     "k8s.io/client-go/kubernetes"
+//     clientsetscheme "k8s.io/client-go/kubernetes/scheme"
+//     aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme"
+//   )
+//
+//   kclientset, _ := kubernetes.NewForConfig(c)
+//   _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)
+//
+// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types
+// correctly.
+var AddToScheme = localSchemeBuilder.AddToScheme
+
+func init() {
+	v1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"})
+	utilruntime.Must(AddToScheme(scheme))
+}
diff --git a/addons/strimzi/duck/v1beta1/client/internalclientset/scheme/doc.go b/addons/strimzi/duck/v1beta1/client/internalclientset/scheme/doc.go
new file mode 100644
index 0000000..dd7d3b5
--- /dev/null
+++ b/addons/strimzi/duck/v1beta1/client/internalclientset/scheme/doc.go
@@ -0,0 +1,21 @@
+/*
+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.
+*/
+
+// Code generated by client-gen. DO NOT EDIT.
+
+// This package contains the scheme of the automatically generated clientset.
+package scheme
diff --git a/addons/strimzi/duck/v1beta1/client/internalclientset/scheme/register.go b/addons/strimzi/duck/v1beta1/client/internalclientset/scheme/register.go
new file mode 100644
index 0000000..4408b11
--- /dev/null
+++ b/addons/strimzi/duck/v1beta1/client/internalclientset/scheme/register.go
@@ -0,0 +1,57 @@
+/*
+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.
+*/
+
+// Code generated by client-gen. DO NOT EDIT.
+
+package scheme
+
+import (
+	kafkav1beta1 "github.com/apache/camel-k/addons/strimzi/duck/v1beta1"
+	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	runtime "k8s.io/apimachinery/pkg/runtime"
+	schema "k8s.io/apimachinery/pkg/runtime/schema"
+	serializer "k8s.io/apimachinery/pkg/runtime/serializer"
+	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
+)
+
+var Scheme = runtime.NewScheme()
+var Codecs = serializer.NewCodecFactory(Scheme)
+var ParameterCodec = runtime.NewParameterCodec(Scheme)
+var localSchemeBuilder = runtime.SchemeBuilder{
+	kafkav1beta1.AddToScheme,
+}
+
+// AddToScheme adds all types of this clientset into the given scheme. This allows composition
+// of clientsets, like in:
+//
+//   import (
+//     "k8s.io/client-go/kubernetes"
+//     clientsetscheme "k8s.io/client-go/kubernetes/scheme"
+//     aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme"
+//   )
+//
+//   kclientset, _ := kubernetes.NewForConfig(c)
+//   _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)
+//
+// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types
+// correctly.
+var AddToScheme = localSchemeBuilder.AddToScheme
+
+func init() {
+	v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"})
+	utilruntime.Must(AddToScheme(Scheme))
+}
diff --git a/addons/strimzi/duck/v1beta1/client/internalclientset/typed/duck/v1beta1/doc.go b/addons/strimzi/duck/v1beta1/client/internalclientset/typed/duck/v1beta1/doc.go
new file mode 100644
index 0000000..69b5e24
--- /dev/null
+++ b/addons/strimzi/duck/v1beta1/client/internalclientset/typed/duck/v1beta1/doc.go
@@ -0,0 +1,21 @@
+/*
+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.
+*/
+
+// Code generated by client-gen. DO NOT EDIT.
+
+// This package has the automatically generated typed clients.
+package v1beta1
diff --git a/addons/strimzi/duck/v1beta1/client/internalclientset/typed/duck/v1beta1/duck_client.go b/addons/strimzi/duck/v1beta1/client/internalclientset/typed/duck/v1beta1/duck_client.go
new file mode 100644
index 0000000..8608c2a
--- /dev/null
+++ b/addons/strimzi/duck/v1beta1/client/internalclientset/typed/duck/v1beta1/duck_client.go
@@ -0,0 +1,95 @@
+/*
+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.
+*/
+
+// Code generated by client-gen. DO NOT EDIT.
+
+package v1beta1
+
+import (
+	v1beta1 "github.com/apache/camel-k/addons/strimzi/duck/v1beta1"
+	"github.com/apache/camel-k/addons/strimzi/duck/v1beta1/client/internalclientset/scheme"
+	rest "k8s.io/client-go/rest"
+)
+
+type KafkaV1beta1Interface interface {
+	RESTClient() rest.Interface
+	KafkasGetter
+	KafkaTopicsGetter
+}
+
+// KafkaV1beta1Client is used to interact with features provided by the kafka.strimzi.io group.
+type KafkaV1beta1Client struct {
+	restClient rest.Interface
+}
+
+func (c *KafkaV1beta1Client) Kafkas(namespace string) KafkaInterface {
+	return newKafkas(c, namespace)
+}
+
+func (c *KafkaV1beta1Client) KafkaTopics(namespace string) KafkaTopicInterface {
+	return newKafkaTopics(c, namespace)
+}
+
+// NewForConfig creates a new KafkaV1beta1Client for the given config.
+func NewForConfig(c *rest.Config) (*KafkaV1beta1Client, error) {
+	config := *c
+	if err := setConfigDefaults(&config); err != nil {
+		return nil, err
+	}
+	client, err := rest.RESTClientFor(&config)
+	if err != nil {
+		return nil, err
+	}
+	return &KafkaV1beta1Client{client}, nil
+}
+
+// NewForConfigOrDie creates a new KafkaV1beta1Client for the given config and
+// panics if there is an error in the config.
+func NewForConfigOrDie(c *rest.Config) *KafkaV1beta1Client {
+	client, err := NewForConfig(c)
+	if err != nil {
+		panic(err)
+	}
+	return client
+}
+
+// New creates a new KafkaV1beta1Client for the given RESTClient.
+func New(c rest.Interface) *KafkaV1beta1Client {
+	return &KafkaV1beta1Client{c}
+}
+
+func setConfigDefaults(config *rest.Config) error {
+	gv := v1beta1.SchemeGroupVersion
+	config.GroupVersion = &gv
+	config.APIPath = "/apis"
+	config.NegotiatedSerializer = scheme.Codecs.WithoutConversion()
+
+	if config.UserAgent == "" {
+		config.UserAgent = rest.DefaultKubernetesUserAgent()
+	}
+
+	return nil
+}
+
+// RESTClient returns a RESTClient that is used to communicate
+// with API server by this client implementation.
+func (c *KafkaV1beta1Client) RESTClient() rest.Interface {
+	if c == nil {
+		return nil
+	}
+	return c.restClient
+}
diff --git a/addons/strimzi/duck/v1beta1/client/internalclientset/typed/duck/v1beta1/fake/doc.go b/addons/strimzi/duck/v1beta1/client/internalclientset/typed/duck/v1beta1/fake/doc.go
new file mode 100644
index 0000000..5d1c76c
--- /dev/null
+++ b/addons/strimzi/duck/v1beta1/client/internalclientset/typed/duck/v1beta1/fake/doc.go
@@ -0,0 +1,21 @@
+/*
+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.
+*/
+
+// Code generated by client-gen. DO NOT EDIT.
+
+// Package fake has the automatically generated clients.
+package fake
diff --git a/addons/strimzi/duck/v1beta1/client/internalclientset/typed/duck/v1beta1/fake/fake_duck_client.go b/addons/strimzi/duck/v1beta1/client/internalclientset/typed/duck/v1beta1/fake/fake_duck_client.go
new file mode 100644
index 0000000..bfeb3b9
--- /dev/null
+++ b/addons/strimzi/duck/v1beta1/client/internalclientset/typed/duck/v1beta1/fake/fake_duck_client.go
@@ -0,0 +1,45 @@
+/*
+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.
+*/
+
+// Code generated by client-gen. DO NOT EDIT.
+
+package fake
+
+import (
+	v1beta1 "github.com/apache/camel-k/addons/strimzi/duck/v1beta1/client/internalclientset/typed/duck/v1beta1"
+	rest "k8s.io/client-go/rest"
+	testing "k8s.io/client-go/testing"
+)
+
+type FakeKafkaV1beta1 struct {
+	*testing.Fake
+}
+
+func (c *FakeKafkaV1beta1) Kafkas(namespace string) v1beta1.KafkaInterface {
+	return &FakeKafkas{c, namespace}
+}
+
+func (c *FakeKafkaV1beta1) KafkaTopics(namespace string) v1beta1.KafkaTopicInterface {
+	return &FakeKafkaTopics{c, namespace}
+}
+
+// RESTClient returns a RESTClient that is used to communicate
+// with API server by this client implementation.
+func (c *FakeKafkaV1beta1) RESTClient() rest.Interface {
+	var ret *rest.RESTClient
+	return ret
+}
diff --git a/addons/strimzi/duck/v1beta1/client/internalclientset/typed/duck/v1beta1/fake/fake_kafka.go b/addons/strimzi/duck/v1beta1/client/internalclientset/typed/duck/v1beta1/fake/fake_kafka.go
new file mode 100644
index 0000000..09d6e59
--- /dev/null
+++ b/addons/strimzi/duck/v1beta1/client/internalclientset/typed/duck/v1beta1/fake/fake_kafka.go
@@ -0,0 +1,79 @@
+/*
+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.
+*/
+
+// Code generated by client-gen. DO NOT EDIT.
+
+package fake
+
+import (
+	v1beta1 "github.com/apache/camel-k/addons/strimzi/duck/v1beta1"
+	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	labels "k8s.io/apimachinery/pkg/labels"
+	schema "k8s.io/apimachinery/pkg/runtime/schema"
+	watch "k8s.io/apimachinery/pkg/watch"
+	testing "k8s.io/client-go/testing"
+)
+
+// FakeKafkas implements KafkaInterface
+type FakeKafkas struct {
+	Fake *FakeKafkaV1beta1
+	ns   string
+}
+
+var kafkasResource = schema.GroupVersionResource{Group: "kafka.strimzi.io", Version: "v1beta1", Resource: "kafkas"}
+
+var kafkasKind = schema.GroupVersionKind{Group: "kafka.strimzi.io", Version: "v1beta1", Kind: "Kafka"}
+
+// Get takes name of the kafka, and returns the corresponding kafka object, and an error if there is any.
+func (c *FakeKafkas) Get(name string, options v1.GetOptions) (result *v1beta1.Kafka, err error) {
+	obj, err := c.Fake.
+		Invokes(testing.NewGetAction(kafkasResource, c.ns, name), &v1beta1.Kafka{})
+
+	if obj == nil {
+		return nil, err
+	}
+	return obj.(*v1beta1.Kafka), err
+}
+
+// List takes label and field selectors, and returns the list of Kafkas that match those selectors.
+func (c *FakeKafkas) List(opts v1.ListOptions) (result *v1beta1.KafkaList, err error) {
+	obj, err := c.Fake.
+		Invokes(testing.NewListAction(kafkasResource, kafkasKind, c.ns, opts), &v1beta1.KafkaList{})
+
+	if obj == nil {
+		return nil, err
+	}
+
+	label, _, _ := testing.ExtractFromListOptions(opts)
+	if label == nil {
+		label = labels.Everything()
+	}
+	list := &v1beta1.KafkaList{ListMeta: obj.(*v1beta1.KafkaList).ListMeta}
+	for _, item := range obj.(*v1beta1.KafkaList).Items {
+		if label.Matches(labels.Set(item.Labels)) {
+			list.Items = append(list.Items, item)
+		}
+	}
+	return list, err
+}
+
+// Watch returns a watch.Interface that watches the requested kafkas.
+func (c *FakeKafkas) Watch(opts v1.ListOptions) (watch.Interface, error) {
+	return c.Fake.
+		InvokesWatch(testing.NewWatchAction(kafkasResource, c.ns, opts))
+
+}
diff --git a/addons/strimzi/duck/v1beta1/client/internalclientset/typed/duck/v1beta1/fake/fake_kafkatopic.go b/addons/strimzi/duck/v1beta1/client/internalclientset/typed/duck/v1beta1/fake/fake_kafkatopic.go
new file mode 100644
index 0000000..4a21468
--- /dev/null
+++ b/addons/strimzi/duck/v1beta1/client/internalclientset/typed/duck/v1beta1/fake/fake_kafkatopic.go
@@ -0,0 +1,79 @@
+/*
+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.
+*/
+
+// Code generated by client-gen. DO NOT EDIT.
+
+package fake
+
+import (
+	v1beta1 "github.com/apache/camel-k/addons/strimzi/duck/v1beta1"
+	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	labels "k8s.io/apimachinery/pkg/labels"
+	schema "k8s.io/apimachinery/pkg/runtime/schema"
+	watch "k8s.io/apimachinery/pkg/watch"
+	testing "k8s.io/client-go/testing"
+)
+
+// FakeKafkaTopics implements KafkaTopicInterface
+type FakeKafkaTopics struct {
+	Fake *FakeKafkaV1beta1
+	ns   string
+}
+
+var kafkatopicsResource = schema.GroupVersionResource{Group: "kafka.strimzi.io", Version: "v1beta1", Resource: "kafkatopics"}
+
+var kafkatopicsKind = schema.GroupVersionKind{Group: "kafka.strimzi.io", Version: "v1beta1", Kind: "KafkaTopic"}
+
+// Get takes name of the kafkaTopic, and returns the corresponding kafkaTopic object, and an error if there is any.
+func (c *FakeKafkaTopics) Get(name string, options v1.GetOptions) (result *v1beta1.KafkaTopic, err error) {
+	obj, err := c.Fake.
+		Invokes(testing.NewGetAction(kafkatopicsResource, c.ns, name), &v1beta1.KafkaTopic{})
+
+	if obj == nil {
+		return nil, err
+	}
+	return obj.(*v1beta1.KafkaTopic), err
+}
+
+// List takes label and field selectors, and returns the list of KafkaTopics that match those selectors.
+func (c *FakeKafkaTopics) List(opts v1.ListOptions) (result *v1beta1.KafkaTopicList, err error) {
+	obj, err := c.Fake.
+		Invokes(testing.NewListAction(kafkatopicsResource, kafkatopicsKind, c.ns, opts), &v1beta1.KafkaTopicList{})
+
+	if obj == nil {
+		return nil, err
+	}
+
+	label, _, _ := testing.ExtractFromListOptions(opts)
+	if label == nil {
+		label = labels.Everything()
+	}
+	list := &v1beta1.KafkaTopicList{ListMeta: obj.(*v1beta1.KafkaTopicList).ListMeta}
+	for _, item := range obj.(*v1beta1.KafkaTopicList).Items {
+		if label.Matches(labels.Set(item.Labels)) {
+			list.Items = append(list.Items, item)
+		}
+	}
+	return list, err
+}
+
+// Watch returns a watch.Interface that watches the requested kafkaTopics.
+func (c *FakeKafkaTopics) Watch(opts v1.ListOptions) (watch.Interface, error) {
+	return c.Fake.
+		InvokesWatch(testing.NewWatchAction(kafkatopicsResource, c.ns, opts))
+
+}
diff --git a/addons/strimzi/duck/v1beta1/client/internalclientset/typed/duck/v1beta1/generated_expansion.go b/addons/strimzi/duck/v1beta1/client/internalclientset/typed/duck/v1beta1/generated_expansion.go
new file mode 100644
index 0000000..218890c
--- /dev/null
+++ b/addons/strimzi/duck/v1beta1/client/internalclientset/typed/duck/v1beta1/generated_expansion.go
@@ -0,0 +1,24 @@
+/*
+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.
+*/
+
+// Code generated by client-gen. DO NOT EDIT.
+
+package v1beta1
+
+type KafkaExpansion interface{}
+
+type KafkaTopicExpansion interface{}
diff --git a/addons/strimzi/duck/v1beta1/client/internalclientset/typed/duck/v1beta1/kafka.go b/addons/strimzi/duck/v1beta1/client/internalclientset/typed/duck/v1beta1/kafka.go
new file mode 100644
index 0000000..8a3e627
--- /dev/null
+++ b/addons/strimzi/duck/v1beta1/client/internalclientset/typed/duck/v1beta1/kafka.go
@@ -0,0 +1,103 @@
+/*
+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.
+*/
+
+// Code generated by client-gen. DO NOT EDIT.
+
+package v1beta1
+
+import (
+	"time"
+
+	v1beta1 "github.com/apache/camel-k/addons/strimzi/duck/v1beta1"
+	scheme "github.com/apache/camel-k/addons/strimzi/duck/v1beta1/client/internalclientset/scheme"
+	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	watch "k8s.io/apimachinery/pkg/watch"
+	rest "k8s.io/client-go/rest"
+)
+
+// KafkasGetter has a method to return a KafkaInterface.
+// A group's client should implement this interface.
+type KafkasGetter interface {
+	Kafkas(namespace string) KafkaInterface
+}
+
+// KafkaInterface has methods to work with Kafka resources.
+type KafkaInterface interface {
+	Get(name string, options v1.GetOptions) (*v1beta1.Kafka, error)
+	List(opts v1.ListOptions) (*v1beta1.KafkaList, error)
+	Watch(opts v1.ListOptions) (watch.Interface, error)
+	KafkaExpansion
+}
+
+// kafkas implements KafkaInterface
+type kafkas struct {
+	client rest.Interface
+	ns     string
+}
+
+// newKafkas returns a Kafkas
+func newKafkas(c *KafkaV1beta1Client, namespace string) *kafkas {
+	return &kafkas{
+		client: c.RESTClient(),
+		ns:     namespace,
+	}
+}
+
+// Get takes name of the kafka, and returns the corresponding kafka object, and an error if there is any.
+func (c *kafkas) Get(name string, options v1.GetOptions) (result *v1beta1.Kafka, err error) {
+	result = &v1beta1.Kafka{}
+	err = c.client.Get().
+		Namespace(c.ns).
+		Resource("kafkas").
+		Name(name).
+		VersionedParams(&options, scheme.ParameterCodec).
+		Do().
+		Into(result)
+	return
+}
+
+// List takes label and field selectors, and returns the list of Kafkas that match those selectors.
+func (c *kafkas) List(opts v1.ListOptions) (result *v1beta1.KafkaList, err error) {
+	var timeout time.Duration
+	if opts.TimeoutSeconds != nil {
+		timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
+	}
+	result = &v1beta1.KafkaList{}
+	err = c.client.Get().
+		Namespace(c.ns).
+		Resource("kafkas").
+		VersionedParams(&opts, scheme.ParameterCodec).
+		Timeout(timeout).
+		Do().
+		Into(result)
+	return
+}
+
+// Watch returns a watch.Interface that watches the requested kafkas.
+func (c *kafkas) Watch(opts v1.ListOptions) (watch.Interface, error) {
+	var timeout time.Duration
+	if opts.TimeoutSeconds != nil {
+		timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
+	}
+	opts.Watch = true
+	return c.client.Get().
+		Namespace(c.ns).
+		Resource("kafkas").
+		VersionedParams(&opts, scheme.ParameterCodec).
+		Timeout(timeout).
+		Watch()
+}
diff --git a/addons/strimzi/duck/v1beta1/client/internalclientset/typed/duck/v1beta1/kafkatopic.go b/addons/strimzi/duck/v1beta1/client/internalclientset/typed/duck/v1beta1/kafkatopic.go
new file mode 100644
index 0000000..4ae4628
--- /dev/null
+++ b/addons/strimzi/duck/v1beta1/client/internalclientset/typed/duck/v1beta1/kafkatopic.go
@@ -0,0 +1,103 @@
+/*
+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.
+*/
+
+// Code generated by client-gen. DO NOT EDIT.
+
+package v1beta1
+
+import (
+	"time"
+
+	v1beta1 "github.com/apache/camel-k/addons/strimzi/duck/v1beta1"
+	scheme "github.com/apache/camel-k/addons/strimzi/duck/v1beta1/client/internalclientset/scheme"
+	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	watch "k8s.io/apimachinery/pkg/watch"
+	rest "k8s.io/client-go/rest"
+)
+
+// KafkaTopicsGetter has a method to return a KafkaTopicInterface.
+// A group's client should implement this interface.
+type KafkaTopicsGetter interface {
+	KafkaTopics(namespace string) KafkaTopicInterface
+}
+
+// KafkaTopicInterface has methods to work with KafkaTopic resources.
+type KafkaTopicInterface interface {
+	Get(name string, options v1.GetOptions) (*v1beta1.KafkaTopic, error)
+	List(opts v1.ListOptions) (*v1beta1.KafkaTopicList, error)
+	Watch(opts v1.ListOptions) (watch.Interface, error)
+	KafkaTopicExpansion
+}
+
+// kafkaTopics implements KafkaTopicInterface
+type kafkaTopics struct {
+	client rest.Interface
+	ns     string
+}
+
+// newKafkaTopics returns a KafkaTopics
+func newKafkaTopics(c *KafkaV1beta1Client, namespace string) *kafkaTopics {
+	return &kafkaTopics{
+		client: c.RESTClient(),
+		ns:     namespace,
+	}
+}
+
+// Get takes name of the kafkaTopic, and returns the corresponding kafkaTopic object, and an error if there is any.
+func (c *kafkaTopics) Get(name string, options v1.GetOptions) (result *v1beta1.KafkaTopic, err error) {
+	result = &v1beta1.KafkaTopic{}
+	err = c.client.Get().
+		Namespace(c.ns).
+		Resource("kafkatopics").
+		Name(name).
+		VersionedParams(&options, scheme.ParameterCodec).
+		Do().
+		Into(result)
+	return
+}
+
+// List takes label and field selectors, and returns the list of KafkaTopics that match those selectors.
+func (c *kafkaTopics) List(opts v1.ListOptions) (result *v1beta1.KafkaTopicList, err error) {
+	var timeout time.Duration
+	if opts.TimeoutSeconds != nil {
+		timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
+	}
+	result = &v1beta1.KafkaTopicList{}
+	err = c.client.Get().
+		Namespace(c.ns).
+		Resource("kafkatopics").
+		VersionedParams(&opts, scheme.ParameterCodec).
+		Timeout(timeout).
+		Do().
+		Into(result)
+	return
+}
+
+// Watch returns a watch.Interface that watches the requested kafkaTopics.
+func (c *kafkaTopics) Watch(opts v1.ListOptions) (watch.Interface, error) {
+	var timeout time.Duration
+	if opts.TimeoutSeconds != nil {
+		timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
+	}
+	opts.Watch = true
+	return c.client.Get().
+		Namespace(c.ns).
+		Resource("kafkatopics").
+		VersionedParams(&opts, scheme.ParameterCodec).
+		Timeout(timeout).
+		Watch()
+}
diff --git a/addons/strimzi/duck/v1beta1/doc.go b/addons/strimzi/duck/v1beta1/doc.go
new file mode 100644
index 0000000..cc460f0
--- /dev/null
+++ b/addons/strimzi/duck/v1beta1/doc.go
@@ -0,0 +1,21 @@
+/*
+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 duck contains a partial schema of the Strimzi APIs
+// +k8s:deepcopy-gen=package,register
+// +groupName=kafka.strimzi.io
+package v1beta1
diff --git a/addons/strimzi/duck/v1beta1/duck_types.go b/addons/strimzi/duck/v1beta1/duck_types.go
new file mode 100644
index 0000000..1828175
--- /dev/null
+++ b/addons/strimzi/duck/v1beta1/duck_types.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 duck contains duck-types for accessing Strimzi resources
+package v1beta1
+
+import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
+const (
+	StrimziGroup            = "kafka.strimzi.io"
+	StrimziVersion          = "v1beta1"
+	StrimziKindTopic        = "KafkaTopic"
+	StrimziKindKafkaCluster = "Kafka"
+
+	StrimziKafkaClusterLabel = "strimzi.io/cluster"
+
+	StrimziListenerTypePlain = "plain"
+)
+
+// +kubebuilder:object:root=true
+// +genclient
+// +genclient:onlyVerbs=get,list,watch
+// +genclient:noStatus
+
+// KafkaTopic is the duck of a KafkaTopic
+type KafkaTopic struct {
+	metav1.TypeMeta   `json:",inline"`
+	metav1.ObjectMeta `json:"metadata,omitempty"`
+}
+
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+// KafkaTopicList contains a list of KafkaTopic
+type KafkaTopicList struct {
+	metav1.TypeMeta `json:",inline"`
+	metav1.ListMeta `json:"metadata,omitempty"`
+	Items           []KafkaTopic `json:"items"`
+}
+
+// +kubebuilder:object:root=true
+// +genclient
+// +genclient:onlyVerbs=get,list,watch
+// +genclient:noStatus
+
+// Kafka is the duck of a Kafka
+type Kafka struct {
+	metav1.TypeMeta   `json:",inline"`
+	metav1.ObjectMeta `json:"metadata,omitempty"`
+
+	Status KafkaStatus `json:"status,omitempty"`
+}
+
+// KafkaStatus contains the relevant info of the Kafka status
+type KafkaStatus struct {
+	Listeners []KafkaStatusListener `json:"listeners,omitempty"`
+}
+
+// KafkaStatusListener contains listener information
+type KafkaStatusListener struct {
+	BootstrapServers string `json:"bootstrapServers,omitempty"`
+	Type             string `json:"type,omitempty"`
+}
+
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+// KafkaList contains a list of Kafka
+type KafkaList struct {
+	metav1.TypeMeta `json:",inline"`
+	metav1.ListMeta `json:"metadata,omitempty"`
+	Items           []Kafka `json:"items"`
+}
diff --git a/addons/strimzi/duck/v1beta1/register.go b/addons/strimzi/duck/v1beta1/register.go
new file mode 100644
index 0000000..203ddee
--- /dev/null
+++ b/addons/strimzi/duck/v1beta1/register.go
@@ -0,0 +1,52 @@
+/*
+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 v1beta1
+
+import (
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/runtime"
+	"k8s.io/apimachinery/pkg/runtime/schema"
+)
+
+var (
+	// SchemeGroupVersion is group version used to register these objects
+	SchemeGroupVersion = schema.GroupVersion{Group: StrimziGroup, Version: StrimziVersion}
+
+	// SchemeBuilder is used to add go types to the GroupVersionKind scheme
+	SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
+
+	// AddToScheme is a shortcut to SchemeBuilder.AddToScheme
+	AddToScheme = SchemeBuilder.AddToScheme
+)
+
+// Resource takes an unqualified resource and returns a Group qualified GroupResource
+func Resource(resource string) schema.GroupResource {
+	return SchemeGroupVersion.WithResource(resource).GroupResource()
+}
+
+// Adds the list of known types to Scheme.
+func addKnownTypes(scheme *runtime.Scheme) error {
+	scheme.AddKnownTypes(SchemeGroupVersion,
+		&KafkaTopic{},
+		&KafkaTopicList{},
+		&Kafka{},
+		&KafkaList{},
+	)
+	metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
+	return nil
+}
diff --git a/addons/strimzi/duck/v1beta1/zz_generated.deepcopy.go b/addons/strimzi/duck/v1beta1/zz_generated.deepcopy.go
new file mode 100644
index 0000000..7b7e8fa
--- /dev/null
+++ b/addons/strimzi/duck/v1beta1/zz_generated.deepcopy.go
@@ -0,0 +1,159 @@
+// +build !ignore_autogenerated
+
+// Code generated by controller-gen. DO NOT EDIT.
+
+package v1beta1
+
+import (
+	"k8s.io/apimachinery/pkg/runtime"
+)
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Kafka) DeepCopyInto(out *Kafka) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+	in.Status.DeepCopyInto(&out.Status)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Kafka.
+func (in *Kafka) DeepCopy() *Kafka {
+	if in == nil {
+		return nil
+	}
+	out := new(Kafka)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *Kafka) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *KafkaList) DeepCopyInto(out *KafkaList) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	in.ListMeta.DeepCopyInto(&out.ListMeta)
+	if in.Items != nil {
+		in, out := &in.Items, &out.Items
+		*out = make([]Kafka, len(*in))
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KafkaList.
+func (in *KafkaList) DeepCopy() *KafkaList {
+	if in == nil {
+		return nil
+	}
+	out := new(KafkaList)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *KafkaList) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *KafkaStatus) DeepCopyInto(out *KafkaStatus) {
+	*out = *in
+	if in.Listeners != nil {
+		in, out := &in.Listeners, &out.Listeners
+		*out = make([]KafkaStatusListener, len(*in))
+		copy(*out, *in)
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KafkaStatus.
+func (in *KafkaStatus) DeepCopy() *KafkaStatus {
+	if in == nil {
+		return nil
+	}
+	out := new(KafkaStatus)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *KafkaStatusListener) DeepCopyInto(out *KafkaStatusListener) {
+	*out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KafkaStatusListener.
+func (in *KafkaStatusListener) DeepCopy() *KafkaStatusListener {
+	if in == nil {
+		return nil
+	}
+	out := new(KafkaStatusListener)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *KafkaTopic) DeepCopyInto(out *KafkaTopic) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KafkaTopic.
+func (in *KafkaTopic) DeepCopy() *KafkaTopic {
+	if in == nil {
+		return nil
+	}
+	out := new(KafkaTopic)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *KafkaTopic) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *KafkaTopicList) DeepCopyInto(out *KafkaTopicList) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	in.ListMeta.DeepCopyInto(&out.ListMeta)
+	if in.Items != nil {
+		in, out := &in.Items, &out.Items
+		*out = make([]KafkaTopic, len(*in))
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KafkaTopicList.
+func (in *KafkaTopicList) DeepCopy() *KafkaTopicList {
+	if in == nil {
+		return nil
+	}
+	out := new(KafkaTopicList)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *KafkaTopicList) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
diff --git a/addons/strimzi/strimzi.go b/addons/strimzi/strimzi.go
new file mode 100644
index 0000000..0ebf265
--- /dev/null
+++ b/addons/strimzi/strimzi.go
@@ -0,0 +1,119 @@
+/*
+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 strimzi contains integrations with the Strimzi project for running Apache Kafka on Kubernetes
+package strimzi
+
+import (
+	"fmt"
+
+	"github.com/apache/camel-k/addons/strimzi/duck/v1beta1"
+	"github.com/apache/camel-k/addons/strimzi/duck/v1beta1/client/internalclientset"
+	typedclient "github.com/apache/camel-k/addons/strimzi/duck/v1beta1/client/internalclientset/typed/duck/v1beta1"
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+	"github.com/apache/camel-k/pkg/util/bindings"
+	"github.com/apache/camel-k/pkg/util/uri"
+	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/runtime/schema"
+)
+
+// StrimziBindingProvider allows to connect to a Kafka topic via KameletBinding
+type StrimziBindingProvider struct {
+	Client typedclient.KafkaV1beta1Interface
+}
+
+func (s StrimziBindingProvider) ID() string {
+	return "strimzi"
+}
+
+func (s StrimziBindingProvider) Translate(ctx bindings.BindingContext, _ v1alpha1.EndpointType, endpoint v1alpha1.Endpoint) (*bindings.Binding, error) {
+	if endpoint.Ref == nil {
+		// React only on refs
+		return nil, nil
+	}
+	gv, err := schema.ParseGroupVersion(endpoint.Ref.APIVersion)
+	if err != nil {
+		return nil, err
+	}
+
+	if gv.Group != v1beta1.StrimziGroup || endpoint.Ref.Kind != v1beta1.StrimziKindTopic {
+		// Only operates on Strimzi Topics
+		return nil, nil
+	}
+
+	props, err := endpoint.Properties.GetPropertyMap()
+	if err != nil {
+		return nil, err
+	}
+	if props == nil {
+		props = make(map[string]string)
+	}
+
+	if props["brokers"] == "" {
+		// build the client if needed
+		if s.Client == nil {
+			kafkaClient, err := internalclientset.NewForConfig(ctx.Client.GetConfig())
+			if err != nil {
+				return nil, err
+			}
+			s.Client = kafkaClient.KafkaV1beta1()
+		}
+
+		// look them up
+		topic, err := s.Client.KafkaTopics(ctx.Namespace).Get(endpoint.Ref.Name, v1.GetOptions{})
+		if err != nil {
+			return nil, err
+		}
+
+		clusterName := topic.Labels[v1beta1.StrimziKafkaClusterLabel]
+		if clusterName == "" {
+			return nil, fmt.Errorf("no %q label defined on topic %s", v1beta1.StrimziKafkaClusterLabel, endpoint.Ref.Name)
+		}
+
+		cluster, err := s.Client.Kafkas(ctx.Namespace).Get(clusterName, v1.GetOptions{})
+		if err != nil {
+			return nil, err
+		}
+
+		var listener *v1beta1.KafkaStatusListener
+		for _, l := range cluster.Status.Listeners {
+			if l.Type == v1beta1.StrimziListenerTypePlain {
+				listener = &l
+				break
+			}
+		}
+
+		if listener == nil {
+			return nil, fmt.Errorf("cluster %q has no listeners of type %q", clusterName, v1beta1.StrimziListenerTypePlain)
+		}
+		if listener.BootstrapServers == "" {
+			return nil, fmt.Errorf("cluster %q has no bootstrap servers in %q listener", clusterName, v1beta1.StrimziListenerTypePlain)
+		}
+		props["brokers"] = listener.BootstrapServers
+	}
+
+	kafkaURI := fmt.Sprintf("kafka:%s", endpoint.Ref.Name)
+	kafkaURI = uri.AppendParameters(kafkaURI, props)
+
+	return &bindings.Binding{
+		URI: kafkaURI,
+	}, nil
+}
+
+func (s StrimziBindingProvider) Order() int {
+	return bindings.OrderStandard
+}
diff --git a/addons/strimzi/strimzi_test.go b/addons/strimzi/strimzi_test.go
new file mode 100644
index 0000000..ad90835
--- /dev/null
+++ b/addons/strimzi/strimzi_test.go
@@ -0,0 +1,113 @@
+package strimzi
+
+import (
+	"context"
+	"encoding/json"
+	"github.com/apache/camel-k/addons/strimzi/duck/v1beta1"
+	"github.com/apache/camel-k/addons/strimzi/duck/v1beta1/client/internalclientset/fake"
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+	"github.com/apache/camel-k/pkg/util/bindings"
+	"github.com/apache/camel-k/pkg/util/test"
+	"github.com/stretchr/testify/assert"
+	v1 "k8s.io/api/core/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"testing"
+)
+
+func TestStrimziDirect(t *testing.T) {
+	ctx, cancel := context.WithCancel(context.Background())
+	defer cancel()
+
+	client, err := test.NewFakeClient()
+	assert.NoError(t, err)
+
+	bindingContext := bindings.BindingContext{
+		Ctx:       ctx,
+		Client:    client,
+		Namespace: "test",
+	}
+
+	endpoint := v1alpha1.Endpoint{
+		Ref: &v1.ObjectReference{
+			Kind:       "KafkaTopic",
+			Name:       "mytopic",
+			APIVersion: "kafka.strimzi.io/v1beta1",
+		},
+		Properties: asEndpointProperties(map[string]string{
+			"brokers": "my-cluster-kafka-bootstrap:9092",
+		}),
+	}
+
+	binding, err := StrimziBindingProvider{}.Translate(bindingContext, v1alpha1.EndpointTypeSink, endpoint)
+	assert.NoError(t, err)
+	assert.NotNil(t, binding)
+	assert.Equal(t, "kafka:mytopic?brokers=my-cluster-kafka-bootstrap%3A9092", binding.URI)
+	assert.Nil(t, binding.Traits)
+}
+
+func TestStrimziLookup(t *testing.T) {
+	ctx, cancel := context.WithCancel(context.Background())
+	defer cancel()
+
+	cluster := v1beta1.Kafka{
+		ObjectMeta: metav1.ObjectMeta{
+			Namespace: "test",
+			Name:      "myclusterx",
+		},
+		Status: v1beta1.KafkaStatus{
+			Listeners: []v1beta1.KafkaStatusListener{
+				{
+					Type: "tls",
+				},
+				{
+					BootstrapServers: "my-clusterx-kafka-bootstrap:9092",
+					Type:             "plain",
+				},
+			},
+		},
+	}
+
+	topic := v1beta1.KafkaTopic{
+		ObjectMeta: metav1.ObjectMeta{
+			Namespace: "test",
+			Name:      "mytopicy",
+			Labels: map[string]string{
+				v1beta1.StrimziKafkaClusterLabel: "myclusterx",
+			},
+		},
+	}
+
+	client := fake.NewSimpleClientset(&cluster, &topic)
+	provider := StrimziBindingProvider{
+		Client: client.KafkaV1beta1(),
+	}
+
+	bindingContext := bindings.BindingContext{
+		Ctx:       ctx,
+		Namespace: "test",
+	}
+
+	endpoint := v1alpha1.Endpoint{
+		Ref: &v1.ObjectReference{
+			Kind:       "KafkaTopic",
+			Name:       "mytopicy",
+			APIVersion: "kafka.strimzi.io/v1beta1",
+		},
+	}
+
+	binding, err := provider.Translate(bindingContext, v1alpha1.EndpointTypeSink, endpoint)
+	assert.NoError(t, err)
+	assert.NotNil(t, binding)
+	assert.Equal(t, "kafka:mytopicy?brokers=my-clusterx-kafka-bootstrap%3A9092", binding.URI)
+	assert.Nil(t, binding.Traits)
+}
+
+func asEndpointProperties(props map[string]string) v1alpha1.EndpointProperties {
+	serialized, err := json.Marshal(props)
+	if err != nil {
+		panic(err)
+	}
+	return v1alpha1.EndpointProperties{
+		RawMessage: serialized,
+	}
+}
diff --git a/deploy/olm-catalog/camel-k-dev/1.2.0-snapshot/camel-k.v1.2.0-snapshot.clusterserviceversion.yaml b/deploy/olm-catalog/camel-k-dev/1.2.0-snapshot/camel-k.v1.2.0-snapshot.clusterserviceversion.yaml
index 77cbde0..fb43d7f 100644
--- a/deploy/olm-catalog/camel-k-dev/1.2.0-snapshot/camel-k.v1.2.0-snapshot.clusterserviceversion.yaml
+++ b/deploy/olm-catalog/camel-k-dev/1.2.0-snapshot/camel-k.v1.2.0-snapshot.clusterserviceversion.yaml
@@ -522,6 +522,15 @@ spec:
           - patch
           - update
           - watch
+        - apiGroups:
+          - "kafka.strimzi.io"
+          resources:
+          - topics
+          - kafkas
+          verbs:
+          - get
+          - list
+          - watch
         serviceAccountName: camel-k-operator
     strategy: deployment
   installModes:
diff --git a/deploy/operator-role-binding-strimzi.yaml b/deploy/operator-role-binding-strimzi.yaml
new file mode 100644
index 0000000..9a860c0
--- /dev/null
+++ b/deploy/operator-role-binding-strimzi.yaml
@@ -0,0 +1,30 @@
+# ---------------------------------------------------------------------------
+# 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.
+# ---------------------------------------------------------------------------
+
+kind: RoleBinding
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
+  name: camel-k-operator-strimzi
+  labels:
+    app: "camel-k"
+subjects:
+- kind: ServiceAccount
+  name: camel-k-operator
+roleRef:
+  kind: Role
+  name: camel-k-operator-strimzi
+  apiGroup: rbac.authorization.k8s.io
diff --git a/deploy/operator-role-olm.yaml b/deploy/operator-role-olm.yaml
index fa6c6f3..53fa59f 100644
--- a/deploy/operator-role-olm.yaml
+++ b/deploy/operator-role-olm.yaml
@@ -234,3 +234,12 @@ rules:
   - patch
   - update
   - watch
+- apiGroups:
+  - "kafka.strimzi.io"
+  resources:
+  - topics
+  - kafkas
+  verbs:
+  - get
+  - list
+  - watch
diff --git a/deploy/operator-role-strimzi.yaml b/deploy/operator-role-strimzi.yaml
new file mode 100644
index 0000000..f0c67a8
--- /dev/null
+++ b/deploy/operator-role-strimzi.yaml
@@ -0,0 +1,33 @@
+# ---------------------------------------------------------------------------
+# 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.
+# ---------------------------------------------------------------------------
+
+kind: Role
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
+  name: camel-k-operator-strimzi
+  labels:
+    app: "camel-k"
+rules:
+- apiGroups:
+  - "kafka.strimzi.io"
+  resources:
+  - topics
+  - kafkas
+  verbs:
+  - get
+  - list
+  - watch
diff --git a/deploy/resources.go b/deploy/resources.go
index 76daba7..e92808f 100644
--- a/deploy/resources.go
+++ b/deploy/resources.go
@@ -186,6 +186,13 @@ var assets = func() http.FileSystem {
 
 			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\x4d\x8f\xdb\x36\x10\xbd\xf3\x57\x3c\x58\x97\x04\x58\xcb\x6d\x4f\x85\x7b\x52\x36\xeb\x56\x68\x60\x03\x96\xd3\x20\x47\x9a\x1a\x4b\x53\x4b\x1c\x75\x48\xad\xe2\xfe\xfa\x82\xb2\xdd\xdd\xa0\x68\x81\x02\xe1\xcd\xf0\xcc\xfb\x98\xf7\x94\x61\xf9\xed\x9e\xc9\xf0\x81\x1d\xf9\x40\x35\xa2\x20\xb6\x84\x62\xb0\xae\x25\x54\x72\x8a\x93\x55\xc2\x46\x46\x5f\xdb\xc8\xe2\xf1\xa6\xa8\x36\x6f\x31\xfa\x9a\x14\xe2\x09\xa2\xe8\x45\xc9\x [...]
 		},
+		"/operator-role-binding-strimzi.yaml": &vfsgen۰CompressedFileInfo{
+			name:             "operator-role-binding-strimzi.yaml",
+			modTime:          time.Time{},
+			uncompressedSize: 1221,
+
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x93\x41\x6f\xfa\x46\x10\xc5\xef\xfb\x29\x9e\xf0\xe5\x1f\x09\x4c\xdb\x53\x45\x4f\x4e\x02\xad\xd5\x08\x24\x4c\x1a\xe5\xb8\xac\x07\x7b\x8a\xbd\xe3\xee\xae\xe3\x90\x4f\x5f\xad\x81\x26\x51\xd5\xea\x7f\xc8\xde\x10\xc3\x9b\xdf\x9b\xf7\x48\x30\xfb\xba\xa7\x12\x3c\xb0\x21\xeb\xa9\x44\x10\x84\x9a\x90\x75\xda\xd4\x84\x42\x0e\x61\xd0\x8e\xb0\x92\xde\x96\x3a\xb0\x58\x7c\xcb\x8a\xd5\x0d\x7a\x5b\x92\x83\x58\x82\x38\xb4\xe2\x48\x [...]
+		},
 		"/operator-role-binding.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "operator-role-binding.yaml",
 			modTime:          time.Time{},
@@ -224,9 +231,9 @@ var assets = func() http.FileSystem {
 		"/operator-role-olm.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "operator-role-olm.yaml",
 			modTime:          time.Time{},
-			uncompressedSize: 3851,
+			uncompressedSize: 3958,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x56\x41\x8f\xdb\x36\x13\xbd\xeb\x57\x0c\xec\x4b\xf2\x61\x2d\x7f\xed\xa9\x70\x4f\x6e\xb2\xdb\x1a\x0d\xbc\xc0\x7a\xd3\x20\xc7\x11\x35\x96\xa6\x4b\x72\x58\x92\xb2\xe3\xfe\xfa\x82\xb4\x9c\xc8\xd1\xba\x49\x81\xa0\xae\x2f\xa6\xc8\xf1\x9b\x37\xef\x8d\xc6\x9c\xc2\xec\xdb\x7d\x8a\x29\xbc\x61\x45\x36\x50\x0d\x51\x20\xb6\x04\x4b\x87\xaa\x25\xd8\xc8\x36\xee\xd1\x13\xdc\x49\x67\x6b\x8c\x2c\x16\x5e\x2c\x37\x77\x2f\xa1\xb3\x35\x [...]
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x56\x41\x8f\xdb\x36\x13\xbd\xeb\x57\x0c\xec\x4b\xf2\x61\x2d\x7f\xed\xa9\x70\x4f\x6e\xb2\xdb\x1a\x0d\xbc\xc0\x7a\xd3\x20\xc7\x31\x35\x96\xa6\x26\x39\x2c\x49\xd9\x71\x7e\x7d\x41\x4a\x4e\xe4\x68\xb7\x49\x81\x00\xae\x2f\xa6\x86\xa3\x99\x37\xef\x0d\x47\x9c\xc2\xec\xfb\xfd\x8a\x29\xbc\x61\x45\x36\x50\x05\x51\x20\x36\x04\x4b\x87\xaa\x21\xd8\xc8\x2e\x1e\xd1\x13\xdc\x49\x6b\x2b\x8c\x2c\x16\x5e\x2c\x37\x77\x2f\xa1\xb5\x15\x [...]
 		},
 		"/operator-role-openshift.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "operator-role-openshift.yaml",
@@ -242,6 +249,13 @@ var assets = func() http.FileSystem {
 
 			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\xc1\x8e\xdb\x36\x10\xbd\xf3\x2b\x1e\xac\x4b\x02\xac\xe5\xb6\xa7\xc2\x3d\xb9\x9b\xdd\x56\x68\x60\x03\x2b\xa7\x41\x8e\x34\x35\x96\x06\x4b\x71\xd4\x21\xb5\x8a\xfb\xf5\x85\x68\xb9\xd9\x45\xae\xe1\xc5\x63\x72\x66\xde\x7b\xf3\x46\x05\xd6\x3f\xee\x98\x02\x1f\xd9\x51\x88\xd4\x20\x09\x52\x47\xd8\x0d\xd6\x75\x84\x5a\xce\x69\xb2\x4a\x78\x94\x31\x34\x36\xb1\x04\xbc\xdb\xd5\x8f\xef\x31\x86\x86\x14\x12\x08\xa2\xe8\x45\xc9\x [...]
 		},
+		"/operator-role-strimzi.yaml": &vfsgen۰CompressedFileInfo{
+			name:             "operator-role-strimzi.yaml",
+			modTime:          time.Time{},
+			uncompressedSize: 1177,
+
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\xc1\x6e\xdb\x46\x10\xbd\xef\x57\x3c\x88\x97\x04\xb0\xa8\xb6\xa7\x42\x3d\xa9\x8e\xdd\x12\x0d\x24\xc0\x54\x1a\xe4\x38\x22\x47\xe4\x40\xe4\x0e\x3b\xbb\x34\xe3\x7c\x7d\xb1\x14\xd5\x38\xe8\xd5\x7b\xe1\x10\xfb\xf8\xe6\xbd\x79\xc3\x0c\xeb\xb7\x3b\x2e\xc3\x47\xa9\xd8\x07\xae\x11\x15\xb1\x65\xec\x06\xaa\x5a\x46\xa9\xe7\x38\x91\x31\x1e\x75\xf4\x35\x45\x51\x8f\x77\xbb\xf2\xf1\x3d\x46\x5f\xb3\x41\x3d\x43\x0d\xbd\x1a\xbb\x [...]
+		},
 		"/operator-service-account.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "operator-service-account.yaml",
 			modTime:          time.Time{},
@@ -344,6 +358,7 @@ var assets = func() http.FileSystem {
 		fs["/operator-role-binding-events.yaml"].(os.FileInfo),
 		fs["/operator-role-binding-knative.yaml"].(os.FileInfo),
 		fs["/operator-role-binding-servicemonitors.yaml"].(os.FileInfo),
+		fs["/operator-role-binding-strimzi.yaml"].(os.FileInfo),
 		fs["/operator-role-binding.yaml"].(os.FileInfo),
 		fs["/operator-role-events.yaml"].(os.FileInfo),
 		fs["/operator-role-knative.yaml"].(os.FileInfo),
@@ -352,6 +367,7 @@ var assets = func() http.FileSystem {
 		fs["/operator-role-olm.yaml"].(os.FileInfo),
 		fs["/operator-role-openshift.yaml"].(os.FileInfo),
 		fs["/operator-role-servicemonitors.yaml"].(os.FileInfo),
+		fs["/operator-role-strimzi.yaml"].(os.FileInfo),
 		fs["/operator-service-account.yaml"].(os.FileInfo),
 		fs["/platform-cr.yaml"].(os.FileInfo),
 		fs["/prometheus-jmx-exporter.yaml"].(os.FileInfo),
diff --git a/helm/camel-k/templates/operator-role.yaml b/helm/camel-k/templates/operator-role.yaml
index c54ead2..0a2fcb9 100644
--- a/helm/camel-k/templates/operator-role.yaml
+++ b/helm/camel-k/templates/operator-role.yaml
@@ -236,3 +236,12 @@ rules:
   - patch
   - update
   - watch
+- apiGroups:
+  - "kafka.strimzi.io"
+  resources:
+  - topics
+  - kafkas
+  verbs:
+  - get
+  - list
+  - watch
diff --git a/pkg/controller/kameletbinding/initialize.go b/pkg/controller/kameletbinding/initialize.go
index 1054c3f..2afefcc 100644
--- a/pkg/controller/kameletbinding/initialize.go
+++ b/pkg/controller/kameletbinding/initialize.go
@@ -58,11 +58,17 @@ func (action *initializeAction) Handle(ctx context.Context, kameletbinding *v1al
 		it.Spec = *kameletbinding.Spec.Integration.DeepCopy()
 	}
 
-	from, err := bindings.Translate(v1alpha1.EndpointTypeSource, kameletbinding.Spec.Source)
+	bindingContext := bindings.BindingContext{
+		Ctx:       ctx,
+		Client:    action.client,
+		Namespace: it.Namespace,
+	}
+
+	from, err := bindings.Translate(bindingContext, v1alpha1.EndpointTypeSource, kameletbinding.Spec.Source)
 	if err != nil {
 		return nil, errors.Wrap(err, "could not determine source URI")
 	}
-	to, err := bindings.Translate(v1alpha1.EndpointTypeSink, kameletbinding.Spec.Sink)
+	to, err := bindings.Translate(bindingContext, v1alpha1.EndpointTypeSink, kameletbinding.Spec.Sink)
 	if err != nil {
 		return nil, errors.Wrap(err, "could not determine sink URI")
 	}
diff --git a/pkg/install/operator.go b/pkg/install/operator.go
index f1ec3f4..bfaa4d3 100644
--- a/pkg/install/operator.go
+++ b/pkg/install/operator.go
@@ -159,6 +159,13 @@ func OperatorOrCollect(ctx context.Context, c client.Client, cfg OperatorConfigu
 		fmt.Println("Warning: the operator will not be able to create servicemonitors for metrics. Try installing as cluster-admin to allow the creation of servicemonitors.")
 	}
 
+	if errmtr := installStrimziBindings(ctx, c, cfg.Namespace, customizer, collection, force); errmtr != nil {
+		if k8serrors.IsAlreadyExists(errmtr) {
+			return errmtr
+		}
+		fmt.Println("Warning: the operator will not be able to lookup strimzi kafka resources. Try installing as cluster-admin to allow the lookup of strimzi kafka resources.")
+	}
+
 	return nil
 }
 
@@ -201,6 +208,13 @@ func installServiceMonitors(ctx context.Context, c client.Client, namespace stri
 	)
 }
 
+func installStrimziBindings(ctx context.Context, c client.Client, namespace string, customizer ResourceCustomizer, collection *kubernetes.Collection, force bool) error {
+	return ResourcesOrCollect(ctx, c, namespace, collection, force, customizer,
+		"operator-role-strimzi.yaml",
+		"operator-role-binding-strimzi.yaml",
+	)
+}
+
 // Platform installs the platform custom resource
 // nolint: lll
 func Platform(ctx context.Context, c client.Client, clusterType string, namespace string, registry v1.IntegrationPlatformRegistrySpec) (*v1.IntegrationPlatform, error) {
diff --git a/pkg/util/bindings/api.go b/pkg/util/bindings/api.go
index c9daf72..f07d8cc 100644
--- a/pkg/util/bindings/api.go
+++ b/pkg/util/bindings/api.go
@@ -19,8 +19,10 @@ limitations under the License.
 package bindings
 
 import (
+	"context"
 	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+	"github.com/apache/camel-k/pkg/client"
 )
 
 const (
@@ -42,7 +44,13 @@ type BindingProvider interface {
 	// ID returns the name of the binding provider
 	ID() string
 	// Translate does the actual mapping
-	Translate(endpointType v1alpha1.EndpointType, endpoint v1alpha1.Endpoint) (*Binding, error)
+	Translate(ctx BindingContext, endpointType v1alpha1.EndpointType, endpoint v1alpha1.Endpoint) (*Binding, error)
 	// Order returns the relative order of execution of the binding provider
 	Order() int
 }
+
+type BindingContext struct {
+	Ctx       context.Context
+	Client    client.Client
+	Namespace string
+}
diff --git a/pkg/util/bindings/bindings_test.go b/pkg/util/bindings/bindings_test.go
index 1f7696a..8ad28a2 100644
--- a/pkg/util/bindings/bindings_test.go
+++ b/pkg/util/bindings/bindings_test.go
@@ -18,8 +18,10 @@ limitations under the License.
 package bindings
 
 import (
+	"context"
 	"encoding/json"
 	"fmt"
+	"github.com/apache/camel-k/pkg/util/test"
 	"net/url"
 	"testing"
 
@@ -166,7 +168,19 @@ func TestBindings(t *testing.T) {
 
 	for i, tc := range testcases {
 		t.Run(fmt.Sprintf("test-%d-%s", i, tc.uri), func(t *testing.T) {
-			binding, err := Translate(tc.endpointType, tc.endpoint)
+			ctx, cancel := context.WithCancel(context.Background())
+			defer cancel()
+
+			client, err := test.NewFakeClient()
+			assert.NoError(t, err)
+
+			bindingContext := BindingContext{
+				Ctx:       ctx,
+				Client:    client,
+				Namespace: "test",
+			}
+
+			binding, err := Translate(bindingContext, tc.endpointType, tc.endpoint)
 			assert.NoError(t, err)
 			assert.NotNil(t, binding)
 			assert.Equal(t, tc.uri, binding.URI)
diff --git a/pkg/util/bindings/camel_uri.go b/pkg/util/bindings/camel_uri.go
index 6dfea5f..a264ff7 100644
--- a/pkg/util/bindings/camel_uri.go
+++ b/pkg/util/bindings/camel_uri.go
@@ -30,7 +30,7 @@ func (k CamelURIBindingProvider) ID() string {
 	return "camel-uri"
 }
 
-func (k CamelURIBindingProvider) Translate(endpointType v1alpha1.EndpointType, e v1alpha1.Endpoint) (*Binding, error) {
+func (k CamelURIBindingProvider) Translate(ctx BindingContext, endpointType v1alpha1.EndpointType, e v1alpha1.Endpoint) (*Binding, error) {
 	if e.URI == nil {
 		// works only on uris
 		return nil, nil
diff --git a/pkg/util/bindings/catalog.go b/pkg/util/bindings/catalog.go
index 0fa42ee..dbe3f74 100644
--- a/pkg/util/bindings/catalog.go
+++ b/pkg/util/bindings/catalog.go
@@ -37,13 +37,13 @@ func RegisterBindingProvider(bp BindingProvider) {
 }
 
 // Translate execute all chained binding providers, returning the first success or the first error
-func Translate(endpointType v1alpha1.EndpointType, endpoint v1alpha1.Endpoint) (*Binding, error) {
-	if err := validateEndpoint(endpoint); err != nil {
+func Translate(ctx BindingContext, endpointType v1alpha1.EndpointType, endpoint v1alpha1.Endpoint) (*Binding, error) {
+	if err := validateEndpoint(ctx, endpoint); err != nil {
 		return nil, err
 	}
 
 	for _, bp := range bindingProviders {
-		b, err := bp.Translate(endpointType, endpoint)
+		b, err := bp.Translate(ctx, endpointType, endpoint)
 		if b != nil || err != nil {
 			return b, err
 		}
@@ -51,11 +51,14 @@ func Translate(endpointType v1alpha1.EndpointType, endpoint v1alpha1.Endpoint) (
 	return nil, nil
 }
 
-func validateEndpoint(e v1alpha1.Endpoint) error {
+func validateEndpoint(ctx BindingContext, e v1alpha1.Endpoint) error {
 	if e.Ref == nil && e.URI == nil {
 		return errors.New("no ref or URI specified in endpoint")
 	} else if e.Ref != nil && e.URI != nil {
 		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")
+	}
 	return nil
 }
diff --git a/pkg/util/bindings/kamelet.go b/pkg/util/bindings/kamelet.go
index 7e8d166..48fc456 100644
--- a/pkg/util/bindings/kamelet.go
+++ b/pkg/util/bindings/kamelet.go
@@ -33,7 +33,7 @@ func (k KameletBindingProvider) ID() string {
 	return "kamelet"
 }
 
-func (k KameletBindingProvider) Translate(endpointType v1alpha1.EndpointType, e v1alpha1.Endpoint) (*Binding, error) {
+func (k KameletBindingProvider) Translate(ctx BindingContext, endpointType v1alpha1.EndpointType, e v1alpha1.Endpoint) (*Binding, error) {
 	if e.Ref == nil {
 		// works only on refs
 		return nil, nil
diff --git a/pkg/util/bindings/knative_ref.go b/pkg/util/bindings/knative_ref.go
index bd7f7a3..e3ad420 100644
--- a/pkg/util/bindings/knative_ref.go
+++ b/pkg/util/bindings/knative_ref.go
@@ -37,7 +37,7 @@ func (k KnativeRefBindingProvider) ID() string {
 	return "knative-ref"
 }
 
-func (k KnativeRefBindingProvider) Translate(endpointType v1alpha1.EndpointType, e v1alpha1.Endpoint) (*Binding, error) {
+func (k KnativeRefBindingProvider) Translate(ctx BindingContext, endpointType v1alpha1.EndpointType, e v1alpha1.Endpoint) (*Binding, error) {
 	if e.Ref == nil {
 		// works only on refs
 		return nil, nil
diff --git a/pkg/util/bindings/knative_uri.go b/pkg/util/bindings/knative_uri.go
index 0f43cfa..88bdd0c 100644
--- a/pkg/util/bindings/knative_uri.go
+++ b/pkg/util/bindings/knative_uri.go
@@ -35,7 +35,7 @@ func (k KnativeURIBindingProvider) ID() string {
 	return "knative-uri"
 }
 
-func (k KnativeURIBindingProvider) Translate(endpointType v1alpha1.EndpointType, e v1alpha1.Endpoint) (*Binding, error) {
+func (k KnativeURIBindingProvider) Translate(ctx BindingContext, endpointType v1alpha1.EndpointType, e v1alpha1.Endpoint) (*Binding, error) {
 	if e.URI == nil {
 		// works only on uris
 		return nil, nil
diff --git a/script/Makefile b/script/Makefile
index 4a2c435..1438292 100644
--- a/script/Makefile
+++ b/script/Makefile
@@ -120,7 +120,7 @@ codegen:
 	@echo "" >> $(VERSIONFILE)
 	gofmt -w pkg/util/defaults/defaults.go
 
-generate: generate-deepcopy generate-crd generate-client generate-doc
+generate: generate-deepcopy generate-crd generate-client generate-doc generate-strimzi
 
 generate-client:
 	./script/gen_client.sh
@@ -134,6 +134,10 @@ generate-doc:
 generate-deepcopy: controller-gen
 	cd pkg/apis/camel && $(CONTROLLER_GEN) paths="./..." object
 
+generate-strimzi:
+	cd addons/strimzi/duck && $(CONTROLLER_GEN) paths="./..." object
+	./script/gen_client_strimzi.sh
+
 build: build-resources build-kamel build-compile-integration-tests build-submodules
 
 test: build
@@ -276,7 +280,7 @@ get-staging-repo:
 get-version:
 	@echo $(VERSION)
 
-.PHONY: build build-kamel build-resources build-olm unsnapshot-olm dep codegen images images-dev images-push images-push-staging test check test-integration clean release cross-compile package-examples set-version git-tag release-notes check-licenses generate-deepcopy generate-client generate-doc build-resources release-helm release-staging release-nightly get-staging-repo get-version build-submodules set-module-version bundle-kamelets
+.PHONY: build build-kamel build-resources build-olm unsnapshot-olm dep codegen images images-dev images-push images-push-staging test check test-integration clean release cross-compile package-examples set-version git-tag release-notes check-licenses generate-deepcopy generate-client generate-doc build-resources release-helm release-staging release-nightly get-staging-repo get-version build-submodules set-module-version bundle-kamelets generate-strimzi
 
 # find or download controller-gen
 # download controller-gen if necessary
diff --git a/script/gen_client_strimzi.sh b/script/gen_client_strimzi.sh
new file mode 100755
index 0000000..f882f78
--- /dev/null
+++ b/script/gen_client_strimzi.sh
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+# 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.
+
+set -e
+
+location=$(dirname $0)
+rootdir=$location/..
+
+unset GOPATH
+GO111MODULE=on
+
+echo "Generating Go client code for Strimzi addon..."
+
+cd $rootdir
+
+go run k8s.io/code-generator/cmd/client-gen \
+  -h script/headers/default.txt \
+  --input duck/v1beta1 \
+  --input-base=github.com/apache/camel-k/addons/strimzi \
+  --output-package=github.com/apache/camel-k/addons/strimzi/duck/v1beta1/client
+
+
+rm -r ./addons/strimzi/duck/v1beta1/client || true
+mv github.com/apache/camel-k/addons/strimzi/duck/v1beta1/client ./addons/strimzi/duck/v1beta1/
+rm -r ./github.com