From 9e6d3f405def9f8a2e63afea79e0da39d5e8d9a7 Mon Sep 17 00:00:00 2001 From: Christoph Deppisch Date: Wed, 29 Jun 2022 08:58:06 +0200 Subject: [PATCH] fix(#3393): Make CronJob functionality optional - Explicitly check for CronJob batch/v1 API availability before using it - CronJob batch/v1 API is not available on OpenShift 3.x - Disable cron job e2e test on OpenShift 3.x --- e2e/common/cli/install_test.go | 6 ++--- e2e/common/cron_test.go | 12 +++++++++ pkg/cmd/operator/operator.go | 26 ++++++++++++++----- .../integration/integration_controller.go | 7 +++-- 4 files changed, 39 insertions(+), 12 deletions(-) diff --git a/e2e/common/cli/install_test.go b/e2e/common/cli/install_test.go index d1a76dc3c6..3de1f837a6 100644 --- a/e2e/common/cli/install_test.go +++ b/e2e/common/cli/install_test.go @@ -38,7 +38,7 @@ import ( "github.com/apache/camel-k/pkg/util/defaults" "github.com/apache/camel-k/pkg/util/kubernetes" "github.com/apache/camel-k/pkg/util/openshift" - console "github.com/openshift/api/console/v1" + consolev1 "github.com/openshift/api/console/v1" corev1 "k8s.io/api/core/v1" ) @@ -98,11 +98,11 @@ func TestConsoleCliDownload(t *testing.T) { ocp, err := openshift.IsOpenShift(TestClient()) assert.Nil(t, err) - ok, err := kubernetes.IsAPIResourceInstalled(TestClient(), "console.openshift.io/v1", reflect.TypeOf(console.ConsoleCLIDownload{}).Name()) + ok, err := kubernetes.IsAPIResourceInstalled(TestClient(), "console.openshift.io/v1", reflect.TypeOf(consolev1.ConsoleCLIDownload{}).Name()) assert.Nil(t, err) if !ocp || !ok { - t.Skip("This test requires ConsoleCliDownload object which is available on OpenShift 4 only.") + t.Skip("This test requires ConsoleCliDownload object which is available on OpenShift 4+ only.") return } diff --git a/e2e/common/cron_test.go b/e2e/common/cron_test.go index dc26197db2..85b5ac211d 100644 --- a/e2e/common/cron_test.go +++ b/e2e/common/cron_test.go @@ -23,17 +23,29 @@ limitations under the License. package common import ( + "reflect" "testing" . "github.com/onsi/gomega" + "github.com/stretchr/testify/assert" + batchv1 "k8s.io/api/batch/v1" corev1 "k8s.io/api/core/v1" . "github.com/apache/camel-k/e2e/support" v1 "github.com/apache/camel-k/pkg/apis/camel/v1" + "github.com/apache/camel-k/pkg/util/kubernetes" ) func TestRunCronExample(t *testing.T) { + ok, err := kubernetes.IsAPIResourceInstalled(TestClient(), batchv1.SchemeGroupVersion.Group, reflect.TypeOf(batchv1.CronJob{}).Name()) + assert.Nil(t, err) + + if !ok { + t.Skip("This test requires CronJob batch/v1 API installed.") + return + } + WithNewTestNamespace(t, func(ns string) { Expect(Kamel("install", "-n", ns).Execute()).To(Succeed()) diff --git a/pkg/cmd/operator/operator.go b/pkg/cmd/operator/operator.go index 16c82dd69f..912c767d62 100644 --- a/pkg/cmd/operator/operator.go +++ b/pkg/cmd/operator/operator.go @@ -23,6 +23,7 @@ import ( "fmt" "math/rand" "os" + "reflect" "runtime" "strconv" "strings" @@ -35,6 +36,7 @@ import ( coordination "k8s.io/api/coordination/v1" corev1 "k8s.io/api/core/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/selection" "k8s.io/client-go/tools/leaderelection/resourcelock" @@ -192,6 +194,22 @@ func Run(healthPort, monitoringPort int32, leaderElection bool, leaderElectionID exitOnError(err, "cannot create Integration label selector") selector := labels.NewSelector().Add(*hasIntegrationLabel) + selectors := cache.SelectorsByObject{ + &corev1.Pod{}: {Label: selector}, + &appsv1.Deployment{}: {Label: selector}, + &batchv1.Job{}: {Label: selector}, + &servingv1.Service{}: {Label: selector}, + } + + if ok, err := kubernetes.IsAPIResourceInstalled(c, batchv1.SchemeGroupVersion.String(), reflect.TypeOf(batchv1.CronJob{}).Name()); ok && err == nil { + selectors[&batchv1.CronJob{}] = struct { + Label labels.Selector + Field fields.Selector + }{ + Label: selector, + } + } + mgr, err := manager.New(c.GetConfig(), manager.Options{ Namespace: watchNamespace, EventBroadcaster: broadcaster, @@ -204,13 +222,7 @@ func Run(healthPort, monitoringPort int32, leaderElection bool, leaderElectionID MetricsBindAddress: ":" + strconv.Itoa(int(monitoringPort)), NewCache: cache.BuilderWithOptions( cache.Options{ - SelectorsByObject: cache.SelectorsByObject{ - &corev1.Pod{}: {Label: selector}, - &appsv1.Deployment{}: {Label: selector}, - &batchv1.CronJob{}: {Label: selector}, - &batchv1.Job{}: {Label: selector}, - &servingv1.Service{}: {Label: selector}, - }, + SelectorsByObject: selectors, }, ), }) diff --git a/pkg/controller/integration/integration_controller.go b/pkg/controller/integration/integration_controller.go index 26a6579e1e..11eb816415 100644 --- a/pkg/controller/integration/integration_controller.go +++ b/pkg/controller/integration/integration_controller.go @@ -205,8 +205,6 @@ func add(mgr manager.Manager, c client.Client, r reconcile.Reconciler) error { })). // Watch for the owned Deployments Owns(&appsv1.Deployment{}, builder.WithPredicates(StatusChangedPredicate{})). - // Watch for the owned CronJobs - Owns(&batchv1.CronJob{}, builder.WithPredicates(StatusChangedPredicate{})). // Watch for the Integration Pods Watches(&source.Kind{Type: &corev1.Pod{}}, handler.EnqueueRequestsFromMapFunc(func(a ctrl.Object) []reconcile.Request { @@ -225,6 +223,11 @@ func add(mgr manager.Manager, c client.Client, r reconcile.Reconciler) error { } })) + if ok, err := kubernetes.IsAPIResourceInstalled(c, batchv1.SchemeGroupVersion.String(), reflect.TypeOf(batchv1.CronJob{}).Name()); ok && err == nil { + // Watch for the owned CronJobs + b.Owns(&batchv1.CronJob{}, builder.WithPredicates(StatusChangedPredicate{})) + } + // Watch for the owned Knative Services conditionally if ok, err := kubernetes.IsAPIResourceInstalled(c, servingv1.SchemeGroupVersion.String(), reflect.TypeOf(servingv1.Service{}).Name()); err != nil { return err