This is an automated email from the ASF dual-hosted git repository.
pcongiusti pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
The following commit(s) were added to refs/heads/main by this push:
new 6dbded5ab feat(kamelets): bundling from jar
6dbded5ab is described below
commit 6dbded5abbda4d4edc1ce8a7bdca3ad37bacacce
Author: Pasquale Congiusti <[email protected]>
AuthorDate: Thu Sep 12 17:34:03 2024 +0200
feat(kamelets): bundling from jar
This is required to simplify the release process and leverage to
distributed catalog as dependency
---
build/Dockerfile | 5 +-
pkg/apis/camel/v1/integrationplatform_types.go | 7 +-
pkg/apis/camel/v1/kamelet_types_support.go | 5 +
pkg/cmd/reset.go | 24 ---
pkg/controller/catalog/initialize.go | 1 -
pkg/controller/integrationplatform/catalog.go | 84 --------
pkg/controller/integrationplatform/catalog_test.go | 235 ---------------------
pkg/controller/integrationplatform/create.go | 150 +++++++++++--
pkg/controller/integrationplatform/create_test.go | 189 ++++++++++++++---
pkg/controller/integrationplatform/initialize.go | 17 +-
.../integrationplatform/initialize_test.go | 81 ++++---
.../integrationplatform_controller.go | 15 +-
pkg/controller/integrationplatform/kamelets.go | 209 ++++++++++++++++++
.../integrationplatform/kamelets_test.go | 153 ++++++++++++++
pkg/controller/integrationplatform/monitor.go | 80 +++----
pkg/controller/integrationplatform/monitor_test.go | 199 +++++++++++------
pkg/install/kamelets.go | 136 ------------
pkg/install/kamelets_test.go | 40 ----
pkg/install/optional.go | 31 ---
pkg/install/testdata/timer-source.kamelet.yaml | 57 -----
pkg/platform/defaults.go | 12 +-
pkg/trait/kamelets.go | 28 ++-
pkg/trait/kamelets_test.go | 1 -
pkg/util/camel/camel_runtime.go | 3 +-
release.adoc | 1 -
script/Makefile | 19 +-
script/bundle_kamelets.sh | 55 -----
27 files changed, 935 insertions(+), 902 deletions(-)
diff --git a/build/Dockerfile b/build/Dockerfile
index 78ff6a3cd..f1523076c 100644
--- a/build/Dockerfile
+++ b/build/Dockerfile
@@ -43,20 +43,17 @@ ENV MAVEN_USER_HOME="${MAVEN_HOME}"
RUN ${MVNW_DIR}/mvnw --version | grep "Maven home:" | sed 's/Maven home: //'
>> ${MVNW_DIR}default \
&& cp -r /usr/share/maven/lib/. $(cat ${MVNW_DIR}default)/lib \
&& rm $(cat ${MVNW_DIR}default)/lib/maven-slf4j-provider* \
- && rm $(cat ${MVNW_DIR}default)/lib/slf4j-api-1.*
+ && rm $(cat ${MVNW_DIR}default)/lib/slf4j-api-1.*
ENV MAVEN_OPTS="${MAVEN_OPTS}
-Dlogback.configurationFile=${MAVEN_HOME}/conf/logback.xml"
ADD build/_maven_output ${MVN_REPO}
# Fix https://github.com/moby/moby/issues/37965
RUN true
-ADD build/_kamelets /kamelets
RUN chgrp -R 0 ${MVN_REPO} \
&& chown -R 1001:0 ${MVN_REPO} \
&& chmod -R 775 ${MVN_REPO} \
- && chgrp -R 0 /kamelets \
- && chmod -R g=u /kamelets \
&& chgrp -R 0 ${MAVEN_HOME} \
&& chown -R 1001:0 ${MAVEN_HOME} \
&& chmod -R 775 ${MAVEN_HOME}
diff --git a/pkg/apis/camel/v1/integrationplatform_types.go
b/pkg/apis/camel/v1/integrationplatform_types.go
index 3cc8e3a65..6c211996b 100644
--- a/pkg/apis/camel/v1/integrationplatform_types.go
+++ b/pkg/apis/camel/v1/integrationplatform_types.go
@@ -192,6 +192,7 @@ const (
// IntegrationPlatformPhaseError when the IntegrationPlatform had some
error (see Conditions).
IntegrationPlatformPhaseError IntegrationPlatformPhase = "Error"
// IntegrationPlatformPhaseCreateCatalog when the IntegrationPlatform
creates a new CamelCatalog.
+ // Deprecated no longer in use.
IntegrationPlatformPhaseCreateCatalog IntegrationPlatformPhase =
"CreateCatalog"
// IntegrationPlatformConditionReady is the condition if the
IntegrationPlatform is ready.
@@ -199,12 +200,12 @@ const (
IntegrationPlatformConditionReady = "Ready"
// IntegrationPlatformConditionTypeCreated is the condition if the
IntegrationPlatform has been created.
IntegrationPlatformConditionTypeCreated
IntegrationPlatformConditionType = "Created"
-
// IntegrationPlatformConditionTypeRegistryAvailable is the condition
for the availability of a container registry.
IntegrationPlatformConditionTypeRegistryAvailable
IntegrationPlatformConditionType = "RegistryAvailable"
-
- // IntegrationPlatformConditionCamelCatalogAvailable is the condition
for the availability of a container registry.
+ // IntegrationPlatformConditionCamelCatalogAvailable is the condition
for the availability of a the CamelCatalog.
IntegrationPlatformConditionCamelCatalogAvailable
IntegrationPlatformConditionType = "CamelCatalogAvailable"
+ // IntegrationPlatformConditionKameletCatalogAvailable is the condition
for the availability of a Kamelet catalog.
+ IntegrationPlatformConditionKameletCatalogAvailable
IntegrationPlatformConditionType = "KameletCatalogAvailable"
// IntegrationPlatformConditionCreatedReason represents the reason that
the IntegrationPlatform is created.
IntegrationPlatformConditionCreatedReason = "IntegrationPlatformCreated"
diff --git a/pkg/apis/camel/v1/kamelet_types_support.go
b/pkg/apis/camel/v1/kamelet_types_support.go
index bb22c998e..aa19fc2b9 100644
--- a/pkg/apis/camel/v1/kamelet_types_support.go
+++ b/pkg/apis/camel/v1/kamelet_types_support.go
@@ -178,6 +178,11 @@ func (k *Kamelet) SortedTypesKeys() []TypeSlot {
return res
}
+// IsBundled returns true if the Kamelet is coming from a pre-bundled
installation.
+func (k *Kamelet) IsBundled() bool {
+ return k.Labels != nil && k.Labels[KameletBundledLabel] == "true"
+}
+
func ValidKameletName(name string) bool {
return !reservedKameletNames[name]
}
diff --git a/pkg/cmd/reset.go b/pkg/cmd/reset.go
index 02a6f414e..c32112e5d 100644
--- a/pkg/cmd/reset.go
+++ b/pkg/cmd/reset.go
@@ -18,7 +18,6 @@ limitations under the License.
package cmd
import (
- "errors"
"fmt"
v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
@@ -93,13 +92,6 @@ func (o *resetCmdOptions) reset(cmd *cobra.Command, _
[]string) {
}
fmt.Fprintln(cmd.OutOrStdout(), n, "integration kits deleted
from namespace", o.Namespace)
}
-
- if err = o.resetIntegrationPlatform(c); err != nil {
- fmt.Fprintln(cmd.ErrOrStderr(), err)
- return
- }
-
- fmt.Fprintln(cmd.OutOrStdout(), "Camel K platform has been reset
successfully!")
}
func (o *resetCmdOptions) deleteAllIntegrations(c client.Client) (int, error) {
@@ -163,22 +155,6 @@ func (o *resetCmdOptions) deleteAllKameletBindings(c
client.Client) (int, error)
return len(list.Items), nil
}
-func (o *resetCmdOptions) resetIntegrationPlatform(c client.Client) error {
- list := v1.NewIntegrationPlatformList()
- if err := c.List(o.Context, &list, k8sclient.InNamespace(o.Namespace));
err != nil {
- return fmt.Errorf("could not retrieve integration platform from
namespace %s: %w", o.Namespace, err)
- }
- if len(list.Items) > 1 {
- return fmt.Errorf("expected 1 integration platform in the
namespace, found: %d", len(list.Items))
- } else if len(list.Items) == 0 {
- return errors.New("no integration platforms found in the
namespace")
- }
- platform := list.Items[0]
- // Let's reset the status
- platform.Status = v1.IntegrationPlatformStatus{}
- return c.Status().Update(o.Context, &platform)
-}
-
func isIntegrationOwned(it v1.Integration) bool {
for _, ref := range it.OwnerReferences {
gv, err := schema.ParseGroupVersion(ref.APIVersion)
diff --git a/pkg/controller/catalog/initialize.go
b/pkg/controller/catalog/initialize.go
index 3aac6ab65..d5f3c7a4a 100644
--- a/pkg/controller/catalog/initialize.go
+++ b/pkg/controller/catalog/initialize.go
@@ -45,7 +45,6 @@ func (action *initializeAction) CanHandle(catalog
*v1.CamelCatalog) bool {
func (action *initializeAction) Handle(ctx context.Context, catalog
*v1.CamelCatalog) (*v1.CamelCatalog, error) {
action.L.Info("Initializing CamelCatalog")
-
platform, err := platformutil.GetForName(ctx, action.client,
catalog.Namespace, defaults.OperatorID())
if err != nil {
diff --git a/pkg/controller/integrationplatform/catalog.go
b/pkg/controller/integrationplatform/catalog.go
deleted file mode 100644
index ea1406f1f..000000000
--- a/pkg/controller/integrationplatform/catalog.go
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
-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 integrationplatform
-
-import (
- "context"
- "fmt"
-
- v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
- "github.com/apache/camel-k/v2/pkg/util/camel"
-
- corev1 "k8s.io/api/core/v1"
-)
-
-// NewCreateCatalogAction returns an action to create a new CamelCatalog.
-func NewCreateCatalogAction() Action {
- return &catalogAction{}
-}
-
-type catalogAction struct {
- baseAction
-}
-
-func (action *catalogAction) Name() string {
- return "catalog"
-}
-
-func (action *catalogAction) CanHandle(platform *v1.IntegrationPlatform) bool {
- return platform.Status.Phase == v1.IntegrationPlatformPhaseCreateCatalog
-}
-
-func (action *catalogAction) Handle(ctx context.Context, platform
*v1.IntegrationPlatform) (*v1.IntegrationPlatform, error) {
- // New runtime version set - check that catalog exists and create it if
it does not exist
- runtimeSpec := v1.RuntimeSpec{
- Version: platform.Status.Build.RuntimeVersion,
- Provider: v1.RuntimeProviderQuarkus,
- }
-
- catalog, err := camel.LoadCatalog(ctx, action.client,
platform.Namespace, runtimeSpec)
- if err != nil {
- action.L.Error(err, "IntegrationPlatform unable to load Camel
catalog",
- "runtime-version", runtimeSpec.Version,
"runtime-provider", runtimeSpec.Provider)
- return platform, nil
- } else if catalog == nil {
- if catalog, err = camel.CreateCatalog(ctx, action.client,
platform.Namespace, platform, runtimeSpec); err != nil {
- action.L.Error(err, "IntegrationPlatform unable to
create Camel catalog",
- "runtime-version", runtimeSpec.Version,
"runtime-provider", runtimeSpec.Provider)
-
- platform.Status.Phase = v1.IntegrationPlatformPhaseError
- platform.Status.SetCondition(
-
v1.IntegrationPlatformConditionCamelCatalogAvailable,
- corev1.ConditionFalse,
-
v1.IntegrationPlatformConditionCamelCatalogAvailableReason,
- fmt.Sprintf("camel catalog %s not available,
please review given runtime version. Error: %s", runtimeSpec.Version, err))
-
- return platform, nil
- }
- }
-
- platform.Status.Phase = v1.IntegrationPlatformPhaseReady
- platform.Status.SetCondition(
- v1.IntegrationPlatformConditionCamelCatalogAvailable,
- corev1.ConditionTrue,
- v1.IntegrationPlatformConditionCamelCatalogAvailableReason,
- fmt.Sprintf("camel catalog %s available", runtimeSpec.Version))
- platform.Status.Build.RuntimeCoreVersion =
catalog.Runtime.Metadata["camel.version"]
-
- return platform, nil
-}
diff --git a/pkg/controller/integrationplatform/catalog_test.go
b/pkg/controller/integrationplatform/catalog_test.go
deleted file mode 100644
index f2c526508..000000000
--- a/pkg/controller/integrationplatform/catalog_test.go
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
-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 integrationplatform
-
-import (
- "context"
- "errors"
- "fmt"
- "os"
- "strings"
- "testing"
-
- "github.com/apache/camel-k/v2/pkg/util/boolean"
-
- v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
- "github.com/apache/camel-k/v2/pkg/platform"
- "github.com/apache/camel-k/v2/pkg/resources"
- "github.com/apache/camel-k/v2/pkg/util/defaults"
- "github.com/apache/camel-k/v2/pkg/util/log"
- "github.com/apache/camel-k/v2/pkg/util/maven"
- "github.com/apache/camel-k/v2/pkg/util/test"
- "github.com/rs/xid"
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
-
- corev1 "k8s.io/api/core/v1"
- "k8s.io/apimachinery/pkg/runtime"
- k8stesting "k8s.io/client-go/testing"
- k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
-)
-
-func TestCanHandlePhaseCreateCatalog(t *testing.T) {
- ip := v1.IntegrationPlatform{}
- ip.Namespace = "ns"
- ip.Name = xid.New().String()
- ip.Spec.Cluster = v1.IntegrationPlatformClusterOpenShift
- ip.Spec.Profile = v1.TraitProfileOpenShift
- ip.Spec.Build.Registry.Address = defaults.OpenShiftRegistryAddress
-
- ip.Spec.Build.RuntimeVersion = defaults.DefaultRuntimeVersion
-
- ip.Status.Phase = v1.IntegrationPlatformPhaseCreateCatalog
-
- c, err := test.NewFakeClient(&ip)
- require.NoError(t, err)
-
- action := NewCreateCatalogAction()
- action.InjectLogger(log.Log)
- action.InjectClient(c)
-
- answer := action.CanHandle(&ip)
- assert.True(t, answer)
-
- ip.Status.Phase = v1.IntegrationPlatformPhaseError
- answer = action.CanHandle(&ip)
- assert.False(t, answer)
-
- ip.Status.Phase = v1.IntegrationPlatformPhaseReady
- answer = action.CanHandle(&ip)
- assert.False(t, answer)
-}
-
-func TestCreateCatalog(t *testing.T) {
- ip := v1.IntegrationPlatform{}
- ip.Namespace = "ns"
- ip.Name = xid.New().String()
- ip.Spec.Cluster = v1.IntegrationPlatformClusterOpenShift
- ip.Spec.Profile = v1.TraitProfileOpenShift
- ip.Spec.Build.Registry.Address = defaults.OpenShiftRegistryAddress
-
- ip.Status.Phase = v1.IntegrationPlatformPhaseCreateCatalog
- ip.Spec.Build.RuntimeVersion = defaults.DefaultRuntimeVersion
- if strings.Contains(ip.Spec.Build.RuntimeVersion, "SNAPSHOT") {
- maven.DefaultMavenRepositories +=
",https://repository.apache.org/content/repositories/snapshots-group@snapshots@id=apache-snapshots"
- }
-
- c, err := test.NewFakeClient(&ip)
- require.NoError(t, err)
-
- // use local Maven executable in tests
- t.Setenv("MAVEN_WRAPPER", boolean.FalseString)
- _, ok := os.LookupEnv("MAVEN_CMD")
- if !ok {
- t.Setenv("MAVEN_CMD", "mvn")
- }
-
- fakeClient := c.(*test.FakeClient) //nolint
- fakeClient.AddReactor("create", "*", func(action k8stesting.Action)
(bool, runtime.Object, error) {
- createAction := action.(k8stesting.CreateAction) //nolint
-
- assert.Equal(t, "ns", createAction.GetNamespace())
-
- return true, createAction.GetObject(), nil
- })
-
- err = platform.ConfigureDefaults(context.TODO(), c, &ip, false)
- require.NoError(t, err)
-
- action := NewCreateCatalogAction()
- action.InjectLogger(log.Log)
- action.InjectClient(c)
-
- answer, err := action.Handle(context.TODO(), &ip)
- require.NoError(t, err)
- assert.NotNil(t, answer)
-
- assert.Equal(t, v1.IntegrationPlatformPhaseReady, answer.Status.Phase,
"Error", answer.Status.Conditions[0].Message)
- assert.Equal(t, corev1.ConditionTrue,
answer.Status.GetCondition(v1.IntegrationPlatformConditionCamelCatalogAvailable).Status)
- // We don't know exactly which is the core version, it is enough to
check is not empty in the test
- assert.NotEqual(t, "", answer.Status.Build.RuntimeCoreVersion)
-
- list := v1.NewCamelCatalogList()
- err = c.List(context.TODO(), &list, k8sclient.InNamespace(ip.Namespace))
-
- require.NoError(t, err)
- assert.NotEmpty(t, list.Items)
-
- items, err := resources.WithPrefix("/camel-catelog-")
- require.NoError(t, err)
-
- for _, k := range items {
- found := false
-
- for _, c := range list.Items {
- n := strings.TrimSuffix(k, ".yaml")
- n = strings.ToLower(n)
-
- if c.Name == n {
- found = true
- }
- }
-
- assert.True(t, found)
- }
-}
-
-func TestCatalogAlreadyPresent(t *testing.T) {
- ip := v1.IntegrationPlatform{}
- ip.Namespace = "ns"
- ip.Name = xid.New().String()
- ip.Spec.Cluster = v1.IntegrationPlatformClusterOpenShift
- ip.Spec.Profile = v1.TraitProfileOpenShift
- ip.Spec.Build.Registry.Address = defaults.OpenShiftRegistryAddress
-
- ip.Status.Phase = v1.IntegrationPlatformPhaseCreateCatalog
-
- catalog := v1.NewCamelCatalog("ns", fmt.Sprintf("camel-catalog-%s",
defaults.DefaultRuntimeVersion))
- catalog.Spec.Runtime.Version = defaults.DefaultRuntimeVersion
- catalog.Spec.Runtime.Provider = v1.RuntimeProviderQuarkus
- catalog.Spec.Runtime.Metadata = map[string]string{
- "camel.version": "4.4.0",
- }
-
- c, err := test.NewFakeClient(&ip, &catalog)
- require.NoError(t, err)
-
- err = platform.ConfigureDefaults(context.TODO(), c, &ip, false)
- require.NoError(t, err)
-
- action := NewMonitorAction()
- action.InjectLogger(log.Log)
- action.InjectClient(c)
-
- answer, err := action.Handle(context.TODO(), &ip)
- require.NoError(t, err)
- assert.NotNil(t, answer)
-
- assert.Equal(t, v1.IntegrationPlatformPhaseReady, answer.Status.Phase)
- assert.Equal(t, "4.4.0", answer.Status.Build.RuntimeCoreVersion)
- assert.Equal(t, corev1.ConditionTrue,
answer.Status.GetCondition(v1.IntegrationPlatformConditionCamelCatalogAvailable).Status)
-}
-
-func TestCreateCatalogError(t *testing.T) {
- ip := v1.IntegrationPlatform{}
- ip.Namespace = "ns"
- ip.Name = xid.New().String()
- ip.Spec.Cluster = v1.IntegrationPlatformClusterOpenShift
- ip.Spec.Profile = v1.TraitProfileOpenShift
- ip.Spec.Build.Registry.Address = defaults.OpenShiftRegistryAddress
-
- ip.Status.Phase = v1.IntegrationPlatformPhaseCreateCatalog
-
- // force catalog build to fail
- ip.Spec.Build.RuntimeVersion = "0.0.0"
-
- c, err := test.NewFakeClient(&ip)
- require.NoError(t, err)
-
- // use local Maven executable in tests
- t.Setenv("MAVEN_WRAPPER", boolean.FalseString)
- _, ok := os.LookupEnv("MAVEN_CMD")
- if !ok {
- t.Setenv("MAVEN_CMD", "mvn")
- }
-
- fakeClient := c.(*test.FakeClient) //nolint
- fakeClient.AddReactor("create", "*", func(action k8stesting.Action)
(bool, runtime.Object, error) {
- createAction := action.(k8stesting.CreateAction) //nolint
-
- assert.Equal(t, "ns", createAction.GetNamespace())
-
- return true, nil, errors.New("failed to create catalog for some
reason")
- })
-
- err = platform.ConfigureDefaults(context.TODO(), c, &ip, false)
- require.NoError(t, err)
-
- action := NewCreateCatalogAction()
- action.InjectLogger(log.Log)
- action.InjectClient(c)
-
- answer, err := action.Handle(context.TODO(), &ip)
- require.NoError(t, err)
- assert.NotNil(t, answer)
-
- assert.Equal(t, v1.IntegrationPlatformPhaseError, answer.Status.Phase)
- assert.Equal(t, corev1.ConditionFalse,
answer.Status.GetCondition(v1.IntegrationPlatformConditionCamelCatalogAvailable).Status)
- assert.Equal(t,
v1.IntegrationPlatformConditionCamelCatalogAvailableReason,
answer.Status.GetCondition(v1.IntegrationPlatformConditionCamelCatalogAvailable).Reason)
- assert.Contains(t,
answer.Status.GetCondition(v1.IntegrationPlatformConditionCamelCatalogAvailable).Message,
"camel catalog 0.0.0 not available, please review given runtime version.
Error:")
-}
diff --git a/pkg/controller/integrationplatform/create.go
b/pkg/controller/integrationplatform/create.go
index 8471ca5e5..85edbf94a 100644
--- a/pkg/controller/integrationplatform/create.go
+++ b/pkg/controller/integrationplatform/create.go
@@ -19,14 +19,17 @@ package integrationplatform
import (
"context"
+ "fmt"
+ "gopkg.in/yaml.v2"
corev1 "k8s.io/api/core/v1"
- ctrl "sigs.k8s.io/controller-runtime/pkg/client"
v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
- "github.com/apache/camel-k/v2/pkg/install"
+ "github.com/apache/camel-k/v2/pkg/client"
"github.com/apache/camel-k/v2/pkg/resources"
+ "github.com/apache/camel-k/v2/pkg/util/camel"
"github.com/apache/camel-k/v2/pkg/util/defaults"
+ k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
)
// NewCreateAction returns the action that creates resources needed by the
platform.
@@ -47,38 +50,141 @@ func (action *createAction) CanHandle(platform
*v1.IntegrationPlatform) bool {
}
func (action *createAction) Handle(ctx context.Context, platform
*v1.IntegrationPlatform) (*v1.IntegrationPlatform, error) {
- paths, err := resources.WithPrefix("/resources/camel-catalog-")
+ runtimeSpec := v1.RuntimeSpec{
+ Version: platform.Status.Build.RuntimeVersion,
+ Provider: platform.Status.Build.RuntimeProvider,
+ }
+ catalog, err := loadCatalog(ctx, action.client, platform.Namespace,
runtimeSpec)
if err != nil {
return nil, err
}
- for _, k := range paths {
- action.L.Infof("Installing camel catalog: %s", k)
- err := install.Resources(ctx, action.client,
platform.Namespace, true,
- func(object ctrl.Object) ctrl.Object {
- action.L.Infof("Copying platform annotations to
catalog: %s", object.GetName())
- object.SetAnnotations(platform.Annotations)
- return object
- },
- k)
+ // if bundled version, load catalog spec from resources
+ if platform.Status.Build.RuntimeVersion ==
defaults.DefaultRuntimeVersion {
+ if platform, err = action.handleBundledCatalog(ctx, platform,
catalog); err != nil {
+ return platform, err
+ }
+ } else {
+ // otherwise get the catalog from external dependency
+ if platform, err = action.handleNewCatalog(ctx, platform,
catalog, runtimeSpec); err != nil {
+ return platform, err
+ }
+ }
+
+ platform.Status.Phase = v1.IntegrationPlatformPhaseReady
+ platform.Status.SetCondition(
+ v1.IntegrationPlatformConditionCamelCatalogAvailable,
+ corev1.ConditionTrue,
+ v1.IntegrationPlatformConditionCamelCatalogAvailableReason,
+ fmt.Sprintf("camel catalog %s available",
platform.Status.Build.RuntimeVersion))
+
+ if platform.Status.Build.RuntimeCoreVersion != "" {
+ action.L.Infof("IntegrationPlatform is about to install Apache
Kamelet Catalog version %s", platform.Status.Build.RuntimeCoreVersion)
+ return installKamelets(ctx, action.client, platform)
+ } else {
+ action.L.Info("IntegrationPlatform has no Camel core version. "
+
+ "It is likely an unsupported specification, please,
update to the latest one")
+ }
+
+ return platform, nil
+}
+
+func loadCatalog(ctx context.Context, c client.Client, namespace string,
runtimeSpec v1.RuntimeSpec) (*v1.CamelCatalog, error) {
+ options := []k8sclient.ListOption{
+ k8sclient.InNamespace(namespace),
+ }
+ list := v1.NewCamelCatalogList()
+ if err := c.List(ctx, &list, options...); err != nil {
+ return nil, err
+ }
+ for _, cc := range list.Items {
+ if cc.Spec.Runtime.Provider == runtimeSpec.Provider &&
cc.Spec.Runtime.Version == runtimeSpec.Version {
+ return &cc, nil
+ }
+ }
+
+ return nil, nil
+}
+
+func (action *createAction) handleBundledCatalog(ctx context.Context, platform
*v1.IntegrationPlatform, catalog *v1.CamelCatalog) (*v1.IntegrationPlatform,
error) {
+ var camelVersion string
+ // Create the catalog only if it was not yet created
+ if catalog == nil {
+ camelCatalogData, err :=
resources.Resource(fmt.Sprintf("/resources/camel-catalog-%s.yaml",
platform.Status.Build.RuntimeVersion))
if err != nil {
return nil, err
}
+ var cat v1.CamelCatalog
+ if err = yaml.Unmarshal(camelCatalogData, &cat); err != nil {
+ return nil, err
+ }
+ // Copy platform annotations to the catalog
+ cat.SetAnnotations(platform.Annotations)
+ cat.SetNamespace(platform.Namespace)
+ action.L.Infof("Installing bundled camel catalog: %s",
platform.Status.Build.RuntimeVersion)
+ if err = action.client.Create(ctx, &cat); err != nil {
+ return nil, err
+ }
+ camelVersion = cat.Spec.GetCamelVersion()
+ } else {
+ camelVersion = catalog.Spec.GetCamelVersion()
}
+ platform.Status.Build.RuntimeCoreVersion = camelVersion
- if defaults.InstallDefaultKamelets() {
- // Kamelet Catalog installed on platform reconciliation for
cases where users install a global operator
- if err := install.KameletCatalog(ctx, action.client,
platform.Namespace); err != nil {
- return nil, err
+ return platform, nil
+}
+
+func (action *createAction) handleNewCatalog(ctx context.Context, platform
*v1.IntegrationPlatform,
+ catalog *v1.CamelCatalog, runtimeSpec v1.RuntimeSpec)
(*v1.IntegrationPlatform, error) {
+ var camelVersion string
+ if catalog == nil {
+ cat, err := camel.CreateCatalog(ctx, action.client,
platform.Namespace, platform, runtimeSpec)
+ if err != nil {
+ action.L.Error(err, "IntegrationPlatform unable to
create Camel catalog",
+ "runtime-version", runtimeSpec.Version,
"runtime-provider", runtimeSpec.Provider)
+
+ platform.Status.Phase = v1.IntegrationPlatformPhaseError
+ platform.Status.SetCondition(
+
v1.IntegrationPlatformConditionCamelCatalogAvailable,
+ corev1.ConditionFalse,
+
v1.IntegrationPlatformConditionCamelCatalogAvailableReason,
+ fmt.Sprintf("camel catalog %s not available,
please review given runtime version. Error: %s", runtimeSpec.Version, err))
+
+ return platform, err
}
+ camelVersion = cat.GetCamelVersion()
+ } else {
+ camelVersion = catalog.Spec.GetCamelVersion()
}
+ platform.Status.Build.RuntimeCoreVersion = camelVersion
- platform.Status.SetCondition(
- v1.IntegrationPlatformConditionTypeCreated,
- corev1.ConditionTrue,
- v1.IntegrationPlatformConditionCreatedReason,
- "integration platform created")
+ return platform, nil
+}
+
+func installKamelets(ctx context.Context, c client.Client, platform
*v1.IntegrationPlatform) (*v1.IntegrationPlatform, error) {
+ // We bundle the Kamelets driven by the catalog
+ if defaults.InstallDefaultKamelets() {
+ camelVersion := platform.Status.Build.RuntimeCoreVersion
+ installedKam, erroredKam, err := installKameletCatalog(ctx, c,
platform, camelVersion)
+ if err != nil {
+ platform.Status.Phase = v1.IntegrationPlatformPhaseError
+ platform.Status.SetCondition(
+
v1.IntegrationPlatformConditionKameletCatalogAvailable,
+ corev1.ConditionFalse,
+ "IntegrationPlatformKameletCatalogAvailable",
+ fmt.Sprintf("kamelet catalog %s not available,
please review given camel version. Error: %s", camelVersion, err),
+ )
+
+ return platform, nil
+ }
+ platform.Status.SetCondition(
+ v1.IntegrationPlatformConditionKameletCatalogAvailable,
+ corev1.ConditionTrue,
+ "IntegrationPlatformKameletCatalogAvailable",
+ fmt.Sprintf("successfully installed Kamelet catalog
version %s: success %d Kamelets, failed %d Kamelets",
+ camelVersion, installedKam, erroredKam),
+ )
+ }
- platform.Status.Phase = v1.IntegrationPlatformPhaseReady
return platform, nil
}
diff --git a/pkg/controller/integrationplatform/create_test.go
b/pkg/controller/integrationplatform/create_test.go
index 55230f024..c47532070 100644
--- a/pkg/controller/integrationplatform/create_test.go
+++ b/pkg/controller/integrationplatform/create_test.go
@@ -19,67 +19,206 @@ package integrationplatform
import (
"context"
+ "errors"
+ "fmt"
+ "os"
"strings"
"testing"
v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
"github.com/apache/camel-k/v2/pkg/platform"
- "github.com/apache/camel-k/v2/pkg/resources"
+ "github.com/apache/camel-k/v2/pkg/util/boolean"
+ "github.com/apache/camel-k/v2/pkg/util/defaults"
"github.com/apache/camel-k/v2/pkg/util/log"
+ "github.com/apache/camel-k/v2/pkg/util/maven"
"github.com/apache/camel-k/v2/pkg/util/test"
- "github.com/rs/xid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+ corev1 "k8s.io/api/core/v1"
+ "k8s.io/apimachinery/pkg/runtime"
+ k8stesting "k8s.io/client-go/testing"
k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
)
func TestCreate(t *testing.T) {
ip := v1.IntegrationPlatform{}
ip.Namespace = "ns"
- ip.Name = xid.New().String()
- ip.Spec.Cluster = v1.IntegrationPlatformClusterOpenShift
- ip.Spec.Profile = v1.TraitProfileOpenShift
+ ip.Name = "ck"
+ ip.Status = v1.IntegrationPlatformStatus{
+ IntegrationPlatformSpec: v1.IntegrationPlatformSpec{
+ Build: v1.IntegrationPlatformBuildSpec{
+ RuntimeProvider: v1.RuntimeProviderQuarkus,
+ RuntimeVersion: defaults.DefaultRuntimeVersion,
+ },
+ },
+ }
+ c, err := test.NewFakeClient(&ip)
+ require.NoError(t, err)
+
+ h := NewCreateAction()
+ h.InjectLogger(log.Log)
+ h.InjectClient(c)
+ // We don't want to test the installation procedure here
+ os.Setenv("KAMEL_INSTALL_DEFAULT_KAMELETS", "false")
+ answer, err := h.Handle(context.TODO(), &ip)
+
+ require.NoError(t, err)
+ assert.NotNil(t, answer)
+ assert.Equal(t, v1.IntegrationPlatformPhaseReady, answer.Status.Phase)
+ assert.Equal(t, defaults.DefaultRuntimeVersion,
answer.Status.Build.RuntimeVersion)
+ assert.Equal(t, v1.RuntimeProviderQuarkus,
answer.Status.Build.RuntimeProvider)
+ assert.NotEqual(t, "", answer.Status.Build.RuntimeCoreVersion)
+ assert.Equal(t, corev1.ConditionTrue,
answer.Status.GetCondition(v1.IntegrationPlatformConditionCamelCatalogAvailable).Status)
+
+ list := v1.NewCamelCatalogList()
+ err = c.List(context.TODO(), &list, k8sclient.InNamespace(ip.Namespace))
+ require.NoError(t, err)
+ assert.NotEmpty(t, list.Items)
+}
+
+func TestCatalogAlreadyPresent(t *testing.T) {
+ ip := v1.IntegrationPlatform{}
+ ip.Namespace = "ns"
+ ip.Name = "ck"
+ ip.Status = v1.IntegrationPlatformStatus{
+ IntegrationPlatformSpec: v1.IntegrationPlatformSpec{
+ Build: v1.IntegrationPlatformBuildSpec{
+ RuntimeProvider: v1.RuntimeProviderQuarkus,
+ RuntimeVersion: defaults.DefaultRuntimeVersion,
+ },
+ },
+ }
+
+ catalog := v1.NewCamelCatalog("ns", fmt.Sprintf("camel-catalog-%s",
defaults.DefaultRuntimeVersion))
+ catalog.Spec.Runtime.Version = defaults.DefaultRuntimeVersion
+ catalog.Spec.Runtime.Provider = v1.RuntimeProviderQuarkus
+ catalog.Spec.Runtime.Metadata = map[string]string{
+ "camel.version": "4.4.0",
+ }
+
+ c, err := test.NewFakeClient(&ip, &catalog)
+ require.NoError(t, err)
+
+ action := NewCreateAction()
+ action.InjectLogger(log.Log)
+ action.InjectClient(c)
+
+ // We don't want to test the installation procedure here
+ os.Setenv("KAMEL_INSTALL_DEFAULT_KAMELETS", "false")
+ answer, err := action.Handle(context.TODO(), &ip)
+ os.Unsetenv("KAMEL_INSTALL_DEFAULT_KAMELETS")
+ require.NoError(t, err)
+ assert.NotNil(t, answer)
+
+ assert.Equal(t, v1.IntegrationPlatformPhaseReady, answer.Status.Phase)
+ assert.Equal(t, "4.4.0", answer.Status.Build.RuntimeCoreVersion)
+ assert.Equal(t, corev1.ConditionTrue,
answer.Status.GetCondition(v1.IntegrationPlatformConditionCamelCatalogAvailable).Status)
+}
+
+func TestCreateNewCatalog(t *testing.T) {
+ ip := v1.IntegrationPlatform{}
+ ip.Namespace = "ns"
+ ip.Name = "ck"
+ ip.Status = v1.IntegrationPlatformStatus{
+ IntegrationPlatformSpec: v1.IntegrationPlatformSpec{
+ Build: v1.IntegrationPlatformBuildSpec{
+ RuntimeProvider: v1.RuntimeProviderQuarkus,
+ RuntimeVersion: defaults.DefaultRuntimeVersion,
+ },
+ },
+ }
+ if strings.Contains(ip.Spec.Build.RuntimeVersion, "SNAPSHOT") {
+ maven.DefaultMavenRepositories +=
",https://repository.apache.org/content/repositories/snapshots-group@snapshots@id=apache-snapshots"
+ }
c, err := test.NewFakeClient(&ip)
require.NoError(t, err)
+ // use local Maven executable in tests
+ t.Setenv("MAVEN_WRAPPER", boolean.FalseString)
+ _, ok := os.LookupEnv("MAVEN_CMD")
+ if !ok {
+ t.Setenv("MAVEN_CMD", "mvn")
+ }
+
+ fakeClient := c.(*test.FakeClient) //nolint
+ fakeClient.AddReactor("create", "*", func(action k8stesting.Action)
(bool, runtime.Object, error) {
+ createAction := action.(k8stesting.CreateAction) //nolint
+
+ assert.Equal(t, "ns", createAction.GetNamespace())
+
+ return true, createAction.GetObject(), nil
+ })
+
err = platform.ConfigureDefaults(context.TODO(), c, &ip, false)
require.NoError(t, err)
- h := NewCreateAction()
- h.InjectLogger(log.Log)
- h.InjectClient(c)
+ action := NewCreateAction()
+ action.InjectLogger(log.Log)
+ action.InjectClient(c)
- answer, err := h.Handle(context.TODO(), &ip)
+ // Set the folder where to install testing kamelets
+ tmpDir, err := os.MkdirTemp("/tmp", "kamelets*")
+ assert.NoError(t, err)
+ os.Setenv(kameletDirEnv, tmpDir)
+ answer, err := action.Handle(context.TODO(), &ip)
+ os.Unsetenv(kameletDirEnv)
require.NoError(t, err)
assert.NotNil(t, answer)
+ assert.Equal(t, v1.IntegrationPlatformPhaseReady, answer.Status.Phase)
+ assert.Equal(t, corev1.ConditionTrue,
answer.Status.GetCondition(v1.IntegrationPlatformConditionCamelCatalogAvailable).Status)
+ // We don't know exactly which is the core version, it is enough to
check is not empty in the test
+ assert.NotEqual(t, "", answer.Status.Build.RuntimeCoreVersion)
+ assert.Equal(t, corev1.ConditionTrue,
answer.Status.GetCondition(v1.IntegrationPlatformConditionKameletCatalogAvailable).Status)
+ assert.Contains(t,
answer.Status.GetCondition(v1.IntegrationPlatformConditionKameletCatalogAvailable).Message,
+ fmt.Sprintf("successfully installed Kamelet catalog version
%s", answer.Status.Build.RuntimeCoreVersion),
+ "failed 0 Kamelets")
+
list := v1.NewCamelCatalogList()
err = c.List(context.TODO(), &list, k8sclient.InNamespace(ip.Namespace))
require.NoError(t, err)
assert.NotEmpty(t, list.Items)
+}
- items, err := resources.WithPrefix("/resources/camel-catalog-")
+func TestCreateCatalogError(t *testing.T) {
+ ip := v1.IntegrationPlatform{}
+ ip.Namespace = "ns"
+ ip.Name = "ck"
+ ip.Spec.Build.RuntimeVersion = "0.0.0"
+ c, err := test.NewFakeClient(&ip)
require.NoError(t, err)
- foundOverall := 0
- for _, k := range items {
- found := false
+ // use local Maven executable in tests
+ t.Setenv("MAVEN_WRAPPER", boolean.FalseString)
+ _, ok := os.LookupEnv("MAVEN_CMD")
+ if !ok {
+ t.Setenv("MAVEN_CMD", "mvn")
+ }
+
+ fakeClient := c.(*test.FakeClient) //nolint
+ fakeClient.AddReactor("create", "*", func(action k8stesting.Action)
(bool, runtime.Object, error) {
+ createAction := action.(k8stesting.CreateAction) //nolint
- for _, c := range list.Items {
- n := strings.TrimSuffix(k, ".yaml")
- n = strings.TrimPrefix(n, "resources/")
- n = strings.ToLower(n)
+ assert.Equal(t, "ns", createAction.GetNamespace())
- if c.Name == n {
- found = true
- foundOverall++
- }
- }
+ return true, nil, errors.New("failed to create catalog for some
reason")
+ })
- assert.True(t, found)
- }
+ err = platform.ConfigureDefaults(context.TODO(), c, &ip, false)
+ require.NoError(t, err)
+
+ action := NewCreateAction()
+ action.InjectLogger(log.Log)
+ action.InjectClient(c)
+
+ answer, err := action.Handle(context.TODO(), &ip)
+ require.Error(t, err)
+ assert.NotNil(t, answer)
- assert.Equal(t, 1, foundOverall)
+ assert.Equal(t, v1.IntegrationPlatformPhaseError, answer.Status.Phase)
+ assert.Equal(t, corev1.ConditionFalse,
answer.Status.GetCondition(v1.IntegrationPlatformConditionCamelCatalogAvailable).Status)
+ assert.Equal(t,
v1.IntegrationPlatformConditionCamelCatalogAvailableReason,
answer.Status.GetCondition(v1.IntegrationPlatformConditionCamelCatalogAvailable).Reason)
+ assert.Contains(t,
answer.Status.GetCondition(v1.IntegrationPlatformConditionCamelCatalogAvailable).Message,
"camel catalog 0.0.0 not available, please review given runtime version.
Error:")
}
diff --git a/pkg/controller/integrationplatform/initialize.go
b/pkg/controller/integrationplatform/initialize.go
index 4b68c2ff9..9a0141f26 100644
--- a/pkg/controller/integrationplatform/initialize.go
+++ b/pkg/controller/integrationplatform/initialize.go
@@ -19,10 +19,11 @@ package integrationplatform
import (
"context"
+ "fmt"
v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
platformutil "github.com/apache/camel-k/v2/pkg/platform"
- "github.com/apache/camel-k/v2/pkg/util/defaults"
+ corev1 "k8s.io/api/core/v1"
)
// NewInitializeAction returns the action that initializes the integration
platform when not provided by the user.
@@ -47,8 +48,18 @@ func (action *initializeAction) Handle(ctx context.Context,
platform *v1.Integra
if err := platformutil.ConfigureDefaults(ctx, action.client, platform,
true); err != nil {
return nil, err
}
- platform.Status.Phase = v1.IntegrationPlatformPhaseCreating
- platform.Status.Version = defaults.Version
+ if platform.Status.Build.RuntimeVersion == "" {
+ platform.Status.Phase = v1.IntegrationPlatformPhaseError
+ platform.Status.SetCondition(
+ v1.IntegrationPlatformConditionTypeCreated,
+ corev1.ConditionFalse,
+ "MissingRuntimeVersionSpec",
+ "Runtime version missing from build spec")
+
+ return platform, fmt.Errorf("runtime version missing from build
spec")
+ } else {
+ platform.Status.Phase = v1.IntegrationPlatformPhaseCreating
+ }
return platform, nil
}
diff --git a/pkg/controller/integrationplatform/initialize_test.go
b/pkg/controller/integrationplatform/initialize_test.go
index b7b396053..14a66deeb 100644
--- a/pkg/controller/integrationplatform/initialize_test.go
+++ b/pkg/controller/integrationplatform/initialize_test.go
@@ -22,28 +22,66 @@ import (
"testing"
"time"
- "github.com/rs/xid"
-
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
"github.com/apache/camel-k/v2/pkg/platform"
+ "github.com/apache/camel-k/v2/pkg/util/defaults"
"github.com/apache/camel-k/v2/pkg/util/log"
"github.com/apache/camel-k/v2/pkg/util/test"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
-func TestTimeouts_Default(t *testing.T) {
+func TestDefaultRuntimeSpec(t *testing.T) {
ip := v1.IntegrationPlatform{}
ip.Namespace = "ns"
- ip.Name = xid.New().String()
- ip.Spec.Cluster = v1.IntegrationPlatformClusterOpenShift
- ip.Spec.Profile = v1.TraitProfileOpenShift
+ ip.Name = "ck"
+ c, err := test.NewFakeClient(&ip)
+ require.NoError(t, err)
+
+ h := NewInitializeAction()
+ h.InjectLogger(log.Log)
+ h.InjectClient(c)
+
+ answer, err := h.Handle(context.TODO(), &ip)
+ require.NoError(t, err)
+ assert.Equal(t, v1.IntegrationPlatformPhaseCreating,
answer.Status.Phase)
+ assert.Equal(t, defaults.DefaultRuntimeVersion,
answer.Status.Build.RuntimeVersion)
+ assert.Equal(t, v1.RuntimeProviderQuarkus,
answer.Status.Build.RuntimeProvider)
+}
+func TestUserRuntimeSpec(t *testing.T) {
+ ip := v1.IntegrationPlatform{}
+ ip.Namespace = "ns"
+ ip.Name = "ck"
+ ip.Spec = v1.IntegrationPlatformSpec{
+ Build: v1.IntegrationPlatformBuildSpec{
+ RuntimeVersion: "1.2.3",
+ RuntimeProvider: "MyProvider",
+ },
+ }
c, err := test.NewFakeClient(&ip)
require.NoError(t, err)
+ h := NewInitializeAction()
+ h.InjectLogger(log.Log)
+ h.InjectClient(c)
+
+ answer, err := h.Handle(context.TODO(), &ip)
+ require.NoError(t, err)
+ assert.Equal(t, v1.IntegrationPlatformPhaseCreating,
answer.Status.Phase)
+ assert.Equal(t, "1.2.3", answer.Status.Build.RuntimeVersion)
+ assert.Equal(t, v1.RuntimeProvider("MyProvider"),
answer.Status.Build.RuntimeProvider)
+}
+
+func TestDefaultTimeouts(t *testing.T) {
+ ip := v1.IntegrationPlatform{}
+ ip.Namespace = "ns"
+ ip.Name = "ck"
+ c, err := test.NewFakeClient(&ip)
+
+ require.NoError(t, err)
require.NoError(t, platform.ConfigureDefaults(context.TODO(), c, &ip,
false))
h := NewInitializeAction()
@@ -52,67 +90,50 @@ func TestTimeouts_Default(t *testing.T) {
answer, err := h.Handle(context.TODO(), &ip)
require.NoError(t, err)
- assert.NotNil(t, answer)
-
+ assert.Equal(t, v1.IntegrationPlatformPhaseCreating,
answer.Status.Phase)
assert.Equal(t, 5*time.Minute,
answer.Status.Build.GetTimeout().Duration)
}
-func TestTimeouts_MavenComputedFromBuild(t *testing.T) {
+func TestMavenComputedFromBuildTimeouts(t *testing.T) {
ip := v1.IntegrationPlatform{}
ip.Namespace = "ns"
- ip.Name = xid.New().String()
- ip.Spec.Cluster = v1.IntegrationPlatformClusterOpenShift
- ip.Spec.Profile = v1.TraitProfileOpenShift
-
+ ip.Name = "ck"
timeout, err := time.ParseDuration("1m1ms")
require.NoError(t, err)
-
ip.Spec.Build.Timeout = &metav1.Duration{
Duration: timeout,
}
-
c, err := test.NewFakeClient(&ip)
require.NoError(t, err)
- require.NoError(t, platform.ConfigureDefaults(context.TODO(), c, &ip,
false))
-
h := NewInitializeAction()
h.InjectLogger(log.Log)
h.InjectClient(c)
-
answer, err := h.Handle(context.TODO(), &ip)
+
require.NoError(t, err)
assert.NotNil(t, answer)
-
assert.Equal(t, 1*time.Minute,
answer.Status.Build.GetTimeout().Duration)
}
-func TestTimeouts_Truncated(t *testing.T) {
+func TestTruncatedTimeouts(t *testing.T) {
ip := v1.IntegrationPlatform{}
ip.Namespace = "ns"
- ip.Name = xid.New().String()
- ip.Spec.Cluster = v1.IntegrationPlatformClusterOpenShift
- ip.Spec.Profile = v1.TraitProfileOpenShift
-
+ ip.Name = "ck"
bt, err := time.ParseDuration("5m1ms")
require.NoError(t, err)
-
ip.Spec.Build.Timeout = &metav1.Duration{
Duration: bt,
}
-
c, err := test.NewFakeClient(&ip)
require.NoError(t, err)
- require.NoError(t, platform.ConfigureDefaults(context.TODO(), c, &ip,
false))
-
h := NewInitializeAction()
h.InjectLogger(log.Log)
h.InjectClient(c)
-
answer, err := h.Handle(context.TODO(), &ip)
+
require.NoError(t, err)
assert.NotNil(t, answer)
-
assert.Equal(t, 5*time.Minute,
answer.Status.Build.GetTimeout().Duration)
}
diff --git
a/pkg/controller/integrationplatform/integrationplatform_controller.go
b/pkg/controller/integrationplatform/integrationplatform_controller.go
index 99197df4a..ba48423da 100644
--- a/pkg/controller/integrationplatform/integrationplatform_controller.go
+++ b/pkg/controller/integrationplatform/integrationplatform_controller.go
@@ -19,7 +19,6 @@ package integrationplatform
import (
"context"
- "time"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
@@ -41,10 +40,6 @@ import (
"github.com/apache/camel-k/v2/pkg/util/monitoring"
)
-const (
- requeueAfterDuration = 5 * time.Second
-)
-
// Add creates a new IntegrationPlatform Controller and adds it to the
Manager. The Manager will set fields
// on the Controller and Start it when the Manager is Started.
func Add(ctx context.Context, mgr manager.Manager, c client.Client) error {
@@ -161,7 +156,6 @@ func (r *reconcileIntegrationPlatform) Reconcile(ctx
context.Context, request re
NewInitializeAction(),
NewCreateAction(),
NewMonitorAction(),
- NewCreateCatalogAction(),
}
var targetPhase v1.IntegrationPlatformPhase
@@ -214,12 +208,5 @@ func (r *reconcileIntegrationPlatform) Reconcile(ctx
context.Context, request re
break
}
- if targetPhase == v1.IntegrationPlatformPhaseReady {
- return reconcile.Result{}, nil
- }
-
- // Requeue
- return reconcile.Result{
- RequeueAfter: requeueAfterDuration,
- }, nil
+ return reconcile.Result{}, nil
}
diff --git a/pkg/controller/integrationplatform/kamelets.go
b/pkg/controller/integrationplatform/kamelets.go
new file mode 100644
index 000000000..370f464e0
--- /dev/null
+++ b/pkg/controller/integrationplatform/kamelets.go
@@ -0,0 +1,209 @@
+/*
+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 integrationplatform
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "io/fs"
+ "os"
+ "os/exec"
+ "path"
+ "path/filepath"
+ "strings"
+
+ v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
+ "github.com/apache/camel-k/v2/pkg/install"
+ "github.com/apache/camel-k/v2/pkg/platform"
+ "knative.dev/pkg/ptr"
+
+ "github.com/apache/camel-k/v2/pkg/client"
+ "github.com/apache/camel-k/v2/pkg/util"
+ "github.com/apache/camel-k/v2/pkg/util/defaults"
+ "github.com/apache/camel-k/v2/pkg/util/log"
+ "github.com/apache/camel-k/v2/pkg/util/maven"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ k8syaml "k8s.io/apimachinery/pkg/util/yaml"
+)
+
+const (
+ kameletDirEnv = "KAMELET_CATALOG_DIR"
+ defaultKameletDir = "/tmp/kamelets/"
+ kamelVersionAnnotation = "camel.apache.org/version"
+)
+
+// installKameletCatalog installs the version Apache Kamelet Catalog into the
specified namespace. It returns the number of Kamelets installed and errored
+// if successful.
+func installKameletCatalog(ctx context.Context, c client.Client, platform
*v1.IntegrationPlatform, version string) (int, int, error) {
+ // Prepare proper privileges for Kamelets installed globally
+ if err := prepareKameletsPermissions(ctx, c, platform.Namespace); err
!= nil {
+ return -1, -1, err
+ }
+ // Prepare directory to contains kamelets
+ kameletDir := prepareKameletDirectory()
+ // Download Kamelet dependency
+ if err := downloadKameletDependency(ctx, version, kameletDir); err !=
nil {
+ return -1, -1, err
+ }
+ // Extract Kamelets files
+ if err := extractKameletsFromDependency(ctx, version, kameletDir); err
!= nil {
+ return -1, -1, err
+ }
+
+ // Store Kamelets as Kubernetes resources
+ return applyKamelets(ctx, c, platform, kameletDir)
+}
+
+func prepareKameletsPermissions(ctx context.Context, c client.Client,
installingNamespace string) error {
+ watchOperatorNamespace := platform.GetOperatorWatchNamespace()
+ operatorNamespace := platform.GetOperatorNamespace()
+ if watchOperatorNamespace == "" && operatorNamespace ==
installingNamespace {
+ // Kamelets installed into the global operator namespace
+ // They need to be visible publicly
+ if err := kameletViewerRole(ctx, c, installingNamespace); err
!= nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func prepareKameletDirectory() string {
+ kameletDir := os.Getenv(kameletDirEnv)
+ if kameletDir == "" {
+ kameletDir = defaultKameletDir
+ }
+
+ return kameletDir
+}
+
+func downloadKameletDependency(ctx context.Context, version, kameletsDir
string) error {
+ // TODO: we may want to add the maven settings coming from the platform
+ // in order to cover any user security setting in place
+ p := maven.NewProjectWithGAV("org.apache.camel.k.kamelets",
"kamelets-catalog", defaults.Version)
+ mc := maven.NewContext(kameletsDir)
+ mc.AddArgument("-q")
+ mc.AddArgument("dependency:copy")
+
mc.AddArgument(fmt.Sprintf("-Dartifact=org.apache.camel.kamelets:camel-kamelets:%s:jar",
version))
+ mc.AddArgument("-Dmdep.useBaseVersion=true")
+ mc.AddArgument(fmt.Sprintf("-DoutputDirectory=%s", kameletsDir))
+
+ return p.Command(mc).Do(ctx)
+}
+
+func extractKameletsFromDependency(ctx context.Context, version, kameletsDir
string) error {
+ args := strings.Split(
+ fmt.Sprintf("-xf camel-kamelets-%s.jar kamelets/", version), "
")
+ cmd := exec.CommandContext(ctx, "jar", args...)
+ cmd.Dir = kameletsDir
+ return util.RunAndLog(ctx, cmd, maven.LogHandler, maven.LogHandler)
+}
+
+func applyKamelets(ctx context.Context, c client.Client, platform
*v1.IntegrationPlatform, kameletDir string) (int, int, error) {
+ appliedKam := 0
+ erroredKam := 0
+ applier := c.ServerOrClientSideApplier()
+ dir := path.Join(kameletDir, "kamelets")
+
+ err := filepath.WalkDir(dir, func(p string, f fs.DirEntry, err error)
error {
+ if err != nil {
+ return err
+ }
+ if !(strings.HasSuffix(f.Name(), ".yaml") ||
strings.HasSuffix(f.Name(), ".yml")) {
+ return nil
+ }
+ kamelet, err := loadKamelet(filepath.Join(dir, f.Name()),
platform)
+ // We cannot return if an error happen, otherwise the creation
of the IntegrationPlatform would result
+ // in a failure. We better report in conditions.
+ if err != nil {
+ erroredKam++
+ log.Errorf(err, "Error occurred whilst loading a
bundled kamelet named %s", f.Name())
+ return nil
+ }
+ err = applier.Apply(ctx, kamelet)
+ if err != nil {
+ erroredKam++
+ log.Error(err, "Error occurred whilst applying a
bundled kamelet named %s", kamelet.GetName())
+ return nil
+ }
+ appliedKam++
+
+ return nil
+ })
+ if err != nil {
+ return appliedKam, erroredKam, err
+ }
+
+ return appliedKam, erroredKam, nil
+}
+
+func loadKamelet(path string, platform *v1.IntegrationPlatform) (*v1.Kamelet,
error) {
+ yamlContent, err := util.ReadFile(path)
+ if err != nil {
+ return nil, err
+ }
+ // Kamelet spec contains raw object spec, for which we need to convert
to json
+ // for a proper serde
+ jsonContent, err := k8syaml.ToJSON(yamlContent)
+ if err != nil {
+ return nil, err
+ }
+ var kamelet *v1.Kamelet
+ if err = json.Unmarshal(jsonContent, &kamelet); err != nil {
+ return nil, err
+ }
+ kamelet.SetNamespace(platform.Namespace)
+ annotations := kamelet.GetAnnotations()
+ if annotations == nil {
+ annotations = make(map[string]string)
+ }
+ annotations[kamelVersionAnnotation] = defaults.Version
+ kamelet.SetAnnotations(annotations)
+ labels := kamelet.GetLabels()
+ if labels == nil {
+ labels = make(map[string]string)
+ }
+ labels[v1.KameletBundledLabel] = "true"
+ labels[v1.KameletReadOnlyLabel] = "true"
+
+ // The Kamelet will be owned by the IntegrationPlatform
+ references := []metav1.OwnerReference{
+ {
+ APIVersion: platform.APIVersion,
+ Kind: platform.Kind,
+ Name: platform.Name,
+ UID: platform.UID,
+ Controller: ptr.Bool(true),
+ BlockOwnerDeletion: ptr.Bool(true),
+ },
+ }
+ kamelet.SetOwnerReferences(references)
+
+ return kamelet, nil
+}
+
+// kameletViewerRole installs the role that allows any user ro access kamelets
in the global namespace.
+func kameletViewerRole(ctx context.Context, c client.Client, namespace string)
error {
+ if err := install.Resource(ctx, c, namespace, true,
install.IdentityResourceCustomizer,
+ "/resources/viewer/user-global-kamelet-viewer-role.yaml"); err
!= nil {
+ return err
+ }
+ return install.Resource(ctx, c, namespace, true,
install.IdentityResourceCustomizer,
+
"/resources/viewer/user-global-kamelet-viewer-role-binding.yaml")
+}
diff --git a/pkg/controller/integrationplatform/kamelets_test.go
b/pkg/controller/integrationplatform/kamelets_test.go
new file mode 100644
index 000000000..7a1a79aa6
--- /dev/null
+++ b/pkg/controller/integrationplatform/kamelets_test.go
@@ -0,0 +1,153 @@
+/*
+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 integrationplatform
+
+import (
+ "context"
+ "fmt"
+ "io/fs"
+ "os"
+ "path"
+ "path/filepath"
+ "strings"
+ "testing"
+
+ v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
+ "github.com/apache/camel-k/v2/pkg/util/boolean"
+ "github.com/apache/camel-k/v2/pkg/util/camel"
+ "github.com/apache/camel-k/v2/pkg/util/test"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func TestLoadKamelet(t *testing.T) {
+ itp := v1.NewIntegrationPlatform("itp-ns", "my-itp")
+ var tmpKameletFile *os.File
+ var err error
+ tmpKameletFile, err = os.CreateTemp("/tmp",
"timer-source-*.kamelet.yaml")
+ require.NoError(t, err)
+ require.NoError(t, tmpKameletFile.Close())
+ require.NoError(t, os.WriteFile(tmpKameletFile.Name(),
[]byte(`apiVersion: camel.apache.org/v1
+kind: Kamelet
+metadata:
+ name: timer-source
+ annotations:
+ camel.apache.org/kamelet.icon: "data:image/svg+xml;base64,XYZABC123"
+ labels:
+ camel.apache.org/kamelet.type: "source"
+spec:
+ definition:
+ title: "Timer Source"
+ description: "Produces periodic events with a custom payload"
+ required:
+ - message
+ properties:
+ period:
+ title: Period
+ description: The interval between two events
+ type: integer
+ default: 1000
+ message:
+ title: Message
+ description: The message to generate
+ type: string
+ example: "hello world"
+ dataTypes:
+ out:
+ default: text
+ types:
+ text:
+ mediaType: text/plain
+ template:
+ from:
+ uri: timer:tick
+ parameters:
+ period: "{{period}}"
+ steps:
+ - setBody:
+ constant: "{{message}}"
+ - to: "kamelet:sink"
+`), 0o400))
+
+ kamelet, err := loadKamelet(tmpKameletFile.Name(), &itp)
+
+ assert.NotNil(t, kamelet)
+ require.NoError(t, err)
+ assert.Equal(t, "timer-source", kamelet.GetName())
+ assert.Equal(t, "itp-ns", kamelet.GetNamespace())
+ assert.Len(t, kamelet.GetLabels(), 3)
+ assert.Equal(t, "true", kamelet.GetLabels()[v1.KameletBundledLabel])
+ assert.Equal(t, "true", kamelet.GetLabels()[v1.KameletReadOnlyLabel])
+ assert.Len(t, kamelet.GetAnnotations(), 2)
+ assert.NotNil(t, kamelet.GetAnnotations()[kamelVersionAnnotation])
+ assert.Equal(t, "my-itp", kamelet.GetOwnerReferences()[0].Name)
+}
+
+func TestPrepareKameletsPermissions(t *testing.T) {
+ c, err := test.NewFakeClient()
+ assert.NoError(t, err)
+ err = prepareKameletsPermissions(context.TODO(), c, "camel-k")
+ assert.NoError(t, err)
+}
+
+func TestPrepareKameletsDirectory(t *testing.T) {
+ kameletDir := prepareKameletDirectory()
+ assert.Equal(t, defaultKameletDir, kameletDir)
+}
+
+func TestDownloadKameletDependencyAndExtract(t *testing.T) {
+ // use local Maven executable in tests
+ t.Setenv("MAVEN_WRAPPER", boolean.FalseString)
+ _, ok := os.LookupEnv("MAVEN_CMD")
+ if !ok {
+ t.Setenv("MAVEN_CMD", "mvn")
+ }
+
+ tmpDir, err := os.MkdirTemp("/tmp", "kamelets*")
+ assert.NoError(t, err)
+ // Load default catalog in order to get the default Camel version
+ c, err := camel.DefaultCatalog()
+ assert.NoError(t, err)
+ camelVersion := c.Runtime.Metadata["camel.version"]
+ assert.NotEqual(t, "", camelVersion)
+ err = downloadKameletDependency(context.TODO(), camelVersion, tmpDir)
+ assert.NoError(t, err)
+ downloadedDependency, err := os.Stat(path.Join(tmpDir,
fmt.Sprintf("camel-kamelets-%s.jar", camelVersion)))
+ assert.NoError(t, err)
+
+ assert.Equal(t, fmt.Sprintf("camel-kamelets-%s.jar", camelVersion),
downloadedDependency.Name())
+
+ // We can extract the Kamelets now
+ err = extractKameletsFromDependency(context.TODO(), camelVersion,
tmpDir)
+ assert.NoError(t, err)
+ kameletsDir, err := os.Stat(path.Join(tmpDir, "kamelets"))
+ assert.NoError(t, err)
+ assert.True(t, kameletsDir.IsDir())
+ count := 0
+ err = filepath.WalkDir(path.Join(tmpDir, "kamelets"), func(p string, f
fs.DirEntry, err error) error {
+ if err != nil {
+ return err
+ }
+ if strings.HasSuffix(f.Name(), ".yaml") ||
strings.HasSuffix(f.Name(), ".yml") {
+ count++
+ }
+ return nil
+ })
+ assert.NoError(t, err)
+ assert.True(t, count > 0)
+}
diff --git a/pkg/controller/integrationplatform/monitor.go
b/pkg/controller/integrationplatform/monitor.go
index 474fe2934..d615525d9 100644
--- a/pkg/controller/integrationplatform/monitor.go
+++ b/pkg/controller/integrationplatform/monitor.go
@@ -24,7 +24,6 @@ import (
v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
platformutil "github.com/apache/camel-k/v2/pkg/platform"
- "github.com/apache/camel-k/v2/pkg/util/camel"
"github.com/apache/camel-k/v2/pkg/util/defaults"
"github.com/apache/camel-k/v2/pkg/util/openshift"
corev1 "k8s.io/api/core/v1"
@@ -47,22 +46,37 @@ func (action *monitorAction) CanHandle(platform
*v1.IntegrationPlatform) bool {
return platform.Status.Phase == v1.IntegrationPlatformPhaseReady ||
platform.Status.Phase == v1.IntegrationPlatformPhaseError
}
-//nolint:nestif
func (action *monitorAction) Handle(ctx context.Context, platform
*v1.IntegrationPlatform) (*v1.IntegrationPlatform, error) {
- // Just track the version of the operator in the platform resource
- if platform.Status.Version != defaults.Version {
- platform.Status.Version = defaults.Version
- action.L.Info("IntegrationPlatform version updated", "version",
platform.Status.Version)
- }
-
- // TODO: refactor the phase transition as it is hard to reason
- platformPhase := v1.IntegrationPlatformPhaseReady
+ runtimeVersion := specOrDefault(platform.Spec.Build.RuntimeVersion)
+ if platform.Status.Build.RuntimeVersion != runtimeVersion {
+ action.L.Infof("IntegrationPlatform version updated from %s to
%s", platform.Status.Build.RuntimeVersion, runtimeVersion)
+ // Reset the status to reinitialize the resource
+ platform.Status = v1.IntegrationPlatformStatus{}
- // Refresh applied configuration
+ return platform, nil
+ }
+ // Sync status configuration
if err := platformutil.ConfigureDefaults(ctx, action.client, platform,
false); err != nil {
return nil, err
}
+ // Get the information about Camel version in the catalog
+ runtimeSpec := v1.RuntimeSpec{
+ Version: platform.Status.Build.RuntimeVersion,
+ Provider: platform.Status.Build.RuntimeProvider,
+ }
+ catalog, err := loadCatalog(ctx, action.client, platform.Namespace,
runtimeSpec)
+ if catalog == nil || err != nil {
+ // error, a catalog must be available
+ platform.Status.Phase = v1.IntegrationPlatformPhaseError
+ platform.Status.SetCondition(
+ v1.IntegrationPlatformConditionCamelCatalogAvailable,
+ corev1.ConditionFalse,
+
v1.IntegrationPlatformConditionCamelCatalogAvailableReason,
+ fmt.Sprintf("camel catalog %s not available, please
review given runtime version", runtimeSpec.Version))
+ return platform, err
+ }
+ platform.Status.Build.RuntimeCoreVersion =
catalog.Spec.GetCamelVersion()
// Registry condition
isOpenshift, err := openshift.IsOpenShift(action.client)
if err != nil {
@@ -77,7 +91,7 @@ func (action *monitorAction) Handle(ctx context.Context,
platform *v1.Integratio
} else {
if platform.Status.Build.Registry.Address == "" {
// error, we need a registry if we're not on Openshift
- platformPhase = v1.IntegrationPlatformPhaseError
+ platform.Status.Phase = v1.IntegrationPlatformPhaseError
platform.Status.SetCondition(
v1.IntegrationPlatformConditionTypeRegistryAvailable,
corev1.ConditionFalse,
@@ -91,41 +105,6 @@ func (action *monitorAction) Handle(ctx context.Context,
platform *v1.Integratio
fmt.Sprintf("registry available at %s",
platform.Status.Build.Registry.Address))
}
}
-
- if platformPhase == v1.IntegrationPlatformPhaseReady {
- // Camel catalog condition
- runtimeSpec := v1.RuntimeSpec{
- Version: platform.Status.Build.RuntimeVersion,
- Provider: v1.RuntimeProviderQuarkus,
- }
- if catalog, err := camel.LoadCatalog(ctx, action.client,
platform.Namespace, runtimeSpec); err != nil {
- action.L.Error(err, "IntegrationPlatform unable to load
Camel catalog",
- "runtime-version", runtimeSpec.Version,
"runtime-provider", runtimeSpec.Provider)
- } else if catalog == nil {
- if platform.Status.Phase !=
v1.IntegrationPlatformPhaseError {
- platformPhase =
v1.IntegrationPlatformPhaseCreateCatalog
- } else {
- // IntegrationPlatform is in error phase for
some reason - that error state must be resolved before we move into create
catalog phase
- // avoids to run into endless loop of error and
catalog creation phase ping pong
- platformPhase = v1.IntegrationPlatformPhaseError
- }
-
- platform.Status.SetCondition(
-
v1.IntegrationPlatformConditionCamelCatalogAvailable,
- corev1.ConditionFalse,
-
v1.IntegrationPlatformConditionCamelCatalogAvailableReason,
- fmt.Sprintf("camel catalog %s not available,
please review given runtime version", runtimeSpec.Version))
- } else {
- platform.Status.SetCondition(
-
v1.IntegrationPlatformConditionCamelCatalogAvailable,
- corev1.ConditionTrue,
-
v1.IntegrationPlatformConditionCamelCatalogAvailableReason,
- fmt.Sprintf("camel catalog %s available",
runtimeSpec.Version))
- platform.Status.Build.RuntimeCoreVersion =
catalog.Runtime.Metadata["camel.version"]
- }
- }
-
- platform.Status.Phase = platformPhase
action.checkTraitAnnotationsDeprecatedNotice(platform)
return platform, nil
@@ -151,3 +130,10 @@ func (action *monitorAction)
checkTraitAnnotationsDeprecatedNotice(platform *v1.
}
}
}
+
+func specOrDefault(runtimeVersionSpec string) string {
+ if runtimeVersionSpec == "" {
+ return defaults.DefaultRuntimeVersion
+ }
+ return runtimeVersionSpec
+}
diff --git a/pkg/controller/integrationplatform/monitor_test.go
b/pkg/controller/integrationplatform/monitor_test.go
index 875c237f8..ddbcc1bdf 100644
--- a/pkg/controller/integrationplatform/monitor_test.go
+++ b/pkg/controller/integrationplatform/monitor_test.go
@@ -23,11 +23,10 @@ import (
"testing"
v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
- "github.com/apache/camel-k/v2/pkg/platform"
+ "github.com/apache/camel-k/v2/pkg/apis/camel/v1/trait"
"github.com/apache/camel-k/v2/pkg/util/defaults"
"github.com/apache/camel-k/v2/pkg/util/log"
"github.com/apache/camel-k/v2/pkg/util/test"
- "github.com/rs/xid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -37,15 +36,8 @@ import (
func TestCanHandlePhaseReadyOrError(t *testing.T) {
ip := v1.IntegrationPlatform{}
ip.Namespace = "ns"
- ip.Name = xid.New().String()
- ip.Spec.Cluster = v1.IntegrationPlatformClusterOpenShift
- ip.Spec.Profile = v1.TraitProfileOpenShift
- ip.Spec.Build.Registry.Address = defaults.OpenShiftRegistryAddress
-
- ip.Spec.Build.RuntimeVersion = defaults.DefaultRuntimeVersion
-
+ ip.Name = "ck"
ip.Status.Phase = v1.IntegrationPlatformPhaseReady
-
c, err := test.NewFakeClient(&ip)
require.NoError(t, err)
@@ -60,29 +52,31 @@ func TestCanHandlePhaseReadyOrError(t *testing.T) {
answer = action.CanHandle(&ip)
assert.True(t, answer)
- ip.Status.Phase = v1.IntegrationPlatformPhaseCreateCatalog
+ ip.Status.Phase = v1.IntegrationPlatformPhaseCreating
answer = action.CanHandle(&ip)
assert.False(t, answer)
}
-func TestMonitor(t *testing.T) {
+func TestMonitorReady(t *testing.T) {
+ catalog := v1.NewCamelCatalog("ns", fmt.Sprintf("camel-catalog-%s",
"1.2.3"))
+ catalog.Spec.Runtime.Version = "1.2.3"
+ catalog.Spec.Runtime.Provider = v1.RuntimeProviderQuarkus
+ catalog.Spec.Runtime.Metadata = map[string]string{
+ "camel.version": "3.2.1",
+ }
ip := v1.IntegrationPlatform{}
ip.Namespace = "ns"
- ip.Name = xid.New().String()
- ip.Spec.Cluster = v1.IntegrationPlatformClusterOpenShift
- ip.Spec.Profile = v1.TraitProfileOpenShift
- ip.Spec.Build.Registry.Address = defaults.OpenShiftRegistryAddress
-
- catalog := v1.NewCamelCatalog("ns", fmt.Sprintf("camel-catalog-%s",
defaults.DefaultRuntimeVersion))
- catalog.Spec.Runtime.Version = defaults.DefaultRuntimeVersion
- catalog.Spec.Runtime.Provider = v1.RuntimeProviderQuarkus
-
+ ip.Name = "ck"
+ ip.Spec.Build.Registry.Address = "1.2.3.4"
+ ip.Spec.Build.RuntimeVersion = "1.2.3"
+ ip.Spec.Build.RuntimeProvider = v1.RuntimeProviderQuarkus
+ ip.Status.Build.RuntimeVersion = "1.2.3"
+ ip.Status.Build.RuntimeProvider = v1.RuntimeProviderQuarkus
+ ip.Status.Build.Registry.Address = "1.2.3.4"
+ ip.Status.Phase = v1.IntegrationPlatformPhaseReady
c, err := test.NewFakeClient(&ip, &catalog)
require.NoError(t, err)
- err = platform.ConfigureDefaults(context.TODO(), c, &ip, false)
- require.NoError(t, err)
-
action := NewMonitorAction()
action.InjectLogger(log.Log)
action.InjectClient(c)
@@ -93,25 +87,22 @@ func TestMonitor(t *testing.T) {
assert.Equal(t, v1.IntegrationPlatformPhaseReady, answer.Status.Phase)
assert.Equal(t, corev1.ConditionTrue,
answer.Status.GetCondition(v1.IntegrationPlatformConditionTypeRegistryAvailable).Status)
- assert.Equal(t, corev1.ConditionTrue,
answer.Status.GetCondition(v1.IntegrationPlatformConditionCamelCatalogAvailable).Status)
+ assert.Equal(t, "3.2.1", answer.Status.Build.RuntimeCoreVersion)
}
-func TestMonitorTransitionToCreateCatalog(t *testing.T) {
+func TestMonitorDriftRuntime(t *testing.T) {
ip := v1.IntegrationPlatform{}
ip.Namespace = "ns"
- ip.Name = xid.New().String()
- ip.Spec.Cluster = v1.IntegrationPlatformClusterOpenShift
- ip.Spec.Profile = v1.TraitProfileOpenShift
- ip.Spec.Build.Registry.Address = defaults.OpenShiftRegistryAddress
-
- ip.Spec.Build.RuntimeVersion = defaults.DefaultRuntimeVersion
-
+ ip.Name = "ck"
+ ip.Spec.Build.RuntimeVersion = "3.2.1"
+ ip.Spec.Build.RuntimeProvider = v1.RuntimeProviderQuarkus
+ ip.Status.Build.RuntimeVersion = "1.2.3"
+ ip.Status.Build.RuntimeProvider = v1.RuntimeProviderQuarkus
+ ip.Status.Build.Registry.Address = "1.2.3.4"
+ ip.Status.Phase = v1.IntegrationPlatformPhaseReady
c, err := test.NewFakeClient(&ip)
require.NoError(t, err)
- err = platform.ConfigureDefaults(context.TODO(), c, &ip, false)
- require.NoError(t, err)
-
action := NewMonitorAction()
action.InjectLogger(log.Log)
action.InjectClient(c)
@@ -120,29 +111,77 @@ func TestMonitorTransitionToCreateCatalog(t *testing.T) {
require.NoError(t, err)
assert.NotNil(t, answer)
- assert.Equal(t, v1.IntegrationPlatformPhaseCreateCatalog,
answer.Status.Phase)
- assert.Equal(t, corev1.ConditionTrue,
answer.Status.GetCondition(v1.IntegrationPlatformConditionTypeRegistryAvailable).Status)
- assert.Equal(t, corev1.ConditionFalse,
answer.Status.GetCondition(v1.IntegrationPlatformConditionCamelCatalogAvailable).Status)
- assert.Equal(t,
v1.IntegrationPlatformConditionCamelCatalogAvailableReason,
answer.Status.GetCondition(v1.IntegrationPlatformConditionCamelCatalogAvailable).Reason)
- assert.Equal(t, fmt.Sprintf("camel catalog %s not available, please
review given runtime version", defaults.DefaultRuntimeVersion),
answer.Status.GetCondition(v1.IntegrationPlatformConditionCamelCatalogAvailable).Message)
+ assert.Equal(t, v1.IntegrationPlatformPhaseNone, answer.Status.Phase)
}
-func TestMonitorRetainErrorState(t *testing.T) {
+func TestMonitorDriftDefault(t *testing.T) {
+ catalog := v1.NewCamelCatalog("ns", fmt.Sprintf("camel-catalog-%s",
defaults.DefaultRuntimeVersion))
+ catalog.Spec.Runtime.Version = defaults.DefaultRuntimeVersion
+ catalog.Spec.Runtime.Provider = v1.RuntimeProviderQuarkus
+ catalog.Spec.Runtime.Metadata = map[string]string{
+ "camel.version": "3.2.1",
+ }
ip := v1.IntegrationPlatform{}
ip.Namespace = "ns"
- ip.Name = xid.New().String()
- ip.Spec.Cluster = v1.IntegrationPlatformClusterOpenShift
- ip.Spec.Profile = v1.TraitProfileOpenShift
- ip.Spec.Build.Registry.Address = defaults.OpenShiftRegistryAddress
-
- ip.Spec.Build.RuntimeVersion = defaults.DefaultRuntimeVersion
+ ip.Name = "ck"
+ ip.Spec.Build.Registry.Address = "1.2.3.4"
+ ip.Status.Build.RuntimeVersion = defaults.DefaultRuntimeVersion
+ ip.Status.Build.RuntimeProvider = v1.RuntimeProviderQuarkus
+ ip.Status.Build.Registry.Address = "1.2.3.4"
+ ip.Status.Phase = v1.IntegrationPlatformPhaseReady
+ c, err := test.NewFakeClient(&ip, &catalog)
+ require.NoError(t, err)
- ip.Status.Phase = v1.IntegrationPlatformPhaseError
+ action := NewMonitorAction()
+ action.InjectLogger(log.Log)
+ action.InjectClient(c)
- c, err := test.NewFakeClient(&ip)
+ answer, err := action.Handle(context.TODO(), &ip)
require.NoError(t, err)
+ assert.NotNil(t, answer)
+
+ assert.Equal(t, v1.IntegrationPlatformPhaseReady, answer.Status.Phase)
+ assert.Equal(t, "3.2.1", answer.Status.Build.RuntimeCoreVersion)
+}
- err = platform.ConfigureDefaults(context.TODO(), c, &ip, false)
+func TestMonitorDriftConfiguration(t *testing.T) {
+ catalog := v1.NewCamelCatalog("ns", fmt.Sprintf("camel-catalog-%s",
defaults.DefaultRuntimeVersion))
+ catalog.Spec.Runtime.Version = defaults.DefaultRuntimeVersion
+ catalog.Spec.Runtime.Provider = v1.RuntimeProviderQuarkus
+ catalog.Spec.Runtime.Metadata = map[string]string{
+ "camel.version": "3.2.1",
+ }
+ ip := v1.IntegrationPlatform{
+ Spec: v1.IntegrationPlatformSpec{
+ Build: v1.IntegrationPlatformBuildSpec{
+ Registry: v1.RegistrySpec{
+ Address: "1.2.3.4",
+ },
+ },
+ Traits: v1.Traits{
+ Container: &trait.ContainerTrait{
+ Name: "override",
+ },
+ },
+ Profile: v1.TraitProfileKnative,
+ },
+ Status: v1.IntegrationPlatformStatus{
+ IntegrationPlatformSpec: v1.IntegrationPlatformSpec{
+ Build: v1.IntegrationPlatformBuildSpec{
+ RuntimeVersion:
defaults.DefaultRuntimeVersion,
+ RuntimeProvider:
v1.RuntimeProviderQuarkus,
+ RuntimeCoreVersion: "3.2.1",
+ Registry: v1.RegistrySpec{
+ Address: "1.2.3.4",
+ },
+ },
+ },
+ Phase: v1.IntegrationPlatformPhaseReady,
+ },
+ }
+ ip.Namespace = "ns"
+ ip.Name = "ck"
+ c, err := test.NewFakeClient(&ip, &catalog)
require.NoError(t, err)
action := NewMonitorAction()
@@ -153,30 +192,30 @@ func TestMonitorRetainErrorState(t *testing.T) {
require.NoError(t, err)
assert.NotNil(t, answer)
- assert.Equal(t, v1.IntegrationPlatformPhaseError, answer.Status.Phase)
- assert.Equal(t, corev1.ConditionTrue,
answer.Status.GetCondition(v1.IntegrationPlatformConditionTypeRegistryAvailable).Status)
- assert.Equal(t, corev1.ConditionFalse,
answer.Status.GetCondition(v1.IntegrationPlatformConditionCamelCatalogAvailable).Status)
- assert.Equal(t,
v1.IntegrationPlatformConditionCamelCatalogAvailableReason,
answer.Status.GetCondition(v1.IntegrationPlatformConditionCamelCatalogAvailable).Reason)
- assert.Equal(t, fmt.Sprintf("camel catalog %s not available, please
review given runtime version", defaults.DefaultRuntimeVersion),
answer.Status.GetCondition(v1.IntegrationPlatformConditionCamelCatalogAvailable).Message)
+ // It should not change the phase, however, it should change the values
+ assert.Equal(t, v1.IntegrationPlatformPhaseReady, answer.Status.Phase)
+ assert.Equal(t, defaults.Version, answer.Status.Version)
+ assert.Equal(t, defaults.DefaultRuntimeVersion,
answer.Status.Build.RuntimeVersion)
+ assert.Equal(t, v1.RuntimeProviderQuarkus,
answer.Status.Build.RuntimeProvider)
+ assert.Equal(t, "3.2.1", answer.Status.Build.RuntimeCoreVersion)
+ assert.Equal(t, v1.TraitProfileKnative, answer.Status.Profile)
+ assert.Equal(t, "override", answer.Status.Traits.Container.Name)
}
func TestMonitorMissingRegistryError(t *testing.T) {
+ catalog := v1.NewCamelCatalog("ns", fmt.Sprintf("camel-catalog-%s",
"1.2.3"))
+ catalog.Spec.Runtime.Version = "1.2.3"
+ catalog.Spec.Runtime.Provider = v1.RuntimeProviderQuarkus
ip := v1.IntegrationPlatform{}
ip.Namespace = "ns"
- ip.Name = xid.New().String()
- ip.Spec.Cluster = v1.IntegrationPlatformClusterOpenShift
- ip.Spec.Profile = v1.TraitProfileOpenShift
-
- catalog := v1.NewCamelCatalog("ns", fmt.Sprintf("camel-catalog-%s",
defaults.DefaultRuntimeVersion))
- catalog.Spec.Runtime.Version = defaults.DefaultRuntimeVersion
- catalog.Spec.Runtime.Provider = v1.RuntimeProviderQuarkus
-
+ ip.Name = "ck"
+ ip.Spec.Build.RuntimeVersion = "1.2.3"
+ ip.Spec.Build.RuntimeProvider = v1.RuntimeProviderQuarkus
+ ip.Status.Build.RuntimeVersion = "1.2.3"
+ ip.Status.Build.RuntimeProvider = v1.RuntimeProviderQuarkus
c, err := test.NewFakeClient(&ip, &catalog)
require.NoError(t, err)
- err = platform.ConfigureDefaults(context.TODO(), c, &ip, false)
- require.NoError(t, err)
-
action := NewMonitorAction()
action.InjectLogger(log.Log)
action.InjectClient(c)
@@ -190,3 +229,29 @@ func TestMonitorMissingRegistryError(t *testing.T) {
assert.Equal(t,
v1.IntegrationPlatformConditionTypeRegistryAvailableReason,
answer.Status.GetCondition(v1.IntegrationPlatformConditionTypeRegistryAvailable).Reason)
assert.Equal(t, "registry address not available, you need to set one",
answer.Status.GetCondition(v1.IntegrationPlatformConditionTypeRegistryAvailable).Message)
}
+
+func TestMonitorMissingCatalogError(t *testing.T) {
+ ip := v1.IntegrationPlatform{}
+ ip.Namespace = "ns"
+ ip.Name = "ck"
+ ip.Status.Build.RuntimeVersion = defaults.DefaultRuntimeVersion
+ ip.Status.Build.RuntimeProvider = v1.RuntimeProviderQuarkus
+ c, err := test.NewFakeClient(&ip)
+ require.NoError(t, err)
+
+ action := NewMonitorAction()
+ action.InjectLogger(log.Log)
+ action.InjectClient(c)
+
+ answer, err := action.Handle(context.TODO(), &ip)
+ require.NoError(t, err)
+ assert.NotNil(t, answer)
+
+ assert.Equal(t, v1.IntegrationPlatformPhaseError, answer.Status.Phase)
+ assert.Equal(t, corev1.ConditionFalse,
answer.Status.GetCondition(v1.IntegrationPlatformConditionCamelCatalogAvailable).Status)
+ assert.Equal(t,
v1.IntegrationPlatformConditionCamelCatalogAvailableReason,
answer.Status.GetCondition(
+ v1.IntegrationPlatformConditionCamelCatalogAvailable).Reason)
+ assert.Equal(t, fmt.Sprintf("camel catalog %s not available, please
review given runtime version",
+ defaults.DefaultRuntimeVersion), answer.Status.GetCondition(
+ v1.IntegrationPlatformConditionCamelCatalogAvailable).Message)
+}
diff --git a/pkg/install/kamelets.go b/pkg/install/kamelets.go
deleted file mode 100644
index daaa7894e..000000000
--- a/pkg/install/kamelets.go
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
-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 install
-
-import (
- "context"
- "fmt"
- "io/fs"
- "os"
- "path/filepath"
- "strings"
-
- "golang.org/x/sync/errgroup"
-
- ctrl "sigs.k8s.io/controller-runtime/pkg/client"
-
- v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
-
- "github.com/apache/camel-k/v2/pkg/client"
- "github.com/apache/camel-k/v2/pkg/util"
- "github.com/apache/camel-k/v2/pkg/util/defaults"
- "github.com/apache/camel-k/v2/pkg/util/kubernetes"
- "github.com/apache/camel-k/v2/pkg/util/log"
-)
-
-const (
- kameletDirEnv = "KAMELET_CATALOG_DIR"
- defaultKameletDir = "/kamelets/"
-)
-
-// KameletCatalog installs the bundled Kamelets into the specified namespace.
-func KameletCatalog(ctx context.Context, c client.Client, namespace string)
error {
- kameletDir := os.Getenv(kameletDirEnv)
- if kameletDir == "" {
- kameletDir = defaultKameletDir
- }
- d, err := os.Stat(kameletDir)
- switch {
- case err != nil && os.IsNotExist(err):
- return nil
- case err != nil:
- return err
- case !d.IsDir():
- return fmt.Errorf("kamelet directory %q is a file", kameletDir)
- }
-
- g, gCtx := errgroup.WithContext(ctx)
- applier := c.ServerOrClientSideApplier()
-
- err = filepath.WalkDir(kameletDir, func(p string, f fs.DirEntry, err
error) error {
- if err != nil {
- return err
- }
- if f.IsDir() && f.Name() != d.Name() {
- return fs.SkipDir
- }
- if !(strings.HasSuffix(f.Name(), ".yaml") ||
strings.HasSuffix(f.Name(), ".yml")) {
- return nil
- }
- // We may want to throttle the creation of Go routines if the
number of bundled Kamelets increases.
- g.Go(func() error {
- kamelet, err := loadKamelet(filepath.Join(kameletDir,
f.Name()), namespace)
- if err != nil {
- return err
- }
- err = applier.Apply(gCtx, kamelet)
- // We only log the error. If we returned the error, the
creation of the ITP would have stopped
- if err != nil {
- log.Error(err, "Error occurred whilst applying
bundled kamelet")
- }
- return nil
- })
- return nil
- })
- if err != nil {
- return err
- }
-
- return g.Wait()
-}
-
-func loadKamelet(path string, namespace string) (ctrl.Object, error) {
- content, err := util.ReadFile(path)
- if err != nil {
- return nil, err
- }
-
- kamelet, err := kubernetes.LoadUnstructuredFromYaml(string(content))
- if err != nil {
- return nil, err
- }
- gvk := kamelet.GetObjectKind().GroupVersionKind()
- if gvk.Group != v1.SchemeGroupVersion.Group || gvk.Kind != "Kamelet" {
- return nil, fmt.Errorf("file %q does not define a Kamelet",
path)
- }
-
- kamelet.SetNamespace(namespace)
-
- annotations := kamelet.GetAnnotations()
- if annotations == nil {
- annotations = make(map[string]string)
- }
- annotations[kamelVersionAnnotation] = defaults.Version
- kamelet.SetAnnotations(annotations)
-
- labels := kamelet.GetLabels()
- if labels == nil {
- labels = make(map[string]string)
- }
- labels[v1.KameletBundledLabel] = "true"
- labels[v1.KameletReadOnlyLabel] = "true"
-
- kamelet.SetLabels(labels)
-
- return kamelet, nil
-}
-
-// KameletViewerRole installs the role that allows any user ro access kamelets
in the global namespace.
-func KameletViewerRole(ctx context.Context, c client.Client, namespace string)
error {
- return Resource(ctx, c, namespace, true, IdentityResourceCustomizer,
"/resources/viewer/user-global-kamelet-viewer-role-binding.yaml")
-}
diff --git a/pkg/install/kamelets_test.go b/pkg/install/kamelets_test.go
deleted file mode 100644
index 67d0cb577..000000000
--- a/pkg/install/kamelets_test.go
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
-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 install
-
-import (
- "testing"
-
- v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
-)
-
-func TestLoadKamelet(t *testing.T) {
- kamelet, err := loadKamelet("testdata/timer-source.kamelet.yaml",
"some-namespace")
-
- assert.NotNil(t, kamelet)
- require.NoError(t, err)
- assert.Equal(t, "timer-source", kamelet.GetName())
- assert.Equal(t, "some-namespace", kamelet.GetNamespace())
- assert.Len(t, kamelet.GetLabels(), 3)
- assert.Equal(t, "true", kamelet.GetLabels()[v1.KameletBundledLabel])
- assert.Equal(t, "true", kamelet.GetLabels()[v1.KameletReadOnlyLabel])
- assert.Len(t, kamelet.GetAnnotations(), 2)
- assert.NotNil(t, kamelet.GetAnnotations()[kamelVersionAnnotation])
-}
diff --git a/pkg/install/optional.go b/pkg/install/optional.go
index eaa5999f7..ddef6f740 100644
--- a/pkg/install/optional.go
+++ b/pkg/install/optional.go
@@ -19,10 +19,8 @@ package install
import (
"context"
- "strings"
"github.com/apache/camel-k/v2/pkg/client"
- "github.com/apache/camel-k/v2/pkg/util/defaults"
logutil "github.com/apache/camel-k/v2/pkg/util/log"
)
@@ -33,33 +31,4 @@ func OperatorStartupOptionalTools(ctx context.Context, c
client.Client, namespac
log.Info("Cannot install OpenShift CLI download link:
skipping.")
log.Debug("Error while installing OpenShift CLI download link",
"error", err)
}
-
- // Try to install Kamelet Catalog automatically
- var kameletNamespace string
- globalOperator := false
- if namespace != "" && !strings.Contains(namespace, ",") {
- kameletNamespace = namespace
- } else {
- kameletNamespace = operatorNamespace
- globalOperator = true
- }
-
- if kameletNamespace != "" {
- if defaults.InstallDefaultKamelets() {
- if err := KameletCatalog(ctx, c, kameletNamespace); err
!= nil {
- log.Info("Cannot install bundled Kamelet
Catalog: skipping.")
- log.Debug("Error while installing bundled
Kamelet Catalog", "error", err)
- }
- } else {
- log.Info("Kamelet Catalog installation is disabled")
- }
-
- if globalOperator {
- // Make sure that Kamelets installed in operator
namespace can be used by others
- if err := KameletViewerRole(ctx, c, kameletNamespace);
err != nil {
- log.Info("Cannot install global Kamelet viewer
role: skipping.")
- log.Debug("Error while installing global
Kamelet viewer role", "error", err)
- }
- }
- }
}
diff --git a/pkg/install/testdata/timer-source.kamelet.yaml
b/pkg/install/testdata/timer-source.kamelet.yaml
deleted file mode 100644
index 3058964c2..000000000
--- a/pkg/install/testdata/timer-source.kamelet.yaml
+++ /dev/null
@@ -1,57 +0,0 @@
-# ---------------------------------------------------------------------------
-# 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.
-# ---------------------------------------------------------------------------
-
-apiVersion: camel.apache.org/v1alpha1
-kind: Kamelet
-metadata:
- name: timer-source
- annotations:
- camel.apache.org/kamelet.icon:
"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gU3ZnIFZlY3RvciBJY29ucyA6IGh0dHA6Ly93d3cub25saW5ld2ViZm9udHMuY29tL2ljb24gLS0+DQo8IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPg0KPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm
[...]
- labels:
- camel.apache.org/kamelet.type: "source"
-spec:
- definition:
- title: "Timer Source"
- description: "Produces periodic events with a custom payload"
- required:
- - message
- properties:
- period:
- title: Period
- description: The interval between two events
- type: integer
- default: 1000
- message:
- title: Message
- description: The message to generate
- type: string
- example: "hello world"
- dataTypes:
- out:
- default: text
- types:
- text:
- mediaType: text/plain
- template:
- from:
- uri: timer:tick
- parameters:
- period: "{{period}}"
- steps:
- - setBody:
- constant: "{{message}}"
- - to: "kamelet:sink"
diff --git a/pkg/platform/defaults.go b/pkg/platform/defaults.go
index 3b6e89a60..66398013a 100644
--- a/pkg/platform/defaults.go
+++ b/pkg/platform/defaults.go
@@ -53,12 +53,22 @@ const (
func ConfigureDefaults(ctx context.Context, c client.Client, p
*v1.IntegrationPlatform, verbose bool) error {
// Reset the state to initial values
p.ResyncStatusFullConfig()
-
+ // Set the operator version controlling this resource
+ p.Status.Version = defaults.Version
// Apply settings from global integration platform that is bound to
this operator
if err := applyGlobalPlatformDefaults(ctx, c, p); err != nil {
return err
}
+ if p.Status.Build.RuntimeProvider == "" {
+ p.Status.Build.RuntimeProvider = v1.RuntimeProviderQuarkus
+ log.Debugf("Integration Platform %s [%s]: setting default
runtime provider %s", p.Name, p.Namespace, v1.RuntimeProviderQuarkus)
+ }
+ if p.Status.Build.RuntimeVersion == "" {
+ p.Status.Build.RuntimeVersion = defaults.DefaultRuntimeVersion
+ log.Debugf("Integration Platform %s [%s]: setting default
runtime version %s", p.Name, p.Namespace, p.Status.Build.PublishStrategy)
+ }
+
// update missing fields in the resource
if p.Status.Cluster == "" {
log.Debugf("Integration Platform %s [%s]: setting cluster
status", p.Name, p.Namespace)
diff --git a/pkg/trait/kamelets.go b/pkg/trait/kamelets.go
index 8e861c5d3..fd764264b 100644
--- a/pkg/trait/kamelets.go
+++ b/pkg/trait/kamelets.go
@@ -121,6 +121,7 @@ func (t *kameletsTrait) collectKamelets(e *Environment)
(map[string]*v1.Kamelet,
kamelets := make(map[string]*v1.Kamelet)
missingKamelets := make([]string, 0)
availableKamelets := make([]string, 0)
+ bundledKamelets := make([]string, 0)
for _, kml := range strings.Split(t.List, ",") {
name := getKameletKey(kml, false)
@@ -138,6 +139,10 @@ func (t *kameletsTrait) collectKamelets(e *Environment)
(map[string]*v1.Kamelet,
} else {
availableKamelets = append(availableKamelets, name)
}
+ if kamelet.IsBundled() {
+ bundledKamelets = append(bundledKamelets, name)
+ }
+ // We control which version to use (if any is specified)
clonedKamelet, err :=
kamelet.CloneWithVersion(getKameletVersion(kml))
if err != nil {
return nil, err
@@ -147,13 +152,12 @@ func (t *kameletsTrait) collectKamelets(e *Environment)
(map[string]*v1.Kamelet,
sort.Strings(availableKamelets)
sort.Strings(missingKamelets)
+ sort.Strings(bundledKamelets)
if len(missingKamelets) > 0 {
- message := fmt.Sprintf("kamelets [%s] found, kamelets [%s] not
found in %s repositories",
- strings.Join(availableKamelets, ","),
+ message := fmt.Sprintf("kamelets [%s] not found in %s
repositories",
strings.Join(missingKamelets, ","),
repo.String())
-
e.Integration.Status.SetCondition(
v1.IntegrationConditionKameletsAvailable,
corev1.ConditionFalse,
@@ -164,6 +168,24 @@ func (t *kameletsTrait) collectKamelets(e *Environment)
(map[string]*v1.Kamelet,
return nil, errors.New(message)
}
+ // TODO:
+ // We list the Kamelets coming from a bundle. We want to warn the user
+ // that in the future we'll use the specification coming from the
dependency runtime
+ // instead of using the one installed in the cluster.
+ // It may be a good idea in the future to let the user specify the
catalog dependency to use
+ // in order to override the one coming from Apache catalog
+ if len(bundledKamelets) > 0 {
+ message := fmt.Sprintf("using bundled kamelets [%s]: make sure
the Kamelet specifications is compatible with this Integration runtime."+
+ " This feature is deprecated as in the future we will
use directly the specification coming from the Kamelet catalog dependency jar.",
+ strings.Join(bundledKamelets, ","))
+ e.Integration.Status.SetCondition(
+
v1.IntegrationConditionType("KameletsDeprecationNotice"),
+ corev1.ConditionTrue,
+ "KameletsDeprecationNotice",
+ message,
+ )
+ }
+
e.Integration.Status.SetCondition(
v1.IntegrationConditionKameletsAvailable,
corev1.ConditionTrue,
diff --git a/pkg/trait/kamelets_test.go b/pkg/trait/kamelets_test.go
index 161ac3714..ac7ad9411 100644
--- a/pkg/trait/kamelets_test.go
+++ b/pkg/trait/kamelets_test.go
@@ -506,7 +506,6 @@ func TestKameletConditionFalse(t *testing.T) {
cond :=
environment.Integration.Status.GetCondition(v1.IntegrationConditionKameletsAvailable)
assert.Equal(t, corev1.ConditionFalse, cond.Status)
assert.Equal(t, v1.IntegrationConditionKameletsAvailableReason,
cond.Reason)
- assert.Contains(t, cond.Message, "[timer] found")
assert.Contains(t, cond.Message, "kamelets [none] not found")
}
diff --git a/pkg/util/camel/camel_runtime.go b/pkg/util/camel/camel_runtime.go
index 063a30a22..753c54801 100644
--- a/pkg/util/camel/camel_runtime.go
+++ b/pkg/util/camel/camel_runtime.go
@@ -33,7 +33,8 @@ import (
)
// CreateCatalog --.
-func CreateCatalog(ctx context.Context, client client.Client, namespace
string, platform *v1.IntegrationPlatform, runtime v1.RuntimeSpec)
(*RuntimeCatalog, error) {
+func CreateCatalog(ctx context.Context, client client.Client, namespace
string, platform *v1.IntegrationPlatform,
+ runtime v1.RuntimeSpec) (*RuntimeCatalog, error) {
ctx, cancel := context.WithTimeout(ctx,
platform.Status.Build.GetTimeout().Duration)
defer cancel()
catalog, err := GenerateCatalog(ctx, client, namespace,
platform.Status.Build.Maven, runtime, []maven.Dependency{})
diff --git a/release.adoc b/release.adoc
index 6f5407a9b..a54dc6979 100644
--- a/release.adoc
+++ b/release.adoc
@@ -1,4 +1,3 @@
-
= Releasing Apache Camel K
This procedure describes all the steps required to release a new version of
Apache Camel K.
diff --git a/script/Makefile b/script/Makefile
index 6a952deab..3f6a8b1d1 100644
--- a/script/Makefile
+++ b/script/Makefile
@@ -90,12 +90,7 @@ OPM := opm
# Used to push pre-release artifacts
STAGING_IMAGE := docker.io/camelk/camel-k
-
-# Kamelets options
INSTALL_DEFAULT_KAMELETS ?= true
-KAMELET_CATALOG_REPO := https://github.com/apache/camel-kamelets.git
-# Make sure to use a released tag or empty if you want to get the latest
development bits
-KAMELET_CATALOG_REPO_TAG := v4.4.1
# When performing integration tests, it is not necessary to always execute
build, especially
# in e2e tests when lots of tests are being executed sequentially & the build
has already taken place.
@@ -356,16 +351,6 @@ endif
build-resources:
./script/get_catalog.sh $(DEFAULT_RUNTIME_VERSION)
-bundle-kamelets:
- @echo "Preparing Kamelets bundle resource..."
-ifneq (,$(findstring release,$(MAKECMDGOALS)))
-ifneq (,$(findstring $(KAMELET_CATALOG_REPO_TAG), main))
- @echo "You cannot set
KAMELET_CATALOG_REPO_TAG=$(KAMELET_CATALOG_REPO_TAG) when doing a release"
- @exit 1
-endif
-endif
- ./script/bundle_kamelets.sh $(KAMELET_CATALOG_REPO)
$(KAMELET_CATALOG_REPO_TAG)
-
build-compile-integration-tests:
@echo "####### Compiling integration tests..."
export CAMEL_K_E2E_JUST_COMPILE="true"; \
@@ -445,7 +430,7 @@ endif
DOCKER_TAG := $(CUSTOM_IMAGE):$(CUSTOM_VERSION)-$(IMAGE_ARCH)
-images: build maven-overlay bundle-kamelets image-build build-kamel-platform
+images: build maven-overlay image-build build-kamel-platform
image-build:
ifneq (,$(findstring SNAPSHOT,$(DEFAULT_RUNTIME_VERSION)))
@@ -550,7 +535,7 @@ release-kustomize:
RELEASE_NAME=$(PACKAGE) \
./script/release_kustomize.sh
-.PHONY: do-build build build-kamel build-kamel-platform build-resources dep
codegen images images-push images-push-staging image-build test check clean
release cross-compile package-examples set-version git-tag check-licenses
build-resources release-helm release-staging release-nightly get-staging-repo
get-version bundle-kamelets
+.PHONY: do-build build build-kamel build-kamel-platform build-resources dep
codegen images images-push images-push-staging image-build test check clean
release cross-compile package-examples set-version git-tag check-licenses
build-resources release-helm release-staging release-nightly get-staging-repo
get-version
.PHONY: controller-gen kubectl kustomize operator-sdk opm
# find or download controller-gen if necessary
diff --git a/script/bundle_kamelets.sh b/script/bundle_kamelets.sh
deleted file mode 100755
index 2d94ab91e..000000000
--- a/script/bundle_kamelets.sh
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/bin/sh
-
-# 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.
-
-location=$(dirname $0)
-rootdir=$location/../
-
-set -e
-
-repo=$1
-tag=$2
-
-cd $rootdir
-target=./build/_kamelets
-
-# Always recreate the dir
-rm -rf $target
-mkdir $target
-
-if [ "$repo" = "" ]; then
- echo "no kamelet catalog defined: skipping"
- exit 0
-fi
-
-if [ "$tag" = "" ]; then
- echo "ERROR: no kamelet catalog version defined"
- exit 1
-fi
-
-echo "Cloning repository $repo from tag $tag to bundle kamelets..."
-
-rm -rf ./tmp_kamelet_catalog
-git clone -q -c advice.detachedHead=false -b $tag --single-branch --depth 1
$repo ./tmp_kamelet_catalog
-
-cp ./tmp_kamelet_catalog/kamelets/*.kamelet.yaml $target
-
-rm -rf ./tmp_kamelet_catalog
-
-#
-# Check that all the kamelets have licences
-#
-./script/add_license.sh $target ./script/headers/yaml.txt