From a29fce29a1588d62fcd21c562f6eb43b43f5c3fe Mon Sep 17 00:00:00 2001 From: Pasquale Congiusti Date: Fri, 5 Apr 2024 11:22:46 +0200 Subject: [PATCH 1/4] feat(trait): allow usage of semver for camel.runtime-version Closes #5311 --- pkg/trait/camel.go | 2 +- pkg/trait/camel_test.go | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/pkg/trait/camel.go b/pkg/trait/camel.go index 3d2a991d8d..d774cfca2b 100644 --- a/pkg/trait/camel.go +++ b/pkg/trait/camel.go @@ -86,7 +86,7 @@ func (t *camelTrait) Apply(e *Environment) error { } } - e.RuntimeVersion = t.RuntimeVersion + e.RuntimeVersion = e.CamelCatalog.Runtime.Version if e.Integration != nil { e.Integration.Status.RuntimeVersion = e.CamelCatalog.Runtime.Version diff --git a/pkg/trait/camel_test.go b/pkg/trait/camel_test.go index a3fc3688d6..5d5a13a4f5 100644 --- a/pkg/trait/camel_test.go +++ b/pkg/trait/camel_test.go @@ -230,3 +230,19 @@ func TestCamelMatches(t *testing.T) { t2.RuntimeVersion = "3.2.1" assert.False(t, t1.Matches(&t2)) } + +func TestCamelCatalogSemver(t *testing.T) { + trait, environment := createNominalCamelTest(true) + trait.RuntimeVersion = "2.x" + environment.CamelCatalog.CamelCatalogSpec.Runtime.Version = "2.16.0" + + configured, condition, err := trait.Configure(environment) + require.NoError(t, err) + assert.Nil(t, condition) + assert.True(t, configured) + + err = trait.Apply(environment) + require.NoError(t, err) + // 2.x will translate with 2.16.0 as it is already existing + assert.Equal(t, environment.CamelCatalog.CamelCatalogSpec.Runtime.Version, environment.RuntimeVersion) +} From 64653eec8259b60d46701bbd410737bc016e76fb Mon Sep 17 00:00:00 2001 From: Pasquale Congiusti Date: Mon, 22 Apr 2024 17:14:25 +0200 Subject: [PATCH 2/4] fix(trait): synthetic Kit While working on #5378 I realized the concept of external Kit is used widely also for the concept of what is a Synthetic Kit. An external Kit is a kit coming from a build from the operator, whilst a synthetic Kit is not coming from an operator. --- .../ROOT/partials/apis/camel-k-crds.adoc | 9 +++++++-- docs/modules/traits/pages/container.adoc | 4 ++++ docs/modules/traits/pages/jvm.adoc | 2 -- e2e/advanced/operator_id_filtering_test.go | 2 +- e2e/install/cli/global_test.go | 2 +- .../crds/crd-integration-platform.yaml | 8 ++++++++ .../camel-k/crds/crd-integration-profile.yaml | 8 ++++++++ helm/camel-k/crds/crd-integration.yaml | 4 ++++ helm/camel-k/crds/crd-kamelet-binding.yaml | 4 ++++ helm/camel-k/crds/crd-pipe.yaml | 4 ++++ pkg/apis/camel/v1/integrationkit_types.go | 8 +++++--- .../camel/v1/integrationkit_types_support.go | 5 +++++ pkg/apis/camel/v1/trait/container.go | 2 ++ pkg/apis/camel/v1/trait/jvm.go | 2 -- .../camel/v1/trait/zz_generated.deepcopy.go | 5 +++++ pkg/cmd/promote.go | 16 ++++----------- pkg/cmd/promote_test.go | 18 ++++++----------- .../integrationkit_controller.go | 2 +- ...camel.apache.org_integrationplatforms.yaml | 8 ++++++++ .../camel.apache.org_integrationprofiles.yaml | 8 ++++++++ .../bases/camel.apache.org_integrations.yaml | 4 ++++ .../camel.apache.org_kameletbindings.yaml | 4 ++++ .../crd/bases/camel.apache.org_pipes.yaml | 4 ++++ pkg/trait/container.go | 5 ++++- pkg/trait/jvm.go | 8 ++------ pkg/trait/jvm_test.go | 20 +------------------ pkg/trait/trait_condition_types.go | 4 ---- 27 files changed, 104 insertions(+), 66 deletions(-) diff --git a/docs/modules/ROOT/partials/apis/camel-k-crds.adoc b/docs/modules/ROOT/partials/apis/camel-k-crds.adoc index edb8c14087..f8586842de 100644 --- a/docs/modules/ROOT/partials/apis/camel-k-crds.adoc +++ b/docs/modules/ROOT/partials/apis/camel-k-crds.adoc @@ -6523,6 +6523,13 @@ string The main container image +|`imageWasKit` + +bool +| + + +A flag to mark the image used is coming from an IntegrationKit created externally. + |`imagePullPolicy` + *https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#pullpolicy-v1-core[Kubernetes core/v1.PullPolicy]* | @@ -7195,8 +7202,6 @@ The JVM trait is used to configure the JVM that runs the Integration. This trait (bound to a container image) built by Camel K operator. If the system detects the usage of a different container image (ie, built externally), then, the trait is disabled by the platform. -WARNING: you can still enable the trait explicitly even when it is disabled by the platform but you should be aware that some configurations could fail. - [cols="2,2a",options="header"] |=== diff --git a/docs/modules/traits/pages/container.adoc b/docs/modules/traits/pages/container.adoc index 65925bc467..3be9861b61 100755 --- a/docs/modules/traits/pages/container.adoc +++ b/docs/modules/traits/pages/container.adoc @@ -77,6 +77,10 @@ The following configuration options are available: | string | The main container image +| container.image-was-kit +| bool +| A flag to mark the image used is coming from an IntegrationKit created externally. + | container.image-pull-policy | PullPolicy | The pull policy: Always\|Never\|IfNotPresent diff --git a/docs/modules/traits/pages/jvm.adoc b/docs/modules/traits/pages/jvm.adoc index 5a2cc1540f..3764610046 100755 --- a/docs/modules/traits/pages/jvm.adoc +++ b/docs/modules/traits/pages/jvm.adoc @@ -5,8 +5,6 @@ The JVM trait is used to configure the JVM that runs the Integration. This trait (bound to a container image) built by Camel K operator. If the system detects the usage of a different container image (ie, built externally), then, the trait is disabled by the platform. -WARNING: you can still enable the trait explicitly even when it is disabled by the platform but you should be aware that some configurations could fail. - This trait is available in the following profiles: **Kubernetes, Knative, OpenShift**. diff --git a/e2e/advanced/operator_id_filtering_test.go b/e2e/advanced/operator_id_filtering_test.go index 390d010c83..c67e3677f8 100644 --- a/e2e/advanced/operator_id_filtering_test.go +++ b/e2e/advanced/operator_id_filtering_test.go @@ -100,7 +100,7 @@ func TestOperatorIDFiltering(t *testing.T) { // Save resources by deleting "moving" integration g.Expect(Kamel(t, ctx, "delete", "moving", "-n", ns).Execute()).To(Succeed()) - g.Expect(KamelRunWithID(t, ctx, "operator-x", ns, "files/yaml.yaml", "--name", "pre-built", "--force", "-t", fmt.Sprintf("container.image=%s", image), "-t", "jvm.enabled=true").Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, "operator-x", ns, "files/yaml.yaml", "--name", "pre-built", "--force", "-t", fmt.Sprintf("container.image=%s", image), "-t", "container.image-was-kit=true").Execute()).To(Succeed()) g.Consistently(IntegrationPhase(t, ctx, ns, "pre-built"), 10*time.Second).Should(BeEmpty()) g.Expect(AssignIntegrationToOperator(t, ctx, ns, "pre-built", operator2)).To(Succeed()) g.Eventually(IntegrationPhase(t, ctx, ns, "pre-built"), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseRunning)) diff --git a/e2e/install/cli/global_test.go b/e2e/install/cli/global_test.go index 436c92e63f..303ca07b97 100644 --- a/e2e/install/cli/global_test.go +++ b/e2e/install/cli/global_test.go @@ -140,7 +140,7 @@ func TestRunGlobalInstall(t *testing.T) { } g.Expect(TestClient(t).Create(ctx, &externalKit)).Should(BeNil()) - g.Expect(KamelRun(t, ctx, ns5, "files/Java.java", "--name", "ext", "--kit", "external", "-t", "jvm.enabled=true").Execute()).To(Succeed()) + g.Expect(KamelRun(t, ctx, ns5, "files/Java.java", "--name", "ext", "--kit", "external").Execute()).To(Succeed()) g.Eventually(IntegrationPodPhase(t, ctx, ns5, "ext"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) g.Eventually(IntegrationLogs(t, ctx, ns5, "ext"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) g.Expect(IntegrationKit(t, ctx, ns5, "ext")()).Should(Equal("external")) diff --git a/helm/camel-k/crds/crd-integration-platform.yaml b/helm/camel-k/crds/crd-integration-platform.yaml index 9d04b2ad8a..12f95132a1 100644 --- a/helm/camel-k/crds/crd-integration-platform.yaml +++ b/helm/camel-k/crds/crd-integration-platform.yaml @@ -701,6 +701,10 @@ spec: - Never - IfNotPresent type: string + imageWasKit: + description: A flag to mark the image used is coming from + an IntegrationKit created externally. + type: boolean limitCPU: description: The maximum amount of CPU required. type: string @@ -2603,6 +2607,10 @@ spec: - Never - IfNotPresent type: string + imageWasKit: + description: A flag to mark the image used is coming from + an IntegrationKit created externally. + type: boolean limitCPU: description: The maximum amount of CPU required. type: string diff --git a/helm/camel-k/crds/crd-integration-profile.yaml b/helm/camel-k/crds/crd-integration-profile.yaml index 21e0c93340..c587cc5a61 100644 --- a/helm/camel-k/crds/crd-integration-profile.yaml +++ b/helm/camel-k/crds/crd-integration-profile.yaml @@ -578,6 +578,10 @@ spec: - Never - IfNotPresent type: string + imageWasKit: + description: A flag to mark the image used is coming from + an IntegrationKit created externally. + type: boolean limitCPU: description: The maximum amount of CPU required. type: string @@ -2363,6 +2367,10 @@ spec: - Never - IfNotPresent type: string + imageWasKit: + description: A flag to mark the image used is coming from + an IntegrationKit created externally. + type: boolean limitCPU: description: The maximum amount of CPU required. type: string diff --git a/helm/camel-k/crds/crd-integration.yaml b/helm/camel-k/crds/crd-integration.yaml index 48c5885ed3..0a4b17f327 100644 --- a/helm/camel-k/crds/crd-integration.yaml +++ b/helm/camel-k/crds/crd-integration.yaml @@ -6597,6 +6597,10 @@ spec: - Never - IfNotPresent type: string + imageWasKit: + description: A flag to mark the image used is coming from + an IntegrationKit created externally. + type: boolean limitCPU: description: The maximum amount of CPU required. type: string diff --git a/helm/camel-k/crds/crd-kamelet-binding.yaml b/helm/camel-k/crds/crd-kamelet-binding.yaml index d856f765f8..eb3476d637 100644 --- a/helm/camel-k/crds/crd-kamelet-binding.yaml +++ b/helm/camel-k/crds/crd-kamelet-binding.yaml @@ -6882,6 +6882,10 @@ spec: - Never - IfNotPresent type: string + imageWasKit: + description: A flag to mark the image used is coming from + an IntegrationKit created externally. + type: boolean limitCPU: description: The maximum amount of CPU required. type: string diff --git a/helm/camel-k/crds/crd-pipe.yaml b/helm/camel-k/crds/crd-pipe.yaml index 860e4c44bc..8b7e891f6a 100644 --- a/helm/camel-k/crds/crd-pipe.yaml +++ b/helm/camel-k/crds/crd-pipe.yaml @@ -6880,6 +6880,10 @@ spec: - Never - IfNotPresent type: string + imageWasKit: + description: A flag to mark the image used is coming from + an IntegrationKit created externally. + type: boolean limitCPU: description: The maximum amount of CPU required. type: string diff --git a/pkg/apis/camel/v1/integrationkit_types.go b/pkg/apis/camel/v1/integrationkit_types.go index d8b0864c4a..b87eda9b47 100644 --- a/pkg/apis/camel/v1/integrationkit_types.go +++ b/pkg/apis/camel/v1/integrationkit_types.go @@ -147,12 +147,14 @@ const ( // IntegrationKitTypeLabel labels the kit type. IntegrationKitTypeLabel = "camel.apache.org/kit.type" - // IntegrationKitTypePlatform identifies a kit created by the platform. + // IntegrationKitTypePlatform identifies a Kit created by the platform. IntegrationKitTypePlatform = "platform" - // IntegrationKitTypeUser identifies a kit created by the user. + // IntegrationKitTypeUser identifies a Kit created by the user. IntegrationKitTypeUser = "user" - // IntegrationKitTypeExternal identifies a kit created by any third party. + // IntegrationKitTypeExternal identifies a Kit created by any third party. IntegrationKitTypeExternal = "external" + // IntegrationKitTypeSynthetic identifies a synthetic Kit (generated for any container image for which the operator cannot make any assumption). + IntegrationKitTypeSynthetic = "synthetic" // IntegrationKitLayoutLabel labels the kit layout. IntegrationKitLayoutLabel = "camel.apache.org/kit.layout" diff --git a/pkg/apis/camel/v1/integrationkit_types_support.go b/pkg/apis/camel/v1/integrationkit_types_support.go index c1c8d2a5f0..b58653227a 100644 --- a/pkg/apis/camel/v1/integrationkit_types_support.go +++ b/pkg/apis/camel/v1/integrationkit_types_support.go @@ -106,6 +106,11 @@ func (in *IntegrationKit) IsExternal() bool { return in.Labels[IntegrationKitTypeLabel] == IntegrationKitTypeExternal } +// IsSynthetic returns true for synthetic IntegrationKits. +func (in *IntegrationKit) IsSynthetic() bool { + return in.Labels[IntegrationKitTypeLabel] == IntegrationKitTypeSynthetic +} + // HasCapability returns true if the Kit is enabled with such a capability. func (in *IntegrationKit) HasCapability(capability string) bool { for _, cap := range in.Spec.Capabilities { diff --git a/pkg/apis/camel/v1/trait/container.go b/pkg/apis/camel/v1/trait/container.go index d5791ec389..4d426993a8 100644 --- a/pkg/apis/camel/v1/trait/container.go +++ b/pkg/apis/camel/v1/trait/container.go @@ -51,6 +51,8 @@ type ContainerTrait struct { Name string `property:"name" json:"name,omitempty"` // The main container image Image string `property:"image" json:"image,omitempty"` + // A flag to mark the image used is coming from an IntegrationKit created externally. + ImageWasKit *bool `property:"image-was-kit" json:"imageWasKit,omitempty"` // The pull policy: Always|Never|IfNotPresent // +kubebuilder:validation:Enum=Always;Never;IfNotPresent ImagePullPolicy corev1.PullPolicy `property:"image-pull-policy" json:"imagePullPolicy,omitempty"` diff --git a/pkg/apis/camel/v1/trait/jvm.go b/pkg/apis/camel/v1/trait/jvm.go index b439381c35..abe1e1185a 100644 --- a/pkg/apis/camel/v1/trait/jvm.go +++ b/pkg/apis/camel/v1/trait/jvm.go @@ -21,8 +21,6 @@ package trait // (bound to a container image) built by Camel K operator. If the system detects the usage of a different container image (ie, built externally), then, the // trait is disabled by the platform. // -// WARNING: you can still enable the trait explicitly even when it is disabled by the platform but you should be aware that some configurations could fail. -// // +camel-k:trait=jvm. type JVMTrait struct { Trait `property:",squash" json:",inline"` diff --git a/pkg/apis/camel/v1/trait/zz_generated.deepcopy.go b/pkg/apis/camel/v1/trait/zz_generated.deepcopy.go index 3aa1253591..5fc1d19646 100644 --- a/pkg/apis/camel/v1/trait/zz_generated.deepcopy.go +++ b/pkg/apis/camel/v1/trait/zz_generated.deepcopy.go @@ -186,6 +186,11 @@ func (in *ContainerTrait) DeepCopyInto(out *ContainerTrait) { *out = new(bool) **out = **in } + if in.ImageWasKit != nil { + in, out := &in.ImageWasKit, &out.ImageWasKit + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerTrait. diff --git a/pkg/cmd/promote.go b/pkg/cmd/promote.go index 9b73e71ee9..a807191f44 100644 --- a/pkg/cmd/promote.go +++ b/pkg/cmd/promote.go @@ -469,12 +469,8 @@ func (o *promoteCmdOptions) editIntegration(it *v1.Integration) *v1.Integration dst.Spec.Traits.Container = &traitv1.ContainerTrait{} } dst.Spec.Traits.Container.Image = contImage - if dst.Spec.Traits.JVM == nil { - dst.Spec.Traits.JVM = &traitv1.JVMTrait{} - } - if dst.Spec.Traits.JVM.Enabled == nil { - dst.Spec.Traits.JVM.Enabled = pointer.Bool(true) - } + dst.Spec.Traits.Container.ImageWasKit = pointer.Bool(true) + return &dst } @@ -520,12 +516,8 @@ func (o *promoteCmdOptions) editPipe(kb *v1.Pipe, it *v1.Integration) *v1.Pipe { dst.Spec.Integration.Traits.Container = &traitv1.ContainerTrait{} } dst.Spec.Integration.Traits.Container.Image = contImage - if dst.Spec.Integration.Traits.JVM == nil { - dst.Spec.Integration.Traits.JVM = &traitv1.JVMTrait{} - } - if dst.Spec.Integration.Traits.JVM.Enabled == nil { - dst.Spec.Integration.Traits.JVM.Enabled = pointer.Bool(true) - } + dst.Spec.Integration.Traits.Container.ImageWasKit = pointer.Bool(true) + if dst.Spec.Source.Ref != nil { dst.Spec.Source.Ref.Namespace = o.To } diff --git a/pkg/cmd/promote_test.go b/pkg/cmd/promote_test.go index 91ebce901f..78779fb4ee 100644 --- a/pkg/cmd/promote_test.go +++ b/pkg/cmd/promote_test.go @@ -102,8 +102,7 @@ spec: traits: container: image: my-special-image - jvm: - enabled: true + imageWasKit: true status: {} `, output) } @@ -144,8 +143,7 @@ spec: traits: container: image: my-special-image - jvm: - enabled: true + imageWasKit: true sink: {} source: {} status: {} @@ -202,8 +200,7 @@ spec: traits: container: image: my-special-image - jvm: - enabled: true + imageWasKit: true status: {} `, output) } @@ -248,8 +245,7 @@ spec: traits: container: image: my-special-image - jvm: - enabled: true + imageWasKit: true sink: {} source: {} status: {} @@ -325,8 +321,7 @@ spec: traits: container: image: my-special-image - jvm: - enabled: true + imageWasKit: true status: {} `, output) // Verify also when the operator Id is set in the integration @@ -349,8 +344,7 @@ spec: traits: container: image: my-special-image - jvm: - enabled: true + imageWasKit: true status: {} `, output) } diff --git a/pkg/controller/integrationkit/integrationkit_controller.go b/pkg/controller/integrationkit/integrationkit_controller.go index 6c3c217455..b1431fa3aa 100644 --- a/pkg/controller/integrationkit/integrationkit_controller.go +++ b/pkg/controller/integrationkit/integrationkit_controller.go @@ -237,7 +237,7 @@ func (r *reconcileIntegrationKit) Reconcile(ctx context.Context, request reconci if target.Status.Phase == v1.IntegrationKitPhaseNone || target.Status.Phase == v1.IntegrationKitPhaseWaitingForPlatform { rlog.Debug("Preparing to shift integration kit phase") - if target.IsExternal() { + if target.IsExternal() || target.IsSynthetic() { target.Status.Phase = v1.IntegrationKitPhaseInitialization return r.update(ctx, &instance, target) } diff --git a/pkg/resources/config/crd/bases/camel.apache.org_integrationplatforms.yaml b/pkg/resources/config/crd/bases/camel.apache.org_integrationplatforms.yaml index 9d04b2ad8a..12f95132a1 100644 --- a/pkg/resources/config/crd/bases/camel.apache.org_integrationplatforms.yaml +++ b/pkg/resources/config/crd/bases/camel.apache.org_integrationplatforms.yaml @@ -701,6 +701,10 @@ spec: - Never - IfNotPresent type: string + imageWasKit: + description: A flag to mark the image used is coming from + an IntegrationKit created externally. + type: boolean limitCPU: description: The maximum amount of CPU required. type: string @@ -2603,6 +2607,10 @@ spec: - Never - IfNotPresent type: string + imageWasKit: + description: A flag to mark the image used is coming from + an IntegrationKit created externally. + type: boolean limitCPU: description: The maximum amount of CPU required. type: string diff --git a/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml b/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml index 21e0c93340..c587cc5a61 100644 --- a/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml +++ b/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml @@ -578,6 +578,10 @@ spec: - Never - IfNotPresent type: string + imageWasKit: + description: A flag to mark the image used is coming from + an IntegrationKit created externally. + type: boolean limitCPU: description: The maximum amount of CPU required. type: string @@ -2363,6 +2367,10 @@ spec: - Never - IfNotPresent type: string + imageWasKit: + description: A flag to mark the image used is coming from + an IntegrationKit created externally. + type: boolean limitCPU: description: The maximum amount of CPU required. type: string diff --git a/pkg/resources/config/crd/bases/camel.apache.org_integrations.yaml b/pkg/resources/config/crd/bases/camel.apache.org_integrations.yaml index 48c5885ed3..0a4b17f327 100644 --- a/pkg/resources/config/crd/bases/camel.apache.org_integrations.yaml +++ b/pkg/resources/config/crd/bases/camel.apache.org_integrations.yaml @@ -6597,6 +6597,10 @@ spec: - Never - IfNotPresent type: string + imageWasKit: + description: A flag to mark the image used is coming from + an IntegrationKit created externally. + type: boolean limitCPU: description: The maximum amount of CPU required. type: string diff --git a/pkg/resources/config/crd/bases/camel.apache.org_kameletbindings.yaml b/pkg/resources/config/crd/bases/camel.apache.org_kameletbindings.yaml index d856f765f8..eb3476d637 100644 --- a/pkg/resources/config/crd/bases/camel.apache.org_kameletbindings.yaml +++ b/pkg/resources/config/crd/bases/camel.apache.org_kameletbindings.yaml @@ -6882,6 +6882,10 @@ spec: - Never - IfNotPresent type: string + imageWasKit: + description: A flag to mark the image used is coming from + an IntegrationKit created externally. + type: boolean limitCPU: description: The maximum amount of CPU required. type: string diff --git a/pkg/resources/config/crd/bases/camel.apache.org_pipes.yaml b/pkg/resources/config/crd/bases/camel.apache.org_pipes.yaml index 860e4c44bc..8b7e891f6a 100644 --- a/pkg/resources/config/crd/bases/camel.apache.org_pipes.yaml +++ b/pkg/resources/config/crd/bases/camel.apache.org_pipes.yaml @@ -6880,6 +6880,10 @@ spec: - Never - IfNotPresent type: string + imageWasKit: + description: A flag to mark the image used is coming from + an IntegrationKit created externally. + type: boolean limitCPU: description: The maximum amount of CPU required. type: string diff --git a/pkg/trait/container.go b/pkg/trait/container.go index 7d32a06d69..ecb5d160f2 100644 --- a/pkg/trait/container.go +++ b/pkg/trait/container.go @@ -137,12 +137,15 @@ func (t *containerTrait) configureImageIntegrationKit(e *Environment) error { // Add some information for post-processing, this may need to be refactored // to a proper data structure kit.Labels = map[string]string{ - v1.IntegrationKitTypeLabel: v1.IntegrationKitTypeExternal, + v1.IntegrationKitTypeLabel: v1.IntegrationKitTypeSynthetic, kubernetes.CamelCreatorLabelKind: v1.IntegrationKind, kubernetes.CamelCreatorLabelName: e.Integration.Name, kubernetes.CamelCreatorLabelNamespace: e.Integration.Namespace, kubernetes.CamelCreatorLabelVersion: e.Integration.ResourceVersion, } + if pointer.BoolDeref(t.ImageWasKit, false) { + kit.Labels[v1.IntegrationKitTypeLabel] = v1.IntegrationKitTypeExternal + } if v, ok := e.Integration.Annotations[v1.PlatformSelectorAnnotation]; ok { v1.SetAnnotation(&kit.ObjectMeta, v1.PlatformSelectorAnnotation, v) diff --git a/pkg/trait/jvm.go b/pkg/trait/jvm.go index c9e3b32645..858ac33e4d 100644 --- a/pkg/trait/jvm.go +++ b/pkg/trait/jvm.go @@ -70,12 +70,8 @@ func (t *jvmTrait) Configure(e *Environment) (bool, *TraitCondition, error) { } } - if e.IntegrationKit != nil && e.IntegrationKit.IsExternal() { - if pointer.BoolDeref(t.Enabled, false) { - return true, NewIntegrationConditionUserEnabledWithMessage("JVM", "integration kit was not created via Camel K operator"), nil - } else { - return false, newIntegrationConditionPlatformDisabledWithMessage("JVM", "integration kit was not created via Camel K operator"), nil - } + if e.IntegrationKit != nil && e.IntegrationKit.IsSynthetic() { + return false, newIntegrationConditionPlatformDisabledWithMessage("JVM", "integration kit was not created via Camel K operator"), nil } return true, nil, nil diff --git a/pkg/trait/jvm_test.go b/pkg/trait/jvm_test.go index b3f33f65d3..3e3906d135 100644 --- a/pkg/trait/jvm_test.go +++ b/pkg/trait/jvm_test.go @@ -95,7 +95,7 @@ func TestConfigureJvmTraitInWrongJvmDisabled(t *testing.T) { } func TestConfigureJvmTraitInWrongIntegrationKitPhaseExternal(t *testing.T) { - trait, environment := createNominalJvmTest(v1.IntegrationKitTypeExternal) + trait, environment := createNominalJvmTest(v1.IntegrationKitTypeSynthetic) expectedCondition := NewIntegrationCondition( "JVM", @@ -111,24 +111,6 @@ func TestConfigureJvmTraitInWrongIntegrationKitPhaseExternal(t *testing.T) { assert.Equal(t, expectedCondition, condition) } -func TestConfigureJvmTraitInRightIntegrationKitPhaseExternalAndJvmEnabled(t *testing.T) { - trait, environment := createNominalJvmTest(v1.IntegrationKitTypeExternal) - trait.Enabled = pointer.Bool(true) - - expectedCondition := NewIntegrationCondition( - "JVM", - v1.IntegrationConditionTraitInfo, - corev1.ConditionTrue, - "TraitConfiguration", - "explicitly enabled by the user: integration kit was not created via Camel K operator", - ) - configured, condition, err := trait.Configure(environment) - require.NoError(t, err) - assert.True(t, configured) - assert.NotNil(t, condition) - assert.Equal(t, expectedCondition, condition) -} - func TestApplyJvmTraitWithDeploymentResource(t *testing.T) { trait, environment := createNominalJvmTest(v1.IntegrationKitTypePlatform) diff --git a/pkg/trait/trait_condition_types.go b/pkg/trait/trait_condition_types.go index 906cf3b577..216993a27b 100644 --- a/pkg/trait/trait_condition_types.go +++ b/pkg/trait/trait_condition_types.go @@ -56,10 +56,6 @@ func NewIntegrationConditionUserDisabled(traitID string) *TraitCondition { return NewIntegrationCondition(traitID, v1.IntegrationConditionTraitInfo, corev1.ConditionTrue, traitConfigurationReason, userDisabledMessage) } -func NewIntegrationConditionUserEnabledWithMessage(traitID string, message string) *TraitCondition { - return NewIntegrationCondition(traitID, v1.IntegrationConditionTraitInfo, corev1.ConditionTrue, traitConfigurationReason, fmt.Sprintf("%s: %s", userEnabledMessage, message)) -} - func newIntegrationConditionPlatformDisabledWithMessage(traitID string, message string) *TraitCondition { return NewIntegrationCondition(traitID, v1.IntegrationConditionTraitInfo, corev1.ConditionTrue, traitConfigurationReason, fmt.Sprintf("%s: %s", platformDisabledMessage, message)) } From 1e701690e0071d996d2b999ebbe0ba5a4e06b440 Mon Sep 17 00:00:00 2001 From: Pasquale Congiusti Date: Wed, 17 Apr 2024 16:20:37 +0200 Subject: [PATCH 3/4] fix(trait): don't report runtime version... ... for external kit or syntetic Integrations. As a side effect, we had to introduce a further check to avoid leveraging a Camel catalog which was taken as default. Closes #5309 --- pkg/trait/camel.go | 15 ++++++++------- pkg/trait/camel_test.go | 29 +++++++++++++++++++++++++++++ pkg/trait/cron.go | 3 +++ pkg/trait/jvm.go | 3 +++ pkg/trait/logging.go | 4 +++- 5 files changed, 46 insertions(+), 8 deletions(-) diff --git a/pkg/trait/camel.go b/pkg/trait/camel.go index d774cfca2b..9f573c5036 100644 --- a/pkg/trait/camel.go +++ b/pkg/trait/camel.go @@ -63,6 +63,13 @@ func (t *camelTrait) Matches(trait Trait) bool { } func (t *camelTrait) Configure(e *Environment) (bool, *TraitCondition, error) { + if e.IntegrationKit != nil && e.IntegrationKit.IsExternal() { + return false, newIntegrationConditionPlatformDisabledWithMessage("Camel", "integration kit was not created via Camel K operator"), nil + } + if e.Integration != nil && e.Integration.IsSynthetic() { + return false, newIntegrationConditionPlatformDisabledWithMessage("Camel", "syntetic integration"), nil + } + if t.RuntimeVersion == "" { if runtimeVersion, err := determineRuntimeVersion(e); err != nil { return false, nil, err @@ -71,21 +78,15 @@ func (t *camelTrait) Configure(e *Environment) (bool, *TraitCondition, error) { } } - // Don't run this trait for a synthetic Integration - return e.Integration == nil || !e.Integration.IsSynthetic(), nil, nil + return true, nil, nil } func (t *camelTrait) Apply(e *Environment) error { - if t.RuntimeVersion == "" { - return errors.New("unable to determine runtime version") - } - if e.CamelCatalog == nil { if err := t.loadOrCreateCatalog(e, t.RuntimeVersion); err != nil { return err } } - e.RuntimeVersion = e.CamelCatalog.Runtime.Version if e.Integration != nil { diff --git a/pkg/trait/camel_test.go b/pkg/trait/camel_test.go index 5d5a13a4f5..2ca58645e3 100644 --- a/pkg/trait/camel_test.go +++ b/pkg/trait/camel_test.go @@ -246,3 +246,32 @@ func TestCamelCatalogSemver(t *testing.T) { // 2.x will translate with 2.16.0 as it is already existing assert.Equal(t, environment.CamelCatalog.CamelCatalogSpec.Runtime.Version, environment.RuntimeVersion) } + +func TestCamelTraitExternalKit(t *testing.T) { + trait, environment := createNominalCamelTest(true) + environment.Integration.Status = v1.IntegrationStatus{} + environment.IntegrationKit.Labels[v1.IntegrationKitTypeLabel] = v1.IntegrationKitTypeExternal + + configured, condition, err := trait.Configure(environment) + require.NoError(t, err) + assert.Equal(t, "explicitly disabled by the platform: integration kit was not created via Camel K operator", condition.message) + assert.False(t, configured) + + assert.Equal(t, v1.RuntimeProvider(""), environment.Integration.Status.RuntimeProvider) + assert.Equal(t, "", environment.Integration.Status.RuntimeVersion) +} + +func TestCamelTraitSyntheticIntegration(t *testing.T) { + trait, environment := createNominalCamelTest(true) + environment.Integration.Status = v1.IntegrationStatus{} + environment.Integration.Annotations = make(map[string]string) + environment.Integration.Annotations[v1.IntegrationSyntheticLabel] = "true" + + configured, condition, err := trait.Configure(environment) + require.NoError(t, err) + assert.Equal(t, "explicitly disabled by the platform: syntetic integration", condition.message) + assert.False(t, configured) + + assert.Equal(t, v1.RuntimeProvider(""), environment.Integration.Status.RuntimeProvider) + assert.Equal(t, "", environment.Integration.Status.RuntimeVersion) +} diff --git a/pkg/trait/cron.go b/pkg/trait/cron.go index adf04f0c3a..3e81c8ea2d 100644 --- a/pkg/trait/cron.go +++ b/pkg/trait/cron.go @@ -83,6 +83,9 @@ func (t *cronTrait) Configure(e *Environment) (bool, *TraitCondition, error) { if !e.IntegrationInPhase(v1.IntegrationPhaseInitialization) && !e.IntegrationInRunningPhases() { return false, nil, nil } + if e.CamelCatalog == nil { + return false, newIntegrationConditionPlatformDisabledWithMessage("Cron", "no camel catalog available for this Integration"), nil + } if _, ok := e.CamelCatalog.Runtime.Capabilities[v1.CapabilityCron]; !ok { return false, NewIntegrationCondition( diff --git a/pkg/trait/jvm.go b/pkg/trait/jvm.go index 858ac33e4d..a47e59f6f0 100644 --- a/pkg/trait/jvm.go +++ b/pkg/trait/jvm.go @@ -74,6 +74,9 @@ func (t *jvmTrait) Configure(e *Environment) (bool, *TraitCondition, error) { return false, newIntegrationConditionPlatformDisabledWithMessage("JVM", "integration kit was not created via Camel K operator"), nil } + if e.CamelCatalog == nil { + return false, newIntegrationConditionPlatformDisabledWithMessage("JVM", "no camel catalog available for this Integration"), nil + } return true, nil, nil } diff --git a/pkg/trait/logging.go b/pkg/trait/logging.go index 00d26369c5..1063e21e7e 100644 --- a/pkg/trait/logging.go +++ b/pkg/trait/logging.go @@ -52,10 +52,12 @@ func (l loggingTrait) Configure(e *Environment) (bool, *TraitCondition, error) { if e.Integration == nil { return false, nil, nil } - if !pointer.BoolDeref(l.Enabled, true) { return false, NewIntegrationConditionUserDisabled("Logging"), nil } + if e.CamelCatalog == nil { + return false, newIntegrationConditionPlatformDisabledWithMessage("Logging", "no camel catalog available for this Integration"), nil + } return e.IntegrationInRunningPhases(), nil, nil } From b3b45945e1b180b263e9d6b338b025b77b374bfb Mon Sep 17 00:00:00 2001 From: Pasquale Congiusti Date: Thu, 18 Apr 2024 15:37:40 +0200 Subject: [PATCH 4/4] chore(trait): disable traits requiring catalog when missing We must explicitly define which are the traits that can be executed and which can't because missing catalog. The catalog has sense only for the "managed" Integrations. --- addons/keda/keda.go | 4 ++- addons/master/master.go | 3 +++ addons/resume/resume.go | 3 +++ addons/telemetry/telemetry.go | 4 ++- addons/tracing/tracing.go | 42 ++++++++++++++---------------- pkg/trait/builder.go | 4 ++- pkg/trait/camel.go | 26 ++++++++++-------- pkg/trait/camel_test.go | 34 +++++++++++++----------- pkg/trait/container.go | 1 - pkg/trait/cron.go | 7 ++--- pkg/trait/dependencies.go | 4 ++- pkg/trait/dependencies_test.go | 8 ++++-- pkg/trait/error_handler.go | 4 ++- pkg/trait/error_handler_test.go | 14 +++++++--- pkg/trait/health.go | 3 +++ pkg/trait/jvm.go | 6 ++--- pkg/trait/kamelets.go | 3 +++ pkg/trait/knative.go | 3 +++ pkg/trait/knative_service.go | 4 +-- pkg/trait/logging.go | 2 +- pkg/trait/openapi.go | 4 ++- pkg/trait/quarkus.go | 3 +++ pkg/trait/service.go | 6 +++-- pkg/trait/service_binding.go | 3 +++ pkg/trait/trait_condition_types.go | 17 +++++++++++- 25 files changed, 138 insertions(+), 74 deletions(-) diff --git a/addons/keda/keda.go b/addons/keda/keda.go index ce4b56ab9a..184dbdb909 100644 --- a/addons/keda/keda.go +++ b/addons/keda/keda.go @@ -120,10 +120,12 @@ func (t *kedaTrait) Configure(e *trait.Environment) (bool, *trait.TraitCondition if e.Integration == nil || !pointer.BoolDeref(t.Enabled, false) { return false, nil, nil } + if e.CamelCatalog == nil { + return false, trait.NewIntegrationConditionPlatformDisabledCatalogMissing(), nil + } if !e.IntegrationInPhase(camelv1.IntegrationPhaseInitialization) && !e.IntegrationInRunningPhases() { return false, nil, nil } - if t.Auto == nil || *t.Auto { if err := t.populateTriggersFromKamelets(e); err != nil { return false, nil, err diff --git a/addons/master/master.go b/addons/master/master.go index 692bfb2c4d..deec026f18 100644 --- a/addons/master/master.go +++ b/addons/master/master.go @@ -92,6 +92,9 @@ func (t *masterTrait) Configure(e *trait.Environment) (bool, *trait.TraitConditi if !pointer.BoolDeref(t.Enabled, true) { return false, trait.NewIntegrationConditionUserDisabled(masterComponent), nil } + if e.CamelCatalog == nil { + return false, trait.NewIntegrationConditionPlatformDisabledCatalogMissing(), nil + } if !e.IntegrationInPhase(v1.IntegrationPhaseInitialization, v1.IntegrationPhaseBuildingKit) && !e.IntegrationInRunningPhases() { return false, nil, nil } diff --git a/addons/resume/resume.go b/addons/resume/resume.go index 221ae0364a..2f44d17018 100644 --- a/addons/resume/resume.go +++ b/addons/resume/resume.go @@ -79,6 +79,9 @@ func (r *resumeTrait) Configure(environment *trait.Environment) (bool, *trait.Tr if !pointer.BoolDeref(r.Enabled, false) { return false, nil, nil } + if environment.CamelCatalog == nil { + return false, trait.NewIntegrationConditionPlatformDisabledCatalogMissing(), nil + } if !environment.IntegrationInPhase(v1.IntegrationPhaseInitialization) && !environment.IntegrationInRunningPhases() { return false, nil, nil } diff --git a/addons/telemetry/telemetry.go b/addons/telemetry/telemetry.go index ec7f7c8581..d6363a868a 100644 --- a/addons/telemetry/telemetry.go +++ b/addons/telemetry/telemetry.go @@ -93,7 +93,9 @@ func (t *telemetryTrait) Configure(e *trait.Environment) (bool, *trait.TraitCond if e.Integration == nil || !pointer.BoolDeref(t.Enabled, false) { return false, nil, nil } - + if e.CamelCatalog == nil { + return false, trait.NewIntegrationConditionPlatformDisabledCatalogMissing(), nil + } var condition *trait.TraitCondition if pointer.BoolDeref(t.Auto, true) { if t.Endpoint == "" { diff --git a/addons/tracing/tracing.go b/addons/tracing/tracing.go index 0cf3852e09..52cb6684c7 100644 --- a/addons/tracing/tracing.go +++ b/addons/tracing/tracing.go @@ -90,6 +90,9 @@ func (t *tracingTrait) Configure(e *trait.Environment) (bool, *trait.TraitCondit if e.Integration == nil || !pointer.BoolDeref(t.Enabled, false) { return false, nil, nil } + if e.CamelCatalog == nil { + return false, trait.NewIntegrationConditionPlatformDisabledCatalogMissing(), nil + } if pointer.BoolDeref(t.Auto, true) { if t.Endpoint == "" { @@ -125,30 +128,23 @@ func (t *tracingTrait) Configure(e *trait.Environment) (bool, *trait.TraitCondit func (t *tracingTrait) Apply(e *trait.Environment) error { util.StringSliceUniqueAdd(&e.Integration.Status.Capabilities, v1.CapabilityTracing) - if e.CamelCatalog != nil { - provider := e.CamelCatalog.CamelCatalogSpec.Runtime.Provider - properties := tracingProperties[provider] - - if appPropEnabled := properties[propEnabled]; appPropEnabled != "" { - e.ApplicationProperties[appPropEnabled] = "true" - } - - if appPropEndpoint := properties[propEndpoint]; appPropEndpoint != "" && t.Endpoint != "" { - e.ApplicationProperties[appPropEndpoint] = t.Endpoint - } - - if appPropServiceName := properties[propServiceName]; appPropServiceName != "" && t.ServiceName != "" { - e.ApplicationProperties[appPropServiceName] = t.ServiceName - } - - if appPropSamplerType := properties[propSamplerType]; appPropSamplerType != "" && t.SamplerType != nil { - e.ApplicationProperties[appPropSamplerType] = *t.SamplerType - } - - if appPropSamplerParam := properties[propSamplerParam]; appPropSamplerParam != "" && t.SamplerParam != nil { - e.ApplicationProperties[appPropSamplerParam] = *t.SamplerParam - } + provider := e.CamelCatalog.CamelCatalogSpec.Runtime.Provider + properties := tracingProperties[provider] + if appPropEnabled := properties[propEnabled]; appPropEnabled != "" { + e.ApplicationProperties[appPropEnabled] = "true" + } + if appPropEndpoint := properties[propEndpoint]; appPropEndpoint != "" && t.Endpoint != "" { + e.ApplicationProperties[appPropEndpoint] = t.Endpoint + } + if appPropServiceName := properties[propServiceName]; appPropServiceName != "" && t.ServiceName != "" { + e.ApplicationProperties[appPropServiceName] = t.ServiceName + } + if appPropSamplerType := properties[propSamplerType]; appPropSamplerType != "" && t.SamplerType != nil { + e.ApplicationProperties[appPropSamplerType] = *t.SamplerType + } + if appPropSamplerParam := properties[propSamplerParam]; appPropSamplerParam != "" && t.SamplerParam != nil { + e.ApplicationProperties[appPropSamplerParam] = *t.SamplerParam } return nil diff --git a/pkg/trait/builder.go b/pkg/trait/builder.go index e4422eedf3..d3c20dc083 100644 --- a/pkg/trait/builder.go +++ b/pkg/trait/builder.go @@ -90,7 +90,9 @@ func (t *builderTrait) Configure(e *Environment) (bool, *TraitCondition, error) if e.IntegrationKit == nil { return false, nil, nil } - + if e.CamelCatalog == nil { + return false, NewIntegrationConditionPlatformDisabledCatalogMissing(), nil + } condition := t.adaptDeprecatedFields() t.setPlatform(e) diff --git a/pkg/trait/camel.go b/pkg/trait/camel.go index 9f573c5036..46a7ef2d39 100644 --- a/pkg/trait/camel.go +++ b/pkg/trait/camel.go @@ -63,11 +63,8 @@ func (t *camelTrait) Matches(trait Trait) bool { } func (t *camelTrait) Configure(e *Environment) (bool, *TraitCondition, error) { - if e.IntegrationKit != nil && e.IntegrationKit.IsExternal() { - return false, newIntegrationConditionPlatformDisabledWithMessage("Camel", "integration kit was not created via Camel K operator"), nil - } if e.Integration != nil && e.Integration.IsSynthetic() { - return false, newIntegrationConditionPlatformDisabledWithMessage("Camel", "syntetic integration"), nil + return false, NewIntegrationConditionPlatformDisabledWithMessage("Camel", "synthetic integration"), nil } if t.RuntimeVersion == "" { @@ -82,13 +79,26 @@ func (t *camelTrait) Configure(e *Environment) (bool, *TraitCondition, error) { } func (t *camelTrait) Apply(e *Environment) error { + if e.IntegrationKitInPhase(v1.IntegrationKitPhaseReady) && e.IntegrationInRunningPhases() { + // Get all resources + maps := t.computeConfigMaps(e) + e.Resources.AddAll(maps) + } + if e.IntegrationKit != nil && e.IntegrationKit.IsSynthetic() { + // This is required as during init phase, the trait set by default these values + // which are widely used in the platform for different purposese. + if e.Integration != nil { + e.Integration.Status.RuntimeVersion = "" + e.Integration.Status.RuntimeProvider = "" + } + return nil + } if e.CamelCatalog == nil { if err := t.loadOrCreateCatalog(e, t.RuntimeVersion); err != nil { return err } } e.RuntimeVersion = e.CamelCatalog.Runtime.Version - if e.Integration != nil { e.Integration.Status.RuntimeVersion = e.CamelCatalog.Runtime.Version e.Integration.Status.RuntimeProvider = e.CamelCatalog.Runtime.Provider @@ -98,12 +108,6 @@ func (t *camelTrait) Apply(e *Environment) error { e.IntegrationKit.Status.RuntimeProvider = e.CamelCatalog.Runtime.Provider } - if e.IntegrationKitInPhase(v1.IntegrationKitPhaseReady) && e.IntegrationInRunningPhases() { - // Get all resources - maps := t.computeConfigMaps(e) - e.Resources.AddAll(maps) - } - return nil } diff --git a/pkg/trait/camel_test.go b/pkg/trait/camel_test.go index 2ca58645e3..175f154c35 100644 --- a/pkg/trait/camel_test.go +++ b/pkg/trait/camel_test.go @@ -45,6 +45,7 @@ func TestConfigureEnabledCamelTraitSucceeds(t *testing.T) { func TestApplyCamelTraitSucceeds(t *testing.T) { trait, environment := createNominalCamelTest(false) + environment.Integration.Status.Phase = v1.IntegrationPhaseBuildingKit configured, condition, err := trait.Configure(environment) require.NoError(t, err) @@ -63,6 +64,22 @@ func TestApplyCamelTraitSucceeds(t *testing.T) { assert.False(t, exactVersionRegexp.MatchString("wroong")) } +func TestApplyCamelTraitExternalKit(t *testing.T) { + trait, environment := createNominalCamelTest(false) + environment.IntegrationKit.Labels[v1.IntegrationKitTypeLabel] = v1.IntegrationKitTypeSynthetic + + configured, condition, err := trait.Configure(environment) + require.NoError(t, err) + assert.Nil(t, condition) + assert.True(t, configured) + err = trait.Apply(environment) + require.NoError(t, err) + assert.Equal(t, "", environment.Integration.Status.RuntimeVersion) + assert.Equal(t, v1.RuntimeProvider(""), environment.Integration.Status.RuntimeProvider) + assert.Equal(t, "", environment.IntegrationKit.Status.RuntimeVersion) + assert.Equal(t, v1.RuntimeProvider(""), environment.Integration.Status.RuntimeProvider) +} + func TestApplyCamelTraitWithoutEnvironmentCatalogAndUnmatchableVersionFails(t *testing.T) { trait, environment := createNominalCamelTest(false) environment.CamelCatalog = nil @@ -233,6 +250,7 @@ func TestCamelMatches(t *testing.T) { func TestCamelCatalogSemver(t *testing.T) { trait, environment := createNominalCamelTest(true) + environment.Integration.Status.Phase = v1.IntegrationPhaseBuildingKit trait.RuntimeVersion = "2.x" environment.CamelCatalog.CamelCatalogSpec.Runtime.Version = "2.16.0" @@ -247,20 +265,6 @@ func TestCamelCatalogSemver(t *testing.T) { assert.Equal(t, environment.CamelCatalog.CamelCatalogSpec.Runtime.Version, environment.RuntimeVersion) } -func TestCamelTraitExternalKit(t *testing.T) { - trait, environment := createNominalCamelTest(true) - environment.Integration.Status = v1.IntegrationStatus{} - environment.IntegrationKit.Labels[v1.IntegrationKitTypeLabel] = v1.IntegrationKitTypeExternal - - configured, condition, err := trait.Configure(environment) - require.NoError(t, err) - assert.Equal(t, "explicitly disabled by the platform: integration kit was not created via Camel K operator", condition.message) - assert.False(t, configured) - - assert.Equal(t, v1.RuntimeProvider(""), environment.Integration.Status.RuntimeProvider) - assert.Equal(t, "", environment.Integration.Status.RuntimeVersion) -} - func TestCamelTraitSyntheticIntegration(t *testing.T) { trait, environment := createNominalCamelTest(true) environment.Integration.Status = v1.IntegrationStatus{} @@ -269,7 +273,7 @@ func TestCamelTraitSyntheticIntegration(t *testing.T) { configured, condition, err := trait.Configure(environment) require.NoError(t, err) - assert.Equal(t, "explicitly disabled by the platform: syntetic integration", condition.message) + assert.Equal(t, "explicitly disabled by the platform: synthetic integration", condition.message) assert.False(t, configured) assert.Equal(t, v1.RuntimeProvider(""), environment.Integration.Status.RuntimeProvider) diff --git a/pkg/trait/container.go b/pkg/trait/container.go index ecb5d160f2..19ab28ee59 100644 --- a/pkg/trait/container.go +++ b/pkg/trait/container.go @@ -168,7 +168,6 @@ func (t *containerTrait) configureImageIntegrationKit(e *Environment) error { kit.SetOperatorID(operatorID) } - t.L.Infof("image %s", kit.Spec.Image) e.Resources.Add(kit) e.Integration.SetIntegrationKit(kit) } diff --git a/pkg/trait/cron.go b/pkg/trait/cron.go index 3e81c8ea2d..67bbd7efb5 100644 --- a/pkg/trait/cron.go +++ b/pkg/trait/cron.go @@ -84,9 +84,8 @@ func (t *cronTrait) Configure(e *Environment) (bool, *TraitCondition, error) { return false, nil, nil } if e.CamelCatalog == nil { - return false, newIntegrationConditionPlatformDisabledWithMessage("Cron", "no camel catalog available for this Integration"), nil + return false, NewIntegrationConditionPlatformDisabledCatalogMissing(), nil } - if _, ok := e.CamelCatalog.Runtime.Capabilities[v1.CapabilityCron]; !ok { return false, NewIntegrationCondition( "Cron", @@ -96,7 +95,6 @@ func (t *cronTrait) Configure(e *Environment) (bool, *TraitCondition, error) { "the runtime provider %s does not declare 'cron' capability", ), nil } - if pointer.BoolDeref(t.Auto, true) { globalCron, err := t.getGlobalCron(e) if err != nil { @@ -309,6 +307,9 @@ func (c *cronInfo) withSchedule(schedule string) *cronInfo { } func (t *cronTrait) getGlobalCron(e *Environment) (*cronInfo, error) { + if e.CamelCatalog == nil { + return nil, nil + } fromURIs, err := t.getSourcesFromURIs(e) if err != nil { return nil, err diff --git a/pkg/trait/dependencies.go b/pkg/trait/dependencies.go index e8d6e5d0f7..b2dc4b7f9e 100644 --- a/pkg/trait/dependencies.go +++ b/pkg/trait/dependencies.go @@ -42,7 +42,9 @@ func (t *dependenciesTrait) Configure(e *Environment) (bool, *TraitCondition, er if e.Integration == nil { return false, nil, nil } - + if e.CamelCatalog == nil { + return false, NewIntegrationConditionPlatformDisabledCatalogMissing(), nil + } return e.IntegrationInPhase(v1.IntegrationPhaseInitialization), nil, nil } diff --git a/pkg/trait/dependencies_test.go b/pkg/trait/dependencies_test.go index bda3b785d0..e3d4aeebae 100644 --- a/pkg/trait/dependencies_test.go +++ b/pkg/trait/dependencies_test.go @@ -28,9 +28,13 @@ import ( ) func TestDependenciesTraitApplicability(t *testing.T) { + catalog, err := camel.DefaultCatalog() + require.NoError(t, err) + e := &Environment{ - Catalog: NewEnvironmentTestCatalog(), - Integration: &v1.Integration{}, + CamelCatalog: catalog, + Catalog: NewEnvironmentTestCatalog(), + Integration: &v1.Integration{}, } trait := newDependenciesTrait() diff --git a/pkg/trait/error_handler.go b/pkg/trait/error_handler.go index c37388e69b..829304073d 100644 --- a/pkg/trait/error_handler.go +++ b/pkg/trait/error_handler.go @@ -44,11 +44,13 @@ func (t *errorHandlerTrait) Configure(e *Environment) (bool, *TraitCondition, er if e.Integration == nil { return false, nil, nil } + if e.CamelCatalog == nil { + return false, NewIntegrationConditionPlatformDisabledCatalogMissing(), nil + } if !e.IntegrationInPhase(v1.IntegrationPhaseInitialization) && !e.IntegrationInRunningPhases() { return false, nil, nil } - if t.ErrorHandlerRef == "" { t.ErrorHandlerRef = e.Integration.Spec.GetConfigurationProperty(v1.ErrorHandlerRefName) } diff --git a/pkg/trait/error_handler_test.go b/pkg/trait/error_handler_test.go index d5579aa957..4f6ed61687 100644 --- a/pkg/trait/error_handler_test.go +++ b/pkg/trait/error_handler_test.go @@ -29,9 +29,12 @@ import ( ) func TestErrorHandlerConfigureFromIntegrationProperty(t *testing.T) { + catalog, err := camel.DefaultCatalog() + require.NoError(t, err) e := &Environment{ - Catalog: NewEnvironmentTestCatalog(), - Integration: &v1.Integration{}, + CamelCatalog: catalog, + Catalog: NewEnvironmentTestCatalog(), + Integration: &v1.Integration{}, } e.Integration.Spec.AddConfigurationProperty(fmt.Sprintf("%v = %s", v1.ErrorHandlerRefName, "defaultErrorHandler")) @@ -56,9 +59,12 @@ func TestErrorHandlerConfigureFromIntegrationProperty(t *testing.T) { } func TestErrorHandlerApplySource(t *testing.T) { + catalog, err := camel.DefaultCatalog() + require.NoError(t, err) e := &Environment{ - Catalog: NewEnvironmentTestCatalog(), - Integration: &v1.Integration{}, + CamelCatalog: catalog, + Catalog: NewEnvironmentTestCatalog(), + Integration: &v1.Integration{}, } e.Integration.Spec.AddConfiguration("property", fmt.Sprintf("%v = %s", v1.ErrorHandlerRefName, "defaultErrorHandler")) e.Integration.Status.Phase = v1.IntegrationPhaseInitialization diff --git a/pkg/trait/health.go b/pkg/trait/health.go index c01c5cb317..a214b71447 100644 --- a/pkg/trait/health.go +++ b/pkg/trait/health.go @@ -53,6 +53,9 @@ func newHealthTrait() Trait { } func (t *healthTrait) Configure(e *Environment) (bool, *TraitCondition, error) { + if e.CamelCatalog == nil { + return false, NewIntegrationConditionPlatformDisabledCatalogMissing(), nil + } if e.Integration == nil || !e.IntegrationInPhase(v1.IntegrationPhaseInitialization) && !e.IntegrationInRunningPhases() { return false, nil, nil diff --git a/pkg/trait/jvm.go b/pkg/trait/jvm.go index a47e59f6f0..57a59081aa 100644 --- a/pkg/trait/jvm.go +++ b/pkg/trait/jvm.go @@ -66,16 +66,16 @@ func (t *jvmTrait) Configure(e *Environment) (bool, *TraitCondition, error) { // The JVM trait must be disabled in case the current IntegrationKit corresponds to a native build if qt := e.Catalog.GetTrait(quarkusTraitID); qt != nil { if quarkus, ok := qt.(*quarkusTrait); ok && quarkus.isNativeIntegration(e) { - return false, newIntegrationConditionPlatformDisabledWithMessage("JVM", "quarkus native build"), nil + return false, NewIntegrationConditionPlatformDisabledWithMessage("JVM", "quarkus native build"), nil } } if e.IntegrationKit != nil && e.IntegrationKit.IsSynthetic() { - return false, newIntegrationConditionPlatformDisabledWithMessage("JVM", "integration kit was not created via Camel K operator"), nil + return false, NewIntegrationConditionPlatformDisabledWithMessage("JVM", "integration kit was not created via Camel K operator"), nil } if e.CamelCatalog == nil { - return false, newIntegrationConditionPlatformDisabledWithMessage("JVM", "no camel catalog available for this Integration"), nil + return false, NewIntegrationConditionPlatformDisabledCatalogMissing(), nil } return true, nil, nil } diff --git a/pkg/trait/kamelets.go b/pkg/trait/kamelets.go index 280501848b..77df3baf2c 100644 --- a/pkg/trait/kamelets.go +++ b/pkg/trait/kamelets.go @@ -79,6 +79,9 @@ func (t *kameletsTrait) Configure(e *Environment) (bool, *TraitCondition, error) if !pointer.BoolDeref(t.Enabled, true) { return false, NewIntegrationConditionUserDisabled("Kamelets"), nil } + if e.CamelCatalog == nil { + return false, NewIntegrationConditionPlatformDisabledCatalogMissing(), nil + } if !e.IntegrationInPhase(v1.IntegrationPhaseInitialization) && !e.IntegrationInRunningPhases() { return false, nil, nil } diff --git a/pkg/trait/knative.go b/pkg/trait/knative.go index 30063f98a0..3328ec6501 100644 --- a/pkg/trait/knative.go +++ b/pkg/trait/knative.go @@ -73,6 +73,9 @@ func (t *knativeTrait) Configure(e *Environment) (bool, *TraitCondition, error) if !pointer.BoolDeref(t.Enabled, true) { return false, NewIntegrationConditionUserDisabled("Knative"), nil } + if e.CamelCatalog == nil { + return false, NewIntegrationConditionPlatformDisabledCatalogMissing(), nil + } if !e.IntegrationInPhase(v1.IntegrationPhaseInitialization) && !e.IntegrationInRunningPhases() { return false, nil, nil } diff --git a/pkg/trait/knative_service.go b/pkg/trait/knative_service.go index e8baaf7d61..a8e53a779e 100644 --- a/pkg/trait/knative_service.go +++ b/pkg/trait/knative_service.go @@ -144,8 +144,8 @@ func (t *knativeServiceTrait) Apply(e *Environment) error { } func (t *knativeServiceTrait) SelectControllerStrategy(e *Environment) (*ControllerStrategy, error) { - if !pointer.BoolDeref(t.Enabled, true) { - // explicitly disabled + if !pointer.BoolDeref(t.Enabled, true) || e.CamelCatalog == nil { + // explicitly disabled or sourceless Integration (missing catalog) return nil, nil } diff --git a/pkg/trait/logging.go b/pkg/trait/logging.go index 1063e21e7e..aaea69eeeb 100644 --- a/pkg/trait/logging.go +++ b/pkg/trait/logging.go @@ -56,7 +56,7 @@ func (l loggingTrait) Configure(e *Environment) (bool, *TraitCondition, error) { return false, NewIntegrationConditionUserDisabled("Logging"), nil } if e.CamelCatalog == nil { - return false, newIntegrationConditionPlatformDisabledWithMessage("Logging", "no camel catalog available for this Integration"), nil + return false, NewIntegrationConditionPlatformDisabledCatalogMissing(), nil } return e.IntegrationInRunningPhases(), nil, nil diff --git a/pkg/trait/openapi.go b/pkg/trait/openapi.go index 1cbc5fe967..1157b80a6c 100644 --- a/pkg/trait/openapi.go +++ b/pkg/trait/openapi.go @@ -59,7 +59,9 @@ func (t *openAPITrait) Configure(e *Environment) (bool, *TraitCondition, error) if !e.IntegrationInPhase(v1.IntegrationPhaseInitialization) { return false, nil, nil } - + if e.CamelCatalog == nil { + return false, NewIntegrationConditionPlatformDisabledCatalogMissing(), nil + } // check if the runtime provides 'rest' capabilities if _, ok := e.CamelCatalog.Runtime.Capabilities[v1.CapabilityRest]; !ok { return false, nil, fmt.Errorf("the runtime provider %s does not declare 'rest' capability", e.CamelCatalog.Runtime.Provider) diff --git a/pkg/trait/quarkus.go b/pkg/trait/quarkus.go index 1140029bee..28b44a382c 100644 --- a/pkg/trait/quarkus.go +++ b/pkg/trait/quarkus.go @@ -140,6 +140,9 @@ func (t *quarkusTrait) Matches(trait Trait) bool { } func (t *quarkusTrait) Configure(e *Environment) (bool, *TraitCondition, error) { + if e.CamelCatalog == nil { + return false, NewIntegrationConditionPlatformDisabledCatalogMissing(), nil + } condition := t.adaptDeprecatedFields() return e.IntegrationInPhase(v1.IntegrationPhaseBuildingKit) || diff --git a/pkg/trait/service.go b/pkg/trait/service.go index b2e081ab2b..5151336582 100644 --- a/pkg/trait/service.go +++ b/pkg/trait/service.go @@ -56,13 +56,15 @@ func (t *serviceTrait) Configure(e *Environment) (bool, *TraitCondition, error) "explicitly disabled", ), nil } - + if e.CamelCatalog == nil { + return false, NewIntegrationConditionPlatformDisabledCatalogMissing(), nil + } // in case the knative-service and service trait are enabled, the knative-service has priority // then this service is disabled if e.GetTrait(knativeServiceTraitID) != nil { knativeServiceTrait, _ := e.GetTrait(knativeServiceTraitID).(*knativeServiceTrait) if pointer.BoolDeref(knativeServiceTrait.Enabled, true) { - return false, newIntegrationConditionPlatformDisabledWithMessage("Service", "knative-service trait has priority over this trait"), nil + return false, NewIntegrationConditionPlatformDisabledWithMessage("Service", "knative-service trait has priority over this trait"), nil } } diff --git a/pkg/trait/service_binding.go b/pkg/trait/service_binding.go index 867c8b4c21..2ed176670a 100644 --- a/pkg/trait/service_binding.go +++ b/pkg/trait/service_binding.go @@ -70,6 +70,9 @@ func (t *serviceBindingTrait) Configure(e *Environment) (bool, *TraitCondition, if !pointer.BoolDeref(t.Enabled, true) { return false, NewIntegrationConditionUserDisabled("ServiceBinding"), nil } + if e.CamelCatalog == nil { + return false, NewIntegrationConditionPlatformDisabledCatalogMissing(), nil + } if len(t.Services) == 0 { return false, nil, nil } diff --git a/pkg/trait/trait_condition_types.go b/pkg/trait/trait_condition_types.go index 216993a27b..86abc5ea2d 100644 --- a/pkg/trait/trait_condition_types.go +++ b/pkg/trait/trait_condition_types.go @@ -56,10 +56,25 @@ func NewIntegrationConditionUserDisabled(traitID string) *TraitCondition { return NewIntegrationCondition(traitID, v1.IntegrationConditionTraitInfo, corev1.ConditionTrue, traitConfigurationReason, userDisabledMessage) } -func newIntegrationConditionPlatformDisabledWithMessage(traitID string, message string) *TraitCondition { +func NewIntegrationConditionUserEnabledWithMessage(traitID string, message string) *TraitCondition { + return NewIntegrationCondition(traitID, v1.IntegrationConditionTraitInfo, corev1.ConditionTrue, traitConfigurationReason, fmt.Sprintf("%s: %s", userEnabledMessage, message)) +} + +func NewIntegrationConditionPlatformDisabledWithMessage(traitID string, message string) *TraitCondition { return NewIntegrationCondition(traitID, v1.IntegrationConditionTraitInfo, corev1.ConditionTrue, traitConfigurationReason, fmt.Sprintf("%s: %s", platformDisabledMessage, message)) } +// This one is reused among different traits in order to avoid polluting the conditions with the same message. +func NewIntegrationConditionPlatformDisabledCatalogMissing() *TraitCondition { + return NewIntegrationCondition( + "Generic", + v1.IntegrationConditionTraitInfo, + corev1.ConditionTrue, + traitConfigurationReason, + "no camel catalog available for this Integration. Several traits have not been executed for this reason. Check applied trait condition to know more.", + ) +} + func (tc *TraitCondition) integrationCondition() (v1.IntegrationConditionType, corev1.ConditionStatus, string, string) { return v1.IntegrationConditionType(fmt.Sprintf("%s%s", tc.traitID, tc.integrationConditionType)), tc.conditionStatus,