This is an automated email from the ASF dual-hosted git repository. astefanutti pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit c9160df4fae2015eab6488f5db923963c602f30c Author: Antonin Stefanutti <anto...@stefanutti.fr> AuthorDate: Wed Feb 10 12:24:55 2021 +0100 fix: ServiceBinding SAR check does not guaranty CRD is installed --- .../integration/integration_controller.go | 34 ++++++++++-------- pkg/install/openshift.go | 21 ++--------- pkg/util/kubernetes/discovery.go | 41 ++++++++++++++++++++++ 3 files changed, 63 insertions(+), 33 deletions(-) diff --git a/pkg/controller/integration/integration_controller.go b/pkg/controller/integration/integration_controller.go index e61ca9e..52cae9d 100644 --- a/pkg/controller/integration/integration_controller.go +++ b/pkg/controller/integration/integration_controller.go @@ -19,6 +19,7 @@ package integration import ( "context" + "reflect" appsv1 "k8s.io/api/apps/v1" "k8s.io/api/batch/v1beta1" @@ -37,6 +38,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" "sigs.k8s.io/controller-runtime/pkg/source" + sb "github.com/redhat-developer/service-binding-operator/pkg/apis/operators/v1alpha1" + v1 "github.com/apache/camel-k/pkg/apis/camel/v1" "github.com/apache/camel-k/pkg/client" camelevent "github.com/apache/camel-k/pkg/event" @@ -45,7 +48,6 @@ import ( "github.com/apache/camel-k/pkg/util/kubernetes" "github.com/apache/camel-k/pkg/util/log" "github.com/apache/camel-k/pkg/util/monitoring" - sb "github.com/redhat-developer/service-binding-operator/pkg/apis/operators/v1alpha1" ) // Add creates a new Integration Controller and adds it to the Manager. The Manager will set fields on the Controller @@ -55,7 +57,7 @@ func Add(mgr manager.Manager) error { if err != nil { return err } - return add(mgr, newReconciler(mgr, c)) + return add(mgr, newReconciler(mgr, c), c) } // newReconciler returns a new reconcile.Reconciler @@ -75,15 +77,15 @@ func newReconciler(mgr manager.Manager, c client.Client) reconcile.Reconciler { } // add adds a new Controller to mgr with r as the reconcile.Reconciler -func add(mgr manager.Manager, r reconcile.Reconciler) error { +func add(mgr manager.Manager, r reconcile.Reconciler, c client.Client) error { // Create a new controller - c, err := controller.New("integration-controller", mgr, controller.Options{Reconciler: r}) + ctrl, err := controller.New("integration-controller", mgr, controller.Options{Reconciler: r}) if err != nil { return err } // Watch for changes to primary resource Integration - err = c.Watch(&source.Kind{Type: &v1.Integration{}}, &handler.EnqueueRequestForObject{}, predicate.Funcs{ + err = ctrl.Watch(&source.Kind{Type: &v1.Integration{}}, &handler.EnqueueRequestForObject{}, predicate.Funcs{ UpdateFunc: func(e event.UpdateEvent) bool { oldIntegration := e.ObjectOld.(*v1.Integration) newIntegration := e.ObjectNew.(*v1.Integration) @@ -105,7 +107,7 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error { // Watch for IntegrationKit phase transitioning to ready or error and // enqueue requests for any integrations that are in phase waiting for // kit - err = c.Watch(&source.Kind{Type: &v1.IntegrationKit{}}, &handler.EnqueueRequestsFromMapFunc{ + err = ctrl.Watch(&source.Kind{Type: &v1.IntegrationKit{}}, &handler.EnqueueRequestsFromMapFunc{ ToRequests: handler.ToRequestsFunc(func(a handler.MapObject) []reconcile.Request { kit := a.Object.(*v1.IntegrationKit) var requests []reconcile.Request @@ -140,7 +142,7 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error { // Watch for IntegrationPlatform phase transitioning to ready and enqueue // requests for any integrations that are in phase waiting for platform - err = c.Watch(&source.Kind{Type: &v1.IntegrationPlatform{}}, &handler.EnqueueRequestsFromMapFunc{ + err = ctrl.Watch(&source.Kind{Type: &v1.IntegrationPlatform{}}, &handler.EnqueueRequestsFromMapFunc{ ToRequests: handler.ToRequestsFunc(func(a handler.MapObject) []reconcile.Request { platform := a.Object.(*v1.IntegrationPlatform) var requests []reconcile.Request @@ -177,7 +179,7 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error { // the EnqueueRequestForOwner handler as the owner depends on the deployment strategy, // either regular deployment or Knative service. In any case, the integration is not the // direct owner of the ReplicaSet. - err = c.Watch(&source.Kind{Type: &appsv1.ReplicaSet{}}, &handler.EnqueueRequestsFromMapFunc{ + err = ctrl.Watch(&source.Kind{Type: &appsv1.ReplicaSet{}}, &handler.EnqueueRequestsFromMapFunc{ ToRequests: handler.ToRequestsFunc(func(a handler.MapObject) []reconcile.Request { rs := a.Object.(*appsv1.ReplicaSet) var requests []reconcile.Request @@ -211,7 +213,7 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error { } // Watch cronjob to update the ready condition - err = c.Watch(&source.Kind{Type: &v1beta1.CronJob{}}, &handler.EnqueueRequestForOwner{ + err = ctrl.Watch(&source.Kind{Type: &v1beta1.CronJob{}}, &handler.EnqueueRequestForOwner{ OwnerType: &v1.Integration{}, IsController: false, }) @@ -219,15 +221,19 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error { return err } - if client, err := client.FromManager(mgr); err != nil { - log.Error(err, "cannot check permissions for watching ServiceBindings") - } else if ok, err := kubernetes.CheckPermission(context.TODO(), client, "operators.coreos.com", "ServiceBinding", "", "", "create"); err != nil { + + // Check the ServiceBinding CRD is present + if ok, err := kubernetes.IsAPIResourceInstalled(c, "operators.coreos.com/v1alpha1", reflect.TypeOf(sb.ServiceBinding{}).Name()); err != nil { + return err + } else if !ok { + log.Info("Service binding is disabled, install the Service Binding Operator if needed") + } else if ok, err := kubernetes.CheckPermission(context.TODO(), c, "operators.coreos.com", "ServiceBinding", "", "", "create"); err != nil { log.Error(err, "cannot check permissions for watching ServiceBindings") } else if !ok { log.Info("ServiceBinding monitoring is disabled, install Service Binding Operator before camel-k if needed") } else { - // Watch ServiceBindings created - err = c.Watch(&source.Kind{Type: &sb.ServiceBinding{}}, &handler.EnqueueRequestForOwner{ + // Watch ServiceBindings and enqueue owning Integrations + err = ctrl.Watch(&source.Kind{Type: &sb.ServiceBinding{}}, &handler.EnqueueRequestForOwner{ OwnerType: &v1.Integration{}, IsController: true, }) diff --git a/pkg/install/openshift.go b/pkg/install/openshift.go index 5d9ea0c..285dc10 100644 --- a/pkg/install/openshift.go +++ b/pkg/install/openshift.go @@ -33,6 +33,7 @@ import ( "github.com/apache/camel-k/pkg/client" "github.com/apache/camel-k/pkg/util/defaults" + "github.com/apache/camel-k/pkg/util/kubernetes" ) const ( @@ -59,7 +60,7 @@ var ( func OpenShiftConsoleDownloadLink(ctx context.Context, c client.Client) error { // Check the ConsoleCLIDownload CRD is present, which should be starting OpenShift version 4.2. // That check is also enough to exclude Kubernetes clusters. - ok, err := isAPIResourceInstalled(c, "console.openshift.io/v1", reflect.TypeOf(console.ConsoleCLIDownload{}).Name()) + ok, err := kubernetes.IsAPIResourceInstalled(c, "console.openshift.io/v1", reflect.TypeOf(console.ConsoleCLIDownload{}).Name()) if err != nil { return err } else if !ok { @@ -161,21 +162,3 @@ func OpenShiftConsoleDownloadLink(ctx context.Context, c client.Client) error { return nil } - -func isAPIResourceInstalled(c client.Client, groupVersion string, kind string) (bool, error) { - resources, err := c.Discovery().ServerResourcesForGroupVersion(groupVersion) - if err != nil { - if errors.IsNotFound(err) { - return false, nil - } - return false, err - } - - for _, resource := range resources.APIResources { - if resource.Kind == kind { - return true, nil - } - } - - return false, nil -} diff --git a/pkg/util/kubernetes/discovery.go b/pkg/util/kubernetes/discovery.go new file mode 100644 index 0000000..4f90696 --- /dev/null +++ b/pkg/util/kubernetes/discovery.go @@ -0,0 +1,41 @@ +/* +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 kubernetes + +import ( + "k8s.io/apimachinery/pkg/api/errors" + + "github.com/apache/camel-k/pkg/client" +) +func IsAPIResourceInstalled(c client.Client, groupVersion string, kind string) (bool, error) { + resources, err := c.Discovery().ServerResourcesForGroupVersion(groupVersion) + if err != nil { + if errors.IsNotFound(err) { + return false, nil + } + return false, err + } + + for _, resource := range resources.APIResources { + if resource.Kind == kind { + return true, nil + } + } + + return false, nil +}