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 2019/10/01 13:53:47 UTC
[camel-k] 04/08: Fix #952: add Knative 0.8.0 compatibility hack
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 dcff4af821f01b3e37817d58c7bde167ec619a2b
Author: nferraro <ni...@gmail.com>
AuthorDate: Thu Sep 26 16:05:52 2019 +0200
Fix #952: add Knative 0.8.0 compatibility hack
---
e2e/test_support.go | 4 +-
...toscheme_knative_eventing_08_compat_v1alpha1.go | 43 ++++++++++++++++++++++
pkg/apis/knative08compat/knative08compat.go | 22 +++++++++++
pkg/trait/istio_test.go | 5 +++
pkg/trait/knative.go | 37 ++++++++++++++++++-
pkg/trait/knative_service_test.go | 6 +++
pkg/util/knative/knative.go | 38 ++++++++++++++-----
pkg/util/kubernetes/errors.go | 9 +++++
8 files changed, 150 insertions(+), 14 deletions(-)
diff --git a/e2e/test_support.go b/e2e/test_support.go
index fd0b1b0..04a5203 100644
--- a/e2e/test_support.go
+++ b/e2e/test_support.go
@@ -39,7 +39,6 @@ import (
"github.com/apache/camel-k/pkg/util/log"
"github.com/apache/camel-k/pkg/util/openshift"
"github.com/google/uuid"
- messaging "knative.dev/eventing/pkg/apis/messaging/v1alpha1"
"github.com/onsi/gomega"
projectv1 "github.com/openshift/api/project/v1"
"github.com/spf13/cobra"
@@ -49,6 +48,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
+ messaging "knative.dev/eventing/pkg/apis/messaging/v1alpha1"
k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
)
@@ -498,7 +498,7 @@ func createKnativeChannel(ns string, name string) func() error {
return func() error {
channel := messaging.InMemoryChannel{
TypeMeta: metav1.TypeMeta{
- Kind: "Channel",
+ Kind: "InMemoryChannel",
APIVersion: messaging.SchemeGroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
diff --git a/pkg/apis/addtoscheme_knative_eventing_08_compat_v1alpha1.go b/pkg/apis/addtoscheme_knative_eventing_08_compat_v1alpha1.go
new file mode 100644
index 0000000..51734f4
--- /dev/null
+++ b/pkg/apis/addtoscheme_knative_eventing_08_compat_v1alpha1.go
@@ -0,0 +1,43 @@
+/*
+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 apis
+
+import (
+ "github.com/apache/camel-k/pkg/apis/knative08compat"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/runtime"
+)
+
+var (
+ compat08SchemeBuilder = runtime.NewSchemeBuilder(eventing08CompatKnownTypes)
+ compat08AddToScheme = compat08SchemeBuilder.AddToScheme
+)
+
+func init() {
+ AddToSchemes = append(AddToSchemes, compat08AddToScheme)
+}
+
+// eventing08CompatKnownTypes Adds the list of known types to Scheme.
+func eventing08CompatKnownTypes(scheme *runtime.Scheme) error {
+ scheme.AddKnownTypes(knative08compat.CompatSchemeGroupVersion,
+ &knative08compat.Subscription{},
+ &knative08compat.SubscriptionList{},
+ )
+ metav1.AddToGroupVersion(scheme, knative08compat.CompatSchemeGroupVersion)
+ return nil
+}
diff --git a/pkg/apis/knative08compat/knative08compat.go b/pkg/apis/knative08compat/knative08compat.go
new file mode 100644
index 0000000..7939754
--- /dev/null
+++ b/pkg/apis/knative08compat/knative08compat.go
@@ -0,0 +1,22 @@
+package knative08compat
+
+import (
+ "k8s.io/apimachinery/pkg/runtime/schema"
+ messaging "knative.dev/eventing/pkg/apis/messaging/v1alpha1"
+)
+
+// CompatSchemeGroupVersion is the old group version used in Knative 0.8
+var CompatSchemeGroupVersion = schema.GroupVersion{
+ Group: "eventing.knative.dev",
+ Version: "v1alpha1",
+}
+
+// Subscription is a Knative 0.8 compatibility version for messaging.Subscription
+type Subscription struct {
+ messaging.Subscription
+}
+
+// SubscriptionList is a Knative 0.8 compatibility version for messaging.SubscriptionList
+type SubscriptionList struct {
+ messaging.SubscriptionList
+}
diff --git a/pkg/trait/istio_test.go b/pkg/trait/istio_test.go
index 7f804e4..cd5830f 100644
--- a/pkg/trait/istio_test.go
+++ b/pkg/trait/istio_test.go
@@ -49,6 +49,11 @@ func NewIstioTestEnv(t *testing.T, d *appsv1.Deployment, s *serving.Service, ena
"istio": {
Configuration: make(map[string]string),
},
+ "knative": {
+ Configuration: map[string]string{
+ "knative-08-compat-mode": "false", // disable it so it does not check resources in the cluster
+ },
+ },
},
},
},
diff --git a/pkg/trait/knative.go b/pkg/trait/knative.go
index 14705ad..f64929a 100644
--- a/pkg/trait/knative.go
+++ b/pkg/trait/knative.go
@@ -25,6 +25,7 @@ import (
"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
"github.com/apache/camel-k/pkg/metadata"
"github.com/apache/camel-k/pkg/util/envvar"
+ "github.com/apache/camel-k/pkg/util/kubernetes"
"github.com/pkg/errors"
"github.com/scylladb/go-set/strset"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
@@ -32,6 +33,9 @@ import (
knativeapi "github.com/apache/camel-k/pkg/apis/camel/v1alpha1/knative"
knativeutil "github.com/apache/camel-k/pkg/util/knative"
+ v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ messaging "knative.dev/eventing/pkg/apis/messaging/v1alpha1"
+ kubeclient "sigs.k8s.io/controller-runtime/pkg/client"
)
type knativeTrait struct {
@@ -44,6 +48,7 @@ type knativeTrait struct {
FilterSourceChannels *bool `property:"filter-source-channels"`
ChannelAPIs []string `property:"channel-apis"`
EndpointAPIs []string `property:"endpoint-apis"`
+ Knative08CompatMode *bool `property:"knative-08-compat-mode"`
Auto *bool `property:"auto"`
}
@@ -147,6 +152,14 @@ func (t *knativeTrait) Configure(e *Environment) (bool, error) {
filter := true
t.FilterSourceChannels = &filter
}
+
+ if t.Knative08CompatMode == nil {
+ compat, err := t.shouldUseKnative08CompatMode(e.Integration.Namespace)
+ if err != nil {
+ return false, err
+ }
+ t.Knative08CompatMode = &compat
+ }
}
return true, nil
@@ -194,13 +207,16 @@ func (t *knativeTrait) createSubscriptions(e *Environment) error {
if err != nil {
return err
}
+
+ compat := t.Knative08CompatMode != nil && *t.Knative08CompatMode
+
for _, ch := range channels {
chRef, err := knativeutil.GetAddressableReference(t.ctx, t.client, types, e.Integration.Namespace, ch)
if err != nil {
return err
}
- sub := knativeutil.CreateSubscription(*chRef, e.Integration.Name)
- e.Resources.Add(&sub)
+ sub := knativeutil.CreateSubscription(*chRef, e.Integration.Name, compat)
+ e.Resources.Add(sub)
}
return nil
@@ -347,6 +363,23 @@ func (t *knativeTrait) extractNames(names string) []string {
return answer
}
+func (t *knativeTrait) shouldUseKnative08CompatMode(namespace string) (bool, error) {
+ lst := messaging.SubscriptionList{
+ TypeMeta: v1.TypeMeta{
+ Kind: "Subscription",
+ APIVersion: messaging.SchemeGroupVersion.String(),
+ },
+ }
+ opts := kubeclient.ListOptions{
+ Namespace: namespace,
+ }
+ err := t.client.List(t.ctx, &opts, &lst)
+ if err != nil && kubernetes.IsUnknownAPIError(err) {
+ return true, nil
+ }
+ return false, err
+}
+
func decodeKindAPIGroupVersions(specs []string) ([]schema.GroupVersionKind, error) {
lst := make([]schema.GroupVersionKind, 0, len(specs))
for _, spec := range specs {
diff --git a/pkg/trait/knative_service_test.go b/pkg/trait/knative_service_test.go
index 04a21c4..0af56d9 100644
--- a/pkg/trait/knative_service_test.go
+++ b/pkg/trait/knative_service_test.go
@@ -45,6 +45,9 @@ func TestKnativeService(t *testing.T) {
assert.Nil(t, err)
traitCatalog := NewCatalog(context.TODO(), nil)
+ knativeTrait := traitCatalog.GetTrait("knative").(*knativeTrait)
+ falze := false
+ knativeTrait.Knative08CompatMode = &falze
environment := Environment{
CamelCatalog: catalog,
@@ -184,6 +187,9 @@ func TestKnativeServiceWithCustomContainerName(t *testing.T) {
assert.Nil(t, err)
traitCatalog := NewCatalog(context.TODO(), nil)
+ knativeTrait := traitCatalog.GetTrait("knative").(*knativeTrait)
+ falze := false
+ knativeTrait.Knative08CompatMode = &falze
environment := Environment{
CamelCatalog: catalog,
diff --git a/pkg/util/knative/knative.go b/pkg/util/knative/knative.go
index 2653701..874c108 100644
--- a/pkg/util/knative/knative.go
+++ b/pkg/util/knative/knative.go
@@ -20,13 +20,16 @@ package knative
import (
"context"
"fmt"
- "k8s.io/apimachinery/pkg/runtime/schema"
"net/url"
+ "github.com/apache/camel-k/pkg/apis/knative08compat"
"github.com/apache/camel-k/pkg/client"
+ kubernetesutils "github.com/apache/camel-k/pkg/util/kubernetes"
"github.com/apache/camel-k/pkg/util/log"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/kubernetes"
controller "sigs.k8s.io/controller-runtime/pkg/client"
k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
@@ -68,10 +71,14 @@ func IsInstalled(ctx context.Context, c kubernetes.Interface) (bool, error) {
}
// CreateSubscription ---
-func CreateSubscription(channelReference corev1.ObjectReference, serviceName string) messaging.Subscription {
- return messaging.Subscription{
+func CreateSubscription(channelReference corev1.ObjectReference, serviceName string, compat08 bool) runtime.Object {
+ apiVersion := messaging.SchemeGroupVersion.String()
+ if compat08 {
+ apiVersion = knative08compat.CompatSchemeGroupVersion.String()
+ }
+ subs := messaging.Subscription{
TypeMeta: metav1.TypeMeta{
- APIVersion: messaging.SchemeGroupVersion.String(),
+ APIVersion: apiVersion,
Kind: "Subscription",
},
ObjectMeta: metav1.ObjectMeta{
@@ -93,21 +100,30 @@ func CreateSubscription(channelReference corev1.ObjectReference, serviceName str
},
},
}
+
+ if compat08 {
+ return &knative08compat.Subscription{
+ Subscription: subs,
+ }
+ }
+ return &subs
}
// GetAnySinkURL looks up the resource among all given types and returns the resource sink URL if present
func GetAnySinkURL(ctx context.Context, c client.Client, types []schema.GroupVersionKind, namespace string, name string) (*url.URL, error) {
for _, gvk := range types {
sink := corev1.ObjectReference{
- Kind: gvk.Kind,
+ Kind: gvk.Kind,
APIVersion: gvk.GroupVersion().String(),
- Namespace: namespace,
- Name: name,
+ Namespace: namespace,
+ Name: name,
}
res, err := GetSinkURI(ctx, c, &sink, namespace)
if err != nil && k8serrors.IsNotFound(err) {
continue
+ } else if err != nil && kubernetesutils.IsUnknownAPIError(err) {
+ continue
} else if err != nil {
return nil, err
}
@@ -120,15 +136,17 @@ func GetAnySinkURL(ctx context.Context, c client.Client, types []schema.GroupVer
func GetAddressableReference(ctx context.Context, c client.Client, types []schema.GroupVersionKind, namespace string, name string) (*corev1.ObjectReference, error) {
for _, gvk := range types {
sink := corev1.ObjectReference{
- Kind: gvk.Kind,
+ Kind: gvk.Kind,
APIVersion: gvk.GroupVersion().String(),
- Namespace: namespace,
- Name: name,
+ Namespace: namespace,
+ Name: name,
}
_, err := GetSinkURI(ctx, c, &sink, namespace)
if err != nil && k8serrors.IsNotFound(err) {
continue
+ } else if err != nil && kubernetesutils.IsUnknownAPIError(err) {
+ continue
} else if err != nil {
return nil, err
}
diff --git a/pkg/util/kubernetes/errors.go b/pkg/util/kubernetes/errors.go
new file mode 100644
index 0000000..4d8f194
--- /dev/null
+++ b/pkg/util/kubernetes/errors.go
@@ -0,0 +1,9 @@
+package kubernetes
+
+import "strings"
+
+// IsUnknownAPIError checks if the given error is due to some missing APIs in the cluster.
+// Apparently there's no such method in Kubernetes Go API.
+func IsUnknownAPIError(err error) bool {
+ return err != nil && strings.HasPrefix(err.Error(), "no matches for kind")
+}