Fix #1047: fix platform lookup and add unit tests
diff --git a/pkg/apis/camel/v1alpha1/integrationplatform_types.go b/pkg/apis/camel/v1alpha1/integrationplatform_types.go
index 3e17daf..72aaea7 100644
--- a/pkg/apis/camel/v1alpha1/integrationplatform_types.go
+++ b/pkg/apis/camel/v1alpha1/integrationplatform_types.go
@@ -91,6 +91,8 @@
TraitProfileKubernetes = "Kubernetes"
// TraitProfileKnative is used by default on OpenShift/Kubernetes clusters powered by Knative
TraitProfileKnative = "Knative"
+ // DefaultTraitProfile is the trait profile used as default when no other profile is set
+ DefaultTraitProfile = TraitProfileKubernetes
)
// AllTraitProfiles contains all allowed profiles
diff --git a/pkg/controller/build/build_controller.go b/pkg/controller/build/build_controller.go
index 71e2cf0..b6d227d 100644
--- a/pkg/controller/build/build_controller.go
+++ b/pkg/controller/build/build_controller.go
@@ -14,6 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
*/
+
package build
import (
@@ -151,7 +152,7 @@
targetLog := rlog.ForBuild(target)
if target.Status.Phase == v1alpha1.BuildPhaseNone || target.Status.Phase == v1alpha1.BuildPhaseWaitingForPlatform {
- pl, err := platform.GetOrLookup(ctx, r.client, target.Namespace, target.Status.Platform)
+ pl, err := platform.GetOrLookupCurrent(ctx, r.client, target.Namespace, target.Status.Platform)
if err != nil || pl.Status.Phase != v1alpha1.IntegrationPlatformPhaseReady {
target.Status.Phase = v1alpha1.BuildPhaseWaitingForPlatform
} else {
diff --git a/pkg/controller/integrationkit/integrationkit_controller.go b/pkg/controller/integrationkit/integrationkit_controller.go
index fa4c13d..ed84f1d 100644
--- a/pkg/controller/integrationkit/integrationkit_controller.go
+++ b/pkg/controller/integrationkit/integrationkit_controller.go
@@ -185,7 +185,7 @@
targetLog := rlog.ForIntegrationKit(target)
if target.Status.Phase == v1alpha1.IntegrationKitPhaseNone || target.Status.Phase == v1alpha1.IntegrationKitPhaseWaitingForPlatform {
- pl, err := platform.GetOrLookup(ctx, r.client, target.Namespace, target.Status.Platform)
+ pl, err := platform.GetOrLookupCurrent(ctx, r.client, target.Namespace, target.Status.Platform)
if err != nil || pl.Status.Phase != v1alpha1.IntegrationPlatformPhaseReady {
target.Status.Phase = v1alpha1.IntegrationKitPhaseWaitingForPlatform
} else {
diff --git a/pkg/platform/platform.go b/pkg/platform/platform.go
index b9b4dad..83c2e82 100644
--- a/pkg/platform/platform.go
+++ b/pkg/platform/platform.go
@@ -32,8 +32,8 @@
DefaultPlatformName = "camel-k"
)
-// GetOrLookup --
-func GetOrLookup(ctx context.Context, c k8sclient.Reader, namespace string, name string) (*v1alpha1.IntegrationPlatform, error) {
+// GetOrLookupCurrent --
+func GetOrLookupCurrent(ctx context.Context, c k8sclient.Reader, namespace string, name string) (*v1alpha1.IntegrationPlatform, error) {
if name != "" {
return Get(ctx, c, namespace, name)
}
@@ -41,6 +41,15 @@
return GetCurrentPlatform(ctx, c, namespace)
}
+// GetOrLookupAny returns the named platform or any other platform in the namespace
+func GetOrLookupAny(ctx context.Context, c k8sclient.Reader, namespace string, name string) (*v1alpha1.IntegrationPlatform, error) {
+ if name != "" {
+ return Get(ctx, c, namespace, name)
+ }
+
+ return getAnyPlatform(ctx, c, namespace, false)
+}
+
// Get returns the currently installed platform
func Get(ctx context.Context, c k8sclient.Reader, namespace string, name string) (*v1alpha1.IntegrationPlatform, error) {
return kubernetes.GetIntegrationPlatform(ctx, c, name, namespace)
@@ -48,6 +57,11 @@
// GetCurrentPlatform returns the currently installed platform
func GetCurrentPlatform(ctx context.Context, c k8sclient.Reader, namespace string) (*v1alpha1.IntegrationPlatform, error) {
+ return getAnyPlatform(ctx, c, namespace, true)
+}
+
+// getAnyPlatform returns the currently installed platform or any platform existing in the namespace
+func getAnyPlatform(ctx context.Context, c k8sclient.Reader, namespace string, active bool) (*v1alpha1.IntegrationPlatform, error) {
lst, err := ListPlatforms(ctx, c, namespace)
if err != nil {
return nil, err
@@ -59,6 +73,13 @@
return &platform, nil
}
}
+
+ if !active && len(lst.Items) > 0 {
+ // does not require the platform to be active, just return one if present
+ res := lst.Items[0]
+ return &res, nil
+ }
+
return nil, k8serrors.NewNotFound(v1alpha1.Resource("IntegrationPlatform"), DefaultPlatformName)
}
diff --git a/pkg/trait/platform.go b/pkg/trait/platform.go
index 2f4da53..06d4872 100644
--- a/pkg/trait/platform.go
+++ b/pkg/trait/platform.go
@@ -92,7 +92,7 @@
}
func (t *platformTrait) getOrCreatePlatform(e *Environment) (*v1alpha1.IntegrationPlatform, error) {
- pl, err := platform.GetOrLookup(t.ctx, t.client, e.Integration.Namespace, e.Integration.Status.Platform)
+ pl, err := platform.GetOrLookupAny(t.ctx, t.client, e.Integration.Namespace, e.Integration.Status.Platform)
if err != nil && k8serrors.IsNotFound(err) {
if t.CreateDefault != nil && *t.CreateDefault {
platformName := e.Integration.Status.Platform
diff --git a/pkg/trait/platform_test.go b/pkg/trait/platform_test.go
new file mode 100644
index 0000000..d9de1f3
--- /dev/null
+++ b/pkg/trait/platform_test.go
@@ -0,0 +1,171 @@
+/*
+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 trait
+
+import (
+ "testing"
+
+ "github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+ "github.com/apache/camel-k/pkg/platform"
+ "github.com/apache/camel-k/pkg/util/kubernetes"
+ "github.com/apache/camel-k/pkg/util/test"
+ "github.com/stretchr/testify/assert"
+ v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+func TestPlatformTraitChangeStatus(t *testing.T) {
+
+ table := []struct {
+ name string
+ initialPhase v1alpha1.IntegrationPhase
+ }{
+ {
+ name: "Setup from [none]",
+ initialPhase: v1alpha1.IntegrationPhaseNone,
+ },
+ {
+ name: "Setup from WaitingForPlatform",
+ initialPhase: v1alpha1.IntegrationPhaseWaitingForPlatform,
+ },
+ }
+
+ for _, entry := range table {
+ input := entry
+ t.Run(input.name, func(t *testing.T) {
+ e := Environment{
+ Resources: kubernetes.NewCollection(),
+ Integration: &v1alpha1.Integration{
+ Status: v1alpha1.IntegrationStatus{
+ Phase: input.initialPhase,
+ },
+ },
+ }
+
+ trait := newPlatformTrait()
+ createPlatform := false
+ trait.CreateDefault = &createPlatform
+
+ var err error
+ trait.client, err = test.NewFakeClient()
+ assert.Nil(t, err)
+
+ enabled, err := trait.Configure(&e)
+ assert.Nil(t, err)
+ assert.True(t, enabled)
+
+ err = trait.Apply(&e)
+ assert.Nil(t, err)
+
+ assert.Equal(t, v1alpha1.IntegrationPhaseWaitingForPlatform, e.Integration.Status.Phase)
+ assert.Empty(t, e.Resources.Items())
+ })
+ }
+}
+
+func TestPlatformTraitCreatesDefaultPlatform(t *testing.T) {
+ e := Environment{
+ Resources: kubernetes.NewCollection(),
+ Integration: &v1alpha1.Integration{
+ ObjectMeta: v1.ObjectMeta{
+ Namespace: "ns1",
+ Name: "xx",
+ },
+ Status: v1alpha1.IntegrationStatus{
+ Phase: v1alpha1.IntegrationPhaseNone,
+ },
+ },
+ }
+
+ trait := newPlatformTrait()
+ createPlatform := true
+ trait.CreateDefault = &createPlatform
+
+ var err error
+ trait.client, err = test.NewFakeClient()
+ assert.Nil(t, err)
+
+ enabled, err := trait.Configure(&e)
+ assert.Nil(t, err)
+ assert.True(t, enabled)
+
+ err = trait.Apply(&e)
+ assert.Nil(t, err)
+
+ assert.Equal(t, v1alpha1.IntegrationPhaseWaitingForPlatform, e.Integration.Status.Phase)
+ assert.Equal(t, 1, len(e.Resources.Items()))
+ defPlatform := v1alpha1.NewIntegrationPlatform("ns1", platform.DefaultPlatformName)
+ assert.Contains(t, e.Resources.Items(), &defPlatform)
+}
+
+func TestPlatformTraitExisting(t *testing.T) {
+
+ table := []struct {
+ name string
+ platformPhase v1alpha1.IntegrationPlatformPhase
+ expectedPhase v1alpha1.IntegrationPhase
+ }{
+ {
+ name: "Wait existing",
+ platformPhase: "",
+ expectedPhase: v1alpha1.IntegrationPhaseWaitingForPlatform,
+ },
+ {
+ name: "Move state",
+ platformPhase: v1alpha1.IntegrationPlatformPhaseReady,
+ expectedPhase: v1alpha1.IntegrationPhaseInitialization,
+ },
+ }
+
+ for _, entry := range table {
+ input := entry
+ t.Run(input.name, func(t *testing.T) {
+ e := Environment{
+ Resources: kubernetes.NewCollection(),
+ Integration: &v1alpha1.Integration{
+ ObjectMeta: v1.ObjectMeta{
+ Namespace: "ns1",
+ Name: "xx",
+ },
+ Status: v1alpha1.IntegrationStatus{
+ Phase: v1alpha1.IntegrationPhaseNone,
+ },
+ },
+ }
+
+ trait := newPlatformTrait()
+ createPlatform := true
+ trait.CreateDefault = &createPlatform
+
+ var err error
+ existingPlatform := v1alpha1.NewIntegrationPlatform("ns1", "existing")
+ existingPlatform.Status.Phase = input.platformPhase
+ trait.client, err = test.NewFakeClient(&existingPlatform)
+ assert.Nil(t, err)
+
+ enabled, err := trait.Configure(&e)
+ assert.Nil(t, err)
+ assert.True(t, enabled)
+
+ err = trait.Apply(&e)
+ assert.Nil(t, err)
+
+ assert.Equal(t, input.expectedPhase, e.Integration.Status.Phase)
+ assert.Empty(t, e.Resources.Items())
+ })
+ }
+}
diff --git a/pkg/trait/trait_catalog.go b/pkg/trait/trait_catalog.go
index 6088506..32d5faa 100644
--- a/pkg/trait/trait_catalog.go
+++ b/pkg/trait/trait_catalog.go
@@ -221,7 +221,7 @@
}
}
- return c.allTraits()
+ return nil
}
func (c *Catalog) apply(environment *Environment) error {
diff --git a/pkg/trait/trait_types.go b/pkg/trait/trait_types.go
index cd7dafe..e21829a 100644
--- a/pkg/trait/trait_types.go
+++ b/pkg/trait/trait_types.go
@@ -220,7 +220,8 @@
if e.Platform != nil {
return platform.GetProfile(e.Platform)
}
- return ""
+
+ return v1alpha1.DefaultTraitProfile
}
// DetermineControllerStrategy determines the type of controller that should be used for the integration