diff --git a/e2e/common/cli/install_test.go b/e2e/common/cli/install_test.go index d1a76dc3c6..236b69652a 100644 --- a/e2e/common/cli/install_test.go +++ b/e2e/common/cli/install_test.go @@ -24,7 +24,6 @@ package common import ( "bytes" - "reflect" "strings" "testing" "text/template" @@ -36,9 +35,8 @@ import ( v1 "github.com/apache/camel-k/pkg/apis/camel/v1" "github.com/apache/camel-k/pkg/install" "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 +96,8 @@ 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()) - assert.Nil(t, err) - - if !ocp || !ok { - t.Skip("This test requires ConsoleCliDownload object which is available on OpenShift 4 only.") + if !ocp || !IsAPIResourceInstalled(t, TestClient(), "console.openshift.io/v1", consolev1.ConsoleCLIDownload{}) { + 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..5ab80768d0 100644 --- a/e2e/common/cron_test.go +++ b/e2e/common/cron_test.go @@ -27,6 +27,7 @@ import ( . "github.com/onsi/gomega" + batchv1 "k8s.io/api/batch/v1" corev1 "k8s.io/api/core/v1" . "github.com/apache/camel-k/e2e/support" @@ -34,6 +35,11 @@ import ( ) func TestRunCronExample(t *testing.T) { + if !IsAPIResourceInstalled(t, TestClient(), "batch/v1", batchv1.CronJob{}) { + 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/e2e/support/test_support.go b/e2e/support/test_support.go index 3fdd06077d..f64ec9a297 100644 --- a/e2e/support/test_support.go +++ b/e2e/support/test_support.go @@ -1933,3 +1933,9 @@ func GetOutputStringAsync(cmd *cobra.Command) func() string { return buffer.String() } } + +func IsAPIResourceInstalled(t *testing.T, client client.Client, groupVersion string, obj interface{}) bool { + ok, err := kubernetes.IsAPIResourceInstalled(client, groupVersion, reflect.TypeOf(obj).Name()) + assert.Nil(t, err) + return ok +} diff --git a/pkg/cmd/operator/operator.go b/pkg/cmd/operator/operator.go index 16c82dd69f..595d9f34ca 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" @@ -192,6 +193,23 @@ 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 = cache.SelectorsByObject{ + &corev1.Pod{}: {Label: selector}, + &appsv1.Deployment{}: {Label: selector}, + &batchv1.CronJob{}: {Label: selector}, + &batchv1.Job{}: {Label: selector}, + &servingv1.Service{}: {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 diff --git a/pkg/trait/container.go b/pkg/trait/container.go index 3b3ca484c5..f032c0573a 100644 --- a/pkg/trait/container.go +++ b/pkg/trait/container.go @@ -20,6 +20,7 @@ package trait import ( "fmt" "path" + "reflect" appsv1 "k8s.io/api/apps/v1" batchv1 "k8s.io/api/batch/v1" @@ -297,17 +298,19 @@ func (t *containerTrait) configureContainer(e *Environment) error { return err } - // CronJob - if err := e.Resources.VisitCronJobE(func(cron *batchv1.CronJob) error { - for _, envVar := range e.EnvVars { - envvar.SetVar(&container.Env, envVar) - } + if ok, err := kubernetes.IsAPIResourceInstalled(e.Client, batchv1.SchemeGroupVersion.String(), reflect.TypeOf(batchv1.CronJob{}).Name()); ok && err == nil { + // CronJob + if err := e.Resources.VisitCronJobE(func(cron *batchv1.CronJob) error { + for _, envVar := range e.EnvVars { + envvar.SetVar(&container.Env, envVar) + } - containers = &cron.Spec.JobTemplate.Spec.Template.Spec.Containers - visited = true - return nil - }); err != nil { - return err + containers = &cron.Spec.JobTemplate.Spec.Template.Spec.Containers + visited = true + return nil + }); err != nil { + return err + } } if visited { diff --git a/pkg/trait/container_probes_test.go b/pkg/trait/container_probes_test.go index 0d4ccbdabd..c81e8b1947 100644 --- a/pkg/trait/container_probes_test.go +++ b/pkg/trait/container_probes_test.go @@ -37,11 +37,13 @@ func newTestProbesEnv(t *testing.T, integration *v1.Integration) Environment { assert.Nil(t, err) assert.NotNil(t, catalog) + client, _ := test.NewFakeClient() traitCatalog := NewCatalog(nil) return Environment{ Catalog: traitCatalog, CamelCatalog: catalog, + Client: client, Platform: &v1.IntegrationPlatform{}, Integration: integration, Resources: kubernetes.NewCollection(), diff --git a/pkg/trait/container_test.go b/pkg/trait/container_test.go index 494dd5b20d..b65803ad37 100644 --- a/pkg/trait/container_test.go +++ b/pkg/trait/container_test.go @@ -40,11 +40,13 @@ func TestContainerWithDefaults(t *testing.T) { catalog, err := camel.DefaultCatalog() assert.Nil(t, err) + client, _ := test.NewFakeClient() traitCatalog := NewCatalog(nil) environment := Environment{ CamelCatalog: catalog, Catalog: traitCatalog, + Client: client, Integration: &v1.Integration{ ObjectMeta: metav1.ObjectMeta{ Name: ServiceTestName, diff --git a/pkg/trait/mount.go b/pkg/trait/mount.go index 039e3ccc38..d0fc7785e0 100644 --- a/pkg/trait/mount.go +++ b/pkg/trait/mount.go @@ -20,6 +20,7 @@ package trait import ( "fmt" "path/filepath" + "reflect" "strings" appsv1 "k8s.io/api/apps/v1" @@ -118,13 +119,15 @@ func (t *mountTrait) Apply(e *Environment) error { return err } - // CronJob - if err := e.Resources.VisitCronJobE(func(cron *batchv1.CronJob) error { - volumes = &cron.Spec.JobTemplate.Spec.Template.Spec.Volumes - visited = true - return nil - }); err != nil { - return err + if ok, err := kubernetes.IsAPIResourceInstalled(e.Client, batchv1.SchemeGroupVersion.String(), reflect.TypeOf(batchv1.CronJob{}).Name()); ok && err == nil { + // CronJob + if err := e.Resources.VisitCronJobE(func(cron *batchv1.CronJob) error { + volumes = &cron.Spec.JobTemplate.Spec.Template.Spec.Volumes + visited = true + return nil + }); err != nil { + return err + } } if visited {